./PaxHeaders.9031/glusterfs-11.10000644000000000000000000000013114522202525014441 xustar000000000000000030 mtime=1699284309.266158751 29 atime=1699284309.68416001 30 ctime=1699284309.266158751 glusterfs-11.1/0002775000175100017510000000000014522202525014643 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/PaxHeaders.9031/xlators0000644000000000000000000000013114522202522015775 xustar000000000000000030 mtime=1699284306.902151631 29 atime=1699284309.68416001 30 ctime=1699284306.902151631 glusterfs-11.1/xlators/0002775000175100017510000000000014522202522016334 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/PaxHeaders.9031/playground0000644000000000000000000000013114522202522020161 xustar000000000000000030 mtime=1699284306.828151408 29 atime=1699284309.68416001 30 ctime=1699284306.828151408 glusterfs-11.1/xlators/playground/0002775000175100017510000000000014522202522020520 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/playground/PaxHeaders.9031/template0000644000000000000000000000013114522202522021774 xustar000000000000000030 mtime=1699284306.861151507 29 atime=1699284309.68416001 30 ctime=1699284306.861151507 glusterfs-11.1/xlators/playground/template/0002775000175100017510000000000014522202522022333 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/playground/template/PaxHeaders.9031/src0000644000000000000000000000013114522202522022563 xustar000000000000000030 mtime=1699284306.898151619 29 atime=1699284309.68416001 30 ctime=1699284306.898151619 glusterfs-11.1/xlators/playground/template/src/0002775000175100017510000000000014522202522023122 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/playground/template/src/PaxHeaders.9031/template.c0000644000000000000000000000013214522202451024621 xustar000000000000000030 mtime=1699284265.769027739 30 atime=1699284265.769027739 30 ctime=1699284306.898151619 glusterfs-11.1/xlators/playground/template/src/template.c0000664000175100017510000001052314522202451025101 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "template.h" #include static int32_t template_mem_acct_init(xlator_t *this) { int ret = -1; GF_VALIDATE_OR_GOTO("template", this, out); ret = xlator_mem_acct_init(this, gf_template_mt_end); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, TEMPLATE_MSG_NO_MEMORY, "Memory accounting init failed"); goto out; } ret = 0; out: return ret; } static int32_t template_priv_to_dict(xlator_t *this, dict_t *dict, char *brickname) { int ret = 0; template_private_t *priv = NULL; priv = this->private; ret = dict_set_uint64(dict, "template.dummy", priv->dummy); if (ret) gf_msg_debug(this->name, ENOMEM, "dict_set of dummy key failed"); return 0; } static int32_t template_priv(xlator_t *this) { template_private_t *priv = NULL; priv = this->private; gf_proc_dump_write("template.dummy", "%" PRId32, priv->dummy); return 0; } static int32_t template_dump_metrics(xlator_t *this, int fd) { template_private_t *priv = NULL; priv = this->private; /* NOTE: currently this is adding private variable, which can be constant here. But in reality, things which are changing can be added here, so we get to plot them on graph. */ dprintf(fd, "%s.private.dummy %d\n", this->name, priv->dummy); return 0; } static int32_t template_init(xlator_t *this) { int ret = -1; template_private_t *priv = NULL; if (!this->children || this->children->next) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, TEMPLATE_MSG_NO_GRAPH, "not configured with exactly one child. exiting"); goto out; } if (!this->parents) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, TEMPLATE_MSG_NO_GRAPH, "dangling volume. check volfile "); goto out; } priv = GF_CALLOC(1, sizeof(template_private_t), gf_template_mt_private_t); if (!priv) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, TEMPLATE_MSG_NO_MEMORY, "priv allocation failed"); goto out; } GF_OPTION_INIT("dummy", priv->dummy, int32, out); this->private = priv; priv = NULL; ret = 0; out: if (priv) GF_FREE(priv); return ret; } static int template_reconfigure(xlator_t *this, dict_t *options) { int ret = -1; template_private_t *priv = NULL; priv = this->private; GF_OPTION_RECONF("dummy", priv->dummy, options, int32, out); ret = 0; out: return ret; } static void template_fini(xlator_t *this) { template_private_t *priv = NULL; priv = this->private; this->private = NULL; GF_FREE(priv); } static int template_notify(xlator_t *this, int32_t event, void *data, ...) { switch (event) { default: default_notify(this, event, data); gf_msg_debug(this->name, 0, "event %d received", event); } return 0; } struct xlator_fops template_fops = {}; struct xlator_cbks template_cbks = {}; struct xlator_dumpops template_dumpops = { .priv = template_priv, .priv_to_dict = template_priv_to_dict, }; struct volume_options template_options[] = { { .key = {"dummy"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 1024, .default_value = "1", .description = "a dummy option to show how to set the option", .op_version = {GD_OP_VERSION_5_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .level = OPT_STATUS_EXPERIMENTAL, .tags = {"development", "experimental", "template"}, }, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = template_init, .fini = template_fini, .notify = template_notify, .reconfigure = template_reconfigure, .mem_acct_init = template_mem_acct_init, .dump_metrics = template_dump_metrics, .op_version = {GD_OP_VERSION_5_0}, .dumpops = &template_dumpops, .fops = &template_fops, .cbks = &template_cbks, .options = template_options, .identifier = "template", }; glusterfs-11.1/xlators/playground/template/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467024716 xustar000000000000000030 mtime=1699284279.211068227 30 atime=1699284291.444105072 30 ctime=1699284306.894151607 glusterfs-11.1/xlators/playground/template/src/Makefile.in0000664000175100017510000005731014522202467025203 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/playground/template/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) template_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_template_la_OBJECTS = template.lo template_la_OBJECTS = $(am_template_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = template_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(template_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(template_la_SOURCES) DIST_SOURCES = $(template_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = template.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/playground template_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) template_la_SOURCES = template.c template_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = template.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/playground/template/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/playground/template/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } template.la: $(template_la_OBJECTS) $(template_la_DEPENDENCIES) $(EXTRA_template_la_DEPENDENCIES) $(AM_V_CCLD)$(template_la_LINK) -rpath $(xlatordir) $(template_la_OBJECTS) $(template_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/template.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/playground/template/src/PaxHeaders.9031/template.h0000644000000000000000000000013214522202451024626 xustar000000000000000030 mtime=1699284265.770027742 30 atime=1699284265.770027742 30 ctime=1699284306.897151616 glusterfs-11.1/xlators/playground/template/src/template.h0000664000175100017510000000236614522202451025114 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013-2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __TEMPLATE_H__ #define __TEMPLATE_H__ #include #include #include #include #include struct template_private { /* Add all the relevant fields you need here */ int32_t dummy; }; typedef struct template_private template_private_t; /* Below section goes to template-mem-types.h */ #include enum gf_template_mem_types_ { gf_template_mt_private_t = gf_common_mt_end + 1, gf_template_mt_end, }; /* This normally goes to another file 'template-messages.h", required for 'gf_msg()'. NOTE: make sure you have added your component (in this case, TEMPLATE) in `libglusterfs/src/glfs-message-id.h`. */ #include GLFS_MSGID(TEMPLATE, TEMPLATE_MSG_NO_MEMORY, TEMPLATE_MSG_NO_GRAPH); #endif /* __TEMPLATE_H__ */ glusterfs-11.1/xlators/playground/template/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024676 xustar000000000000000030 mtime=1699284265.769027739 30 atime=1699284279.172068109 30 ctime=1699284306.896151612 glusterfs-11.1/xlators/playground/template/src/Makefile.am0000664000175100017510000000072214522202451025156 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = template.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/playground template_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) template_la_SOURCES = template.c template_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = template.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/playground/template/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467024127 xustar000000000000000030 mtime=1699284279.162068079 30 atime=1699284291.423105009 30 ctime=1699284306.856151492 glusterfs-11.1/xlators/playground/template/Makefile.in0000664000175100017510000005264114522202467024416 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/playground/template DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/playground/template/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/playground/template/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/playground/template/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024107 xustar000000000000000030 mtime=1699284265.769027739 30 atime=1699284279.138068007 30 ctime=1699284306.858151498 glusterfs-11.1/xlators/playground/template/Makefile.am0000664000175100017510000000001714522202451024364 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/playground/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467022314 xustar000000000000000030 mtime=1699284279.127067974 30 atime=1699284291.402104946 30 ctime=1699284306.823151393 glusterfs-11.1/xlators/playground/Makefile.in0000664000175100017510000005271214522202467022602 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/playground DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = template CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/playground/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/playground/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/playground/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451022274 xustar000000000000000030 mtime=1699284265.768027736 30 atime=1699284279.103067902 30 ctime=1699284306.824151396 glusterfs-11.1/xlators/playground/Makefile.am0000664000175100017510000000004014522202451022545 0ustar00jenkinsjenkins00000000000000SUBDIRS = template CLEANFILES = glusterfs-11.1/xlators/PaxHeaders.9031/meta0000644000000000000000000000013114522202522016723 xustar000000000000000030 mtime=1699284306.939151742 29 atime=1699284309.68416001 30 ctime=1699284306.939151742 glusterfs-11.1/xlators/meta/0002775000175100017510000000000014522202522017262 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/meta/PaxHeaders.9031/src0000644000000000000000000000013114522202523017513 xustar000000000000000030 mtime=1699284307.026152004 29 atime=1699284309.68416001 30 ctime=1699284307.026152004 glusterfs-11.1/xlators/meta/src/0002775000175100017510000000000014522202523020052 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/mallinfo-file.c0000644000000000000000000000013214522202451022453 xustar000000000000000030 mtime=1699284265.702027537 30 atime=1699284265.701027534 30 ctime=1699284307.022151992 glusterfs-11.1/xlators/meta/src/mallinfo-file.c0000664000175100017510000000160114522202451022730 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include static int mallinfo_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { gf_proc_dump_mallinfo(strfd); return strfd->size; } static struct meta_ops mallinfo_file_ops = { .file_fill = mallinfo_file_fill, }; int meta_mallinfo_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &mallinfo_file_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/loglevel-file.c0000644000000000000000000000013214522202451022463 xustar000000000000000030 mtime=1699284265.701027534 30 atime=1699284265.701027534 30 ctime=1699284307.003151935 glusterfs-11.1/xlators/meta/src/loglevel-file.c0000664000175100017510000000235014522202451022742 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include static int loglevel_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { strprintf(strfd, "%d\n", this->ctx->log.loglevel); return strfd->size; } static int loglevel_file_write(xlator_t *this, fd_t *fd, struct iovec *iov, int count) { long int level = -1; level = strtol(iov[0].iov_base, NULL, 0); if (level >= GF_LOG_NONE && level <= GF_LOG_TRACE) gf_log_set_loglevel(this->ctx, level); return iov_length(iov, count); } static struct meta_ops loglevel_file_ops = { .file_fill = loglevel_file_fill, .file_write = loglevel_file_write, }; int meta_loglevel_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &loglevel_file_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/measure-file.c0000644000000000000000000000013214522202451022313 xustar000000000000000030 mtime=1699284265.702027537 30 atime=1699284265.702027537 30 ctime=1699284307.025152001 glusterfs-11.1/xlators/meta/src/measure-file.c0000664000175100017510000000224114522202451022571 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include static int measure_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { strprintf(strfd, "%d\n", this->ctx->measure_latency); return strfd->size; } static int measure_file_write(xlator_t *this, fd_t *fd, struct iovec *iov, int count) { long int num = -1; num = strtol(iov[0].iov_base, NULL, 0); this->ctx->measure_latency = !!num; return iov_length(iov, count); } static struct meta_ops measure_file_ops = { .file_fill = measure_file_fill, .file_write = measure_file_write, }; int meta_measure_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &measure_file_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/volfile-file.c0000644000000000000000000000013214522202451022312 xustar000000000000000030 mtime=1699284265.704027543 30 atime=1699284265.704027543 30 ctime=1699284307.006151944 glusterfs-11.1/xlators/meta/src/volfile-file.c0000664000175100017510000000347414522202451022601 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include static int xldump_options(dict_t *this, char *key, data_t *value, void *strfd) { strprintf(strfd, " option %s %s\n", key, value->data); return 0; } static void xldump_subvolumes(xlator_t *this, void *strfd) { xlator_list_t *subv = NULL; if (!this->children) return; strprintf(strfd, " subvolumes"); for (subv = this->children; subv; subv = subv->next) strprintf(strfd, " %s", subv->xlator->name); strprintf(strfd, "\n"); } static void xldump(xlator_t *each, void *strfd) { strprintf(strfd, "volume %s\n", each->name); strprintf(strfd, " type %s\n", each->type); dict_foreach(each->options, xldump_options, strfd); xldump_subvolumes(each, strfd); strprintf(strfd, "end-volume\n"); strprintf(strfd, "\n"); } static int volfile_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { glusterfs_graph_t *graph = NULL; graph = meta_ctx_get(file, this); xlator_foreach_depth_first(graph->top, xldump, strfd); return strfd->size; } static struct meta_ops volfile_file_ops = { .file_fill = volfile_file_fill, }; int meta_volfile_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &volfile_file_ops); meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/options-dir.c0000644000000000000000000000013014522202451022202 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 30 ctime=1699284307.014151968 glusterfs-11.1/xlators/meta/src/options-dir.c0000664000175100017510000000305214522202451022463 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static int dict_key_add(dict_t *dict, char *key, data_t *value, void *data) { struct meta_dirent **direntp = data; (*direntp)->name = gf_strdup(key); (*direntp)->type = IA_IFREG; (*direntp)->hook = meta_option_file_hook; (*direntp)++; return 0; } static int options_dir_fill(xlator_t *this, inode_t *inode, struct meta_dirent **dp) { struct meta_dirent *dirent = NULL; struct meta_dirent *direntp = NULL; xlator_t *xl = NULL; xl = meta_ctx_get(inode, this); dirent = GF_CALLOC(sizeof(*dirent), xl->options->count, gf_meta_mt_dirents_t); if (!dirent) return -1; direntp = dirent; dict_foreach(xl->options, dict_key_add, &direntp); *dp = dirent; return xl->options->count; } static struct meta_ops options_dir_ops = {.dir_fill = options_dir_fill}; int meta_options_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); meta_ops_set(loc->inode, this, &options_dir_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/logfile-link.c0000644000000000000000000000013214522202451022311 xustar000000000000000030 mtime=1699284265.701027534 30 atime=1699284265.701027534 30 ctime=1699284307.002151932 glusterfs-11.1/xlators/meta/src/logfile-link.c0000664000175100017510000000152714522202451022575 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" static int logfile_link_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) { strprintf(strfd, "%s", this->ctx->log.filename); return 0; } struct meta_ops logfile_link_ops = {.link_fill = logfile_link_fill}; int meta_logfile_link_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &logfile_link_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/graphs-dir.c0000644000000000000000000000013214522202451021775 xustar000000000000000030 mtime=1699284265.701027534 30 atime=1699284265.701027534 30 ctime=1699284306.992151902 glusterfs-11.1/xlators/meta/src/graphs-dir.c0000664000175100017510000000321714522202451022257 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static struct meta_dirent graphs_dir_dirents[] = { DOT_DOTDOT, { .name = "active", .type = IA_IFLNK, .hook = meta_active_link_hook, }, {.name = NULL}}; static int graphs_dir_fill(xlator_t *this, inode_t *dir, struct meta_dirent **dp) { glusterfs_graph_t *graph = NULL; int graphs_count = 0; int i = 0; struct meta_dirent *dirents = NULL; list_for_each_entry(graph, &this->ctx->graphs, list) { graphs_count++; } dirents = GF_CALLOC(sizeof(*dirents), graphs_count + 3, gf_meta_mt_dirents_t); if (!dirents) return -1; i = 0; list_for_each_entry(graph, &this->ctx->graphs, list) { dirents[i].name = gf_strdup(graph->graph_uuid); dirents[i].type = IA_IFDIR; dirents[i].hook = meta_graph_dir_hook; i++; } *dp = dirents; return i; } struct meta_ops graphs_dir_ops = {.fixed_dirents = graphs_dir_dirents, .dir_fill = graphs_dir_fill}; int meta_graphs_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &graphs_dir_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/active-link.c0000644000000000000000000000013214522202451022143 xustar000000000000000030 mtime=1699284265.701027534 30 atime=1699284265.700027531 30 ctime=1699284306.996151914 glusterfs-11.1/xlators/meta/src/active-link.c0000664000175100017510000000152714522202451022427 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" static int active_link_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) { strprintf(strfd, "%s", this->ctx->active->graph_uuid); return 0; } struct meta_ops active_link_ops = {.link_fill = active_link_fill}; int meta_active_link_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &active_link_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/meta-helpers.c0000644000000000000000000000013114522202451022322 xustar000000000000000030 mtime=1699284265.702027537 30 atime=1699284265.702027537 29 ctime=1699284306.98815189 glusterfs-11.1/xlators/meta/src/meta-helpers.c0000664000175100017510000001435514522202451022612 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" meta_fd_t * meta_fd_get(fd_t *fd, xlator_t *this) { meta_fd_t *meta_fd = NULL; LOCK(&fd->lock); { meta_fd = __fd_ctx_get_ptr(fd, this); if (!meta_fd) { meta_fd = GF_CALLOC(1, sizeof(*meta_fd), gf_meta_mt_fd_t); if (!meta_fd) goto unlock; __fd_ctx_set(fd, this, (long)meta_fd); } } unlock: UNLOCK(&fd->lock); return meta_fd; } int meta_fd_release(fd_t *fd, xlator_t *this) { meta_fd_t *meta_fd = NULL; int i = 0; meta_fd = fd_ctx_del_ptr(fd, this); if (meta_fd) { if (meta_fd->dirents) { for (i = 0; i < meta_fd->size; i++) GF_FREE((void *)meta_fd->dirents[i].name); GF_FREE(meta_fd->dirents); } GF_FREE(meta_fd->data); GF_FREE(meta_fd); } return 0; } struct meta_ops * meta_ops_get(inode_t *inode, xlator_t *this) { struct meta_ops *ops = NULL; uint64_t value = 0; inode_ctx_get2(inode, this, NULL, &value); ops = (void *)(uintptr_t)value; return ops; } struct xlator_fops * meta_fops_get(inode_t *inode, xlator_t *this) { struct meta_ops *ops = NULL; ops = meta_ops_get(inode, this); if (!ops) return default_fops; return &ops->fops; } int meta_ops_set(inode_t *inode, xlator_t *this, struct meta_ops *ops) { uint64_t value = 0; int ret = 0; meta_defaults_init(&ops->fops); value = (long)ops; ret = inode_ctx_set2(inode, this, NULL, &value); return ret; } void * meta_ctx_get(inode_t *inode, xlator_t *this) { void *ctx = NULL; uint64_t value = 0; inode_ctx_get2(inode, this, &value, 0); ctx = (void *)(uintptr_t)value; return ctx; } int meta_ctx_set(inode_t *inode, xlator_t *this, void *ctx) { uint64_t value = 0; int ret = 0; value = (long)ctx; ret = inode_ctx_set2(inode, this, &value, 0); return ret; } void meta_local_cleanup(meta_local_t *local) { if (!local) return; if (local->xdata) dict_unref(local->xdata); GF_FREE(local); return; } static meta_local_t * meta_local(call_frame_t *frame) { meta_local_t *local = NULL; local = frame->local; if (!local) local = frame->local = GF_CALLOC(1, sizeof(*local), gf_meta_mt_local_t); return local; } dict_t * meta_direct_io_mode(dict_t *xdata, call_frame_t *frame) { meta_local_t *local = NULL; if (!xdata) { local = meta_local(frame); if (!local) return NULL; xdata = local->xdata = dict_new(); if (!xdata) return NULL; } if (dict_set_int8(xdata, "direct-io-mode", 1) != 0) return NULL; return xdata; } static void meta_uuid_copy(uuid_t dst, uuid_t src) { if (gf_uuid_is_null(src)) gf_uuid_generate(dst); else gf_uuid_copy(dst, src); } static void default_meta_iatt_fill(struct iatt *iatt, inode_t *inode, ia_type_t type, gf_boolean_t is_tunable) { struct timespec ts = { 0, }; iatt->ia_type = type; switch (type) { case IA_IFDIR: iatt->ia_prot = ia_prot_from_st_mode(0555); iatt->ia_nlink = 2; break; case IA_IFLNK: iatt->ia_prot = ia_prot_from_st_mode(0777); iatt->ia_nlink = 1; break; default: iatt->ia_prot = ia_prot_from_st_mode(is_tunable ? 0644 : 0444); iatt->ia_nlink = 1; break; } iatt->ia_uid = 0; iatt->ia_gid = 0; iatt->ia_size = 0; meta_uuid_copy(iatt->ia_gfid, inode->gfid); iatt->ia_ino = gfid_to_ino(iatt->ia_gfid); timespec_now_realtime(&ts); iatt->ia_mtime = iatt->ia_ctime = iatt->ia_atime = ts.tv_sec; iatt->ia_mtime_nsec = iatt->ia_ctime_nsec = iatt->ia_atime_nsec = ts.tv_nsec; } void meta_iatt_fill(xlator_t *this, struct iatt *iatt, inode_t *inode, ia_type_t type) { struct meta_ops *ops = NULL; xlator_t *xl = this; if (xl == NULL) xl = THIS; ops = meta_ops_get(inode, xl); if (!ops) return; if (!ops->iatt_fill) default_meta_iatt_fill(iatt, inode, type, !!ops->file_write); else ops->iatt_fill(xl, inode, iatt); return; } int meta_inode_discover(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { struct iatt iatt = {}; struct iatt postparent = {}; meta_iatt_fill(this, &iatt, loc->inode, loc->inode->ia_type); META_STACK_UNWIND(lookup, frame, 0, 0, loc->inode, &iatt, xdata, &postparent); return 0; } int meta_file_fill(xlator_t *this, meta_fd_t *meta_fd, fd_t *fd) { strfd_t *strfd = NULL; struct meta_ops *ops = NULL; int ret = 0; if (meta_fd->data) return meta_fd->size; strfd = strfd_open(); if (!strfd) return -1; ops = meta_ops_get(fd->inode, this); if (!ops) { strfd_close(strfd); return -1; } if (ops->file_fill) ret = ops->file_fill(this, fd->inode, strfd); if (ret >= 0) { meta_fd->data = strfd->data; meta_fd->size = strfd->size; strfd->data = NULL; } strfd_close(strfd); return meta_fd->size; } int meta_dir_fill(xlator_t *this, meta_fd_t *meta_fd, struct meta_ops *ops, fd_t *fd) { struct meta_dirent *dp = NULL; int ret = 0; if (meta_fd->dirents) return meta_fd->size; if (ops->dir_fill) ret = ops->dir_fill(this, fd->inode, &dp); if (dp) { meta_fd->dirents = dp; meta_fd->size = ret; } return meta_fd->size; } int fixed_dirents_len(struct meta_dirent *dirents) { int i = 0; struct meta_dirent *dirent = NULL; if (!dirents) return 0; for (dirent = dirents; dirent->name; dirent++) i++; return i; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/meta.c0000644000000000000000000000013214522202451020663 xustar000000000000000030 mtime=1699284265.702027537 30 atime=1699284265.702027537 30 ctime=1699284306.986151884 glusterfs-11.1/xlators/meta/src/meta.c0000664000175100017510000001457714522202451021160 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static int meta_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { inode_t *inode = NULL; meta_priv_t *priv = this->private; if ((loc->name && !strcmp(loc->name, priv->meta_dir_name) && __is_root_gfid(loc->pargfid)) || !gf_uuid_compare(loc->gfid, priv->meta_root_gfid)) { struct iatt iatt = {}; struct iatt parent = {}; meta_root_dir_hook(frame, this, loc, xdata); meta_iatt_fill(this, &iatt, loc->inode, IA_IFDIR); gf_uuid_copy(iatt.ia_gfid, priv->meta_root_gfid); META_STACK_UNWIND(lookup, frame, 0, 0, loc->inode, &iatt, xdata, &parent); return 0; } if (loc->parent) inode = loc->parent; else inode = loc->inode; META_FOP(inode, lookup, frame, this, loc, xdata); return 0; } int meta_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { META_FOP(fd->inode, opendir, frame, this, loc, fd, xdata); return 0; } int meta_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, fd_t *fd, dict_t *xdata) { META_FOP(fd->inode, open, frame, this, loc, flags, fd, xdata); return 0; } int meta_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { META_FOP(fd->inode, readv, frame, this, fd, size, offset, flags, xdata); return 0; } int meta_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { META_FOP(fd->inode, flush, frame, this, fd, xdata); return 0; } int meta_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { META_FOP(loc->inode, stat, frame, this, loc, xdata); return 0; } int meta_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { META_FOP(fd->inode, fstat, frame, this, fd, xdata); return 0; } int meta_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { META_FOP(fd->inode, readdir, frame, this, fd, size, offset, xdata); return 0; } int meta_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { META_FOP(fd->inode, readdirp, frame, this, fd, size, offset, xdata); return 0; } int meta_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { META_FOP(loc->inode, readlink, frame, this, loc, size, xdata); return 0; } int meta_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *iov, int count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { META_FOP(fd->inode, writev, frame, this, fd, iov, count, offset, flags, iobref, xdata); return 0; } int meta_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { META_FOP(loc->inode, truncate, frame, this, loc, offset, xdata); return 0; } int meta_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { META_FOP(fd->inode, ftruncate, frame, this, fd, offset, xdata); return 0; } int32_t meta_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { META_FOP(fd->inode, fsync, frame, this, fd, flags, xdata); return 0; } int32_t meta_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { META_FOP(fd->inode, fsyncdir, frame, this, fd, flags, xdata); return 0; } int meta_forget(xlator_t *this, inode_t *inode) { return 0; } int meta_release(xlator_t *this, fd_t *fd) { return meta_fd_release(fd, this); } int meta_releasedir(xlator_t *this, fd_t *fd) { return meta_fd_release(fd, this); } int mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_meta_mt_end); if (ret != 0) { gf_log(this->name, GF_LOG_ERROR, "Memory accounting init failed"); return ret; } return ret; } int init(xlator_t *this) { meta_priv_t *priv = NULL; int ret = -1; priv = GF_MALLOC(sizeof(meta_priv_t), gf_meta_mt_priv_t); if (!priv) return ret; GF_OPTION_INIT("meta-dir-name", priv->meta_dir_name, str, err); gf_uuid_parse(META_ROOT_GFID, priv->meta_root_gfid); this->private = priv; return 0; err: GF_FREE(priv); return ret; } void fini(xlator_t *this) { GF_FREE(this->private); return; } struct xlator_fops fops = {.lookup = meta_lookup, .opendir = meta_opendir, .open = meta_open, .readv = meta_readv, .flush = meta_flush, .stat = meta_stat, .fstat = meta_fstat, .readdir = meta_readdir, .readdirp = meta_readdirp, .readlink = meta_readlink, .writev = meta_writev, .truncate = meta_truncate, .ftruncate = meta_ftruncate, .fsync = meta_fsync, .fsyncdir = meta_fsyncdir}; struct xlator_cbks cbks = { .forget = meta_forget, .release = meta_release, .releasedir = meta_releasedir, }; struct volume_options options[] = { {.key = {"meta-dir-name"}, .type = GF_OPTION_TYPE_STR, .default_value = DEFAULT_META_DIR_NAME, .description = "Name of default meta directory."}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "meta", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/meta-hooks.h0000644000000000000000000000013214522202451022011 xustar000000000000000030 mtime=1699284265.702027537 30 atime=1699284265.702027537 30 ctime=1699284306.983151874 glusterfs-11.1/xlators/meta/src/meta-hooks.h0000664000175100017510000000255014522202451022272 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __META_HOOKS_H #define __META_HOOKS_H #define DECLARE_HOOK(name) \ int meta_##name##_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, \ dict_t *xdata) DECLARE_HOOK(root_dir); DECLARE_HOOK(graphs_dir); DECLARE_HOOK(frames_file); DECLARE_HOOK(graph_dir); DECLARE_HOOK(active_link); DECLARE_HOOK(xlator_dir); DECLARE_HOOK(top_link); DECLARE_HOOK(logging_dir); DECLARE_HOOK(logfile_link); DECLARE_HOOK(loglevel_file); DECLARE_HOOK(process_uuid_file); DECLARE_HOOK(volfile_file); DECLARE_HOOK(view_dir); DECLARE_HOOK(subvolumes_dir); DECLARE_HOOK(subvolume_link); DECLARE_HOOK(type_file); DECLARE_HOOK(version_file); DECLARE_HOOK(options_dir); DECLARE_HOOK(option_file); DECLARE_HOOK(cmdline_file); DECLARE_HOOK(name_file); DECLARE_HOOK(private_file); DECLARE_HOOK(mallinfo_file); DECLARE_HOOK(history_file); DECLARE_HOOK(root); DECLARE_HOOK(meminfo_file); DECLARE_HOOK(measure_file); DECLARE_HOOK(profile_file); #endif glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/root-dir.c0000644000000000000000000000013014522202451021472 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 30 ctime=1699284306.991151899 glusterfs-11.1/xlators/meta/src/root-dir.c0000664000175100017510000000336214522202451021757 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static struct meta_dirent root_dir_dirents[] = { DOT_DOTDOT, { .name = "graphs", .type = IA_IFDIR, .hook = meta_graphs_dir_hook, }, { .name = "frames", .type = IA_IFREG, .hook = meta_frames_file_hook, }, { .name = "logging", .type = IA_IFDIR, .hook = meta_logging_dir_hook, }, { .name = "process_uuid", .type = IA_IFREG, .hook = meta_process_uuid_file_hook, }, { .name = "version", .type = IA_IFREG, .hook = meta_version_file_hook, }, { .name = "cmdline", .type = IA_IFREG, .hook = meta_cmdline_file_hook, }, { .name = "mallinfo", .type = IA_IFREG, .hook = meta_mallinfo_file_hook, }, { .name = "root", .type = IA_IFDIR, .hook = meta_root_hook, }, { .name = "measure_latency", .type = IA_IFREG, .hook = meta_measure_file_hook, }, {.name = NULL}}; static struct meta_ops meta_root_dir_ops = {.fixed_dirents = root_dir_dirents}; int meta_root_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &meta_root_dir_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/graph-dir.c0000644000000000000000000000013214522202451021612 xustar000000000000000030 mtime=1699284265.701027534 30 atime=1699284265.701027534 30 ctime=1699284306.995151911 glusterfs-11.1/xlators/meta/src/graph-dir.c0000664000175100017510000000430614522202451022074 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static struct meta_dirent graph_dir_dirents[] = { DOT_DOTDOT, { .name = "top", .type = IA_IFLNK, .hook = meta_top_link_hook, }, { .name = "volfile", .type = IA_IFREG, .hook = meta_volfile_file_hook, }, {.name = NULL}}; static int graph_dir_fill(xlator_t *this, inode_t *inode, struct meta_dirent **dp) { struct meta_dirent *dirents = NULL; glusterfs_graph_t *graph = NULL; int i = 0; int count = 0; xlator_t *xl = NULL; graph = meta_ctx_get(inode, this); for (xl = graph->first; xl; xl = xl->next) count++; dirents = GF_MALLOC(sizeof(*dirents) * count, gf_meta_mt_dirents_t); if (!dirents) return -1; i = 0; for (xl = graph->first; xl; xl = xl->next) { dirents[i].name = gf_strdup(xl->name); dirents[i].type = IA_IFDIR; dirents[i].hook = meta_xlator_dir_hook; i++; } *dp = dirents; return i; } struct meta_ops graph_dir_ops = { .fixed_dirents = graph_dir_dirents, .dir_fill = graph_dir_fill, }; static glusterfs_graph_t * glusterfs_graph_lookup(xlator_t *this, const char *graph_uuid) { glusterfs_graph_t *graph = NULL; glusterfs_graph_t *tmp = NULL; list_for_each_entry(tmp, &this->ctx->graphs, list) { if (strcmp(graph_uuid, tmp->graph_uuid) == 0) { graph = tmp; break; } } return graph; } int meta_graph_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { glusterfs_graph_t *graph = NULL; graph = glusterfs_graph_lookup(this, loc->name); meta_ops_set(loc->inode, this, &graph_dir_ops); meta_ctx_set(loc->inode, this, (void *)graph); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/history-file.c0000644000000000000000000000013214522202451022353 xustar000000000000000030 mtime=1699284265.701027534 30 atime=1699284265.701027534 30 ctime=1699284307.021151989 glusterfs-11.1/xlators/meta/src/history-file.c0000664000175100017510000000204714522202451022635 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int history_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { xlator_t *xl = NULL; xl = meta_ctx_get(file, this); gf_proc_dump_xlator_history(xl, strfd); return strfd->size; } static struct meta_ops history_file_ops = { .file_fill = history_file_fill, }; int meta_history_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &history_file_ops); meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/meta-mem-types.h0000644000000000000000000000013214522202451022606 xustar000000000000000030 mtime=1699284265.702027537 30 atime=1699284265.702027537 30 ctime=1699284306.985151881 glusterfs-11.1/xlators/meta/src/meta-mem-types.h0000664000175100017510000000125214522202451023065 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __META_MEM_TYPES_H__ #define __META_MEM_TYPES_H__ #include enum gf_meta_mem_types_ { gf_meta_mt_priv_t = gf_common_mt_end + 1, gf_meta_mt_fd_t, gf_meta_mt_fd_data_t, gf_meta_mt_strfd_t, gf_meta_mt_dirents_t, gf_meta_mt_local_t, gf_meta_mt_end }; #endif glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/top-link.c0000644000000000000000000000013014522202451021470 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 30 ctime=1699284306.999151923 glusterfs-11.1/xlators/meta/src/top-link.c0000664000175100017510000000173214522202451021754 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" static int top_link_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) { glusterfs_graph_t *graph = NULL; graph = meta_ctx_get(inode, this); strprintf(strfd, "%s", ((xlator_t *)graph->top)->name); return 0; } struct meta_ops top_link_ops = {.link_fill = top_link_fill}; int meta_top_link_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &top_link_ops); meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/meminfo-file.c0000644000000000000000000000013214522202451022304 xustar000000000000000030 mtime=1699284265.702027537 30 atime=1699284265.702027537 30 ctime=1699284307.024151998 glusterfs-11.1/xlators/meta/src/meminfo-file.c0000664000175100017510000000204714522202451022566 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int meminfo_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { xlator_t *xl = NULL; xl = meta_ctx_get(file, this); gf_proc_dump_xlator_meminfo(xl, strfd); return strfd->size; } static struct meta_ops meminfo_file_ops = { .file_fill = meminfo_file_fill, }; int meta_meminfo_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &meminfo_file_ops); meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/profile-file.c0000644000000000000000000000013014522202451022310 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 30 ctime=1699284307.026152004 glusterfs-11.1/xlators/meta/src/profile-file.c0000664000175100017510000000204714522202451022574 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int profile_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { xlator_t *xl = NULL; xl = meta_ctx_get(file, this); gf_proc_dump_xlator_profile(xl, strfd); return strfd->size; } static struct meta_ops profile_file_ops = { .file_fill = profile_file_fill, }; int meta_profile_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &profile_file_ops); meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/version-file.c0000644000000000000000000000013214522202451022337 xustar000000000000000030 mtime=1699284265.704027543 30 atime=1699284265.704027543 30 ctime=1699284307.013151965 glusterfs-11.1/xlators/meta/src/version-file.c0000664000175100017510000000170314522202451022617 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int version_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { strprintf(strfd, "{ \n \"Package Version\": \"%s\"\n}", PACKAGE_VERSION); return strfd->size; } static struct meta_ops version_file_ops = { .file_fill = version_file_fill, }; int meta_version_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &version_file_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/frames-file.c0000644000000000000000000000013214522202451022127 xustar000000000000000030 mtime=1699284265.701027534 30 atime=1699284265.701027534 30 ctime=1699284306.994151908 glusterfs-11.1/xlators/meta/src/frames-file.c0000664000175100017510000000732514522202451022415 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int frames_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { struct call_pool *pool = NULL; call_stack_t *stack = NULL; call_frame_t *frame = NULL; int i = 0; int j = 1; if (!this || !file || !strfd) return -1; pool = this->ctx->pool; strprintf(strfd, "{ \n\t\"Stack\": [\n"); LOCK(&pool->lock); { list_for_each_entry(stack, &pool->all_frames, all_frames) { strprintf(strfd, "\t {\n"); strprintf(strfd, "\t\t\"Number\": %d,\n", ++i); strprintf(strfd, "\t\t\"Frame\": [\n"); j = 1; list_for_each_entry(frame, &stack->myframes, frames) { strprintf(strfd, "\t\t {\n"); strprintf(strfd, "\t\t\t\"Number\": %d,\n", j++); strprintf(strfd, "\t\t\t\"Xlator\": \"%s\",\n", frame->this->name); if (frame->begin.tv_sec) strprintf(strfd, "\t\t\t\"Creation_time\": %d.%09d,\n", (int)frame->begin.tv_sec, (int)frame->begin.tv_nsec); if (frame->parent) strprintf(strfd, "\t\t\t\"Parent\": \"%s\",\n", frame->parent->this->name); if (frame->wind_from) strprintf(strfd, "\t\t\t\"Wind_from\": \"%s\",\n", frame->wind_from); if (frame->wind_to) strprintf(strfd, "\t\t\t\"Wind_to\": \"%s\",\n", frame->wind_to); if (frame->unwind_from) strprintf(strfd, "\t\t\t\"Unwind_from\": \"%s\",\n", frame->unwind_from); if (frame->unwind_to) strprintf(strfd, "\t\t\t\"Unwind_to\": \"%s\",\n", frame->unwind_to); strprintf(strfd, "\t\t\t\"Complete\": %d\n", frame->complete); if (list_is_last(&frame->frames, &stack->myframes)) strprintf(strfd, "\t\t }\n"); else strprintf(strfd, "\t\t },\n"); } strprintf(strfd, "\t\t],\n"); strprintf(strfd, "\t\t\"Unique\": %" PRId64 ",\n", stack->unique); strprintf(strfd, "\t\t\"Type\": \"%s\",\n", gf_fop_list[stack->op]); strprintf(strfd, "\t\t\"UID\": %d,\n", stack->uid); strprintf(strfd, "\t\t\"GID\": %d,\n", stack->gid); strprintf(strfd, "\t\t\"LK_owner\": \"%s\"\n", lkowner_utoa(&stack->lk_owner)); if (i == (int)pool->cnt) strprintf(strfd, "\t }\n"); else strprintf(strfd, "\t },\n"); } strprintf(strfd, "\t],\n"); strprintf(strfd, "\t\"Call_Count\": %d\n", (int)pool->cnt); strprintf(strfd, "}"); } UNLOCK(&pool->lock); return strfd->size; } static struct meta_ops frames_file_ops = { .file_fill = frames_file_fill, }; int meta_frames_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &frames_file_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/process_uuid-file.c0000644000000000000000000000013014522202451023354 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 30 ctime=1699284307.005151941 glusterfs-11.1/xlators/meta/src/process_uuid-file.c0000664000175100017510000000171114522202451023635 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int process_uuid_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { strprintf(strfd, "%s\n", this->ctx->process_uuid); return strfd->size; } static struct meta_ops process_uuid_file_ops = { .file_fill = process_uuid_file_fill, }; int meta_process_uuid_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &process_uuid_file_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/option-file.c0000644000000000000000000000013014522202451022160 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 30 ctime=1699284307.016151974 glusterfs-11.1/xlators/meta/src/option-file.c0000664000175100017510000000211314522202451022436 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static int option_file_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) { data_t *data = NULL; data = meta_ctx_get(inode, this); strprintf(strfd, "%s\n", data_to_str(data)); return strfd->size; } static struct meta_ops option_file_ops = {.file_fill = option_file_fill}; int meta_option_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { xlator_t *xl = NULL; xl = meta_ctx_get(loc->parent, this); meta_ctx_set(loc->inode, this, dict_get(xl->options, (char *)loc->name)); meta_ops_set(loc->inode, this, &option_file_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/meta-defaults.c0000644000000000000000000000013214522202451022470 xustar000000000000000030 mtime=1699284265.702027537 30 atime=1699284265.702027537 30 ctime=1699284306.989151893 glusterfs-11.1/xlators/meta/src/meta-defaults.c0000664000175100017510000004173114522202451022755 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include int meta_default_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { return default_fgetxattr_failure_cbk(frame, EPERM); } int meta_default_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { return default_fsetxattr_failure_cbk(frame, EPERM); } int meta_default_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { return default_setxattr_failure_cbk(frame, EPERM); } int meta_default_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { return default_statfs_failure_cbk(frame, EPERM); } int meta_default_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { return default_fsyncdir_failure_cbk(frame, EPERM); } int meta_default_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { META_STACK_UNWIND(opendir, frame, 0, 0, fd, xdata); return 0; } int meta_default_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { struct iatt iatt = {}; meta_iatt_fill(this, &iatt, fd->inode, fd->inode->ia_type); META_STACK_UNWIND(fstat, frame, 0, 0, &iatt, xdata); return 0; } int meta_default_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { return default_fsync_failure_cbk(frame, EPERM); } int meta_default_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { META_STACK_UNWIND(flush, frame, 0, 0, xdata); return 0; } int meta_default_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { struct meta_ops *ops = NULL; int ret = 0; struct iatt dummy = {}; ops = meta_ops_get(fd->inode, this); if (!ops) goto err; if (!ops->file_write) goto err; ret = ops->file_write(this, fd, vector, count); META_STACK_UNWIND(writev, frame, (ret >= 0 ? ret : -1), (ret < 0 ? -ret : 0), &dummy, &dummy, xdata); return 0; err: return default_writev_failure_cbk(frame, EPERM); } int meta_default_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { meta_fd_t *meta_fd = NULL; struct iovec iov = {}; struct iobuf *iobuf = NULL; struct iobref *iobref = NULL; off_t copy_offset = 0; int copy_size = 0; struct iatt iatt = {}; meta_fd = meta_fd_get(fd, this); if (!meta_fd) return default_readv_failure_cbk(frame, ENODATA); if (!meta_fd->size) meta_file_fill(this, meta_fd, fd); iobuf = iobuf_get2(this->ctx->iobuf_pool, size); if (!iobuf) return default_readv_failure_cbk(frame, ENOMEM); iobref = iobref_new(); if (!iobref) { iobuf_unref(iobuf); return default_readv_failure_cbk(frame, ENOMEM); } if (iobref_add(iobref, iobuf) != 0) { iobref_unref(iobref); iobuf_unref(iobuf); return default_readv_failure_cbk(frame, ENOMEM); } iov.iov_base = iobuf_ptr(iobuf); /* iobref would have taken a ref */ iobuf_unref(iobuf); copy_offset = min(meta_fd->size, offset); copy_size = min(size, (meta_fd->size - copy_offset)); if (copy_size) memcpy(iov.iov_base, meta_fd->data + copy_offset, copy_size); iov.iov_len = copy_size; META_STACK_UNWIND(readv, frame, copy_size, 0, &iov, 1, &iatt, iobref, 0); iobref_unref(iobref); return 0; } int meta_default_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { dict_t *xdata_rsp = NULL; xdata_rsp = meta_direct_io_mode(xdata, frame); META_STACK_UNWIND(open, frame, 0, 0, fd, xdata_rsp); return 0; } int meta_default_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { return default_create_failure_cbk(frame, EPERM); } int meta_default_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { return default_link_failure_cbk(frame, EPERM); } int meta_default_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { return default_rename_failure_cbk(frame, EPERM); } int meta_default_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { return default_symlink_failure_cbk(frame, EPERM); } int meta_default_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { return default_rmdir_failure_cbk(frame, EPERM); } int meta_default_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { return default_unlink_failure_cbk(frame, EPERM); } int meta_default_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { return default_mkdir_failure_cbk(frame, EPERM); } int meta_default_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { return default_mknod_failure_cbk(frame, EPERM); } int meta_default_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { struct meta_ops *ops = NULL; strfd_t *strfd = NULL; struct iatt iatt = {}; int len = -1; ops = meta_ops_get(loc->inode, this); if (!ops || !ops->link_fill) { META_STACK_UNWIND(readlink, frame, -1, EPERM, 0, 0, 0); return 0; } strfd = strfd_open(); if (!strfd) { META_STACK_UNWIND(readlink, frame, -1, ENOMEM, 0, 0, 0); return 0; } ops->link_fill(this, loc->inode, strfd); meta_iatt_fill(this, &iatt, loc->inode, IA_IFLNK); if (strfd->data) { len = strlen(strfd->data); META_STACK_UNWIND(readlink, frame, len, 0, strfd->data, &iatt, xdata); } else META_STACK_UNWIND(readlink, frame, -1, ENODATA, 0, 0, 0); strfd_close(strfd); return 0; } int meta_default_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { return default_access_failure_cbk(frame, EPERM); } int meta_default_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { struct iatt iatt = {}; meta_iatt_fill(this, &iatt, fd->inode, IA_IFREG); META_STACK_UNWIND(ftruncate, frame, 0, 0, &iatt, &iatt, xdata); return 0; } int meta_default_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { return default_getxattr_failure_cbk(frame, EPERM); } int meta_default_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { return default_xattrop_failure_cbk(frame, EPERM); } int meta_default_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { return default_fxattrop_failure_cbk(frame, EPERM); } int meta_default_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { return default_removexattr_failure_cbk(frame, EPERM); } int meta_default_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { return default_fremovexattr_failure_cbk(frame, EPERM); } int meta_default_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { return default_lk_failure_cbk(frame, EPERM); } int meta_default_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { return default_inodelk_failure_cbk(frame, EPERM); } int meta_default_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { return default_finodelk_failure_cbk(frame, EPERM); } int meta_default_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { return default_entrylk_failure_cbk(frame, EPERM); } int meta_default_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { return default_fentrylk_failure_cbk(frame, EPERM); } int meta_default_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, int32_t len, dict_t *xdata) { return default_rchecksum_failure_cbk(frame, EPERM); } int meta_default_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { meta_fd_t *meta_fd = NULL; int i = 0; gf_dirent_t head; gf_dirent_t *list = NULL; int ret = 0; int this_size = 0; int filled_size = 0; int fixed_size = 0; int dyn_size = 0; struct meta_dirent *fixed_dirents = NULL; struct meta_dirent *dyn_dirents = NULL; struct meta_dirent *dirents = NULL; struct meta_dirent *end = NULL; struct meta_ops *ops = NULL; size_t dirents_name_len; INIT_LIST_HEAD(&head.list); ops = meta_ops_get(fd->inode, this); if (!ops) goto err; meta_fd = meta_fd_get(fd, this); if (!meta_fd) goto err; meta_dir_fill(this, meta_fd, ops, fd); fixed_dirents = ops->fixed_dirents; fixed_size = fixed_dirents_len(fixed_dirents); dyn_dirents = meta_fd->dirents; dyn_size = meta_fd->size; for (i = off; i < (fixed_size + dyn_size);) { if (i >= fixed_size) { dirents = dyn_dirents + (i - fixed_size); end = dyn_dirents + dyn_size; } else { dirents = fixed_dirents + i; end = fixed_dirents + fixed_size; } while (dirents < end) { dirents_name_len = strlen(dirents->name); this_size = gf_dirent_len(dirents_name_len); if (this_size + filled_size > size) goto unwind; list = gf_dirent_for_name2( dirents->name, dirents_name_len, i + 42, i + 1, gf_d_type_from_ia_type(dirents->type), NULL); if (!list) break; list_add_tail(&list->list, &head.list); ret++; i++; dirents++; filled_size += this_size; } } unwind: META_STACK_UNWIND(readdir, frame, ret, 0, &head, xdata); gf_dirent_free(&head); return 0; err: META_STACK_UNWIND(readdir, frame, -1, ENOMEM, 0, 0); return 0; } int meta_default_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { return meta_default_readdir(frame, this, fd, size, off, xdata); } int meta_default_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { return default_setattr_failure_cbk(frame, EPERM); } int meta_default_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { struct iatt iatt = {}; meta_iatt_fill(this, &iatt, loc->inode, IA_IFREG); META_STACK_UNWIND(truncate, frame, 0, 0, &iatt, &iatt, xdata); return 0; } int meta_default_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { struct iatt iatt = {}; meta_iatt_fill(this, &iatt, loc->inode, loc->inode->ia_type); META_STACK_UNWIND(stat, frame, 0, 0, &iatt, xdata); return 0; } int meta_default_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { struct meta_ops *ops = NULL; struct meta_dirent *dirent = NULL; struct meta_dirent *dp = NULL; int i = 0; int ret = 0; if (!loc->name) return meta_inode_discover(frame, this, loc, xdata); ops = meta_ops_get(loc->parent, this); if (!ops) return default_lookup_failure_cbk(frame, EPERM); for (dirent = ops->fixed_dirents; dirent && dirent->name; dirent++) { if (strcmp(dirent->name, loc->name) == 0) goto hook; } dirent = NULL; if (ops->dir_fill) ret = ops->dir_fill(this, loc->parent, &dp); for (i = 0; i < ret; i++) { if (strcmp(dp[i].name, loc->name) == 0) { dirent = &dp[i]; goto hook; } } hook: if (dirent && dirent->hook) { struct iatt parent = {}; struct iatt iatt = {}; dirent->hook(frame, this, loc, xdata); meta_iatt_fill(this, &iatt, loc->inode, dirent->type); META_STACK_UNWIND(lookup, frame, 0, 0, loc->inode, &iatt, xdata, &parent); } else { META_STACK_UNWIND(lookup, frame, -1, ENOENT, 0, 0, 0, 0); } for (i = 0; i < ret; i++) GF_FREE((void *)dp[i].name); GF_FREE(dp); return 0; } int meta_default_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { return default_fsetattr_failure_cbk(frame, EPERM); } int meta_default_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_size, off_t offset, size_t len, dict_t *xdata) { return default_fallocate_failure_cbk(frame, EPERM); } int meta_default_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { return default_discard_failure_cbk(frame, EPERM); } int meta_default_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { return default_zerofill_failure_cbk(frame, EPERM); } #define SET_META_DEFAULT_FOP(f, name) \ do { \ if (!f->name) \ f->name = meta_default_##name; \ } while (0) struct xlator_fops * meta_defaults_init(struct xlator_fops *fops) { SET_META_DEFAULT_FOP(fops, create); SET_META_DEFAULT_FOP(fops, open); SET_META_DEFAULT_FOP(fops, stat); SET_META_DEFAULT_FOP(fops, readlink); SET_META_DEFAULT_FOP(fops, mknod); SET_META_DEFAULT_FOP(fops, mkdir); SET_META_DEFAULT_FOP(fops, unlink); SET_META_DEFAULT_FOP(fops, rmdir); SET_META_DEFAULT_FOP(fops, symlink); SET_META_DEFAULT_FOP(fops, rename); SET_META_DEFAULT_FOP(fops, link); SET_META_DEFAULT_FOP(fops, truncate); SET_META_DEFAULT_FOP(fops, readv); SET_META_DEFAULT_FOP(fops, writev); SET_META_DEFAULT_FOP(fops, statfs); SET_META_DEFAULT_FOP(fops, flush); SET_META_DEFAULT_FOP(fops, fsync); SET_META_DEFAULT_FOP(fops, setxattr); SET_META_DEFAULT_FOP(fops, getxattr); SET_META_DEFAULT_FOP(fops, fsetxattr); SET_META_DEFAULT_FOP(fops, fgetxattr); SET_META_DEFAULT_FOP(fops, removexattr); SET_META_DEFAULT_FOP(fops, fremovexattr); SET_META_DEFAULT_FOP(fops, opendir); SET_META_DEFAULT_FOP(fops, readdir); SET_META_DEFAULT_FOP(fops, readdirp); SET_META_DEFAULT_FOP(fops, fsyncdir); SET_META_DEFAULT_FOP(fops, access); SET_META_DEFAULT_FOP(fops, ftruncate); SET_META_DEFAULT_FOP(fops, fstat); SET_META_DEFAULT_FOP(fops, lk); SET_META_DEFAULT_FOP(fops, inodelk); SET_META_DEFAULT_FOP(fops, finodelk); SET_META_DEFAULT_FOP(fops, entrylk); SET_META_DEFAULT_FOP(fops, fentrylk); SET_META_DEFAULT_FOP(fops, lookup); SET_META_DEFAULT_FOP(fops, rchecksum); SET_META_DEFAULT_FOP(fops, xattrop); SET_META_DEFAULT_FOP(fops, fxattrop); SET_META_DEFAULT_FOP(fops, setattr); SET_META_DEFAULT_FOP(fops, fsetattr); SET_META_DEFAULT_FOP(fops, fallocate); SET_META_DEFAULT_FOP(fops, discard); SET_META_DEFAULT_FOP(fops, zerofill); return fops; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/cmdline-file.c0000644000000000000000000000013214522202451022265 xustar000000000000000030 mtime=1699284265.701027534 30 atime=1699284265.701027534 30 ctime=1699284307.017151977 glusterfs-11.1/xlators/meta/src/cmdline-file.c0000664000175100017510000000177114522202451022552 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int cmdline_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { if (this->ctx->cmdlinestr) strprintf(strfd, "{ \n \"Cmdlinestr\": \"%s\"\n}", this->ctx->cmdlinestr); return strfd->size; } static struct meta_ops cmdline_file_ops = { .file_fill = cmdline_file_fill, }; int meta_cmdline_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &cmdline_file_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/type-file.c0000644000000000000000000000013114522202451021632 xustar000000000000000030 mtime=1699284265.704027543 29 atime=1699284265.70302754 30 ctime=1699284307.011151959 glusterfs-11.1/xlators/meta/src/type-file.c0000664000175100017510000000201714522202451022112 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int type_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { xlator_t *xl = NULL; xl = meta_ctx_get(file, this); strprintf(strfd, "%s\n", xl->type); return strfd->size; } static struct meta_ops type_file_ops = { .file_fill = type_file_fill, }; int meta_type_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &type_file_ops); meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/private-file.c0000644000000000000000000000013014522202451022322 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 30 ctime=1699284307.020151986 glusterfs-11.1/xlators/meta/src/private-file.c0000664000175100017510000000204714522202451022606 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int private_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { xlator_t *xl = NULL; xl = meta_ctx_get(file, this); gf_proc_dump_xlator_private(xl, strfd); return strfd->size; } static struct meta_ops private_file_ops = { .file_fill = private_file_fill, }; int meta_private_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &private_file_ops); meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465021643 xustar000000000000000030 mtime=1699284277.809064004 30 atime=1699284288.762096994 30 ctime=1699284306.979151862 glusterfs-11.1/xlators/meta/src/Makefile.in0000664000175100017510000006530214522202465022130 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/meta/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) meta_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_meta_la_OBJECTS = meta.lo meta-helpers.lo meta-defaults.lo \ root-dir.lo graphs-dir.lo frames-file.lo graph-dir.lo \ active-link.lo xlator-dir.lo top-link.lo logging-dir.lo \ logfile-link.lo loglevel-file.lo process_uuid-file.lo \ volfile-file.lo view-dir.lo subvolumes-dir.lo \ subvolume-link.lo type-file.lo version-file.lo options-dir.lo \ option-file.lo cmdline-file.lo name-file.lo private-file.lo \ history-file.lo mallinfo-file.lo meminfo-file.lo \ measure-file.lo profile-file.lo meta_la_OBJECTS = $(am_meta_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = meta_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(meta_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(meta_la_SOURCES) DIST_SOURCES = $(meta_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = meta.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator meta_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) meta_la_SOURCES = meta.c meta-helpers.c meta-defaults.c \ root-dir.c \ graphs-dir.c \ frames-file.c \ graph-dir.c \ active-link.c \ xlator-dir.c \ top-link.c \ logging-dir.c \ logfile-link.c \ loglevel-file.c \ process_uuid-file.c \ volfile-file.c \ view-dir.c \ subvolumes-dir.c \ subvolume-link.c \ type-file.c \ version-file.c \ options-dir.c \ option-file.c \ cmdline-file.c \ name-file.c \ private-file.c \ history-file.c \ mallinfo-file.c \ meminfo-file.c \ measure-file.c \ profile-file.c meta_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = meta.h meta-hooks.h meta-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/meta/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/meta/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } meta.la: $(meta_la_OBJECTS) $(meta_la_DEPENDENCIES) $(EXTRA_meta_la_DEPENDENCIES) $(AM_V_CCLD)$(meta_la_LINK) -rpath $(xlatordir) $(meta_la_OBJECTS) $(meta_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/active-link.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmdline-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frames-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph-dir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graphs-dir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/history-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logfile-link.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging-dir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loglevel-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mallinfo-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meminfo-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta-defaults.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/name-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/option-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options-dir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/private-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_uuid-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/root-dir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subvolume-link.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subvolumes-dir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top-link.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/type-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view-dir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/volfile-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlator-dir.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/logging-dir.c0000644000000000000000000000013214522202451022137 xustar000000000000000030 mtime=1699284265.701027534 30 atime=1699284265.701027534 30 ctime=1699284307.000151926 glusterfs-11.1/xlators/meta/src/logging-dir.c0000664000175100017510000000202314522202451022413 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static struct meta_dirent logging_dir_dirents[] = { DOT_DOTDOT, { .name = "logfile", .type = IA_IFLNK, .hook = meta_logfile_link_hook, }, { .name = "loglevel", .type = IA_IFREG, .hook = meta_loglevel_file_hook, }, {.name = NULL}}; struct meta_ops logging_dir_ops = { .fixed_dirents = logging_dir_dirents, }; int meta_logging_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &logging_dir_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451021625 xustar000000000000000030 mtime=1699284265.700027531 30 atime=1699284277.769063884 30 ctime=1699284306.980151866 glusterfs-11.1/xlators/meta/src/Makefile.am0000664000175100017510000000167714522202451022117 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = meta.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator meta_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) meta_la_SOURCES = meta.c meta-helpers.c meta-defaults.c \ root-dir.c \ graphs-dir.c \ frames-file.c \ graph-dir.c \ active-link.c \ xlator-dir.c \ top-link.c \ logging-dir.c \ logfile-link.c \ loglevel-file.c \ process_uuid-file.c \ volfile-file.c \ view-dir.c \ subvolumes-dir.c \ subvolume-link.c \ type-file.c \ version-file.c \ options-dir.c \ option-file.c \ cmdline-file.c \ name-file.c \ private-file.c \ history-file.c \ mallinfo-file.c \ meminfo-file.c \ measure-file.c \ profile-file.c meta_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = meta.h meta-hooks.h meta-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/view-dir.c0000644000000000000000000000013214522202451021463 xustar000000000000000030 mtime=1699284265.704027543 30 atime=1699284265.704027543 30 ctime=1699284307.007151947 glusterfs-11.1/xlators/meta/src/view-dir.c0000664000175100017510000000163014522202451021742 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static struct meta_dirent view_dir_dirents[] = {DOT_DOTDOT, {.name = NULL}}; static struct meta_ops view_dir_ops = {.fixed_dirents = view_dir_dirents}; int meta_view_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); meta_ops_set(loc->inode, this, &view_dir_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/name-file.c0000644000000000000000000000012714522202451021576 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 29 ctime=1699284307.01815198 glusterfs-11.1/xlators/meta/src/name-file.c0000664000175100017510000000201714522202451022051 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include #include static int name_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) { xlator_t *xl = NULL; xl = meta_ctx_get(file, this); strprintf(strfd, "%s\n", xl->name); return strfd->size; } static struct meta_ops name_file_ops = { .file_fill = name_file_fill, }; int meta_name_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ops_set(loc->inode, this, &name_file_ops); meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/subvolumes-dir.c0000644000000000000000000000013014522202451022713 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 30 ctime=1699284307.009151953 glusterfs-11.1/xlators/meta/src/subvolumes-dir.c0000664000175100017510000000303614522202451023176 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static int subvolumes_dir_fill(xlator_t *this, inode_t *dir, struct meta_dirent **dp) { struct meta_dirent *dirents = NULL; xlator_t *xl = NULL; xlator_list_t *subv = NULL; int i = 0; int count = 0; xl = meta_ctx_get(dir, this); for (subv = xl->children; subv; subv = subv->next) count++; dirents = GF_MALLOC(sizeof(*dirents) * count, gf_meta_mt_dirents_t); if (!dirents) return -1; for (subv = xl->children; subv; subv = subv->next) { char num[16] = {}; snprintf(num, 16, "%d", i); dirents[i].name = gf_strdup(num); dirents[i].type = IA_IFLNK; dirents[i].hook = meta_subvolume_link_hook; i++; } *dp = dirents; return count; } static struct meta_ops subvolumes_dir_ops = {.dir_fill = subvolumes_dir_fill}; int meta_subvolumes_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); meta_ops_set(loc->inode, this, &subvolumes_dir_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/subvolume-link.c0000644000000000000000000000013014522202451022707 xustar000000000000000029 mtime=1699284265.70302754 29 atime=1699284265.70302754 30 ctime=1699284307.010151956 glusterfs-11.1/xlators/meta/src/subvolume-link.c0000664000175100017510000000246514522202451023177 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" static int subvolume_link_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) { xlator_t *xl = NULL; xl = meta_ctx_get(inode, this); strprintf(strfd, "../../%s", xl->name); return 0; } struct meta_ops subvolume_link_ops = {.link_fill = subvolume_link_fill}; int meta_subvolume_link_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int count = 0; int i = 0; xlator_t *xl = NULL; xlator_list_t *subv = NULL; xlator_t *subvol = NULL; count = strtol(loc->name, 0, 0); xl = meta_ctx_get(loc->parent, this); for (subv = xl->children; subv; subv = subv->next) { if (i == count) { subvol = subv->xlator; break; } i++; } meta_ctx_set(loc->inode, this, subvol); meta_ops_set(loc->inode, this, &subvolume_link_ops); return 0; } glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/meta.h0000644000000000000000000000013114522202451020667 xustar000000000000000029 mtime=1699284265.70302754 30 atime=1699284265.702027537 30 ctime=1699284306.982151872 glusterfs-11.1/xlators/meta/src/meta.h0000664000175100017510000001046414522202451021154 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __META_H__ #define __META_H__ #include #define DEFAULT_META_DIR_NAME ".meta" #define META_ROOT_GFID "ba926388-bb9c-4eec-ad60-79dba4cc083a" typedef int (*meta_hook_t)(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata); typedef struct { dict_t *xdata; } meta_local_t; typedef struct { char *meta_dir_name; unsigned char meta_root_gfid[GF_UUID_BUF_SIZE]; } meta_priv_t; struct meta_dirent { const char *name; ia_type_t type; meta_hook_t hook; }; #define DOT_DOTDOT \ {.name = ".", .type = IA_IFDIR}, { .name = "..", .type = IA_IFDIR } struct meta_ops { struct meta_dirent *fixed_dirents; int (*dir_fill)(xlator_t *this, inode_t *dir, struct meta_dirent **entries); int (*file_fill)(xlator_t *this, inode_t *file, strfd_t *strfd); int (*iatt_fill)(xlator_t *this, inode_t *inode, struct iatt *iatt); int (*link_fill)(xlator_t *this, inode_t *inode, strfd_t *strfd); int (*file_write)(xlator_t *this, fd_t *fd, struct iovec *iov, int count); struct xlator_fops fops; struct xlator_cbks cbks; }; typedef struct { char *data; struct meta_dirent *dirents; size_t size; } meta_fd_t; #define COUNT(arr) (sizeof(arr) / sizeof(arr[0])) #define META_STACK_UNWIND(fop, frame, params...) \ do { \ meta_local_t *__local = NULL; \ if (frame) { \ __local = frame->local; \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ if (__local) { \ meta_local_cleanup(__local); \ } \ } while (0) #define META_FOP(i, fop, fr, t, params...) \ { \ struct xlator_fops *_fops = NULL; \ \ _fops = meta_fops_get(i, t); \ \ _fops->fop(fr, t, params); \ } \ while (0) void meta_iatt_fill(xlator_t *this, struct iatt *iatt, inode_t *inode, ia_type_t type); int meta_inode_discover(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata); int meta_ops_set(inode_t *inode, xlator_t *this, struct meta_ops *ops); struct xlator_fops * meta_fops_get(inode_t *inode, xlator_t *this); struct xlator_cbks * meta_cbks_get(inode_t *inode, xlator_t *this); struct meta_ops * meta_ops_get(inode_t *inode, xlator_t *this); int meta_ctx_set(inode_t *inode, xlator_t *this, void *ctx); void * meta_ctx_get(inode_t *inode, xlator_t *this); void meta_local_cleanup(meta_local_t *local); struct xlator_fops * meta_defaults_init(struct xlator_fops *fops); meta_fd_t * meta_fd_get(fd_t *fd, xlator_t *this); int meta_fd_release(fd_t *fd, xlator_t *this); dict_t * meta_direct_io_mode(dict_t *xdata, call_frame_t *frame); int meta_file_fill(xlator_t *this, meta_fd_t *meta_fd, fd_t *fd); int meta_dir_fill(xlator_t *this, meta_fd_t *meta_fd, struct meta_ops *ops, fd_t *fd); int fixed_dirents_len(struct meta_dirent *dirents); #endif /* __META_H__ */ glusterfs-11.1/xlators/meta/src/PaxHeaders.9031/xlator-dir.c0000644000000000000000000000013114522202451022021 xustar000000000000000030 mtime=1699284265.704027543 30 atime=1699284265.704027543 29 ctime=1699284306.99815192 glusterfs-11.1/xlators/meta/src/xlator-dir.c0000664000175100017510000000420414522202451022301 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "meta-mem-types.h" #include "meta.h" #include "meta-hooks.h" static struct meta_dirent xlator_dir_dirents[] = { DOT_DOTDOT, { .name = "view", .type = IA_IFDIR, .hook = meta_view_dir_hook, }, { .name = "type", .type = IA_IFREG, .hook = meta_type_file_hook, }, { .name = "name", .type = IA_IFREG, .hook = meta_name_file_hook, }, { .name = "subvolumes", .type = IA_IFDIR, .hook = meta_subvolumes_dir_hook, }, { .name = "options", .type = IA_IFDIR, .hook = meta_options_dir_hook, }, { .name = "private", .type = IA_IFREG, .hook = meta_private_file_hook, }, { .name = "history", .type = IA_IFREG, .hook = meta_history_file_hook, }, { .name = "meminfo", .type = IA_IFREG, .hook = meta_meminfo_file_hook, }, { .name = "profile", .type = IA_IFREG, .hook = meta_profile_file_hook, }, {.name = NULL}}; static struct meta_ops xlator_dir_ops = {.fixed_dirents = xlator_dir_dirents}; int meta_xlator_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { glusterfs_graph_t *graph = NULL; xlator_t *xl = NULL; graph = meta_ctx_get(loc->parent, this); xl = xlator_search_by_name(graph->first, loc->name); meta_ctx_set(loc->inode, this, xl); meta_ops_set(loc->inode, this, &xlator_dir_ops); return 0; } int meta_root_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { meta_ctx_set(loc->inode, this, this->ctx->root); meta_ops_set(loc->inode, this, &xlator_dir_ops); return 0; } glusterfs-11.1/xlators/meta/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465021054 xustar000000000000000030 mtime=1699284277.759063854 30 atime=1699284288.742096934 30 ctime=1699284306.932151721 glusterfs-11.1/xlators/meta/Makefile.in0000664000175100017510000005256414522202465021347 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/meta DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/meta/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/meta/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/meta/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451021036 xustar000000000000000030 mtime=1699284265.700027531 30 atime=1699284277.735063781 30 ctime=1699284306.934151727 glusterfs-11.1/xlators/meta/Makefile.am0000664000175100017510000000001614522202451021312 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/PaxHeaders.9031/protocol0000644000000000000000000000013114522202515017640 xustar000000000000000030 mtime=1699284301.825136339 29 atime=1699284309.68416001 30 ctime=1699284301.825136339 glusterfs-11.1/xlators/protocol/0002775000175100017510000000000014522202515020177 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/PaxHeaders.9031/client0000644000000000000000000000012714522202515021123 xustar000000000000000029 mtime=1699284301.77213618 29 atime=1699284309.68416001 29 ctime=1699284301.77213618 glusterfs-11.1/xlators/protocol/client/0002775000175100017510000000000014522202515021455 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/client/PaxHeaders.9031/src0000644000000000000000000000012714522202515021712 xustar000000000000000029 mtime=1699284301.82213633 29 atime=1699284309.68416001 29 ctime=1699284301.82213633 glusterfs-11.1/xlators/protocol/client/src/0002775000175100017510000000000014522202515022244 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client-helpers.c0000644000000000000000000000013214522202451025044 xustar000000000000000030 mtime=1699284265.773027751 30 atime=1699284265.773027751 30 ctime=1699284301.817136315 glusterfs-11.1/xlators/protocol/client/src/client-helpers.c0000664000175100017510000003273014522202451025330 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "client.h" #include #include "client-messages.h" #include "client-common.h" #include #include int client_fd_lk_list_empty(fd_lk_ctx_t *lk_ctx, gf_boolean_t try_lock) { int ret = 1; if (!lk_ctx) { ret = -1; goto out; } if (try_lock) { ret = TRY_LOCK(&lk_ctx->lock); if (ret != 0) { ret = -1; goto out; } } else { LOCK(&lk_ctx->lock); } ret = list_empty(&lk_ctx->lk_list); UNLOCK(&lk_ctx->lock); out: return ret; } clnt_fd_ctx_t * this_fd_del_ctx(fd_t *file, xlator_t *this) { clnt_fd_ctx_t *ctxaddr = NULL; ctxaddr = fd_ctx_del_ptr(file, this); if (!ctxaddr) { /* check that we did not pass NULL to either this or file */ GF_VALIDATE_OR_GOTO("client", this, out); GF_VALIDATE_OR_GOTO(this->name, file, out); } out: return ctxaddr; } clnt_fd_ctx_t * this_fd_get_ctx(fd_t *file, xlator_t *this) { clnt_fd_ctx_t *ctxaddr = NULL; ctxaddr = fd_ctx_get_ptr(file, this); if (!ctxaddr) { /* check that we did not pass NULL to either this or file */ GF_VALIDATE_OR_GOTO("client", this, out); GF_VALIDATE_OR_GOTO(this->name, file, out); } out: return ctxaddr; } void this_fd_set_ctx(fd_t *file, xlator_t *this, loc_t *loc, clnt_fd_ctx_t *ctx) { uint64_t oldaddr = 0; int32_t ret = -1; GF_VALIDATE_OR_GOTO("client", this, out); GF_VALIDATE_OR_GOTO(this->name, file, out); oldaddr = fd_ctx_get(file, this); if (oldaddr) { if (loc) gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_FD_DUPLICATE_TRY, "path=%s", loc->path, "gfid=%s", uuid_utoa(loc->inode->gfid), NULL); else gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_FD_DUPLICATE_TRY, "file=%p", file, NULL); } ret = fd_ctx_set(file, this, (uint64_t)(unsigned long)ctx); if (ret < 0) { if (loc) gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FD_SET_FAIL, "path=%s", loc->path, "gfid=%s", uuid_utoa(loc->inode->gfid), NULL); else gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FD_SET_FAIL, "file=%p", file, NULL); } out: return; } int client_local_wipe(clnt_local_t *local) { if (local) { loc_wipe(&local->loc); loc_wipe(&local->loc2); if (local->fd) { fd_unref(local->fd); } if (local->iobref) { iobref_unref(local->iobref); } GF_FREE(local->name); mem_put(local); } return 0; } int unserialize_rsp_dirent_v2(xlator_t *this, struct gfx_readdir_rsp *rsp, gf_dirent_t *entries) { struct gfx_dirlist *trav = NULL; gf_dirent_t *entry = NULL; int ret = -1; clnt_conf_t *conf = NULL; conf = this->private; trav = rsp->reply; while (trav) { entry = gf_dirent_for_name2(trav->name, trav->d_len, trav->d_ino, 0, trav->d_type, NULL); if (!entry) goto out; gf_itransform(this, trav->d_off, &entry->d_off, conf->client_id); list_add_tail(&entry->list, &entries->list); trav = trav->nextentry; } ret = 0; out: return ret; } int unserialize_rsp_direntp_v2(xlator_t *this, fd_t *fd, struct gfx_readdirp_rsp *rsp, gf_dirent_t *entries) { struct gfx_dirplist *trav = NULL; gf_dirent_t *entry = NULL; inode_table_t *itable = NULL; int ret = -1; clnt_conf_t *conf = NULL; trav = rsp->reply; if (fd) itable = fd->inode->table; conf = this->private; if (!conf) goto out; while (trav) { entry = gf_dirent_for_name2(trav->name, trav->d_len, trav->d_ino, 0, trav->d_type, NULL); if (!entry) goto out; gf_itransform(this, trav->d_off, &entry->d_off, conf->client_id); gfx_stat_to_iattx(&trav->stat, &entry->d_stat); xdr_to_dict(&trav->dict, &entry->dict); entry->inode = inode_find(itable, entry->d_stat.ia_gfid); if (!entry->inode) entry->inode = inode_new(itable); list_add_tail(&entry->list, &entries->list); trav = trav->nextentry; } ret = 0; out: return ret; } int clnt_readdirp_rsp_cleanup_v2(gfx_readdirp_rsp *rsp) { gfx_dirplist *prev = NULL; gfx_dirplist *trav = NULL; trav = rsp->reply; prev = trav; while (trav) { trav = trav->nextentry; free(prev->name); free(prev); prev = trav; } return 0; } int clnt_readdir_rsp_cleanup_v2(gfx_readdir_rsp *rsp) { gfx_dirlist *prev = NULL; gfx_dirlist *trav = NULL; trav = rsp->reply; prev = trav; while (trav) { trav = trav->nextentry; /* on client, the rpc lib allocates this */ free(prev->name); free(prev); prev = trav; } return 0; } int client_get_remote_fd(xlator_t *this, fd_t *fd, int flags, int64_t *remote_fd, enum gf_fop_procnum fop) { clnt_fd_ctx_t *fdctx = NULL; clnt_conf_t *conf = NULL; gf_boolean_t locks_involved = _gf_false; GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, remote_fd, out); conf = this->private; pthread_spin_lock(&conf->fd_lock); { fdctx = this_fd_get_ctx(fd, this); if (!fdctx) { if (fd->anonymous) { *remote_fd = GF_ANON_FD_NO; } else { if (conf->strict_locks && (fop == GFS3_OP_WRITE || fop == GFS3_OP_FTRUNCATE || fop == GFS3_OP_FALLOCATE || fop == GFS3_OP_ZEROFILL || fop == GFS3_OP_DISCARD)) { locks_involved = _gf_true; } *remote_fd = -1; gf_msg_debug(this->name, EBADF, "not a valid fd for gfid: %s", uuid_utoa(fd->inode->gfid)); } } else { if (__is_fd_reopen_in_progress(fdctx)) { *remote_fd = -1; } else { *remote_fd = fdctx->remote_fd; } locks_involved = !fd_lk_ctx_empty(fdctx->lk_ctx); } } pthread_spin_unlock(&conf->fd_lock); if ((flags & FALLBACK_TO_ANON_FD) && (*remote_fd == -1) && (!locks_involved)) { *remote_fd = GF_ANON_FD_NO; } return 0; out: return -1; } gf_boolean_t client_is_reopen_needed(fd_t *fd, xlator_t *this, int64_t remote_fd) { clnt_conf_t *conf = NULL; clnt_fd_ctx_t *fdctx = NULL; gf_boolean_t res = _gf_false; conf = this->private; pthread_spin_lock(&conf->fd_lock); { fdctx = this_fd_get_ctx(fd, this); if (fdctx && (fdctx->remote_fd == -1) && (remote_fd == GF_ANON_FD_NO)) res = _gf_true; } pthread_spin_unlock(&conf->fd_lock); return res; } int client_fd_fop_prepare_local(call_frame_t *frame, fd_t *fd, int64_t remote_fd) { xlator_t *this = NULL; clnt_local_t *local = NULL; int ret = 0; if (!frame || !fd) { ret = -EINVAL; goto out; } this = frame->this; frame->local = mem_get0(this->local_pool); if (frame->local == NULL) { ret = -ENOMEM; goto out; } local = frame->local; local->fd = fd_ref(fd); local->attempt_reopen = client_is_reopen_needed(fd, this, remote_fd); return 0; out: return ret; } void clnt_getactivelk_rsp_cleanup_v2(gfx_getactivelk_rsp *rsp) { gfs3_locklist *trav = NULL; gfs3_locklist *next = NULL; trav = rsp->reply; while (trav) { next = trav->nextentry; free(trav->client_uid); free(trav); trav = next; } } int clnt_unserialize_rsp_locklist_v2(struct gfx_getactivelk_rsp *rsp, lock_migration_info_t *lmi) { struct gfs3_locklist *trav = NULL; lock_migration_info_t *temp = NULL; int ret = -1; trav = rsp->reply; while (trav) { /* TODO: move to GF_MALLOC() */ temp = GF_CALLOC(1, sizeof(*lmi), gf_common_mt_lock_mig); if (temp == NULL) { gf_smsg(THIS->name, GF_LOG_ERROR, 0, PC_MSG_NO_MEM, NULL); goto out; } INIT_LIST_HEAD(&temp->list); gf_proto_flock_to_flock(&trav->flock, &temp->flock); temp->lk_flags = trav->lk_flags; temp->client_uid = gf_strdup(trav->client_uid); list_add_tail(&temp->list, &lmi->list); trav = trav->nextentry; } ret = 0; out: return ret; } void clnt_setactivelk_req_cleanup_v2(gfx_setactivelk_req *req) { gfs3_locklist *trav = NULL; gfs3_locklist *next = NULL; trav = req->request; while (trav) { next = trav->nextentry; GF_FREE(trav->client_uid); GF_FREE(trav); trav = next; } } int serialize_req_locklist_v2(lock_migration_info_t *locklist, gfx_setactivelk_req *req) { lock_migration_info_t *tmp = NULL; gfs3_locklist *trav = NULL; gfs3_locklist *prev = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("server", locklist, out); GF_VALIDATE_OR_GOTO("server", req, out); list_for_each_entry(tmp, &locklist->list, list) { trav = GF_CALLOC(1, sizeof(*trav), gf_client_mt_clnt_lock_request_t); if (!trav) goto out; switch (tmp->flock.l_type) { case F_RDLCK: tmp->flock.l_type = GF_LK_F_RDLCK; break; case F_WRLCK: tmp->flock.l_type = GF_LK_F_WRLCK; break; case F_UNLCK: tmp->flock.l_type = GF_LK_F_UNLCK; break; default: gf_smsg(THIS->name, GF_LOG_ERROR, 0, PC_MSG_UNKNOWN_LOCK_TYPE, "type=%" PRId32, tmp->flock.l_type, NULL); break; } gf_proto_flock_from_flock(&trav->flock, &tmp->flock); trav->lk_flags = tmp->lk_flags; trav->client_uid = gf_strdup(tmp->client_uid); if (!trav->client_uid) { gf_smsg(THIS->name, GF_LOG_ERROR, 0, PC_MSG_CLIENT_UID_ALLOC_FAILED, NULL); ret = -1; goto out; } if (prev) prev->nextentry = trav; else req->request = trav; prev = trav; trav = NULL; } ret = 0; out: GF_FREE(trav); return ret; } extern int client3_3_releasedir_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe); extern int client3_3_release_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe); extern int client4_0_releasedir_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe); extern int client4_0_release_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe); static int send_release4_0_over_wire(xlator_t *this, clnt_fd_ctx_t *fdctx, call_frame_t *fr) { clnt_conf_t *conf = NULL; conf = (clnt_conf_t *)this->private; if (fdctx->is_dir) { gfx_releasedir_req req = { { 0, }, }; memcpy(req.gfid, fdctx->gfid, 16); req.fd = fdctx->remote_fd; gf_msg_trace(this->name, 0, "sending releasedir on fd"); (void)client_submit_request( this, &req, fr, conf->fops, GFS3_OP_RELEASEDIR, client4_0_releasedir_cbk, NULL, (xdrproc_t)xdr_gfx_releasedir_req); } else { gfx_release_req req = { { 0, }, }; memcpy(req.gfid, fdctx->gfid, 16); req.fd = fdctx->remote_fd; gf_msg_trace(this->name, 0, "sending release on fd"); (void)client_submit_request(this, &req, fr, conf->fops, GFS3_OP_RELEASE, client4_0_release_cbk, NULL, (xdrproc_t)xdr_gfx_release_req); } return 0; } int client_fdctx_destroy(xlator_t *this, clnt_fd_ctx_t *fdctx) { clnt_conf_t *conf = NULL; call_frame_t *fr = NULL; int32_t ret = -1; char parent_down = 0; fd_lk_ctx_t *lk_ctx = NULL; GF_VALIDATE_OR_GOTO("client", this, out); GF_VALIDATE_OR_GOTO(this->name, fdctx, out); conf = (clnt_conf_t *)this->private; if (fdctx->remote_fd == -1) { gf_msg_debug(this->name, 0, "not a valid fd"); goto out; } pthread_mutex_lock(&conf->lock); { parent_down = conf->parent_down; } pthread_mutex_unlock(&conf->lock); lk_ctx = fdctx->lk_ctx; fdctx->lk_ctx = NULL; if (lk_ctx) fd_lk_ctx_unref(lk_ctx); if (!parent_down) rpc_clnt_ref(conf->rpc); else goto out; fr = create_frame(this, this->ctx->pool); if (fr == NULL) { goto out; } ret = 0; send_release4_0_over_wire(this, fdctx, fr); rpc_clnt_unref(conf->rpc); out: if (fdctx) { fdctx->remote_fd = -1; GF_FREE(fdctx); } return ret; } glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client-handshake.c0000644000000000000000000000013214522202451025330 xustar000000000000000030 mtime=1699284265.773027751 30 atime=1699284265.772027748 30 ctime=1699284301.819136321 glusterfs-11.1/xlators/protocol/client/src/client-handshake.c0000664000175100017510000010027314522202451025612 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "client.h" #include "rpc-common-xdr.h" #include #include "portmap-xdr.h" #include "client-messages.h" #include "xdr-rpc.h" #define CLIENT_REOPEN_MAX_ATTEMPTS 1024 #define GLUSTER_PROCESS_UUID_FMT \ "CTX_ID:%s-GRAPH_ID:%d-PID:%d-HOST:%s-PC_NAME:%s-RECON_NO:%s" extern rpc_clnt_prog_t clnt4_0_fop_prog; extern rpc_clnt_prog_t clnt_pmap_prog; void client_save_number_fds(clnt_conf_t *conf, int count) { LOCK(&conf->rec_lock); { conf->reopen_fd_count = count; } UNLOCK(&conf->rec_lock); } int32_t client3_getspec(call_frame_t *frame, xlator_t *this, void *data) { CLIENT_STACK_UNWIND(getspec, frame, -1, ENOSYS, NULL); return 0; } static int client_notify_parents_child_up(xlator_t *this) { clnt_conf_t *conf = NULL; int ret = 0; GF_VALIDATE_OR_GOTO("client", this, out); conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); if (conf->child_up) { ret = client_notify_dispatch_uniq(this, GF_EVENT_CHILD_UP, NULL); if (ret) { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_UP_NOTIFY_FAILED, NULL); goto out; } } else { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_STATUS, NULL); } out: return 0; } void client_default_reopen_done(clnt_fd_ctx_t *fdctx, int64_t rfd, xlator_t *this) { gf_log_callingfn(this->name, GF_LOG_WARNING, "This function should never be called"); } static void client_reopen_done(clnt_fd_ctx_t *fdctx, int64_t rfd, xlator_t *this) { clnt_conf_t *conf = this->private; gf_boolean_t destroy = _gf_false; pthread_spin_lock(&conf->fd_lock); { fdctx->remote_fd = rfd; fdctx->reopen_attempts = 0; fdctx->reopen_done = client_default_reopen_done; if (!fdctx->released) list_add_tail(&fdctx->sfd_pos, &conf->saved_fds); else destroy = _gf_true; } pthread_spin_unlock(&conf->fd_lock); if (destroy) client_fdctx_destroy(this, fdctx); } static void client_child_up_reopen_done(clnt_fd_ctx_t *fdctx, int64_t rfd, xlator_t *this) { clnt_conf_t *conf = this->private; uint64_t fd_count = 0; LOCK(&conf->rec_lock); { fd_count = --(conf->reopen_fd_count); } UNLOCK(&conf->rec_lock); client_reopen_done(fdctx, rfd, this); if (fd_count == 0) { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_UP_NOTIFY, NULL); client_notify_parents_child_up(this); } } /* v4.x + */ int client4_0_reopen_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { int32_t ret = -1; gfx_open_rsp rsp = { 0, }; call_frame_t *frame = myframe; xlator_t *this = frame->this; clnt_local_t *local = frame->local; clnt_fd_ctx_t *fdctx = local->fdctx; if (-1 == req->rpc_status) { gf_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, PC_MSG_RPC_STATUS_ERROR, NULL); rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_open_rsp); if (ret < 0) { gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (rsp.op_ret < 0) { gf_smsg(frame->this->name, GF_LOG_WARNING, rsp.op_errno, PC_MSG_REOPEN_FAILED, "path=%s", local->loc.path, NULL); } else { gf_msg_debug(frame->this->name, 0, "reopen on %s succeeded (remote-fd = %" PRId64 ")", local->loc.path, rsp.fd); } if (rsp.op_ret == -1) { goto out; } out: fdctx->reopen_done(fdctx, (rsp.op_ret) ? -1 : rsp.fd, this); frame->local = NULL; STACK_DESTROY(frame->root); client_local_wipe(local); return 0; } int client4_0_reopendir_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { int32_t ret = -1; gfx_open_rsp rsp = { 0, }; call_frame_t *frame = myframe; clnt_local_t *local = frame->local; clnt_fd_ctx_t *fdctx = local->fdctx; if (-1 == req->rpc_status) { gf_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, PC_MSG_RPC_STATUS_ERROR, NULL); rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_open_rsp); if (ret < 0) { gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (rsp.op_ret < 0) { gf_smsg(frame->this->name, GF_LOG_WARNING, rsp.op_errno, PC_MSG_DIR_OP_FAILED, "dir-path=%s", local->loc.path, NULL); } else { gf_smsg(frame->this->name, GF_LOG_INFO, 0, PC_MSG_DIR_OP_SUCCESS, "path=%s", local->loc.path, "fd=%" PRId64, rsp.fd, NULL); } if (-1 == rsp.op_ret) { goto out; } out: fdctx->reopen_done(fdctx, (rsp.op_ret) ? -1 : rsp.fd, frame->this); frame->local = NULL; STACK_DESTROY(frame->root); client_local_wipe(local); return 0; } static int protocol_client_reopendir_v2(clnt_fd_ctx_t *fdctx, xlator_t *this) { int ret = -1; gfx_opendir_req req = { { 0, }, }; call_frame_t *frame = NULL; clnt_conf_t *conf = this->private; clnt_local_t *local = mem_get0(this->local_pool); if (!local) { ret = -1; goto out; } local->fdctx = fdctx; gf_uuid_copy(local->loc.gfid, fdctx->gfid); ret = loc_path(&local->loc, NULL); if (ret < 0) goto out; frame = create_frame(this, this->ctx->pool); if (!frame) { ret = -1; goto out; } memcpy(req.gfid, fdctx->gfid, 16); gf_msg_debug(frame->this->name, 0, "attempting reopen on %s", local->loc.path); frame->local = local; ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPENDIR, client4_0_reopendir_cbk, NULL, (xdrproc_t)xdr_gfx_opendir_req); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DIR_OP_FAILED, NULL); } return 0; out: if (local) client_local_wipe(local); fdctx->reopen_done(fdctx, fdctx->remote_fd, this); return 0; } static int protocol_client_reopenfile_v2(clnt_fd_ctx_t *fdctx, xlator_t *this) { int ret = -1; gfx_open_req req = { { 0, }, }; clnt_local_t *local = NULL; clnt_conf_t *conf = this->private; call_frame_t *frame = create_frame(this, this->ctx->pool); if (!frame) { ret = -1; goto out; } local = mem_get0(this->local_pool); if (!local) { ret = -1; goto out; } local->fdctx = fdctx; gf_uuid_copy(local->loc.gfid, fdctx->gfid); ret = loc_path(&local->loc, NULL); if (ret < 0) goto out; frame->local = local; memcpy(req.gfid, fdctx->gfid, 16); req.flags = gf_flags_from_flags(fdctx->flags); req.flags = req.flags & (~(O_TRUNC | O_CREAT | O_EXCL)); gf_msg_debug(frame->this->name, 0, "attempting reopen on %s", local->loc.path); ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPEN, client4_0_reopen_cbk, NULL, (xdrproc_t)xdr_gfx_open_req); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DIR_OP_FAILED, NULL); } return 0; out: if (frame) { frame->local = NULL; STACK_DESTROY(frame->root); } if (local) client_local_wipe(local); fdctx->reopen_done(fdctx, fdctx->remote_fd, this); return 0; } static void protocol_client_reopen_v2(clnt_fd_ctx_t *fdctx, xlator_t *this) { if (fdctx->is_dir) protocol_client_reopendir_v2(fdctx, this); else protocol_client_reopenfile_v2(fdctx, this); } gf_boolean_t __is_fd_reopen_in_progress(clnt_fd_ctx_t *fdctx) { if (fdctx->reopen_done == client_default_reopen_done) return _gf_false; return _gf_true; } void client_attempt_reopen(fd_t *fd, xlator_t *this) { if (!fd || !this) goto out; clnt_conf_t *conf = this->private; clnt_fd_ctx_t *fdctx = NULL; gf_boolean_t reopen = _gf_false; pthread_spin_lock(&conf->fd_lock); { fdctx = this_fd_get_ctx(fd, this); if (!fdctx) { pthread_spin_unlock(&conf->fd_lock); goto out; } if (__is_fd_reopen_in_progress(fdctx)) goto unlock; if (fdctx->remote_fd != -1) goto unlock; if (fdctx->reopen_attempts == CLIENT_REOPEN_MAX_ATTEMPTS) { reopen = _gf_true; fdctx->reopen_done = client_reopen_done; list_del_init(&fdctx->sfd_pos); } else { fdctx->reopen_attempts++; } } unlock: pthread_spin_unlock(&conf->fd_lock); if (reopen) { protocol_client_reopen_v2(fdctx, this); } out: return; } static int client_post_handshake(call_frame_t *frame, xlator_t *this) { clnt_conf_t *conf = NULL; clnt_fd_ctx_t *tmp = NULL; clnt_fd_ctx_t *fdctx = NULL; struct list_head reopen_head; int count = 0; if (!this || !this->private) goto out; conf = this->private; INIT_LIST_HEAD(&reopen_head); pthread_spin_lock(&conf->fd_lock); { list_for_each_entry_safe(fdctx, tmp, &conf->saved_fds, sfd_pos) { if (fdctx->remote_fd != -1 || (!fd_lk_ctx_empty(fdctx->lk_ctx) && conf->strict_locks)) continue; fdctx->reopen_done = client_child_up_reopen_done; list_del_init(&fdctx->sfd_pos); list_add_tail(&fdctx->sfd_pos, &reopen_head); count++; } } pthread_spin_unlock(&conf->fd_lock); /* Delay notifying CHILD_UP to parents until all locks are recovered */ if (count > 0) { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_UP_NOTIFY_DELAY, "count=%d", count, NULL); client_save_number_fds(conf, count); list_for_each_entry_safe(fdctx, tmp, &reopen_head, sfd_pos) { list_del_init(&fdctx->sfd_pos); protocol_client_reopen_v2(fdctx, this); } } else { gf_msg_debug(this->name, 0, "No fds to open - notifying all parents child " "up"); client_notify_parents_child_up(this); } out: return 0; } int client_setvolume_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = myframe; xlator_t *this = frame->this; clnt_conf_t *conf = this->private; dict_t *reply = NULL; char *process_uuid = NULL; char *volume_id = NULL; char *remote_error = NULL; char *remote_subvol = NULL; gf_setvolume_rsp rsp = { 0, }; int ret = 0; int32_t op_ret = 0; int32_t op_errno = 0; gf_boolean_t auth_fail = _gf_false; glusterfs_ctx_t *ctx = NULL; GF_VALIDATE_OR_GOTO(this->name, conf, out); ctx = this->ctx; GF_VALIDATE_OR_GOTO(this->name, ctx, out); if (-1 == req->rpc_status) { gf_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, PC_MSG_RPC_STATUS_ERROR, NULL); op_ret = -1; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_setvolume_rsp); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); op_ret = -1; goto out; } op_ret = rsp.op_ret; op_errno = gf_error_to_errno(rsp.op_errno); if (-1 == rsp.op_ret) { gf_smsg(frame->this->name, GF_LOG_WARNING, op_errno, PC_MSG_VOL_SET_FAIL, NULL); } reply = dict_new(); if (!reply) goto out; if (rsp.dict.dict_len) { ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &reply); if (ret < 0) { gf_smsg(frame->this->name, GF_LOG_WARNING, 0, PC_MSG_DICT_UNSERIALIZE_FAIL, NULL); goto out; } } ret = dict_get_str_sizen(reply, "ERROR", &remote_error); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_DICT_GET_FAILED, "ERROR string", NULL); } ret = dict_get_str_sizen(reply, "process-uuid", &process_uuid); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_DICT_GET_FAILED, "process-uuid", NULL); } if (op_ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, op_errno, PC_MSG_SETVOLUME_FAIL, "remote-error=%s", remote_error, NULL); errno = op_errno; if (remote_error && (op_errno == EACCES)) { auth_fail = _gf_true; op_ret = 0; } if ((op_errno == ENOENT) && this->ctx->cmd_args.subdir_mount && (ctx->graph_id <= 1)) { /* A case of subdir not being present at the moment, ride on auth_fail framework to notify the error */ /* Make sure this case is handled only in the new graph, so mount may fail in this case. In case of 'add-brick' etc, we need to continue retry */ auth_fail = _gf_true; op_ret = 0; } if (op_errno == ESTALE) { ret = client_notify_dispatch(this, GF_EVENT_VOLFILE_MODIFIED, NULL); if (ret) gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_VOLFILE_NOTIFY_FAILED, NULL); } goto out; } ret = dict_get_str_sizen(this->options, "remote-subvolume", &remote_subvol); if (ret || !remote_subvol) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FIND_KEY_FAILED, "remote-subvolume", NULL); goto out; } ret = dict_get_str_sizen(reply, "volume-id", &volume_id); if (ret < 0) { /* this can happen if the server is of old version, so treat it as just debug message */ gf_msg_debug(this->name, EINVAL, "failed to get 'volume-id' from reply dict"); } else if (ctx->root && strncmp("snapd", remote_subvol, 5)) { /* TODO: if it is a fuse mount or a snapshot enabled client, don't bother */ /* If any value is set, the first element will be non-0. It would be '0', but not '\0' :-) */ if (ctx->volume_id[0]) { if (strcmp(ctx->volume_id, volume_id)) { /* Ideally it shouldn't even come here, as server itself should fail the handshake in that case */ gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_VOL_ID_CHANGED, "vol-id=%s", volume_id, "ctx->vol-id=%s", ctx->volume_id, NULL); op_ret = -1; goto out; } } else { strncpy(ctx->volume_id, volume_id, GF_UUID_BUF_SIZE - 1); ctx->volume_id[GF_UUID_BUF_SIZE - 1] = '\0'; } } uint32_t child_up_int; ret = dict_get_uint32(reply, "child_up", &child_up_int); if (ret) { /* * This would happen in cases where the server trying to * * connect to this client is running an older version. Hence * * setting the child_up to _gf_true in this case. * */ gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FIND_KEY_FAILED, "child_up", NULL); conf->child_up = _gf_true; } else { conf->child_up = (child_up_int != 0); } /* TODO: currently setpeer path is broken */ /* if (process_uuid && req->conn && !strcmp (this->ctx->process_uuid, process_uuid)) { rpc_transport_t *peer_trans = NULL; uint64_t peertrans_int = 0; ret = dict_get_uint64 (reply, "transport-ptr", &peertrans_int); if (ret) goto out; gf_log (this->name, GF_LOG_WARNING, "attaching to the local volume '%s'", remote_subvol); peer_trans = (void *) (long) (peertrans_int); rpc_transport_setpeer (req->conn->trans, peer_trans); } */ conf->client_id = glusterfs_leaf_position(this); gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_REMOTE_VOL_CONNECTED, "conn-name=%s", conf->rpc->conn.name, "remote_subvol=%s", remote_subvol, NULL); op_ret = 0; conf->connected = 1; client_post_handshake(frame, frame->this); out: if (auth_fail) { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_AUTH_FAILED, NULL); ret = client_notify_dispatch(this, GF_EVENT_AUTH_FAILED, NULL); if (ret) gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_AUTH_FAILED_NOTIFY_FAILED, NULL); conf->connected = 0; ret = -1; } if (-1 == op_ret) { /* Let the connection/re-connection happen in * background, for now, don't hang here, * tell the parents that i am all ok.. */ gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_CONNECTING_EVENT, NULL); ret = client_notify_dispatch(this, GF_EVENT_CHILD_CONNECTING, NULL); if (ret) gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_CONNECTING_NOTIFY_FAILED, NULL); /* * The reconnection *won't* happen in the background (see * previous comment) unless we kill the current connection. */ rpc_transport_disconnect(conf->rpc->conn.trans, _gf_false); ret = 0; } free(rsp.dict.dict_val); STACK_DESTROY(frame->root); if (reply) dict_unref(reply); return ret; } int client_setvolume(xlator_t *this, struct rpc_clnt *rpc) { int ret = 0; gf_setvolume_req req = { { 0, }, }; call_frame_t *fr = NULL; char *process_uuid_xl = NULL; char *remote_subvol = NULL; clnt_conf_t *conf = this->private; dict_t *options = this->options; char counter_str[32] = {0}; if (conf->fops) { ret = dict_set_int32_sizen(options, "fops-version", conf->fops->prognum); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SET_FAILED, "version-fops=%d", conf->fops->prognum, NULL); goto fail; } } if (conf->mgmt) { ret = dict_set_int32_sizen(options, "mgmt-version", conf->mgmt->prognum); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SET_FAILED, "version-mgmt=%d", conf->mgmt->prognum, NULL); goto fail; } } /* * Connection-id should always be unique so that server never gets to * reuse the previous connection resources so it cleans up the resources * on every disconnect. Otherwise it may lead to stale resources, i.e. * leaked file descriptors, inode/entry locks */ snprintf(counter_str, sizeof(counter_str), "-%" PRIu64, conf->setvol_count); conf->setvol_count++; ret = gf_asprintf(&process_uuid_xl, GLUSTER_PROCESS_UUID_FMT, this->ctx->process_uuid, this->graph->id, getpid(), gf_gethostname(), this->name, counter_str); if (-1 == ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_PROCESS_UUID_SET_FAIL, NULL); goto fail; } ret = dict_set_dynstr_sizen(options, "process-uuid", process_uuid_xl); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SET_FAILED, "process-uuid=%s", process_uuid_xl, NULL); goto fail; } if (this->ctx->cmd_args.process_name) { ret = dict_set_str_sizen(options, "process-name", this->ctx->cmd_args.process_name); if (ret < 0) { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_DICT_SET_FAILED, "process-name", NULL); } } ret = dict_set_str_sizen(options, "client-version", PACKAGE_VERSION); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_DICT_SET_FAILED, "client-version=%s", PACKAGE_VERSION, NULL); } ret = dict_get_str_sizen(this->options, "remote-subvolume", &remote_subvol); if (ret || !remote_subvol) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FIND_KEY_FAILED, "remote-subvolume", NULL); goto fail; } /* volume-id to be sent only for regular volume, not snap volume */ if (strncmp("snapd", remote_subvol, 5)) { /* If any value is set, the first element will be non-0. It would be '0', but not '\0' :-) */ if (!this->ctx->volume_id[0]) { strncpy(this->ctx->volume_id, this->graph->volume_id, GF_UUID_BUF_SIZE); this->ctx->volume_id[GF_UUID_BUF_SIZE - 1] = '\0'; } if (this->ctx->volume_id[0]) { ret = dict_set_str(options, "volume-id", this->ctx->volume_id); if (ret < 0) { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_DICT_SET_FAILED, "volume-id", NULL); } } } if (this->ctx->cmd_args.volfile_server) { if (this->ctx->cmd_args.volfile_id) { ret = dict_set_str_sizen(options, "volfile-key", this->ctx->cmd_args.volfile_id); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_VOLFILE_KEY_SET_FAILED, NULL); } ret = dict_set_uint32(options, "volfile-checksum", this->graph->volfile_checksum); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_VOLFILE_CHECKSUM_FAILED, NULL); } if (this->ctx->cmd_args.subdir_mount) { ret = dict_set_str_sizen(options, "subdir-mount", this->ctx->cmd_args.subdir_mount); if (ret) { gf_log(THIS->name, GF_LOG_ERROR, "Failed to set subdir_mount"); /* It makes sense to fail, as per the CLI, we should be doing a subdir_mount */ goto fail; } } /* Insert a dummy key value pair to avoid failure at server side for * clnt-lk-version with new clients. */ ret = dict_set_uint32(options, "clnt-lk-version", 1); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_DICT_SET_FAILED, "clnt-lk-version(1)", NULL); } ret = dict_set_int32_sizen(options, "opversion", GD_OP_VERSION_MAX); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SET_FAILED, "client opversion", NULL); } ret = dict_allocate_and_serialize(options, (char **)&req.dict.dict_val, &req.dict.dict_len); if (ret != 0) { ret = -1; gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SERIALIZE_FAIL, NULL); goto fail; } fr = create_frame(this, this->ctx->pool); if (!fr) goto fail; ret = client_submit_request(this, &req, fr, conf->handshake, GF_HNDSK_SETVOLUME, client_setvolume_cbk, NULL, (xdrproc_t)xdr_gf_setvolume_req); fail: GF_FREE(req.dict.dict_val); return ret; } static int select_server_supported_programs(xlator_t *this, gf_prog_detail *prog) { gf_prog_detail *trav = NULL; clnt_conf_t *conf = NULL; int ret = -1; if (!this || !prog) { gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_PGM_NOT_FOUND, NULL); goto out; } conf = this->private; trav = prog; while (trav) { /* Select 'programs' */ if ((clnt4_0_fop_prog.prognum == trav->prognum) && (clnt4_0_fop_prog.progver == trav->progver)) { conf->fops = &clnt4_0_fop_prog; if (conf->rpc) conf->rpc->auth_value = AUTH_GLUSTERFS_v3; ret = 0; /* this is latest program, lets use this program only */ /* if we are testing for old-protocol, lets not break this */ if (!conf->old_protocol) goto done; } if (ret) { gf_msg_debug(this->name, 0, "%s (%" PRId64 ") not supported", trav->progname, trav->progver); } trav = trav->next; } done: if (!ret) gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_VERSION_INFO, "Program-name=%s", conf->fops->progname, "Num=%d", conf->fops->prognum, "Version=%d", conf->fops->progver, NULL); out: return ret; } int server_has_portmap(xlator_t *this, gf_prog_detail *prog) { gf_prog_detail *trav = NULL; int ret = -1; if (!this || !prog) { gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_PGM_NOT_FOUND, NULL); goto out; } trav = prog; while (trav) { if ((trav->prognum == GLUSTER_PMAP_PROGRAM) && (trav->progver == GLUSTER_PMAP_VERSION)) { gf_msg_debug(this->name, 0, "detected portmapper on server"); ret = 0; break; } trav = trav->next; } out: return ret; } int client_query_portmap_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { struct pmap_port_by_brick_rsp rsp = { 0, }; call_frame_t *frame = NULL; clnt_conf_t *conf = NULL; int ret = -1; struct rpc_clnt_config config = { 0, }; xlator_t *this = NULL; frame = myframe; if (!frame || !frame->this || !frame->this->private) { gf_smsg(THIS->name, GF_LOG_WARNING, EINVAL, PC_MSG_FRAME_NOT_FOUND, NULL); goto out; } this = frame->this; conf = frame->this->private; if (-1 == req->rpc_status) { gf_smsg(this->name, GF_LOG_WARNING, ENOTCONN, PC_MSG_RPC_STATUS_ERROR, NULL); goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); goto out; } if (-1 == rsp.op_ret) { ret = -1; if (!conf->portmap_err_logged) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_PORT_NUM_ERROR, NULL); } else { gf_msg_debug(this->name, 0, "failed to get the port number for " "remote subvolume. Please run 'gluster " "volume status' on server to see " "if brick process is running."); } conf->portmap_err_logged = 1; goto out; } conf->portmap_err_logged = 0; conf->disconnect_err_logged = 0; config.remote_port = rsp.port; rpc_clnt_reconfig(conf->rpc, &config); conf->skip_notify = 1; conf->quick_reconnect = 1; out: if (frame) STACK_DESTROY(frame->root); if (conf) { /* Need this to connect the same transport on different port */ /* ie, glusterd to glusterfsd */ rpc_transport_disconnect(conf->rpc->conn.trans, _gf_false); } return ret; } int client_query_portmap(xlator_t *this, struct rpc_clnt *rpc) { int ret = -1; pmap_port_by_brick_req req = { 0, }; call_frame_t *fr = NULL; dict_t *options = NULL; char *remote_subvol = NULL; char *xprt = NULL; char brick_name[PATH_MAX] = { 0, }; options = this->options; ret = dict_get_str_sizen(options, "remote-subvolume", &remote_subvol); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_REMOTE_SUBVOL_SET_FAIL, NULL); goto fail; } req.brick = remote_subvol; if (!dict_get_str_sizen(options, "transport-type", &xprt)) { if (!strcmp(xprt, "rdma")) { snprintf(brick_name, sizeof(brick_name), "%s.rdma", remote_subvol); req.brick = brick_name; } } fr = create_frame(this, this->ctx->pool); if (!fr) { ret = -1; goto fail; } ret = client_submit_request(this, &req, fr, &clnt_pmap_prog, GF_PMAP_PORTBYBRICK, client_query_portmap_cbk, NULL, (xdrproc_t)xdr_pmap_port_by_brick_req); fail: return ret; } static int client_dump_version_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gf_dump_rsp rsp = { 0, }; gf_prog_detail *trav = NULL; gf_prog_detail *next = NULL; call_frame_t *frame = NULL; clnt_conf_t *conf = NULL; int ret = 0; frame = myframe; conf = frame->this->private; if (-1 == req->rpc_status) { gf_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, PC_MSG_RPC_STATUS_ERROR, NULL); goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_dump_rsp); if (ret < 0) { gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); goto out; } if (-1 == rsp.op_ret) { gf_smsg(frame->this->name, GF_LOG_WARNING, 0, PC_MSG_VERSION_ERROR, NULL); goto out; } if (server_has_portmap(frame->this, rsp.prog) == 0) { ret = client_query_portmap(frame->this, conf->rpc); goto out; } /* Check for the proper version string */ /* Reply in "Name:Program-Number:Program-Version,..." format */ ret = select_server_supported_programs(frame->this, rsp.prog); if (ret) { gf_smsg(frame->this->name, GF_LOG_ERROR, 0, PC_MSG_VERSION_ERROR, NULL); goto out; } client_setvolume(frame->this, conf->rpc); out: /* don't use GF_FREE, buffer was allocated by libc */ if (rsp.prog) { trav = rsp.prog; while (trav) { next = trav->next; free(trav->progname); free(trav); trav = next; } } STACK_DESTROY(frame->root); if (ret != 0) rpc_transport_disconnect(conf->rpc->conn.trans, _gf_false); return ret; } int client_handshake(xlator_t *this, struct rpc_clnt *rpc) { call_frame_t *frame = NULL; clnt_conf_t *conf = NULL; gf_dump_req req = { 0, }; int ret = 0; conf = this->private; if (!conf->handshake) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_HANDSHAKE_PGM_NOT_FOUND, NULL); goto out; } frame = create_frame(this, this->ctx->pool); if (!frame) goto out; req.gfs_id = 0xcaed; ret = client_submit_request(this, &req, frame, conf->dump, GF_DUMP_DUMP, client_dump_version_cbk, NULL, (xdrproc_t)xdr_gf_dump_req); out: return ret; } char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = { [GF_HNDSK_NULL] = "NULL", [GF_HNDSK_SETVOLUME] = "SETVOLUME", [GF_HNDSK_GETSPEC] = "GETSPEC", [GF_HNDSK_PING] = "PING", }; rpc_clnt_prog_t clnt_handshake_prog = { .progname = "GlusterFS Handshake", .prognum = GLUSTER_HNDSK_PROGRAM, .progver = GLUSTER_HNDSK_VERSION, .procnames = clnt_handshake_procs, }; char *clnt_dump_proc[GF_DUMP_MAXVALUE] = { [GF_DUMP_NULL] = "NULL", [GF_DUMP_DUMP] = "DUMP", }; rpc_clnt_prog_t clnt_dump_prog = { .progname = "GF-DUMP", .prognum = GLUSTER_DUMP_PROGRAM, .progver = GLUSTER_DUMP_VERSION, .procnames = clnt_dump_proc, }; char *clnt_pmap_procs[GF_PMAP_MAXVALUE] = { [GF_PMAP_PORTBYBRICK] = "PORTBYBRICK", }; rpc_clnt_prog_t clnt_pmap_prog = { .progname = "PORTMAP", .prognum = GLUSTER_PMAP_PROGRAM, .progver = GLUSTER_PMAP_VERSION, .procnames = clnt_pmap_procs, }; glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client.c0000644000000000000000000000013214522202451023404 xustar000000000000000030 mtime=1699284265.775027757 30 atime=1699284265.775027757 30 ctime=1699284301.815136309 glusterfs-11.1/xlators/protocol/client/src/client.c0000664000175100017510000022603714522202451023675 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "socket.h" #include "client.h" #include #include #include #include #include "glusterfs3.h" #include "client-messages.h" extern rpc_clnt_prog_t clnt_handshake_prog; extern rpc_clnt_prog_t clnt_dump_prog; extern struct rpcclnt_cb_program gluster_cbk_prog; int client_handshake(xlator_t *this, struct rpc_clnt *rpc); static int client_destroy_rpc(xlator_t *this); static void client_filter_o_direct(clnt_conf_t *conf, int32_t *flags) { if (conf->filter_o_direct) *flags = (*flags & ~O_DIRECT); } static int client_fini_complete(xlator_t *this) { GF_VALIDATE_OR_GOTO(this->name, this->private, out); clnt_conf_t *conf = this->private; if (!conf->destroy) return 0; pthread_mutex_lock(&conf->lock); { conf->fini_completed = _gf_true; pthread_cond_broadcast(&conf->fini_complete_cond); } pthread_mutex_unlock(&conf->lock); out: return 0; } static int client_is_last_child_down(xlator_t *this, int32_t event, struct rpc_clnt *rpc) { rpc_clnt_connection_t *conn = NULL; clnt_conf_t *conf = NULL; int ret = 0; if (!this || !rpc) goto out; conf = this->private; if (!conf) goto out; if (!conf->parent_down) goto out; if (event != GF_EVENT_CHILD_DOWN) goto out; conn = &rpc->conn; pthread_mutex_lock(&conn->lock); { if (!conn->reconnect && rpc->disabled) { ret = 1; } } pthread_mutex_unlock(&conn->lock); out: return ret; } int client_notify_dispatch_uniq(xlator_t *this, int32_t event, void *data, ...) { clnt_conf_t *conf = this->private; glusterfs_ctx_t *ctx = this->ctx; glusterfs_graph_t *graph = this->graph; pthread_mutex_lock(&ctx->notify_lock); { while (ctx->notifying) pthread_cond_wait(&ctx->notify_cond, &ctx->notify_lock); if (client_is_last_child_down(this, event, data) && graph) { pthread_mutex_lock(&graph->mutex); { graph->parent_down++; if (graph->parent_down == graph_total_client_xlator(graph)) { graph->used = 0; pthread_cond_broadcast(&graph->child_down_cond); } } pthread_mutex_unlock(&graph->mutex); } } pthread_mutex_unlock(&ctx->notify_lock); if (conf->last_sent_event == event) return 0; return client_notify_dispatch(this, event, data); /* Please avoid any code that access xlator object here * Because for a child down event, once we do the signal * we will start cleanup. */ } int client_notify_dispatch(xlator_t *this, int32_t event, void *data, ...) { int ret = -1; glusterfs_ctx_t *ctx = this->ctx; clnt_conf_t *conf = this->private; pthread_mutex_lock(&ctx->notify_lock); { while (ctx->notifying) pthread_cond_wait(&ctx->notify_cond, &ctx->notify_lock); ctx->notifying = 1; } pthread_mutex_unlock(&ctx->notify_lock); /* We assume that all translators in the graph handle notification * events in sequence. * */ ret = default_notify(this, event, data); /* NB (Even) with MT-epoll and EPOLLET|EPOLLONESHOT we are guaranteed * that there would be atmost one poller thread executing this * notification function. This allows us to update last_sent_event * without explicit synchronization. See epoll(7). */ conf->last_sent_event = event; pthread_mutex_lock(&ctx->notify_lock); { ctx->notifying = 0; pthread_cond_signal(&ctx->notify_cond); } pthread_mutex_unlock(&ctx->notify_lock); /* Please avoid any code that access xlator object here * Because for a child down event, once we do the signal * we will start cleanup. */ return ret; } int client_submit_request(xlator_t *this, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn, client_payload_t *cp, xdrproc_t xdrproc) { int ret = -1; clnt_conf_t *conf = NULL; struct iovec iov = { 0, }; struct iobuf *iobuf = NULL; int count = 0; struct iobref *new_iobref = NULL; ssize_t xdr_size = 0; struct rpc_req rpcreq = { 0, }; GF_VALIDATE_OR_GOTO("client", this, out); GF_VALIDATE_OR_GOTO(this->name, prog, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); conf = this->private; /* If 'setvolume' is not successful, we should not send frames to server, mean time we should be able to send 'DUMP' and 'SETVOLUME' call itself even if its not connected */ if (!(conf->connected || ((prog->prognum == GLUSTER_DUMP_PROGRAM) || (prog->prognum == GLUSTER_PMAP_PROGRAM) || ((prog->prognum == GLUSTER_HNDSK_PROGRAM) && (procnum == GF_HNDSK_SETVOLUME))))) { /* This particular error captured/logged in functions calling this */ gf_msg_debug(this->name, 0, "connection in disconnected state"); goto out; } if (req && xdrproc) { xdr_size = xdr_sizeof(xdrproc, req); iobuf = iobuf_get2(this->ctx->iobuf_pool, xdr_size); if (!iobuf) { goto out; } new_iobref = iobref_new(); if (!new_iobref) { goto out; } if (cp && cp->iobref != NULL) { ret = iobref_merge(new_iobref, cp->iobref); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, PC_MSG_MERGE_IOBREF_FAILED, NULL); } } ret = iobref_add(new_iobref, iobuf); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, PC_MSG_ADD_IOBUF_FAILED, NULL); goto out; } iov.iov_base = iobuf->ptr; iov.iov_len = iobuf_size(iobuf); /* Create the xdr payload */ ret = xdr_serialize_generic(iov, req, xdrproc); if (ret == -1) { /* callingfn so that, we can get to know which xdr function was called */ gf_log_callingfn(this->name, GF_LOG_WARNING, "XDR payload creation failed"); goto out; } iov.iov_len = ret; count = 1; } /* do not send all groups if they are resolved server-side */ if (!conf->send_gids) { /* We don't need to send the gids of the user. Just reset the list to * a single item with the primary gid. */ frame->root->groups_small[0] = frame->root->gid; frame->root->groups = frame->root->groups_small; frame->root->ngrps = 1; } /* Send the msg */ if (cp) { ret = rpc_clnt_submit(conf->rpc, prog, procnum, cbkfn, &iov, count, cp->payload, cp->payload_cnt, new_iobref, frame, cp->rsphdr, cp->rsphdr_cnt, cp->rsp_payload, cp->rsp_payload_cnt, cp->rsp_iobref); } else { ret = rpc_clnt_submit(conf->rpc, prog, procnum, cbkfn, &iov, count, NULL, 0, new_iobref, frame, NULL, 0, NULL, 0, NULL); } if (ret < 0) { gf_msg_debug(this->name, 0, "rpc_clnt_submit failed"); } ret = 0; if (new_iobref) iobref_unref(new_iobref); if (iobuf) iobuf_unref(iobuf); return ret; out: rpcreq.rpc_status = -1; cbkfn(&rpcreq, NULL, 0, frame); if (new_iobref) iobref_unref(new_iobref); if (iobuf) iobuf_unref(iobuf); return ret; } static int32_t client_forget(xlator_t *this, inode_t *inode) { /* Nothing here */ return 0; } static int32_t client_releasedir(xlator_t *this, fd_t *fd) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_RELEASEDIR]; if (proc->fn) { args.fd = fd; ret = proc->fn(NULL, this, &args); } out: if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_RELEASE_DIR_OP_FAILED, NULL); return 0; } static int32_t client_release(xlator_t *this, fd_t *fd) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_RELEASE]; if (proc->fn) { args.fd = fd; ret = proc->fn(NULL, this, &args); } out: if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FILE_OP_FAILED, NULL); return 0; } static int32_t client_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_LOOKUP]; if (proc->fn) { args.loc = loc; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: /* think of avoiding a missing frame */ if (ret) STACK_UNWIND_STRICT(lookup, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL); return 0; } static int32_t client_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_STAT]; if (proc->fn) { args.loc = loc; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(stat, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_TRUNCATE]; if (proc->fn) { args.loc = loc; args.offset = offset; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(truncate, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FTRUNCATE]; if (proc->fn) { args.fd = fd; args.offset = offset; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(ftruncate, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_ACCESS]; if (proc->fn) { args.loc = loc; args.mask = mask; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(access, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_READLINK]; if (proc->fn) { args.loc = loc; args.size = size; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(readlink, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int client_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_MKNOD]; if (proc->fn) { args.loc = loc; args.mode = mode; args.rdev = rdev; args.umask = umask; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(mknod, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, NULL); return 0; } static int client_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_MKDIR]; if (proc->fn) { args.loc = loc; args.mode = mode; args.umask = umask; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(mkdir, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t client_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_UNLINK]; if (proc->fn) { args.loc = loc; args.xdata = xdata; args.flags = xflag; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(unlink, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_RMDIR]; if (proc->fn) { args.loc = loc; args.flags = flags; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: /* think of avoiding a missing frame */ if (ret) STACK_UNWIND_STRICT(rmdir, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int client_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_SYMLINK]; if (proc->fn) { args.linkname = linkpath; args.loc = loc; args.umask = umask; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(symlink, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t client_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_RENAME]; if (proc->fn) { args.oldloc = oldloc; args.newloc = newloc; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(rename, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t client_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_LINK]; if (proc->fn) { args.oldloc = oldloc; args.newloc = newloc; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(link, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t client_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_CREATE]; if (proc->fn) { args.loc = loc; args.mode = mode; args.fd = fd; args.umask = umask; args.xdata = xdata; args.flags = flags; client_filter_o_direct(conf, &args.flags); ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(create, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t client_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { int ret = 0; int op_errno = ENOTCONN; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_fd_ctx_t *fdctx = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; if (conf->strict_locks) { pthread_spin_lock(&conf->fd_lock); { fdctx = this_fd_get_ctx(fd, this); if (fdctx && !fd_lk_ctx_empty(fdctx->lk_ctx)) { ret = -1; op_errno = EBADFD; } } pthread_spin_unlock(&conf->fd_lock); if (ret) goto out; } proc = &conf->fops->proctable[GF_FOP_OPEN]; if (proc->fn) { args.loc = loc; args.fd = fd; args.xdata = xdata; args.flags = flags; client_filter_o_direct(conf, &args.flags); ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(open, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t client_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_READ]; if (proc->fn) { args.fd = fd; args.size = size; args.offset = offset; args.flags = flags; args.xdata = xdata; client_filter_o_direct(conf, &args.flags); ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(readv, frame, -1, ENOTCONN, NULL, 0, NULL, NULL, NULL); return 0; } static int32_t client_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_WRITE]; if (proc->fn) { args.fd = fd; args.vector = vector; args.count = count; args.offset = off; args.size = iov_length(vector, count); args.flags = flags; args.iobref = iobref; args.xdata = xdata; client_filter_o_direct(conf, &args.flags); ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(writev, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FLUSH]; if (proc->fn) { args.fd = fd; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(flush, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FSYNC]; if (proc->fn) { args.fd = fd; args.flags = flags; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fsync, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FSTAT]; if (proc->fn) { args.fd = fd; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fstat, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_OPENDIR]; if (proc->fn) { args.loc = loc; args.fd = fd; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(opendir, frame, -1, ENOTCONN, NULL, NULL); return 0; } int32_t client_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FSYNCDIR]; if (proc->fn) { args.fd = fd; args.flags = flags; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fsyncdir, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_STATFS]; if (proc->fn) { args.loc = loc; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(statfs, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_copy_file_range(call_frame_t *frame, xlator_t *this, fd_t *fd_in, off_t off_in, fd_t *fd_out, off_t off_out, size_t len, uint32_t flags, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_COPY_FILE_RANGE]; if (proc->fn) { args.fd = fd_in; args.fd_out = fd_out; args.offset = off_in; args.off_out = off_out; args.size = len; args.flags = flags; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(copy_file_range, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL); return 0; } static gf_boolean_t is_client_rpc_init_command(dict_t *dict, xlator_t *this, char **value) { gf_boolean_t ret = _gf_false; int dict_ret = dict_get_str_sizen(dict, CLIENT_CMD_CONNECT, value); if (dict_ret) { gf_msg_trace(this->name, 0, "key %s not present", CLIENT_CMD_CONNECT); goto out; } ret = _gf_true; out: return ret; } static gf_boolean_t is_client_rpc_destroy_command(dict_t *dict, xlator_t *this) { gf_boolean_t ret = _gf_false; int dict_ret = -1; char *dummy = NULL; if (strncmp(this->name, "replace-brick", 13)) { gf_msg_trace(this->name, 0, "name is !replace-brick"); goto out; } dict_ret = dict_get_str_sizen(dict, CLIENT_CMD_DISCONNECT, &dummy); if (dict_ret) { gf_msg_trace(this->name, 0, "key %s not present", CLIENT_CMD_DISCONNECT); goto out; } ret = _gf_true; out: return ret; } static int client_set_remote_options(char *value, xlator_t *this) { char *dup_value = NULL; char *host = NULL; char *subvol = NULL; char *host_dup = NULL; char *subvol_dup = NULL; char *remote_port_str = NULL; char *tmp = NULL; int remote_port = 0; int ret = -1; dup_value = gf_strdup(value); if (dup_value == NULL) { goto out; } host = strtok_r(dup_value, ":", &tmp); subvol = strtok_r(NULL, ":", &tmp); remote_port_str = strtok_r(NULL, ":", &tmp); if (host) { host_dup = gf_strdup(host); if (!host_dup) { goto out; } ret = dict_set_dynstr_sizen(this->options, "remote-host", host_dup); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_REMOTE_HOST_SET_FAILED, "host=%s", host, NULL); GF_FREE(host_dup); goto out; } } if (subvol) { subvol_dup = gf_strdup(subvol); if (!subvol_dup) { goto out; } ret = dict_set_dynstr_sizen(this->options, "remote-subvolume", subvol_dup); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_REMOTE_HOST_SET_FAILED, "host=%s", host, NULL); GF_FREE(subvol_dup); goto out; } } if (remote_port_str) { remote_port = atoi(remote_port_str); ret = dict_set_int32_sizen(this->options, "remote-port", remote_port); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_REMOTE_PORT_SET_FAILED, "remote-port=%d", remote_port, NULL); goto out; } } ret = 0; out: GF_FREE(dup_value); return ret; } static int32_t client_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { int ret = -1; int op_ret = -1; int op_errno = ENOTCONN; int need_unwind = 0; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; char *value = NULL; if (is_client_rpc_init_command(dict, this, &value) == _gf_true) { GF_ASSERT(value); gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_RPC_INIT, NULL); ret = client_set_remote_options(value, this); if (!ret) { op_ret = 0; op_errno = 0; } need_unwind = 1; goto out; } if (is_client_rpc_destroy_command(dict, this) == _gf_true) { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_RPC_DESTROY, NULL); ret = client_destroy_rpc(this); if (ret) { op_ret = 0; op_errno = 0; } need_unwind = 1; goto out; } conf = this->private; if (!conf || !conf->fops) { op_errno = ENOTCONN; need_unwind = 1; goto out; } proc = &conf->fops->proctable[GF_FOP_SETXATTR]; if (proc->fn) { args.loc = loc; args.xattr = dict; args.flags = flags; args.xdata = xdata; ret = proc->fn(frame, this, &args); if (ret) { need_unwind = 1; } } out: if (need_unwind) STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, NULL); return 0; } static int32_t client_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FSETXATTR]; if (proc->fn) { args.fd = fd; args.xattr = dict; args.flags = flags; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fsetxattr, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FGETXATTR]; if (proc->fn) { args.fd = fd; args.name = name; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fgetxattr, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_GETXATTR]; if (proc->fn) { args.name = name; args.loc = loc; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(getxattr, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_XATTROP]; if (proc->fn) { args.loc = loc; args.flags = flags; args.xattr = dict; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(xattrop, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FXATTROP]; if (proc->fn) { args.fd = fd; args.flags = flags; args.xattr = dict; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fxattrop, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_REMOVEXATTR]; if (proc->fn) { args.name = name; args.loc = loc; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(removexattr, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FREMOVEXATTR]; if (proc->fn) { args.name = name; args.fd = fd; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fremovexattr, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_lease(call_frame_t *frame, xlator_t *this, loc_t *loc, struct gf_lease *lease, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_LEASE]; if (proc->fn) { args.loc = loc; args.lease = lease; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(lk, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_LK]; if (proc->fn) { args.fd = fd; args.cmd = cmd; args.flock = lock; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(lk, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; GF_ASSERT(!is_lk_owner_null(&frame->root->lk_owner)); proc = &conf->fops->proctable[GF_FOP_INODELK]; if (proc->fn) { args.loc = loc; args.cmd = cmd; args.flock = lock; args.volume = volume; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(inodelk, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; GF_ASSERT(!is_lk_owner_null(&frame->root->lk_owner)); proc = &conf->fops->proctable[GF_FOP_FINODELK]; if (proc->fn) { args.fd = fd; args.cmd = cmd; args.flock = lock; args.volume = volume; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(finodelk, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; GF_ASSERT(!is_lk_owner_null(&frame->root->lk_owner)); proc = &conf->fops->proctable[GF_FOP_ENTRYLK]; if (proc->fn) { args.loc = loc; args.basename = basename; args.type = type; args.volume = volume; args.cmd_entrylk = cmd; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(entrylk, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; GF_ASSERT(!is_lk_owner_null(&frame->root->lk_owner)); proc = &conf->fops->proctable[GF_FOP_FENTRYLK]; if (proc->fn) { args.fd = fd; args.basename = basename; args.type = type; args.volume = volume; args.cmd_entrylk = cmd; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fentrylk, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, int32_t len, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_RCHECKSUM]; if (proc->fn) { args.fd = fd; args.offset = offset; args.len = len; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(rchecksum, frame, -1, ENOTCONN, 0, NULL, NULL); return 0; } int32_t client_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_READDIR]; if (proc->fn) { if (off != 0) off = gf_dirent_orig_offset(this, off); args.fd = fd; args.size = size; args.offset = off; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(readdir, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *dict) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_READDIRP]; if (proc->fn) { if (off != 0) off = gf_dirent_orig_offset(this, off); args.fd = fd; args.size = size; args.offset = off; args.xdata = dict; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(readdirp, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_SETATTR]; if (proc->fn) { args.loc = loc; args.stbuf = stbuf; args.valid = valid; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(setattr, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FSETATTR]; if (proc->fn) { args.fd = fd; args.stbuf = stbuf; args.valid = valid; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fsetattr, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_FALLOCATE]; if (proc->fn) { args.fd = fd; args.flags = mode; args.offset = offset; args.size = len; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(fallocate, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_DISCARD]; if (proc->fn) { args.fd = fd; args.offset = offset; args.size = len; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(discard, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_ZEROFILL]; if (proc->fn) { args.fd = fd; args.offset = offset; args.size = len; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(zerofill, frame, -1, ENOTCONN, NULL, NULL, NULL); return 0; } static int32_t client_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_IPC]; if (proc->fn) { args.cmd = op; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(ipc, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_SEEK]; if (proc->fn) { args.fd = fd; args.offset = offset; args.what = what; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(seek, frame, -1, ENOTCONN, 0, NULL); return 0; } static int32_t client_getactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_GETACTIVELK]; if (proc->fn) { args.loc = loc; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(getactivelk, frame, -1, ENOTCONN, NULL, NULL); return 0; } static int32_t client_setactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc, lock_migration_info_t *locklist, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_SETACTIVELK]; if (proc->fn) { args.loc = loc; args.xdata = xdata; args.locklist = locklist; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(setactivelk, frame, -1, ENOTCONN, NULL); return 0; } static int32_t client_getspec(call_frame_t *frame, xlator_t *this, const char *key, int32_t flags) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops || !conf->handshake) goto out; /* For all other xlators, getspec is an fop, hence its in fops table */ proc = &conf->fops->proctable[GF_FOP_GETSPEC]; if (proc->fn) { args.name = key; args.flags = flags; /* But at protocol level, this is handshake */ ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(getspec, frame, -1, EINVAL, NULL); return 0; } static int32_t client_compound(call_frame_t *frame, xlator_t *this, void *data, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; compound_args_t *args = data; rpc_clnt_procedure_t *proc = NULL; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_COMPOUND]; if (proc->fn) { args->xdata = xdata; ret = proc->fn(frame, this, args); } out: if (ret) STACK_UNWIND_STRICT(compound, frame, -1, ENOTCONN, NULL, NULL); return 0; } int32_t client_namelink(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int32_t ret = -1; clnt_conf_t *conf = NULL; clnt_args_t args = { 0, }; rpc_clnt_procedure_t *proc = NULL; conf = this->private; if (!conf || !conf->fops || !conf->handshake) goto out; proc = &conf->fops->proctable[GF_FOP_NAMELINK]; if (proc->fn) { args.loc = loc; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(namelink, frame, -1, EINVAL, NULL, NULL, NULL); return 0; } static int32_t client_icreate(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dict_t *xdata) { int32_t ret = -1; clnt_conf_t *conf = NULL; clnt_args_t args = { 0, }; rpc_clnt_procedure_t *proc = NULL; conf = this->private; if (!conf || !conf->fops || !conf->handshake) goto out; proc = &conf->fops->proctable[GF_FOP_ICREATE]; if (proc->fn) { args.loc = loc; args.mode = mode; args.xdata = xdata; ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(icreate, frame, -1, EINVAL, NULL, NULL, NULL); return 0; } static int32_t client_put(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, uint32_t flags, struct iovec *vector, int32_t count, off_t off, struct iobref *iobref, dict_t *xattr, dict_t *xdata) { int ret = -1; clnt_conf_t *conf = NULL; rpc_clnt_procedure_t *proc = NULL; clnt_args_t args = { 0, }; conf = this->private; if (!conf || !conf->fops) goto out; proc = &conf->fops->proctable[GF_FOP_PUT]; if (proc->fn) { args.loc = loc; args.mode = mode; args.umask = umask; args.flags = flags; args.vector = vector; args.count = count; args.offset = off; args.size = iov_length(vector, count); args.iobref = iobref; args.xattr = xattr; args.xdata = xdata; client_filter_o_direct(conf, &args.flags); ret = proc->fn(frame, this, &args); } out: if (ret) STACK_UNWIND_STRICT(put, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, NULL); return 0; } static void client_mark_fd_bad(xlator_t *this) { clnt_conf_t *conf = this->private; clnt_fd_ctx_t *tmp = NULL, *fdctx = NULL; pthread_spin_lock(&conf->fd_lock); { list_for_each_entry_safe(fdctx, tmp, &conf->saved_fds, sfd_pos) { fdctx->remote_fd = -1; } } pthread_spin_unlock(&conf->fd_lock); } int client_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, void *data) { xlator_t *this = NULL; clnt_conf_t *conf = NULL; gf_boolean_t is_parent_down = _gf_false; int ret = 0; this = mydata; if (!this || !this->private) { gf_smsg("client", GF_LOG_ERROR, EINVAL, PC_MSG_XLATOR_NULL, (this != NULL) ? "private structue" : "", NULL); goto out; } conf = this->private; switch (event) { case RPC_CLNT_PING: { if (conf->connection_to_brick) { ret = default_notify(this, GF_EVENT_CHILD_PING, data); if (ret) gf_log(this->name, GF_LOG_INFO, "CHILD_PING notify failed"); conf->last_sent_event = GF_EVENT_CHILD_PING; } break; } case RPC_CLNT_CONNECT: { conf->can_log_disconnect = 1; // connect happened, send 'get_supported_versions' mop gf_msg_debug(this->name, 0, "got RPC_CLNT_CONNECT"); ret = client_handshake(this, rpc); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_HANDSHAKE_RETURN, "ret=%d", ret, NULL); break; } case RPC_CLNT_DISCONNECT: gf_msg_debug(this->name, 0, "got RPC_CLNT_DISCONNECT"); client_mark_fd_bad(this); if (!conf->skip_notify) { if (conf->can_log_disconnect) { if (!conf->disconnect_err_logged) { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CLIENT_DISCONNECTED, "conn-name=%s", conf->rpc->conn.name, NULL); } else { gf_msg_debug(this->name, 0, "disconnected from %s. " "Client process will keep" " trying to connect to " "glusterd until brick's " "port is available", conf->rpc->conn.name); } if (conf->portmap_err_logged) conf->disconnect_err_logged = 1; } /* * Once we complete the child down notification, * There is a chance that the graph might get freed, * So it is not safe to access any xlator contens * So here we are checking whether the parent is down * or not. */ pthread_mutex_lock(&conf->lock); { is_parent_down = conf->parent_down; } pthread_mutex_unlock(&conf->lock); /* If the CHILD_DOWN event goes to parent xlator multiple times, the logic of parent xlator notify may get screwed up.. (eg. CHILD_MODIFIED event in replicate), hence make sure events which are passed to parent are genuine */ ret = client_notify_dispatch_uniq(this, GF_EVENT_CHILD_DOWN, rpc); if (is_parent_down) { /* If parent is down, then there should not be any * operation after a child down. */ goto out; } if (ret) gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_DOWN_NOTIFY_FAILED, NULL); } else { if (conf->can_log_disconnect) gf_msg_debug(this->name, 0, "disconnected (skipped notify)"); } conf->connected = 0; conf->can_log_disconnect = 0; conf->skip_notify = 0; if (conf->quick_reconnect) { conf->connection_to_brick = _gf_true; conf->quick_reconnect = 0; rpc_clnt_cleanup_and_start(rpc); } else { int32_t remote_port = 0; ret = dict_get_int32(this->options, "remote-port", &remote_port); if (IS_ERROR(ret)) { /* this is optional, so it may be error in most cases. Add a * trace log */ gf_msg_trace( this->name, 0, "volfile doesn't have remote-port, resetting to 0"); } conf->rpc_conf.remote_port = remote_port; conf->connection_to_brick = _gf_false; } break; case RPC_CLNT_DESTROY: ret = client_fini_complete(this); break; default: gf_msg_trace(this->name, 0, "got some other RPC event %d", event); break; } out: return 0; } int notify(xlator_t *this, int32_t event, void *data, ...) { clnt_conf_t *conf = NULL; glusterfs_graph_t *graph = this->graph; int ret = -1; conf = this->private; if (!conf) return 0; switch (event) { case GF_EVENT_PARENT_UP: { gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_PARENT_UP, NULL); rpc_clnt_start(conf->rpc); break; } case GF_EVENT_PARENT_DOWN: gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_PARENT_DOWN, NULL); pthread_mutex_lock(&conf->lock); { conf->parent_down = 1; } pthread_mutex_unlock(&conf->lock); ret = rpc_clnt_disable(conf->rpc); if (ret == -1 && graph) { pthread_mutex_lock(&graph->mutex); { graph->parent_down++; if (graph->parent_down == graph_total_client_xlator(graph)) { graph->used = 0; pthread_cond_broadcast(&graph->child_down_cond); } } pthread_mutex_unlock(&graph->mutex); } break; default: gf_msg_debug(this->name, 0, "got %d, calling default_notify ()", event); default_notify(this, event, data); conf->last_sent_event = event; break; } return 0; } static int client_check_remote_host(xlator_t *this, dict_t *options) { char *remote_host = NULL; int ret = -1; ret = dict_get_str_sizen(options, "remote-host", &remote_host); if (ret < 0) { gf_smsg(this->name, GF_LOG_INFO, EINVAL, PC_MSG_REMOTE_HOST_NOT_SET, NULL); if (!this->ctx->cmd_args.volfile_server) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_NOREMOTE_HOST, NULL); goto out; } ret = dict_set_str_sizen(options, "remote-host", this->ctx->cmd_args.volfile_server); if (ret == -1) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_REMOTE_HOST_SET_FAILED, NULL); goto out; } } ret = 0; out: return ret; } static int build_client_config(xlator_t *this, clnt_conf_t *conf) { int ret = -1; GF_OPTION_INIT("frame-timeout", conf->rpc_conf.rpc_timeout, time, out); GF_OPTION_INIT("remote-port", conf->rpc_conf.remote_port, int32, out); GF_OPTION_INIT("ping-timeout", conf->opt.ping_timeout, time, out); GF_OPTION_INIT("remote-subvolume", conf->opt.remote_subvolume, path, out); if (!conf->opt.remote_subvolume) gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_REMOTE_SUBVOL_NOT_GIVEN, NULL); GF_OPTION_INIT("filter-O_DIRECT", conf->filter_o_direct, bool, out); GF_OPTION_INIT("send-gids", conf->send_gids, bool, out); GF_OPTION_INIT("testing.old-protocol", conf->old_protocol, bool, out); GF_OPTION_INIT("strict-locks", conf->strict_locks, bool, out); conf->client_id = glusterfs_leaf_position(this); ret = client_check_remote_host(this, this->options); if (ret) goto out; ret = 0; out: return ret; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_client_mt_end); if (ret != 0) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, PC_MSG_NO_MEMORY, NULL); return ret; } return ret; } static int client_destroy_rpc(xlator_t *this) { int ret = -1; clnt_conf_t *conf = NULL; conf = this->private; if (!conf) goto out; if (conf->rpc) { /* cleanup the saved-frames before last unref */ rpc_clnt_connection_cleanup(&conf->rpc->conn); conf->rpc = rpc_clnt_unref(conf->rpc); ret = 0; gf_msg_debug(this->name, 0, "Client rpc conn destroyed"); goto out; } gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_RPC_INVALID_CALL, NULL); out: return ret; } static int client_init_rpc(xlator_t *this) { int ret = -1; clnt_conf_t *conf = NULL; conf = this->private; if (conf->rpc) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_RPC_INITED_ALREADY, NULL); ret = -1; goto out; } conf->rpc = rpc_clnt_new(this->options, this, this->name, 0); if (!conf->rpc) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_RPC_INIT_FAILED, NULL); goto out; } ret = rpc_clnt_register_notify(conf->rpc, client_rpc_notify, this); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_RPC_NOTIFY_FAILED, NULL); goto out; } conf->handshake = &clnt_handshake_prog; conf->dump = &clnt_dump_prog; ret = rpcclnt_cbk_program_register(conf->rpc, &gluster_cbk_prog, this); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_RPC_CBK_FAILED, NULL); goto out; } ret = 0; gf_msg_debug(this->name, 0, "client init successful"); out: return ret; } static int client_check_event_threads(xlator_t *this, clnt_conf_t *conf, int32_t old, int32_t new) { if (old == new) return 0; conf->event_threads = new; return gf_event_reconfigure_threads(this->ctx->event_pool, conf->event_threads); } int reconfigure(xlator_t *this, dict_t *options) { clnt_conf_t *conf = NULL; int ret = -1; int subvol_ret = 0; char *old_remote_subvol = NULL; char *new_remote_subvol = NULL; char *old_remote_host = NULL; char *new_remote_host = NULL; int32_t new_nthread = 0; struct rpc_clnt_config rpc_config = { 0, }; conf = this->private; GF_OPTION_RECONF("frame-timeout", conf->rpc_conf.rpc_timeout, options, time, out); GF_OPTION_RECONF("ping-timeout", rpc_config.ping_timeout, options, time, out); GF_OPTION_RECONF("event-threads", new_nthread, options, int32, out); ret = client_check_event_threads(this, conf, conf->event_threads, new_nthread); if (ret) goto out; ret = client_check_remote_host(this, options); if (ret) goto out; subvol_ret = dict_get_str_sizen(this->options, "remote-host", &old_remote_host); if (subvol_ret == 0) { subvol_ret = dict_get_str_sizen(options, "remote-host", &new_remote_host); if (subvol_ret == 0) { if (strcmp(old_remote_host, new_remote_host)) { ret = 1; goto out; } } } subvol_ret = dict_get_str_sizen(this->options, "remote-subvolume", &old_remote_subvol); if (subvol_ret == 0) { subvol_ret = dict_get_str_sizen(options, "remote-subvolume", &new_remote_subvol); if (subvol_ret == 0) { if (strcmp(old_remote_subvol, new_remote_subvol)) { ret = 1; goto out; } } } /* Reconfiguring client xlator's @rpc with new frame-timeout * and ping-timeout */ rpc_clnt_reconfig(conf->rpc, &rpc_config); GF_OPTION_RECONF("filter-O_DIRECT", conf->filter_o_direct, options, bool, out); GF_OPTION_RECONF("send-gids", conf->send_gids, options, bool, out); GF_OPTION_RECONF("strict-locks", conf->strict_locks, options, bool, out); ret = 0; out: return ret; } int init(xlator_t *this) { int ret = -1; clnt_conf_t *conf = NULL; if (this->children) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_FATAL_CLIENT_PROTOCOL, NULL); goto out; } if (!this->parents) { gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_VOL_DANGLING, NULL); } conf = GF_CALLOC(1, sizeof(*conf), gf_client_mt_clnt_conf_t); if (!conf) goto out; pthread_mutex_init(&conf->lock, NULL); pthread_cond_init(&conf->fini_complete_cond, NULL); pthread_spin_init(&conf->fd_lock, 0); INIT_LIST_HEAD(&conf->saved_fds); conf->child_up = _gf_false; /* Set event threads to the configured default */ GF_OPTION_INIT("event-threads", conf->event_threads, int32, out); ret = client_check_event_threads(this, conf, STARTING_EVENT_THREADS, conf->event_threads); if (ret) goto out; LOCK_INIT(&conf->rec_lock); conf->last_sent_event = -1; /* To start with we don't have any events */ this->private = conf; /* If it returns -1, then its a failure, if it returns +1 we need have to understand that 'this' is subvolume of a xlator which, will set the remote host and remote subvolume in a setxattr call. */ ret = build_client_config(this, conf); if (ret == -1) goto out; if (ret) { ret = 0; goto out; } this->local_pool = mem_pool_new(clnt_local_t, 64); if (!this->local_pool) { ret = -1; gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, PC_MSG_CREATE_MEM_POOL_FAILED, NULL); goto out; } ret = client_init_rpc(this); out: if (ret) this->fini(this); return ret; } void fini(xlator_t *this) { clnt_conf_t *conf = NULL; conf = this->private; if (!conf) return; conf->fini_completed = _gf_false; conf->destroy = 1; if (conf->rpc) { /* cleanup the saved-frames before last unref */ rpc_clnt_connection_cleanup(&conf->rpc->conn); rpc_clnt_unref(conf->rpc); } pthread_mutex_lock(&conf->lock); { while (!conf->fini_completed) pthread_cond_wait(&conf->fini_complete_cond, &conf->lock); } pthread_mutex_unlock(&conf->lock); pthread_spin_destroy(&conf->fd_lock); pthread_mutex_destroy(&conf->lock); pthread_cond_destroy(&conf->fini_complete_cond); GF_FREE(conf); /* Saved Fds */ /* TODO: */ return; } static void client_fd_lk_ctx_dump(xlator_t *this, fd_lk_ctx_t *lk_ctx, int nth_fd) { gf_boolean_t use_try_lock = _gf_true; int ret = -1; int lock_no = 0; fd_lk_ctx_t *lk_ctx_ref = NULL; fd_lk_ctx_node_t *plock = NULL; char key[GF_DUMP_MAX_BUF_LEN] = { 0, }; lk_ctx_ref = fd_lk_ctx_ref(lk_ctx); if (!lk_ctx_ref) return; ret = client_fd_lk_list_empty(lk_ctx_ref, (use_try_lock = _gf_true)); if (ret != 0) return; gf_proc_dump_write("------", "------"); lock_no = 0; ret = TRY_LOCK(&lk_ctx_ref->lock); if (ret) return; list_for_each_entry(plock, &lk_ctx_ref->lk_list, next) { snprintf(key, sizeof(key), "granted-posix-lock[%d]", lock_no++); gf_proc_dump_write( key, "owner = %s, cmd = %s " "fl_type = %s, fl_start = %" PRId64 ", fl_end = %" PRId64 ", user_flock: l_type = %s, " "l_start = %" PRId64 ", l_len = %" PRId64, lkowner_utoa(&plock->user_flock.l_owner), get_lk_cmd(plock->cmd), get_lk_type(plock->fl_type), plock->fl_start, plock->fl_end, get_lk_type(plock->user_flock.l_type), plock->user_flock.l_start, plock->user_flock.l_len); } UNLOCK(&lk_ctx_ref->lock); gf_proc_dump_write("------", "------"); fd_lk_ctx_unref(lk_ctx_ref); } static int client_priv_dump(xlator_t *this) { clnt_conf_t *conf = NULL; int ret = -1; clnt_fd_ctx_t *tmp = NULL; int i = 0; char key[GF_DUMP_MAX_BUF_LEN]; char key_prefix[GF_DUMP_MAX_BUF_LEN]; rpc_clnt_connection_t *conn = NULL; if (!this) return -1; conf = this->private; if (!conf) return -1; gf_proc_dump_build_key(key_prefix, "xlator.protocol.client", "%s.priv", this->name); gf_proc_dump_add_section("%s", key_prefix); ret = pthread_mutex_trylock(&conf->lock); if (ret) return -1; pthread_spin_lock(&conf->fd_lock); list_for_each_entry(tmp, &conf->saved_fds, sfd_pos) { sprintf(key, "fd.%d.remote_fd", i); gf_proc_dump_write(key, "%" PRId64, tmp->remote_fd); client_fd_lk_ctx_dump(this, tmp->lk_ctx, i); i++; } pthread_spin_unlock(&conf->fd_lock); gf_proc_dump_write("connected", "%d", conf->connected); if (conf->rpc) { conn = &conf->rpc->conn; gf_proc_dump_write("total_bytes_read", "%" PRIu64, conn->trans->total_bytes_read); gf_proc_dump_write("ping_timeout", "%ld", conn->ping_timeout); gf_proc_dump_write("total_bytes_written", "%" PRIu64, conn->trans->total_bytes_write); gf_proc_dump_write("ping_msgs_sent", "%" PRIu64, conn->pingcnt); gf_proc_dump_write("msgs_sent", "%" PRIu64, conn->msgcnt); } pthread_mutex_unlock(&conf->lock); return 0; } int32_t client_inodectx_dump(xlator_t *this, inode_t *inode) { if (!inode) return -1; if (!this) return -1; /*TODO*/ return 0; } struct xlator_cbks cbks = {.forget = client_forget, .release = client_release, .releasedir = client_releasedir}; struct xlator_fops fops = { .stat = client_stat, .readlink = client_readlink, .mknod = client_mknod, .mkdir = client_mkdir, .unlink = client_unlink, .rmdir = client_rmdir, .symlink = client_symlink, .rename = client_rename, .link = client_link, .truncate = client_truncate, .open = client_open, .readv = client_readv, .writev = client_writev, .statfs = client_statfs, .flush = client_flush, .fsync = client_fsync, .setxattr = client_setxattr, .getxattr = client_getxattr, .fsetxattr = client_fsetxattr, .fgetxattr = client_fgetxattr, .removexattr = client_removexattr, .fremovexattr = client_fremovexattr, .opendir = client_opendir, .readdir = client_readdir, .readdirp = client_readdirp, .fsyncdir = client_fsyncdir, .access = client_access, .ftruncate = client_ftruncate, .fstat = client_fstat, .create = client_create, .lk = client_lk, .inodelk = client_inodelk, .finodelk = client_finodelk, .entrylk = client_entrylk, .fentrylk = client_fentrylk, .lookup = client_lookup, .rchecksum = client_rchecksum, .xattrop = client_xattrop, .fxattrop = client_fxattrop, .setattr = client_setattr, .fsetattr = client_fsetattr, .fallocate = client_fallocate, .discard = client_discard, .zerofill = client_zerofill, .getspec = client_getspec, .ipc = client_ipc, .seek = client_seek, .lease = client_lease, .compound = client_compound, .getactivelk = client_getactivelk, .setactivelk = client_setactivelk, .icreate = client_icreate, .namelink = client_namelink, .put = client_put, .copy_file_range = client_copy_file_range, }; struct xlator_dumpops dumpops = { .priv = client_priv_dump, .inodectx = client_inodectx_dump, }; struct volume_options options[] = { {.key = {"username"}, .type = GF_OPTION_TYPE_ANY}, {.key = {"password"}, .type = GF_OPTION_TYPE_ANY}, { .key = {"transport-type"}, .value = {"tcp", "socket", "ib-verbs", "unix", "ib-sdp", "tcp/client", "ib-verbs/client", "rdma"}, .type = GF_OPTION_TYPE_STR, .default_value = "tcp", }, {.key = {"remote-host"}, .type = GF_OPTION_TYPE_INTERNET_ADDRESS, .default_value = "{{ brick.hostname }}"}, { .key = {"remote-port"}, .type = GF_OPTION_TYPE_INT, }, {.key = {"remote-subvolume"}, .type = GF_OPTION_TYPE_ANY, .default_value = "{{ brick.path }}"}, {.key = {"frame-timeout", "rpc-timeout"}, .type = GF_OPTION_TYPE_TIME, .min = 0, .max = 86400, .default_value = "1800", .description = "Time frame after which the (file) operation would be " "declared as dead, if the server does not respond for " "a particular (file) operation.", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"ping-timeout"}, .type = GF_OPTION_TYPE_TIME, .min = 0, .max = 1013, .default_value = TOSTRING(GF_NETWORK_TIMEOUT), .description = "Time duration for which the client waits to " "check if the server is responsive.", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"client-bind-insecure"}, .type = GF_OPTION_TYPE_BOOL}, {.key = {"tcp-window-size"}, .type = GF_OPTION_TYPE_SIZET, .min = GF_MIN_SOCKET_WINDOW_SIZE, .max = GF_MAX_SOCKET_WINDOW_SIZE, .description = "Specifies the window size for tcp socket.", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"filter-O_DIRECT"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "disable", .description = "If enabled, in open/creat/readv/writev fops, " "O_DIRECT flag will be filtered at the client protocol level so " "server will still continue to cache the file. This works similar to " "NFS's behavior of O_DIRECT. Anon-fds can choose to readv/writev " "using O_DIRECT", .op_version = {2}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"send-gids"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {GD_OP_VERSION_3_6_0}, .flags = OPT_FLAG_SETTABLE}, {.key = {"event-threads"}, .type = GF_OPTION_TYPE_INT, .min = CLIENT_MIN_EVENT_THREADS, .max = CLIENT_MAX_EVENT_THREADS, .default_value = TOSTRING(STARTING_EVENT_THREADS), .description = "Specifies the number of event threads to execute in " "parallel. Larger values would help process responses " "faster, depending on available processing power.", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE}, /* This option is required for running code-coverage tests with old protocol */ { .key = {"testing.old-protocol"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .op_version = {GD_OP_VERSION_7_0}, .flags = OPT_FLAG_SETTABLE, }, {.key = {"strict-locks"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .op_version = {GD_OP_VERSION_7_0}, .flags = OPT_FLAG_SETTABLE, .description = "When set, doesn't reopen saved fds after reconnect " "if POSIX locks are held on them. Hence subsequent " "operations on these fds will fail. This is " "necessary for stricter lock complaince as bricks " "cleanup any granted locks when a client " "disconnects."}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "client", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client.h0000644000000000000000000000013014522202451023407 xustar000000000000000029 mtime=1699284265.77602776 29 atime=1699284265.77602776 30 ctime=1699284301.809136291 glusterfs-11.1/xlators/protocol/client/src/client.h0000664000175100017510000002712614522202451023700 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CLIENT_H #define _CLIENT_H #include #include #include "rpc-clnt.h" #include #include "client-mem-types.h" #include #include "client-messages.h" /* Threading limits for client event threads. */ #define CLIENT_MIN_EVENT_THREADS 1 #define CLIENT_MAX_EVENT_THREADS 32 #define CLIENT_DUMP_LOCKS "trusted.glusterfs.clientlk-dump" typedef struct { int fop_enum; unsigned int fop_length; int *enum_list; default_args_t *req_list; dict_t *xdata; } compound_args_t; typedef enum { DEFAULT_REMOTE_FD = 0, FALLBACK_TO_ANON_FD = 1 } clnt_remote_fd_flags_t; #define CLIENT_POST_FOP(fop, this_rsp_u, this_args_cbk, params...) \ do { \ gf_common_rsp *_this_rsp = &CPD_RSP_FIELD(this_rsp_u, fop); \ \ int _op_ret = _this_rsp->op_ret; \ int _op_errno = gf_error_to_errno(_this_rsp->op_errno); \ args_##fop##_cbk_store(this_args_cbk, _op_ret, _op_errno, params); \ } while (0) #define CLIENT_GET_REMOTE_FD(xl, fd, flags, remote_fd, op_errno, fop, label) \ do { \ int _ret = 0; \ _ret = client_get_remote_fd(xl, fd, flags, &remote_fd, fop); \ if (_ret < 0) { \ op_errno = errno; \ goto label; \ } \ if (remote_fd == -1) { \ gf_smsg(xl->name, GF_LOG_WARNING, EBADFD, PC_MSG_BAD_FD, \ "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); \ op_errno = EBADFD; \ goto label; \ } \ } while (0) #define CLIENT_STACK_UNWIND(op, frame, params...) \ do { \ if (!frame) \ break; \ clnt_local_t *__local = frame->local; \ frame->local = NULL; \ STACK_UNWIND_STRICT(op, frame, params); \ client_local_wipe(__local); \ } while (0) struct clnt_options { char *remote_subvolume; time_t ping_timeout; }; typedef struct clnt_conf { struct rpc_clnt *rpc; struct clnt_options opt; struct rpc_clnt_config rpc_conf; struct list_head saved_fds; pthread_spinlock_t fd_lock; /* protects saved_fds list * and all fdctx */ int connected; pthread_mutex_t lock; rpc_clnt_prog_t *fops; rpc_clnt_prog_t *mgmt; rpc_clnt_prog_t *handshake; rpc_clnt_prog_t *dump; int client_id; int event_threads; /* # of event threads * configured */ uint64_t reopen_fd_count; /* Count of fds reopened after a connection is established */ gf_lock_t rec_lock; /* set volume is the op which results in creating/re-using * the conn-id and is called once per connection, this remembers * how manytimes set_volume is called */ uint64_t setvol_count; int skip_notify; int last_sent_event; /* Flag used to make sure we are not repeating the same event which was sent earlier */ char portmap_err_logged; /* flag used to prevent excessive logging */ char disconnect_err_logged; /* flag used to prevent excessive disconnect logging */ char parent_down; gf_boolean_t quick_reconnect; /* When reconnecting after portmap query, do not let the reconnection happen after the usual 3-second wait */ gf_boolean_t filter_o_direct; /* if set, filter O_DIRECT from the flags list of open() */ gf_boolean_t send_gids; /* let the server resolve gids */ gf_boolean_t destroy; /* if enabled implies fini was called * on @this xlator instance */ gf_boolean_t child_up; /* Set to true, when child is up, and * false, when child is down */ gf_boolean_t can_log_disconnect; /* socket level connection is * up, disconnects can be * logged */ gf_boolean_t old_protocol; /* used only for old-protocol testing */ gf_boolean_t fini_completed; gf_boolean_t strict_locks; /* When set, doesn't reopen saved fds after reconnect if POSIX locks are held on them. Hence subsequent operations on these fds will fail. This is necessary for stricter lock complaince as bricks cleanup any granted locks when a client disconnects. */ gf_boolean_t connection_to_brick; /*True from attempt to connect to brick till disconnection to brick*/ pthread_cond_t fini_complete_cond; /* Used to wait till we finsh the fini compltely, ie client_fini_complete to return*/ } clnt_conf_t; typedef struct _client_fd_ctx { struct list_head sfd_pos; /* Stores the reference to this fd's position in the saved_fds list. */ int64_t remote_fd; char is_dir; char released; int32_t flags; fd_lk_ctx_t *lk_ctx; uuid_t gfid; void (*reopen_done)(struct _client_fd_ctx *, int64_t rfd, xlator_t *); int32_t reopen_attempts; } clnt_fd_ctx_t; typedef struct client_local { loc_t loc; loc_t loc2; fd_t *fd; fd_t *fd_out; /* used in copy_file_range */ clnt_fd_ctx_t *fdctx; uint32_t flags; struct iobref *iobref; gf_lkowner_t owner; int32_t cmd; int32_t check_reopen; struct list_head lock_list; pthread_mutex_t mutex; char *name; gf_boolean_t attempt_reopen; /* * The below boolean variable is used * only for copy_file_range fop */ gf_boolean_t attempt_reopen_out; } clnt_local_t; typedef struct client_args { loc_t *loc; /* * This is the source fd for copy_file_range and * the default fd for any other fd based fop which * requires only one fd (i.e. opetates on one fd) */ fd_t *fd; fd_t *fd_out; /* this is the destination fd for copy_file_range */ const char *linkname; struct iobref *iobref; struct iovec *vector; dict_t *xattr; struct iatt *stbuf; loc_t *oldloc; loc_t *newloc; const char *name; struct gf_flock *flock; const char *volume; const char *basename; off_t offset; /* * According to the man page of copy_file_range, * the offsets for source and destination file * are of type loff_t. But the type loff_t is * linux specific and is actual a typedef of * off64_t. */ off64_t off_in; /* used in copy_file_range for source fd */ off64_t off_out; /* used in copy_file_range for dst fd */ int32_t mask; int32_t cmd; size_t size; mode_t mode; int32_t flags; dev_t rdev; int32_t count; int32_t datasync; entrylk_cmd cmd_entrylk; entrylk_type type; gf_xattrop_flags_t optype; int32_t valid; int32_t len; gf_seek_what_t what; struct gf_lease *lease; mode_t umask; dict_t *xdata; lock_migration_info_t *locklist; } clnt_args_t; typedef struct client_payload { struct iobref *iobref; struct iovec *payload; struct iovec *rsphdr; struct iovec *rsp_payload; struct iobref *rsp_iobref; int payload_cnt; int rsphdr_cnt; int rsp_payload_cnt; } client_payload_t; typedef ssize_t (*gfs_serialize_t)(struct iovec outmsg, void *args); clnt_fd_ctx_t * this_fd_get_ctx(fd_t *file, xlator_t *this); clnt_fd_ctx_t * this_fd_del_ctx(fd_t *file, xlator_t *this); void this_fd_set_ctx(fd_t *file, xlator_t *this, loc_t *loc, clnt_fd_ctx_t *ctx); int client_local_wipe(clnt_local_t *local); int client_submit_request(xlator_t *this, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbk, client_payload_t *cp, xdrproc_t xdrproc); int client_fdctx_destroy(xlator_t *this, clnt_fd_ctx_t *fdctx); int client_fd_lk_list_empty(fd_lk_ctx_t *lk_ctx, gf_boolean_t use_try_lock); void client_default_reopen_done(clnt_fd_ctx_t *fdctx, int64_t rfd, xlator_t *this); void client_attempt_reopen(fd_t *fd, xlator_t *this); int client_get_remote_fd(xlator_t *this, fd_t *fd, int flags, int64_t *remote_fd, enum gf_fop_procnum fop); int client_fd_fop_prepare_local(call_frame_t *frame, fd_t *fd, int64_t remote_fd); gf_boolean_t __is_fd_reopen_in_progress(clnt_fd_ctx_t *fdctx); int client_notify_dispatch(xlator_t *this, int32_t event, void *data, ...); int client_notify_dispatch_uniq(xlator_t *this, int32_t event, void *data, ...); gf_boolean_t client_is_reopen_needed(fd_t *fd, xlator_t *this, int64_t remote_fd); int client_add_fd_to_saved_fds(xlator_t *this, fd_t *fd, loc_t *loc, int32_t flags, int64_t remote_fd, int is_dir); void clnt_getactivelk_rsp_cleanup_v2(gfx_getactivelk_rsp *rsp); void clnt_setactivelk_req_cleanup_v2(gfx_setactivelk_req *req); int serialize_req_locklist_v2(lock_migration_info_t *locklist, gfx_setactivelk_req *req); int clnt_unserialize_rsp_locklist_v2(struct gfx_getactivelk_rsp *rsp, lock_migration_info_t *lmi); int unserialize_rsp_dirent_v2(xlator_t *this, struct gfx_readdir_rsp *rsp, gf_dirent_t *entries); int unserialize_rsp_direntp_v2(xlator_t *this, fd_t *fd, struct gfx_readdirp_rsp *rsp, gf_dirent_t *entries); int clnt_readdir_rsp_cleanup_v2(gfx_readdir_rsp *rsp); int clnt_readdirp_rsp_cleanup_v2(gfx_readdirp_rsp *rsp); int client_add_lock_for_recovery(fd_t *fd, struct gf_flock *flock, gf_lkowner_t *owner, int32_t cmd); int client_is_setlk(int32_t cmd); int32_t client_cmd_to_gf_cmd(int32_t cmd, int32_t *gf_cmd); #endif /* !_CLIENT_H */ glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client-messages.h0000644000000000000000000000013014522202451025214 xustar000000000000000030 mtime=1699284265.774027754 30 atime=1699284265.773027751 28 ctime=1699284301.8121363 glusterfs-11.1/xlators/protocol/client/src/client-messages.h0000664000175100017510000002452414522202451025504 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _PC_MESSAGES_H__ #define _PC_MESSAGES_H__ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID( PC, PC_MSG_TIMER_EXPIRED, PC_MSG_DIR_OP_FAILED, PC_MSG_FILE_OP_FAILED, PC_MSG_TIMER_REG, PC_MSG_GRACE_TIMER_CANCELLED, PC_MSG_DICT_SET_FAILED, PC_MSG_DICT_GET_FAILED, PC_MSG_NO_MEMORY, PC_MSG_RPC_CBK_FAILED, PC_MSG_FUNCTION_CALL_ERROR, PC_MSG_RPC_INITED_ALREADY, PC_MSG_RPC_INIT, PC_MSG_RPC_DESTROY, PC_MSG_RPC_INVALID_CALL, PC_MSG_INVALID_ENTRY, PC_MSG_HANDSHAKE_RETURN, PC_MSG_CHILD_UP_NOTIFY_FAILED, PC_MSG_CLIENT_DISCONNECTED, PC_MSG_CHILD_DOWN_NOTIFY_FAILED, PC_MSG_PARENT_UP, PC_MSG_PARENT_DOWN, PC_MSG_RPC_INIT_FAILED, PC_MSG_RPC_NOTIFY_FAILED, PC_MSG_FD_DUPLICATE_TRY, PC_MSG_FD_SET_FAIL, PC_MSG_DICT_UNSERIALIZE_FAIL, PC_MSG_FD_GET_FAIL, PC_MSG_FD_CTX_INVALID, PC_MSG_FOP_SEND_FAILED, PC_MSG_XDR_DECODING_FAILED, PC_MSG_REMOTE_OP_FAILED, PC_MSG_RPC_STATUS_ERROR, PC_MSG_VOL_FILE_NOT_FOUND, PC_MSG_SEND_REQ_FAIL, PC_MSG_LOCK_VERSION_SERVER, PC_MSG_SET_LK_VERSION_ERROR, PC_MSG_LOCK_REQ_FAIL, PC_MSG_CLIENT_REQ_FAIL, PC_MSG_LOCK_ERROR, PC_MSG_LOCK_REACQUIRE, PC_MSG_CHILD_UP_NOTIFY, PC_MSG_CHILD_UP_NOTIFY_DELAY, PC_MSG_VOL_SET_FAIL, PC_MSG_SETVOLUME_FAIL, PC_MSG_VOLFILE_NOTIFY_FAILED, PC_MSG_REMOTE_VOL_CONNECTED, PC_MSG_LOCK_MISMATCH, PC_MSG_LOCK_MATCH, PC_MSG_AUTH_FAILED, PC_MSG_AUTH_FAILED_NOTIFY_FAILED, PC_MSG_CHILD_CONNECTING_EVENT, PC_MSG_CHILD_CONNECTING_NOTIFY_FAILED, PC_MSG_PROCESS_UUID_SET_FAIL, PC_MSG_DICT_ERROR, PC_MSG_DICT_SERIALIZE_FAIL, PC_MSG_PGM_NOT_FOUND, PC_MSG_VERSION_INFO, PC_MSG_PORT_NUM_ERROR, PC_MSG_VERSION_ERROR, PC_MSG_DIR_OP_SUCCESS, PC_MSG_BAD_FD, PC_MSG_CLIENT_LOCK_INFO, PC_MSG_CACHE_INVALIDATION_FAIL, PC_MSG_CHILD_STATUS, PC_MSG_GFID_NULL, PC_MSG_RECALL_LEASE_FAIL, PC_MSG_INODELK_CONTENTION_FAIL, PC_MSG_ENTRYLK_CONTENTION_FAIL, PC_MSG_BIGGER_SIZE, PC_MSG_CLIENT_DUMP_LOCKS_FAILED, PC_MSG_UNKNOWN_CMD, PC_MSG_REOPEN_FAILED, PC_MSG_FIND_KEY_FAILED, PC_MSG_VOL_ID_CHANGED, PC_MSG_GETHOSTNAME_FAILED, PC_MSG_VOLFILE_KEY_SET_FAILED, PC_MSG_VOLFILE_CHECKSUM_FAILED, PC_MSG_FRAME_NOT_FOUND, PC_MSG_REMOTE_SUBVOL_SET_FAIL, PC_MSG_HANDSHAKE_PGM_NOT_FOUND, PC_MSG_MERGE_IOBREF_FAILED, PC_MSG_ADD_IOBUF_FAILED, PC_MSG_RELEASE_DIR_OP_FAILED, PC_MSG_REMOTE_HOST_SET_FAILED, PC_MSG_REMOTE_PORT_SET_FAILED, PC_MSG_REMOTE_HOST_NOT_SET, PC_MSG_NOREMOTE_HOST, PC_MSG_REMOTE_SUBVOL_NOT_GIVEN, PC_MSG_FATAL_CLIENT_PROTOCOL, PC_MSG_VOL_DANGLING, PC_MSG_CREATE_MEM_POOL_FAILED, PC_MSG_PVT_XLATOR_NULL, PC_MSG_XLATOR_NULL, PC_MSG_LEASE_FOP_FAILED, PC_MSG_DICT_SET_FAIL, PC_MSG_NO_MEM, PC_MSG_UNKNOWN_LOCK_TYPE, PC_MSG_CLIENT_UID_ALLOC_FAILED); #define PC_MSG_REMOTE_OP_FAILED_STR "remote operation failed." #define PC_MSG_XDR_DECODING_FAILED_STR "XDR decoding failed" #define PC_MSG_FOP_SEND_FAILED_STR "failed to send the fop" #define PC_MSG_BIGGER_SIZE_STR "read-size is bigger than iobuf isze" #define PC_MSG_CLIENT_DUMP_LOCKS_FAILED_STR "client dump locks failed" #define PC_MSG_UNKNOWN_CMD_STR "Unknown cmd" #define PC_MSG_CHILD_UP_NOTIFY_FAILED_STR "notify of CHILD_UP failed" #define PC_MSG_CHILD_STATUS_STR \ "Defering sending CHILD_UP message as the client translators are not yet " \ "ready to serve" #define PC_MSG_CHILD_UP_NOTIFY_STR "last fd open'd - notifying CHILD_UP" #define PC_MSG_RPC_STATUS_ERROR_STR \ "received RPC status error, returning ENOTCONN" #define PC_MSG_REOPEN_FAILED_STR "reopen failed" #define PC_MSG_DIR_OP_SUCCESS_STR "reopen dir succeeded" #define PC_MSG_DIR_OP_FAILED_STR "failed to send the re-opendir request" #define PC_MSG_CHILD_UP_NOTIFY_DELAY_STR \ "fds open - Delaying child_up until they are re-opened" #define PC_MSG_VOL_SET_FAIL_STR "failed to set the volume" #define PC_MSG_DICT_UNSERIALIZE_FAIL_STR "failed to unserialize buffer to dict" #define PC_MSG_DICT_GET_FAILED_STR "failed to get from reply dict" #define PC_MSG_SETVOLUME_FAIL_STR "SETVOLUME on remote-host failed" #define PC_MSG_VOLFILE_NOTIFY_FAILED_STR "notify of VOLFILE_MODIFIED failed" #define PC_MSG_FIND_KEY_FAILED_STR "failed to find key in the options" #define PC_MSG_VOL_ID_CHANGED_STR \ "volume-id changed, can't connect to server. Needs remount" #define PC_MSG_REMOTE_VOL_CONNECTED_STR "Connected, attached to remote volume" #define PC_MSG_AUTH_FAILED_STR "sending AUTH_FAILED event" #define PC_MSG_AUTH_FAILED_NOTIFY_FAILED_STR "notify of AUTH_FAILED failed" #define PC_MSG_CHILD_CONNECTING_EVENT_STR "sending CHILD_CONNECTING event" #define PC_MSG_CHILD_CONNECTING_NOTIFY_FAILED_STR \ "notify of CHILD_CONNECTING failed" #define PC_MSG_DICT_SET_FAILED_STR "failed to set in handshake msg" #define PC_MSG_GETHOSTNAME_FAILED_STR "gethostname: failed" #define PC_MSG_PROCESS_UUID_SET_FAIL_STR \ "asprintf failed while setting process_uuid" #define PC_MSG_VOLFILE_KEY_SET_FAILED_STR "failed to set volfile-key" #define PC_MSG_VOLFILE_CHECKSUM_FAILED_STR "failed to set volfile-checksum" #define PC_MSG_DICT_SERIALIZE_FAIL_STR "failed to serialize dictionary" #define PC_MSG_PGM_NOT_FOUND_STR "xlator not found OR RPC program not found" #define PC_MSG_VERSION_INFO_STR "Using Program" #define PC_MSG_FRAME_NOT_FOUND_STR "frame not found with rpc request" #define PC_MSG_PORT_NUM_ERROR_STR \ "failed to get the port number for remote subvolume. Please run gluster " \ "volume status on server to see if brick process is running" #define PC_MSG_REMOTE_SUBVOL_SET_FAIL_STR "remote-subvolume not set in volfile" #define PC_MSG_VERSION_ERROR_STR "failed to get the version from server" #define PC_MSG_NO_VERSION_SUPPORT_STR "server doesn't support the version" #define PC_MSG_HANDSHAKE_PGM_NOT_FOUND_STR "handshake program not found" #define PC_MSG_MERGE_IOBREF_FAILED_STR \ "cannot merge iobref passed from caller into new_iobref" #define PC_MSG_ADD_IOBUF_FAILED_STR "cannot add iobuf into iobref" #define PC_MSG_RELEASE_DIR_OP_FAILED_STR "release dir op failed" #define PC_MSG_FILE_OP_FAILED_STR "release fop failed" #define PC_MSG_REMOTE_HOST_SET_FAILED_STR "failed to set remote-host" #define PC_MSG_REMOTE_PORT_SET_FAILED_STR "failed to set remote-port" #define PC_MSG_RPC_INIT_STR "client rpc init command" #define PC_MSG_RPC_DESTROY_STR "client rpc destroy command" #define PC_MSG_HANDSHAKE_RETURN_STR "handshake msg returned" #define PC_MSG_CLIENT_DISCONNECTED_STR \ "disconnected from client, process will keep trying to connect glusterd " \ "until brick's port is available" #define PC_MSG_CHILD_DOWN_NOTIFY_FAILED_STR "CHILD_DOWN notify failed" #define PC_MSG_PARENT_UP_STR \ "parent translators are ready, attempting connect on transport" #define PC_MSG_PARENT_DOWN_STR \ "current graph is no longer active, destroying rpc_client" #define PC_MSG_REMOTE_HOST_NOT_SET_STR \ "Remote host is not set. Assuming the volfile server as remote host" #define PC_MSG_NOREMOTE_HOST_STR "No remote host to connect" #define PC_MSG_REMOTE_SUBVOL_NOT_GIVEN_STR "option 'remote-subvolume' not given" #define PC_MSG_NO_MEMORY_STR "Memory accounting init failed" #define PC_MSG_RPC_INVALID_CALL_STR \ "RPC destroy called on already destroyed connection" #define PC_MSG_RPC_INITED_ALREADY_STR "client rpc already init'ed" #define PC_MSG_RPC_INIT_FAILED_STR "failed to initialize RPC" #define PC_MSG_RPC_NOTIFY_FAILED_STR "failed to register notify" #define PC_MSG_RPC_CBK_FAILED_STR "failed to reister callback program" #define PC_MSG_FATAL_CLIENT_PROTOCOL_STR \ "FATAL: client protocol, translator cannot have any subvolumes" #define PC_MSG_VOL_DANGLING_STR "Volume is dangling" #define PC_MSG_CREATE_MEM_POOL_FAILED_STR \ "failed to create local_t's memory pool" #define PC_MSG_XLATOR_NULL_STR "xlator is NULL" #define PC_MSG_PVT_XLATOR_NULL_STR "private structure of the xlator is NULL" #define PC_MSG_LEASE_FOP_FAILED_STR "Lease fop failed" #define PC_MSG_LOCK_ERROR_STR \ "Unexpected case in subtract_locks. Please send a bug report to " \ "gluster-devel@gluster.org" #define PC_MSG_FD_CTX_INVALID_STR "fdctx not valid" #define PC_MSG_FD_GET_FAIL_STR "failed to get fd context. sending EBADFD" #define PC_MSG_DICT_SET_FAIL_STR "could not set dict" #define PC_MSG_CLIENT_LOCK_INFO_STR "client lock info" #define PC_MSG_BAD_FD_STR "remote_fd is -1. EBADFD" #define PC_MSG_FUNCTION_CALL_ERROR_STR "this function should not be called" #define PC_MSG_RECALL_LEASE_FAIL_STR "XDR decode of recall lease failed" #define PC_MSG_CACHE_INVALIDATION_FAIL_STR \ "XDR decode of cache_invalidation failed" #define PC_MSG_INODELK_CONTENTION_FAIL_STR \ "XDR decode of inodelk contention failed" #define PC_MSG_ENTRYLK_CONTENTION_FAIL_STR \ "XDR decode of entrylk contention failed" #define PC_MSG_FD_DUPLICATE_TRY_STR "trying duplicate remote fd set" #define PC_MSG_FD_SET_FAIL_STR "failed to set remote-fd" #define PC_MSG_NO_MEM_STR "No memory" #define PC_MSG_UNKNOWN_LOCK_TYPE_STR "Unknown lock type" #define PC_MSG_CLIENT_UID_ALLOC_FAILED_STR "client-uid could not be allocated" #endif /* !_PC_MESSAGES_H__ */ glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client-mem-types.h0000644000000000000000000000013214522202451025327 xustar000000000000000030 mtime=1699284265.773027751 30 atime=1699284265.773027751 30 ctime=1699284301.811136297 glusterfs-11.1/xlators/protocol/client/src/client-mem-types.h0000664000175100017510000000130314522202451025603 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __CLIENT_MEM_TYPES_H__ #define __CLIENT_MEM_TYPES_H__ #include enum gf_client_mem_types_ { gf_client_mt_clnt_conf_t = gf_common_mt_end + 1, gf_client_mt_clnt_req_buf_t, gf_client_mt_clnt_fdctx_t, gf_client_mt_clnt_lock_request_t, gf_client_mt_end, }; #endif /* __CLIENT_MEM_TYPES_H__ */ glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467024036 xustar000000000000000030 mtime=1699284279.527069179 30 atime=1699284289.971100636 30 ctime=1699284301.806136282 glusterfs-11.1/xlators/protocol/client/src/Makefile.in0000664000175100017510000006074214522202467024326 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol/client/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) client_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la am_client_la_OBJECTS = client.lo client-helpers.lo \ client-rpc-fops_v2.lo client-handshake.lo client-callback.lo \ client-common.lo client_la_OBJECTS = $(am_client_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = client_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(client_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(client_la_SOURCES) DIST_SOURCES = $(client_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = client.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol client_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la client_la_SOURCES = client.c client-helpers.c client-rpc-fops_v2.c \ client-handshake.c client-callback.c client-common.c noinst_HEADERS = client.h client-mem-types.h client-messages.h client-common.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-transport/socket/src \ -I$(top_srcdir)/rpc/rpc-lib/src/ AM_CFLAGS = -Wall $(GF_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/client/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/client/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } client.la: $(client_la_OBJECTS) $(client_la_DEPENDENCIES) $(EXTRA_client_la_DEPENDENCIES) $(AM_V_CCLD)$(client_la_LINK) -rpath $(xlatordir) $(client_la_OBJECTS) $(client_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client-callback.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client-handshake.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client-rpc-fops_v2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client-common.c0000644000000000000000000000013114522202451024671 xustar000000000000000030 mtime=1699284265.772027748 30 atime=1699284265.771027745 29 ctime=1699284301.82213633 glusterfs-11.1/xlators/protocol/client/src/client-common.c0000664000175100017510000011165214522202451025157 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "client.h" int32_t client_cmd_to_gf_cmd(int32_t cmd, int32_t *gf_cmd) { int ret = 0; if (cmd == F_GETLK || cmd == F_GETLK64) *gf_cmd = GF_LK_GETLK; else if (cmd == F_SETLK || cmd == F_SETLK64) *gf_cmd = GF_LK_SETLK; else if (cmd == F_SETLKW || cmd == F_SETLKW64) *gf_cmd = GF_LK_SETLKW; else if (cmd == F_RESLK_LCK) *gf_cmd = GF_LK_RESLK_LCK; else if (cmd == F_RESLK_LCKW) *gf_cmd = GF_LK_RESLK_LCKW; else if (cmd == F_RESLK_UNLCK) *gf_cmd = GF_LK_RESLK_UNLCK; else if (cmd == F_GETLK_FD) *gf_cmd = GF_LK_GETLK_FD; else ret = -1; return ret; } /* New PRE and POST functions */ int client_post_common_iatt(gfx_common_iatt_rsp *rsp, struct iatt *iatt, dict_t **xdata) { if (-1 != rsp->op_ret) { gfx_stat_to_iattx(&rsp->stat, iatt); } return xdr_to_dict(&rsp->xdata, xdata); } int client_post_common_2iatt(gfx_common_2iatt_rsp *rsp, struct iatt *iatt, struct iatt *iatt2, dict_t **xdata) { if (-1 != rsp->op_ret) { gfx_stat_to_iattx(&rsp->prestat, iatt); gfx_stat_to_iattx(&rsp->poststat, iatt2); } return xdr_to_dict(&rsp->xdata, xdata); } int client_post_common_3iatt(gfx_common_3iatt_rsp *rsp, struct iatt *iatt, struct iatt *iatt2, struct iatt *iatt3, dict_t **xdata) { if (-1 != rsp->op_ret) { gfx_stat_to_iattx(&rsp->stat, iatt); gfx_stat_to_iattx(&rsp->preparent, iatt2); gfx_stat_to_iattx(&rsp->postparent, iatt3); } return xdr_to_dict(&rsp->xdata, xdata); } int client_post_common_dict(gfx_common_dict_rsp *rsp, dict_t **dict, dict_t **xdata) { int ret = 0; ret = xdr_to_dict(&rsp->dict, dict); if (ret) gf_msg_debug(THIS->name, EINVAL, "while decoding found empty dictionary"); xdr_to_dict(&rsp->xdata, xdata); return ret; } int client_post_readv_v2(gfx_read_rsp *rsp, struct iobref **iobref, struct iobref *rsp_iobref, struct iatt *stat, struct iovec *vector, struct iovec *rsp_vector, int *rspcount, dict_t **xdata) { int ret = -1; if (rsp->op_ret != -1) { *iobref = rsp_iobref; gfx_stat_to_iattx(&rsp->stat, stat); vector[0].iov_len = rsp->op_ret; if (rsp->op_ret > 0) vector[0].iov_base = rsp_vector->iov_base; *rspcount = 1; } ret = xdr_to_dict(&rsp->xdata, xdata); #ifdef GF_TESTING_IO_XDATA dict_dump_to_log(xdata); #endif return ret; } int client_pre_stat_v2(gfx_stat_req *req, loc_t *loc, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_readlink_v2(gfx_readlink_req *req, loc_t *loc, size_t size, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); req->size = size; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_mknod_v2(gfx_mknod_req *req, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->parent)) goto out; if (!gf_uuid_is_null(loc->parent->gfid)) memcpy(req->pargfid, loc->parent->gfid, 16); else memcpy(req->pargfid, loc->pargfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->pargfid)), out, op_errno, EINVAL); req->bname = (char *)loc->name; req->mode = mode; req->dev = rdev; req->umask = umask; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_mkdir_v2(gfx_mkdir_req *req, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->parent)) goto out; if (!gf_uuid_is_null(loc->parent->gfid)) memcpy(req->pargfid, loc->parent->gfid, 16); else memcpy(req->pargfid, loc->pargfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->pargfid)), out, op_errno, EINVAL); req->bname = (char *)loc->name; req->mode = mode; req->umask = umask; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_unlink_v2(gfx_unlink_req *req, loc_t *loc, int32_t flags, dict_t *xdata) { int op_errno = 0; if (!(loc && loc->parent)) goto out; if (!gf_uuid_is_null(loc->parent->gfid)) memcpy(req->pargfid, loc->parent->gfid, 16); else memcpy(req->pargfid, loc->pargfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->pargfid)), out, op_errno, EINVAL); req->bname = (char *)loc->name; req->xflags = flags; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_rmdir_v2(gfx_rmdir_req *req, loc_t *loc, int32_t flags, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->parent)) goto out; if (!gf_uuid_is_null(loc->parent->gfid)) memcpy(req->pargfid, loc->parent->gfid, 16); else memcpy(req->pargfid, loc->pargfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->pargfid)), out, op_errno, EINVAL); req->bname = (char *)loc->name; req->xflags = flags; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_symlink_v2(gfx_symlink_req *req, loc_t *loc, const char *linkname, mode_t umask, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->parent)) goto out; if (!gf_uuid_is_null(loc->parent->gfid)) memcpy(req->pargfid, loc->parent->gfid, 16); else memcpy(req->pargfid, loc->pargfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->pargfid)), out, op_errno, EINVAL); req->linkname = (char *)linkname; req->bname = (char *)loc->name; req->umask = umask; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_rename_v2(gfx_rename_req *req, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int op_errno = ESTALE; if (!(oldloc && newloc && oldloc->parent && newloc->parent)) goto out; if (!gf_uuid_is_null(oldloc->parent->gfid)) memcpy(req->oldgfid, oldloc->parent->gfid, 16); else memcpy(req->oldgfid, oldloc->pargfid, 16); if (!gf_uuid_is_null(newloc->parent->gfid)) memcpy(req->newgfid, newloc->parent->gfid, 16); else memcpy(req->newgfid, newloc->pargfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->oldgfid)), out, op_errno, EINVAL); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->newgfid)), out, op_errno, EINVAL); req->oldbname = (char *)oldloc->name; req->newbname = (char *)newloc->name; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_link_v2(gfx_link_req *req, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int op_errno = ESTALE; if (!(oldloc && oldloc->inode && newloc && newloc->parent)) goto out; if (!gf_uuid_is_null(oldloc->inode->gfid)) memcpy(req->oldgfid, oldloc->inode->gfid, 16); else memcpy(req->oldgfid, oldloc->gfid, 16); if (!gf_uuid_is_null(newloc->parent->gfid)) memcpy(req->newgfid, newloc->parent->gfid, 16); else memcpy(req->newgfid, newloc->pargfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->oldgfid)), out, op_errno, EINVAL); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->newgfid)), out, op_errno, EINVAL); req->newbname = (char *)newloc->name; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_truncate_v2(gfx_truncate_req *req, loc_t *loc, off_t offset, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); req->offset = offset; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_open_v2(gfx_open_req *req, loc_t *loc, fd_t *fd, int32_t flags, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); req->flags = gf_flags_from_flags(flags); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_readv_v2(xlator_t *this, gfx_read_req *req, fd_t *fd, size_t size, off_t offset, int32_t flags, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, GFS3_OP_READ, out); req->size = size; req->offset = offset; req->fd = remote_fd; req->flag = flags; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_writev_v2(xlator_t *this, gfx_write_req *req, fd_t *fd, size_t size, off_t offset, int32_t flags, dict_t **xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, GFS3_OP_WRITE, out); req->size = size; req->offset = offset; req->fd = remote_fd; req->flag = flags; memcpy(req->gfid, fd->inode->gfid, 16); #ifdef GF_TESTING_IO_XDATA if (!*xdata) *xdata = dict_new(); ret = dict_set_str(*xdata, "testing-the-xdata-key", "testing-the-xdata-value"); #endif dict_to_xdr(*xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_copy_file_range_v2(xlator_t *this, gfx_copy_file_range_req *req, fd_t *fd_in, off64_t off_in, fd_t *fd_out, off64_t off_out, size_t size, int32_t flags, dict_t **xdata) { int64_t remote_fd_in = -1; int64_t remote_fd_out = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd_in, FALLBACK_TO_ANON_FD, remote_fd_in, op_errno, GFS3_OP_COPY_FILE_RANGE, out); CLIENT_GET_REMOTE_FD(this, fd_out, FALLBACK_TO_ANON_FD, remote_fd_out, op_errno, GFS3_OP_COPY_FILE_RANGE, out); req->size = size; req->off_in = off_in; req->off_out = off_out; req->fd_in = remote_fd_in; req->fd_out = remote_fd_out; req->flag = flags; memcpy(req->gfid1, fd_in->inode->gfid, 16); memcpy(req->gfid2, fd_out->inode->gfid, 16); dict_to_xdr(*xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_statfs_v2(gfx_statfs_req *req, loc_t *loc, dict_t *xdata) { int op_errno = ESTALE; if (!loc) goto out; if (loc->inode) { if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); } else { req->gfid[15] = 1; } GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_flush_v2(xlator_t *this, gfx_flush_req *req, fd_t *fd, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FLUSH, out); req->fd = remote_fd; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fsync_v2(xlator_t *this, gfx_fsync_req *req, fd_t *fd, int32_t flags, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = 0; CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, GFS3_OP_FSYNC, out); req->fd = remote_fd; req->data = flags; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_setxattr_v2(gfx_setxattr_req *req, loc_t *loc, dict_t *xattr, int32_t flags, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); if (xattr) { dict_to_xdr(xattr, &req->dict); } req->flags = flags; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_getxattr_v2(gfx_getxattr_req *req, loc_t *loc, const char *name, dict_t *xdata) { int op_errno = ESTALE; if (!loc) { op_errno = EINVAL; goto out; } if (loc->inode && !gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); req->namelen = 1; /* Use it as a flag */ req->name = (char *)name; if (!req->name) { req->name = ""; req->namelen = 0; } dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_removexattr_v2(gfx_removexattr_req *req, loc_t *loc, const char *name, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); req->name = (char *)name; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_opendir_v2(gfx_opendir_req *req, loc_t *loc, fd_t *fd, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fsyncdir_v2(xlator_t *this, gfx_fsyncdir_req *req, fd_t *fd, int32_t flags, dict_t *xdata) { int32_t op_errno = ESTALE; int64_t remote_fd = -1; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FSYNCDIR, out); req->fd = remote_fd; req->data = flags; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_access_v2(gfx_access_req *req, loc_t *loc, int32_t mask, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); req->mask = mask; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_create_v2(gfx_create_req *req, loc_t *loc, fd_t *fd, mode_t mode, int32_t flags, mode_t umask, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->parent)) goto out; if (!gf_uuid_is_null(loc->parent->gfid)) memcpy(req->pargfid, loc->parent->gfid, 16); else memcpy(req->pargfid, loc->pargfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->pargfid)), out, op_errno, EINVAL); req->bname = (char *)loc->name; req->mode = mode; req->flags = gf_flags_from_flags(flags); req->umask = umask; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_ftruncate_v2(xlator_t *this, gfx_ftruncate_req *req, fd_t *fd, off_t offset, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = EINVAL; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FTRUNCATE, out); req->offset = offset; req->fd = remote_fd; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fstat_v2(xlator_t *this, gfx_fstat_req *req, fd_t *fd, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FSTAT, out); req->fd = remote_fd; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_lk_v2(xlator_t *this, gfx_lk_req *req, int32_t cmd, struct gf_flock *flock, fd_t *fd, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; int32_t gf_cmd = 0; int32_t gf_type = 0; int ret = 0; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_LK, out); ret = client_cmd_to_gf_cmd(cmd, &gf_cmd); if (ret) { op_errno = EINVAL; gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, "gf_cmd=%d", gf_cmd, NULL); goto out; } switch (flock->l_type) { case F_RDLCK: gf_type = GF_LK_F_RDLCK; break; case F_WRLCK: gf_type = GF_LK_F_WRLCK; break; case F_UNLCK: gf_type = GF_LK_F_UNLCK; break; } req->fd = remote_fd; req->cmd = gf_cmd; req->type = gf_type; gf_proto_flock_from_flock(&req->flock, flock); memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_lookup_v2(xlator_t *this, gfx_lookup_req *req, loc_t *loc, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if ((loc->parent) && (!gf_uuid_is_null(loc->parent->gfid))) memcpy(req->pargfid, loc->parent->gfid, 16); else memcpy(req->pargfid, loc->pargfid, 16); if ((loc->inode) && (!gf_uuid_is_null(loc->inode->gfid))) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); if (loc->name) req->bname = (char *)loc->name; else req->bname = ""; if (xdata) { dict_to_xdr(xdata, &req->xdata); } return 0; out: return -op_errno; } int client_pre_readdir_v2(xlator_t *this, gfx_readdir_req *req, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_READDIR, out); req->size = size; req->offset = offset; req->fd = remote_fd; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_inodelk_v2(gfx_inodelk_req *req, loc_t *loc, int cmd, struct gf_flock *flock, const char *volume, dict_t *xdata) { int op_errno = ESTALE; int32_t gf_cmd = 0; int32_t gf_type = 0; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->gfid)) memcpy(req->gfid, loc->gfid, 16); else memcpy(req->gfid, loc->inode->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); if (cmd == F_GETLK || cmd == F_GETLK64) gf_cmd = GF_LK_GETLK; else if (cmd == F_SETLK || cmd == F_SETLK64) gf_cmd = GF_LK_SETLK; else if (cmd == F_SETLKW || cmd == F_SETLKW64) gf_cmd = GF_LK_SETLKW; else { gf_smsg(THIS->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, "gf_cmd=%d", gf_cmd, NULL); op_errno = EINVAL; goto out; } switch (flock->l_type) { case F_RDLCK: gf_type = GF_LK_F_RDLCK; break; case F_WRLCK: gf_type = GF_LK_F_WRLCK; break; case F_UNLCK: gf_type = GF_LK_F_UNLCK; break; } req->volume = (char *)volume; req->cmd = gf_cmd; req->type = gf_type; gf_proto_flock_from_flock(&req->flock, flock); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_finodelk_v2(xlator_t *this, gfx_finodelk_req *req, fd_t *fd, int cmd, struct gf_flock *flock, const char *volume, dict_t *xdata) { int op_errno = ESTALE; int64_t remote_fd = -1; int32_t gf_type = 0; int32_t gf_cmd = 0; CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, GFS3_OP_FINODELK, out); if (cmd == F_GETLK || cmd == F_GETLK64) gf_cmd = GF_LK_GETLK; else if (cmd == F_SETLK || cmd == F_SETLK64) gf_cmd = GF_LK_SETLK; else if (cmd == F_SETLKW || cmd == F_SETLKW64) gf_cmd = GF_LK_SETLKW; else { gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, "gf_cmd=%d", gf_cmd, NULL); goto out; } switch (flock->l_type) { case F_RDLCK: gf_type = GF_LK_F_RDLCK; break; case F_WRLCK: gf_type = GF_LK_F_WRLCK; break; case F_UNLCK: gf_type = GF_LK_F_UNLCK; break; } req->volume = (char *)volume; req->fd = remote_fd; req->cmd = gf_cmd; req->type = gf_type; gf_proto_flock_from_flock(&req->flock, flock); memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_entrylk_v2(gfx_entrylk_req *req, loc_t *loc, entrylk_cmd cmd_entrylk, entrylk_type type, const char *volume, const char *basename, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->gfid)) memcpy(req->gfid, loc->gfid, 16); else memcpy(req->gfid, loc->inode->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); req->cmd = cmd_entrylk; req->type = type; req->volume = (char *)volume; req->name = ""; if (basename) { req->name = (char *)basename; req->namelen = 1; } dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fentrylk_v2(xlator_t *this, gfx_fentrylk_req *req, fd_t *fd, entrylk_cmd cmd_entrylk, entrylk_type type, const char *volume, const char *basename, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FENTRYLK, out); req->fd = remote_fd; req->cmd = cmd_entrylk; req->type = type; req->volume = (char *)volume; req->name = ""; if (basename) { req->name = (char *)basename; req->namelen = 1; } memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_xattrop_v2(gfx_xattrop_req *req, loc_t *loc, dict_t *xattr, int32_t flags, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); dict_to_xdr(xattr, &req->dict); req->flags = flags; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fxattrop_v2(xlator_t *this, gfx_fxattrop_req *req, fd_t *fd, dict_t *xattr, int32_t flags, dict_t *xdata) { int op_errno = ESTALE; int64_t remote_fd = -1; CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, GFS3_OP_FXATTROP, out); req->fd = remote_fd; req->flags = flags; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xattr, &req->dict); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fgetxattr_v2(xlator_t *this, gfx_fgetxattr_req *req, fd_t *fd, const char *name, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FGETXATTR, out); req->namelen = 1; /* Use it as a flag */ req->fd = remote_fd; req->name = (char *)name; if (!req->name) { req->name = ""; req->namelen = 0; } memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fsetxattr_v2(xlator_t *this, gfx_fsetxattr_req *req, fd_t *fd, int32_t flags, dict_t *xattr, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FSETXATTR, out); req->fd = remote_fd; req->flags = flags; memcpy(req->gfid, fd->inode->gfid, 16); if (xattr) { dict_to_xdr(xattr, &req->dict); } dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_rchecksum_v2(xlator_t *this, gfx_rchecksum_req *req, fd_t *fd, int32_t len, off_t offset, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_RCHECKSUM, out); req->len = len; req->offset = offset; req->fd = remote_fd; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_setattr_v2(gfx_setattr_req *req, loc_t *loc, int32_t valid, struct iatt *stbuf, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->inode)) return -op_errno; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); req->valid = valid; gfx_stat_from_iattx(&req->stbuf, stbuf); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fsetattr_v2(xlator_t *this, gfx_fsetattr_req *req, fd_t *fd, int32_t valid, struct iatt *stbuf, dict_t *xdata) { int op_errno = ESTALE; int64_t remote_fd = -1; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FSETATTR, out); memcpy(req->gfid, fd->inode->gfid, 16); req->fd = remote_fd; req->valid = valid; gfx_stat_from_iattx(&req->stbuf, stbuf); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_readdirp_v2(xlator_t *this, gfx_readdirp_req *req, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { int op_errno = ESTALE; int64_t remote_fd = -1; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_READDIRP, out); req->size = size; req->offset = offset; req->fd = remote_fd; memcpy(req->gfid, fd->inode->gfid, 16); /* dict itself is 'xdata' here */ dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fremovexattr_v2(xlator_t *this, gfx_fremovexattr_req *req, fd_t *fd, const char *name, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; if (!(fd && fd->inode)) goto out; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FREMOVEXATTR, out); memcpy(req->gfid, fd->inode->gfid, 16); req->name = (char *)name; req->fd = remote_fd; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_fallocate_v2(xlator_t *this, gfx_fallocate_req *req, fd_t *fd, int32_t flags, off_t offset, size_t size, dict_t *xdata) { int op_errno = ESTALE; int64_t remote_fd = -1; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_FALLOCATE, out); req->fd = remote_fd; req->flags = flags; req->offset = offset; req->size = size; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_discard_v2(xlator_t *this, gfx_discard_req *req, fd_t *fd, off_t offset, size_t size, dict_t *xdata) { int op_errno = ESTALE; int64_t remote_fd = -1; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_DISCARD, out); req->fd = remote_fd; req->offset = offset; req->size = size; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_zerofill_v2(xlator_t *this, gfx_zerofill_req *req, fd_t *fd, off_t offset, size_t size, dict_t *xdata) { int op_errno = ESTALE; int64_t remote_fd = -1; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_ZEROFILL, out); req->fd = remote_fd; req->offset = offset; req->size = size; memcpy(req->gfid, fd->inode->gfid, 16); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_ipc_v2(gfx_ipc_req *req, int32_t cmd, dict_t *xdata) { req->op = cmd; dict_to_xdr(xdata, &req->xdata); return 0; } int client_pre_seek_v2(xlator_t *this, gfx_seek_req *req, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { int64_t remote_fd = -1; int op_errno = ESTALE; CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_SEEK, out); memcpy(req->gfid, fd->inode->gfid, 16); req->fd = remote_fd; req->offset = offset; req->what = what; dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_pre_lease_v2(gfx_lease_req *req, loc_t *loc, struct gf_lease *lease, dict_t *xdata) { int op_errno = 0; if (!(loc && loc->inode)) goto out; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req->gfid, loc->inode->gfid, 16); else memcpy(req->gfid, loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->gfid)), out, op_errno, EINVAL); gf_proto_lease_from_lease(&req->lease, lease); dict_to_xdr(xdata, &req->xdata); out: return -op_errno; } int client_pre_put_v2(gfx_put_req *req, loc_t *loc, mode_t mode, mode_t umask, int32_t flags, size_t size, off_t offset, dict_t *xattr, dict_t *xdata) { int op_errno = ESTALE; if (!(loc && loc->parent)) goto out; if (!gf_uuid_is_null(loc->parent->gfid)) memcpy(req->pargfid, loc->parent->gfid, 16); else memcpy(req->pargfid, loc->pargfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req->pargfid)), out, op_errno, EINVAL); req->bname = (char *)loc->name; req->mode = mode; req->umask = umask; req->flag = gf_flags_from_flags(flags); req->size = size; req->offset = offset; if (xattr) dict_to_xdr(xattr, &req->xattr); dict_to_xdr(xdata, &req->xdata); return 0; out: return -op_errno; } int client_post_create_v2(gfx_create_rsp *rsp, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, clnt_local_t *local, dict_t **xdata) { if (-1 != rsp->op_ret) { gfx_stat_to_iattx(&rsp->stat, stbuf); gfx_stat_to_iattx(&rsp->preparent, preparent); gfx_stat_to_iattx(&rsp->postparent, postparent); gf_uuid_copy(local->loc.gfid, stbuf->ia_gfid); } return xdr_to_dict(&rsp->xdata, xdata); } int client_post_lease_v2(gfx_lease_rsp *rsp, struct gf_lease *lease, dict_t **xdata) { if (rsp->op_ret >= 0) { gf_proto_lease_to_lease(&rsp->lease, lease); } return xdr_to_dict(&rsp->xdata, xdata); } int client_post_lk_v2(gfx_lk_rsp *rsp, struct gf_flock *lock, dict_t **xdata) { if (rsp->op_ret >= 0) { gf_proto_flock_to_flock(&rsp->flock, lock); } return xdr_to_dict(&rsp->xdata, xdata); } int client_post_readdir_v2(xlator_t *this, gfx_readdir_rsp *rsp, gf_dirent_t *entries, dict_t **xdata) { if (rsp->op_ret > 0) { unserialize_rsp_dirent_v2(this, rsp, entries); } return xdr_to_dict(&rsp->xdata, xdata); } int client_post_readdirp_v2(xlator_t *this, gfx_readdirp_rsp *rsp, fd_t *fd, gf_dirent_t *entries, dict_t **xdata) { if (rsp->op_ret > 0) { unserialize_rsp_direntp_v2(this, fd, rsp, entries); } return xdr_to_dict(&rsp->xdata, xdata); } int client_post_rename_v2(gfx_rename_rsp *rsp, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t **xdata) { if (-1 != rsp->op_ret) { gfx_stat_to_iattx(&rsp->stat, stbuf); gfx_stat_to_iattx(&rsp->preoldparent, preoldparent); gfx_stat_to_iattx(&rsp->postoldparent, postoldparent); gfx_stat_to_iattx(&rsp->prenewparent, prenewparent); gfx_stat_to_iattx(&rsp->postnewparent, postnewparent); } return xdr_to_dict(&rsp->xdata, xdata); } void set_fd_reopen_status(xlator_t *this, dict_t *xdata, enum gf_fd_reopen_status fd_reopen_status) { clnt_conf_t *conf = NULL; conf = this->private; if (!conf) { gf_msg_debug(this->name, ENOMEM, "Failed to get client conf"); return; } if (!conf->strict_locks) fd_reopen_status = FD_REOPEN_ALLOWED; if (dict_set_int32(xdata, "fd-reopen-status", fd_reopen_status)) gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, PC_MSG_NO_MEM, NULL); return; } glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client-common.h0000644000000000000000000000013214522202451024677 xustar000000000000000030 mtime=1699284265.772027748 30 atime=1699284265.772027748 30 ctime=1699284301.814136306 glusterfs-11.1/xlators/protocol/client/src/client-common.h0000664000175100017510000002171714522202451025166 0ustar00jenkinsjenkins00000000000000/* Copyright (c); 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later);, or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __CLIENT_COMMON_H__ #define __CLIENT_COMMON_H__ #include #include "glusterfs3.h" #include "client.h" /* New functions for version 4 */ int client_post_common_dict(gfx_common_dict_rsp *rsp, dict_t **dict, dict_t **xdata); int client_post_common_3iatt(gfx_common_3iatt_rsp *rsp, struct iatt *iatt, struct iatt *iatt2, struct iatt *iatt3, dict_t **xdata); int client_post_common_2iatt(gfx_common_2iatt_rsp *rsp, struct iatt *iatt, struct iatt *iatt2, dict_t **xdata); int client_post_common_iatt(gfx_common_iatt_rsp *rsp, struct iatt *iatt, dict_t **xdata); int client_post_common_rsp(xlator_t *this, gfx_common_rsp *rsp, dict_t **xdata); int client_pre_stat_v2(gfx_stat_req *req, loc_t *loc, dict_t *xdata); int client_pre_readlink_v2(gfx_readlink_req *req, loc_t *loc, size_t size, dict_t *xdata); int client_pre_mknod_v2(gfx_mknod_req *req, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata); int client_pre_mkdir_v2(gfx_mkdir_req *req, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata); int client_pre_unlink_v2(gfx_unlink_req *req, loc_t *loc, int32_t flags, dict_t *xdata); int client_pre_rmdir_v2(gfx_rmdir_req *req, loc_t *loc, int32_t flags, dict_t *xdata); int client_pre_symlink_v2(gfx_symlink_req *req, loc_t *loc, const char *linkname, mode_t umask, dict_t *xdata); int client_pre_rename_v2(gfx_rename_req *req, loc_t *oldloc, loc_t *newloc, dict_t *xdata); int client_pre_link_v2(gfx_link_req *req, loc_t *oldloc, loc_t *newloc, dict_t *xdata); int client_pre_truncate_v2(gfx_truncate_req *req, loc_t *loc, off_t offset, dict_t *xdata); int client_pre_open_v2(gfx_open_req *req, loc_t *loc, fd_t *fd, int32_t flags, dict_t *xdata); int client_pre_readv_v2(xlator_t *this, gfx_read_req *req, fd_t *fd, size_t size, off_t offset, int32_t flags, dict_t *xdata); int client_pre_writev_v2(xlator_t *this, gfx_write_req *req, fd_t *fd, size_t size, off_t offset, int32_t flags, dict_t **xdata); int client_pre_statfs_v2(gfx_statfs_req *req, loc_t *loc, dict_t *xdata); int client_pre_flush_v2(xlator_t *this, gfx_flush_req *req, fd_t *fd, dict_t *xdata); int client_pre_fsync_v2(xlator_t *this, gfx_fsync_req *req, fd_t *fd, int32_t flags, dict_t *xdata); int client_pre_setxattr_v2(gfx_setxattr_req *req, loc_t *loc, dict_t *xattr, int32_t flags, dict_t *xdata); int client_pre_getxattr_v2(gfx_getxattr_req *req, loc_t *loc, const char *name, dict_t *xdata); int client_pre_removexattr_v2(gfx_removexattr_req *req, loc_t *loc, const char *name, dict_t *xdata); int client_pre_opendir_v2(gfx_opendir_req *req, loc_t *loc, fd_t *fd, dict_t *xdata); int client_pre_fsyncdir_v2(xlator_t *this, gfx_fsyncdir_req *req, fd_t *fd, int32_t flags, dict_t *xdata); int client_pre_access_v2(gfx_access_req *req, loc_t *loc, int32_t mask, dict_t *xdata); int client_pre_create_v2(gfx_create_req *req, loc_t *loc, fd_t *fd, mode_t mode, int32_t flags, mode_t umask, dict_t *xdata); int client_pre_ftruncate_v2(xlator_t *this, gfx_ftruncate_req *req, fd_t *fd, off_t offset, dict_t *xdata); int client_pre_fstat_v2(xlator_t *this, gfx_fstat_req *req, fd_t *fd, dict_t *xdata); int client_pre_lk_v2(xlator_t *this, gfx_lk_req *req, int32_t cmd, struct gf_flock *flock, fd_t *fd, dict_t *xdata); int client_pre_lookup_v2(xlator_t *this, gfx_lookup_req *req, loc_t *loc, dict_t *xdata); int client_pre_readdir_v2(xlator_t *this, gfx_readdir_req *req, fd_t *fd, size_t size, off_t offset, dict_t *xdata); int client_pre_inodelk_v2(gfx_inodelk_req *req, loc_t *loc, int cmd, struct gf_flock *flock, const char *volume, dict_t *xdata); int client_pre_finodelk_v2(xlator_t *this, gfx_finodelk_req *req, fd_t *fd, int cmd, struct gf_flock *flock, const char *volume, dict_t *xdata); int client_pre_entrylk_v2(gfx_entrylk_req *req, loc_t *loc, entrylk_cmd cmd_entrylk, entrylk_type type, const char *volume, const char *basename, dict_t *xdata); int client_pre_fentrylk_v2(xlator_t *this, gfx_fentrylk_req *req, fd_t *fd, entrylk_cmd cmd_entrylk, entrylk_type type, const char *volume, const char *basename, dict_t *xdata); int client_pre_xattrop_v2(gfx_xattrop_req *req, loc_t *loc, dict_t *xattr, int32_t flags, dict_t *xdata); int client_pre_fxattrop_v2(xlator_t *this, gfx_fxattrop_req *req, fd_t *fd, dict_t *xattr, int32_t flags, dict_t *xdata); int client_pre_fgetxattr_v2(xlator_t *this, gfx_fgetxattr_req *req, fd_t *fd, const char *name, dict_t *xdata); int client_pre_fsetxattr_v2(xlator_t *this, gfx_fsetxattr_req *req, fd_t *fd, int32_t flags, dict_t *xattr, dict_t *xdata); int client_pre_seek_v2(xlator_t *this, gfx_seek_req *req, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata); int client_pre_rchecksum_v2(xlator_t *this, gfx_rchecksum_req *req, fd_t *fd, int32_t len, off_t offset, dict_t *xdata); int client_pre_setattr_v2(gfx_setattr_req *req, loc_t *loc, int32_t valid, struct iatt *stbuf, dict_t *xdata); int client_pre_fsetattr_v2(xlator_t *this, gfx_fsetattr_req *req, fd_t *fd, int32_t valid, struct iatt *stbuf, dict_t *xdata); int client_pre_readdirp_v2(xlator_t *this, gfx_readdirp_req *req, fd_t *fd, size_t size, off_t offset, dict_t *xdata); int client_pre_fremovexattr_v2(xlator_t *this, gfx_fremovexattr_req *req, fd_t *fd, const char *name, dict_t *xdata); int client_pre_fallocate_v2(xlator_t *this, gfx_fallocate_req *req, fd_t *fd, int32_t flags, off_t offset, size_t size, dict_t *xdata); int client_pre_discard_v2(xlator_t *this, gfx_discard_req *req, fd_t *fd, off_t offset, size_t size, dict_t *xdata); int client_pre_zerofill_v2(xlator_t *this, gfx_zerofill_req *req, fd_t *fd, off_t offset, size_t size, dict_t *xdata); int client_pre_ipc_v2(gfx_ipc_req *req, int32_t cmd, dict_t *xdata); int client_pre_lease_v2(gfx_lease_req *req, loc_t *loc, struct gf_lease *lease, dict_t *xdata); int client_pre_put_v2(gfx_put_req *req, loc_t *loc, mode_t mode, mode_t umask, int32_t flags, size_t size, off_t offset, dict_t *xattr, dict_t *xdata); int client_post_readv_v2(gfx_read_rsp *rsp, struct iobref **iobref, struct iobref *rsp_iobref, struct iatt *stat, struct iovec *vector, struct iovec *rsp_vector, int *rspcount, dict_t **xdata); int client_post_create_v2(gfx_create_rsp *rsp, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, clnt_local_t *local, dict_t **xdata); int client_post_lease_v2(gfx_lease_rsp *rsp, struct gf_lease *lease, dict_t **xdata); int client_post_lk_v2(gfx_lk_rsp *rsp, struct gf_flock *lock, dict_t **xdata); int client_post_readdir_v2(xlator_t *this, gfx_readdir_rsp *rsp, gf_dirent_t *entries, dict_t **xdata); int client_post_readdirp_v2(xlator_t *this, gfx_readdirp_rsp *rsp, fd_t *fd, gf_dirent_t *entries, dict_t **xdata); int client_post_rename_v2(gfx_rename_rsp *rsp, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t **xdata); int client_pre_copy_file_range_v2(xlator_t *this, gfx_copy_file_range_req *req, fd_t *fd_in, off64_t off_in, fd_t *fd_out, off64_t off_out, size_t size, int32_t flags, dict_t **xdata); void set_fd_reopen_status(xlator_t *this, dict_t *xdata, enum gf_fd_reopen_status fd_reopen_allowed); #endif /* __CLIENT_COMMON_H__ */ glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client-callback.c0000644000000000000000000000013214522202451025136 xustar000000000000000030 mtime=1699284265.771027745 30 atime=1699284265.771027745 30 ctime=1699284301.821136327 glusterfs-11.1/xlators/protocol/client/src/client-callback.c0000664000175100017510000002007714522202451025423 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "client.h" #include "rpc-clnt.h" #include "client-messages.h" static int client_cbk_null(struct rpc_clnt *rpc, void *mydata, void *data) { gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_FUNCTION_CALL_ERROR, NULL); return 0; } static int client_cbk_fetchspec(struct rpc_clnt *rpc, void *mydata, void *data) { /* Ignore this */ gf_smsg(THIS->name, GF_LOG_DEBUG, 0, PC_MSG_FUNCTION_CALL_ERROR, NULL); return 0; } static int client_cbk_ino_flush(struct rpc_clnt *rpc, void *mydata, void *data) { gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_FUNCTION_CALL_ERROR, NULL); return 0; } static int client_cbk_recall_lease(struct rpc_clnt *rpc, void *mydata, void *data) { int ret = -1; struct iovec *iov = NULL; struct gf_upcall upcall_data = { 0, }; struct gf_upcall_recall_lease rl_data = { 0, }; gfs3_recall_lease_req recall_lease = { { 0, }, }; xlator_t *this; GF_VALIDATE_OR_GOTO("client-callback", data, out); this = THIS; iov = (struct iovec *)data; ret = xdr_to_generic(*iov, &recall_lease, (xdrproc_t)xdr_gfs3_recall_lease_req); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, -ret, PC_MSG_RECALL_LEASE_FAIL, NULL); goto out; } upcall_data.data = &rl_data; ret = gf_proto_recall_lease_to_upcall(this, &recall_lease, &upcall_data); if (ret < 0) goto out; upcall_data.event_type = GF_UPCALL_RECALL_LEASE; gf_msg_trace(this->name, 0, "Upcall gfid = %s, ret = %d", recall_lease.gfid, ret); default_notify(this, GF_EVENT_UPCALL, &upcall_data); out: if (recall_lease.xdata.xdata_val) free(recall_lease.xdata.xdata_val); if (rl_data.dict) dict_unref(rl_data.dict); return ret; } static int client_cbk_cache_invalidation(struct rpc_clnt *rpc, void *mydata, void *data) { int ret = -1; struct iovec *iov = NULL; struct gf_upcall upcall_data = { 0, }; struct gf_upcall_cache_invalidation ca_data = { 0, }; gfs3_cbk_cache_invalidation_req ca_req = { 0, }; xlator_t *this = THIS; gf_msg_trace(this->name, 0, "Upcall callback is called"); if (!data) goto out; iov = (struct iovec *)data; ret = xdr_to_generic(*iov, &ca_req, (xdrproc_t)xdr_gfs3_cbk_cache_invalidation_req); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, -ret, PC_MSG_CACHE_INVALIDATION_FAIL, NULL); goto out; } upcall_data.data = &ca_data; ret = gf_proto_cache_invalidation_to_upcall(this, &ca_req, &upcall_data); if (ret < 0) goto out; gf_msg_trace(this->name, 0, "Cache invalidation cbk received for gfid:" " %s, ret = %d", ca_req.gfid, ret); default_notify(this, GF_EVENT_UPCALL, &upcall_data); out: if (ca_req.gfid) free(ca_req.gfid); if (ca_req.xdata.xdata_val) free(ca_req.xdata.xdata_val); if (ca_data.dict) dict_unref(ca_data.dict); return 0; } static int client_cbk_child_up(struct rpc_clnt *rpc, void *mydata, void *data) { clnt_conf_t *conf = NULL; xlator_t *this = THIS; GF_VALIDATE_OR_GOTO("client", this, out); conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); gf_msg_debug(this->name, 0, "Received CHILD_UP"); conf->child_up = _gf_true; this->notify(this, GF_EVENT_CHILD_UP, NULL); out: return 0; } static int client_cbk_child_down(struct rpc_clnt *rpc, void *mydata, void *data) { clnt_conf_t *conf = NULL; xlator_t *this = THIS; GF_VALIDATE_OR_GOTO("client", this, out); conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); gf_msg_debug(this->name, 0, "Received CHILD_DOWN"); conf->child_up = _gf_false; this->notify(this, GF_EVENT_CHILD_DOWN, NULL); out: return 0; } static int client_cbk_inodelk_contention(struct rpc_clnt *rpc, void *mydata, void *data) { int ret = -1; struct iovec *iov = NULL; struct gf_upcall upcall_data = { 0, }; struct gf_upcall_inodelk_contention lc = { { 0, }, }; gfs4_inodelk_contention_req proto_lc = { { 0, }, }; xlator_t *this; GF_VALIDATE_OR_GOTO("client-callback", data, out); this = THIS; iov = (struct iovec *)data; ret = xdr_to_generic(*iov, &proto_lc, (xdrproc_t)xdr_gfs4_inodelk_contention_req); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, -ret, PC_MSG_INODELK_CONTENTION_FAIL, NULL); goto out; } upcall_data.data = &lc; ret = gf_proto_inodelk_contention_to_upcall(this, &proto_lc, &upcall_data); if (ret < 0) goto out; upcall_data.event_type = GF_UPCALL_INODELK_CONTENTION; default_notify(this, GF_EVENT_UPCALL, &upcall_data); out: if (proto_lc.domain) free(proto_lc.domain); if (proto_lc.xdata.xdata_val) free(proto_lc.xdata.xdata_val); if (lc.xdata) dict_unref(lc.xdata); return ret; } static int client_cbk_entrylk_contention(struct rpc_clnt *rpc, void *mydata, void *data) { int ret = -1; struct iovec *iov = NULL; struct gf_upcall upcall_data = { 0, }; struct gf_upcall_entrylk_contention lc = { 0, }; gfs4_entrylk_contention_req proto_lc = { { 0, }, }; xlator_t *this; GF_VALIDATE_OR_GOTO("client-callback", data, out); this = THIS; iov = (struct iovec *)data; ret = xdr_to_generic(*iov, &proto_lc, (xdrproc_t)xdr_gfs4_entrylk_contention_req); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, -ret, PC_MSG_ENTRYLK_CONTENTION_FAIL, NULL); goto out; } upcall_data.data = &lc; ret = gf_proto_entrylk_contention_to_upcall(this, &proto_lc, &upcall_data); if (ret < 0) goto out; upcall_data.event_type = GF_UPCALL_ENTRYLK_CONTENTION; default_notify(this, GF_EVENT_UPCALL, &upcall_data); out: if (proto_lc.name) free(proto_lc.name); if (proto_lc.domain) free(proto_lc.domain); if (proto_lc.xdata.xdata_val) free(proto_lc.xdata.xdata_val); if (lc.xdata) dict_unref(lc.xdata); return ret; } static rpcclnt_cb_actor_t gluster_cbk_actors[GF_CBK_MAXVALUE] = { [GF_CBK_NULL] = {"NULL", client_cbk_null, GF_CBK_NULL}, [GF_CBK_FETCHSPEC] = {"FETCHSPEC", client_cbk_fetchspec, GF_CBK_FETCHSPEC}, [GF_CBK_INO_FLUSH] = {"INO_FLUSH", client_cbk_ino_flush, GF_CBK_INO_FLUSH}, [GF_CBK_CACHE_INVALIDATION] = {"CACHE_INVALIDATION", client_cbk_cache_invalidation, GF_CBK_CACHE_INVALIDATION}, [GF_CBK_CHILD_UP] = {"CHILD_UP", client_cbk_child_up, GF_CBK_CHILD_UP}, [GF_CBK_CHILD_DOWN] = {"CHILD_DOWN", client_cbk_child_down, GF_CBK_CHILD_DOWN}, [GF_CBK_RECALL_LEASE] = {"RECALL_LEASE", client_cbk_recall_lease, GF_CBK_RECALL_LEASE}, [GF_CBK_INODELK_CONTENTION] = {"INODELK_CONTENTION", client_cbk_inodelk_contention, GF_CBK_INODELK_CONTENTION}, [GF_CBK_ENTRYLK_CONTENTION] = {"ENTRYLK_CONTENTION", client_cbk_entrylk_contention, GF_CBK_ENTRYLK_CONTENTION}, }; struct rpcclnt_cb_program gluster_cbk_prog = { .progname = "GlusterFS Callback", .prognum = GLUSTER_CBK_PROGRAM, .progver = GLUSTER_CBK_VERSION, .actors = gluster_cbk_actors, .numactors = GF_CBK_MAXVALUE, }; glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024016 xustar000000000000000030 mtime=1699284265.771027745 30 atime=1699284279.489069064 30 ctime=1699284301.808136288 glusterfs-11.1/xlators/protocol/client/src/Makefile.am0000664000175100017510000000137114522202451024277 0ustar00jenkinsjenkins00000000000000 xlator_LTLIBRARIES = client.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol client_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la client_la_SOURCES = client.c client-helpers.c client-rpc-fops_v2.c \ client-handshake.c client-callback.c client-common.c noinst_HEADERS = client.h client-mem-types.h client-messages.h client-common.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-transport/socket/src \ -I$(top_srcdir)/rpc/rpc-lib/src/ AM_CFLAGS = -Wall $(GF_CFLAGS) glusterfs-11.1/xlators/protocol/client/src/PaxHeaders.9031/client-rpc-fops_v2.c0000644000000000000000000000013214522202451025542 xustar000000000000000030 mtime=1699284265.775027757 30 atime=1699284265.774027754 30 ctime=1699284301.818136318 glusterfs-11.1/xlators/protocol/client/src/client-rpc-fops_v2.c0000664000175100017510000045156714522202451026043 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "client.h" #include "glusterfs3.h" #include #include "client-messages.h" #include "client-common.h" extern int32_t client3_getspec(call_frame_t *frame, xlator_t *this, void *data); int client_is_setlk(int32_t cmd) { if ((cmd == F_SETLK) || (cmd == F_SETLK64) || (cmd == F_SETLKW) || (cmd == F_SETLKW64)) { return 1; } return 0; } int _copy_gfid_from_inode_holders(uuid_t gfid, loc_t *loc, fd_t *fd) { int ret = 0; if (fd && fd->inode && !gf_uuid_is_null(fd->inode->gfid)) { gf_uuid_copy(gfid, fd->inode->gfid); goto out; } if (!loc) { GF_ASSERT(0); ret = -1; goto out; } if (loc->inode && !gf_uuid_is_null(loc->inode->gfid)) { gf_uuid_copy(gfid, loc->inode->gfid); } else if (!gf_uuid_is_null(loc->gfid)) { gf_uuid_copy(gfid, loc->gfid); } else { GF_ASSERT(0); ret = -1; } out: return ret; } int client_add_fd_to_saved_fds(xlator_t *this, fd_t *fd, loc_t *loc, int32_t flags, int64_t remote_fd, int is_dir) { int ret = 0; uuid_t gfid = {0}; clnt_conf_t *conf = NULL; clnt_fd_ctx_t *fdctx = NULL; conf = this->private; ret = _copy_gfid_from_inode_holders(gfid, loc, fd); if (ret) { ret = -EINVAL; goto out; } fdctx = GF_CALLOC(1, sizeof(*fdctx), gf_client_mt_clnt_fdctx_t); if (!fdctx) { ret = -ENOMEM; goto out; } gf_uuid_copy(fdctx->gfid, gfid); fdctx->is_dir = is_dir; fdctx->remote_fd = remote_fd; fdctx->flags = flags; fdctx->lk_ctx = fd_lk_ctx_ref(fd->lk_ctx); fdctx->reopen_done = client_default_reopen_done; INIT_LIST_HEAD(&fdctx->sfd_pos); pthread_spin_lock(&conf->fd_lock); { this_fd_set_ctx(fd, this, loc, fdctx); list_add_tail(&fdctx->sfd_pos, &conf->saved_fds); } pthread_spin_unlock(&conf->fd_lock); out: return ret; } int client4_0_symlink_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_3iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt stbuf = { 0, }; struct iatt preparent = { 0, }; struct iatt postparent = { 0, }; int ret = 0; clnt_local_t *local = NULL; inode_t *inode = NULL; dict_t *xdata = NULL; frame = myframe; local = frame->local; inode = local->loc.inode; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_3iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_3iatt(&rsp, &stbuf, &preparent, &postparent, &xdata); out: if (rsp.op_ret == -1) { if (GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { /* no need to print the gfid, because it will be null, * since symlink operation failed. */ gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, "source=%s", local->loc.path, "target=%s", local->loc2.path, NULL); } } CLIENT_STACK_UNWIND(symlink, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), inode, &stbuf, &preparent, &postparent, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_mknod_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_3iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt stbuf = { 0, }; struct iatt preparent = { 0, }; struct iatt postparent = { 0, }; int ret = 0; clnt_local_t *local = NULL; inode_t *inode = NULL; dict_t *xdata = NULL; frame = myframe; local = frame->local; inode = local->loc.inode; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_3iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_3iatt(&rsp, &stbuf, &preparent, &postparent, &xdata); out: if (rsp.op_ret == -1 && GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { gf_smsg(THIS->name, fop_log_level(GF_FOP_MKNOD, gf_error_to_errno(rsp.op_errno)), gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, NULL); } CLIENT_STACK_UNWIND(mknod, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), inode, &stbuf, &preparent, &postparent, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_mkdir_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_3iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt stbuf = { 0, }; struct iatt preparent = { 0, }; struct iatt postparent = { 0, }; int ret = 0; clnt_local_t *local = NULL; inode_t *inode = NULL; dict_t *xdata = NULL; frame = myframe; local = frame->local; inode = local->loc.inode; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_3iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_3iatt(&rsp, &stbuf, &preparent, &postparent, &xdata); out: if (rsp.op_ret == -1 && GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { gf_smsg(THIS->name, fop_log_level(GF_FOP_MKDIR, gf_error_to_errno(rsp.op_errno)), gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, NULL); } CLIENT_STACK_UNWIND(mkdir, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), inode, &stbuf, &preparent, &postparent, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_open_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { clnt_local_t *local = NULL; call_frame_t *frame = NULL; fd_t *fd = NULL; int ret = 0; gfx_open_rsp rsp = { 0, }; dict_t *xdata = NULL; frame = myframe; local = frame->local; fd = local->fd; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_open_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (-1 != rsp.op_ret) { ret = client_add_fd_to_saved_fds(frame->this, fd, &local->loc, local->flags, rsp.fd, 0); if (ret) { rsp.op_ret = -1; rsp.op_errno = -ret; goto out; } } ret = xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, fop_log_level(GF_FOP_OPEN, gf_error_to_errno(rsp.op_errno)), gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, "gfid=%s", loc_gfid_utoa(&local->loc), NULL); } CLIENT_STACK_UNWIND(open, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), fd, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_stat_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt iatt = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_iatt(&rsp, &iatt, &xdata); out: if (rsp.op_ret == -1) { /* stale filehandles are possible during normal operations, no * need to spam the logs with these */ if (rsp.op_errno == ESTALE) { gf_msg_debug(THIS->name, gf_error_to_errno(rsp.op_errno), "remote operation failed"); } else { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } } CLIENT_STACK_UNWIND(stat, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &iatt, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_readlink_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_readlink_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt iatt = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_readlink_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } gfx_stat_to_iattx(&rsp.buf, &iatt); ret = xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { if (gf_error_to_errno(rsp.op_errno) == ENOENT) { gf_msg_debug(THIS->name, gf_error_to_errno(rsp.op_errno), "remote operation failed"); } else { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } } CLIENT_STACK_UNWIND(readlink, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), rsp.path, &iatt, xdata); /* This is allocated by the libc while decoding RPC msg */ /* Hence no 'GF_FREE', but just 'free' */ free(rsp.path); if (xdata) dict_unref(xdata); return 0; } int client4_0_unlink_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_2iatt_rsp rsp = { 0, }; struct iatt preparent = { 0, }; struct iatt postparent = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &preparent, &postparent, &xdata); out: if (rsp.op_ret == -1) { if (gf_error_to_errno(rsp.op_errno) == ENOENT) { gf_msg_debug(THIS->name, gf_error_to_errno(rsp.op_errno), "remote operation failed"); } else { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } } CLIENT_STACK_UNWIND(unlink, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &preparent, &postparent, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_rmdir_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_2iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt preparent = { 0, }; struct iatt postparent = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &preparent, &postparent, &xdata); out: if (rsp.op_ret == -1) { if (GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } } CLIENT_STACK_UNWIND(rmdir, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &preparent, &postparent, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_truncate_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_2iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &prestat, &poststat, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(truncate, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_statfs_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_statfs_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct statvfs statfs = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_statfs_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (-1 != rsp.op_ret) { gf_statfs_to_statfs(&rsp.statfs, &statfs); } ret = xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(statfs, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &statfs, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_writev_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_2iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; dict_t *xdata = NULL; clnt_local_t *local = NULL; frame = myframe; local = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &prestat, &poststat, &xdata); if (ret < 0) goto out; out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } else if (rsp.op_ret >= 0) { if (local->attempt_reopen) client_attempt_reopen(local->fd, THIS); } CLIENT_STACK_UNWIND(writev, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } static int client4_0_flush_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; dict_t *xdata = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, fop_log_level(GF_FOP_FLUSH, gf_error_to_errno(rsp.op_errno)), gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(flush, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_fsync_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_2iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &prestat, &poststat, &xdata); if (ret < 0) goto out; out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(fsync, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_setxattr_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; int op_errno = EINVAL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: op_errno = gf_error_to_errno(rsp.op_errno); if (rsp.op_ret == -1) { if (op_errno == ENOTSUP) { gf_msg_debug(THIS->name, op_errno, "remote operation failed"); } else { gf_smsg(THIS->name, GF_LOG_WARNING, op_errno, PC_MSG_REMOTE_OP_FAILED, NULL); } } CLIENT_STACK_UNWIND(setxattr, frame, rsp.op_ret, op_errno, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_getxattr_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_dict_rsp rsp = { 0, }; call_frame_t *frame = NULL; dict_t *dict = NULL; int op_errno = EINVAL; int ret = 0; clnt_local_t *local = NULL; xlator_t *this = NULL; dict_t *xdata = NULL; this = THIS; frame = myframe; local = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_dict_rsp); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; op_errno = EINVAL; goto out; } op_errno = gf_error_to_errno(rsp.op_errno); ret = client_post_common_dict(&rsp, &dict, &xdata); if (ret) { op_errno = -ret; goto out; } out: if (rsp.op_ret == -1) { if ((op_errno == ENOTSUP) || (op_errno == ENODATA) || (op_errno == ESTALE) || (op_errno == ENOENT)) { gf_msg_debug(this->name, op_errno, "remote operation failed. Path: %s " "(%s). Key: %s", local->loc.path, loc_gfid_utoa(&local->loc), (local->name) ? local->name : "(null)"); } else { gf_smsg(this->name, GF_LOG_WARNING, op_errno, PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, "gfid=%s", loc_gfid_utoa(&local->loc), "key=%s", (local->name) ? local->name : "(null)", NULL); } } else { /* This is required as many places, `if (ret)` is checked for syncop_getxattr() */ gf_msg_debug(this->name, 0, "resetting op_ret to 0 from %d", rsp.op_ret); rsp.op_ret = 0; } CLIENT_STACK_UNWIND(getxattr, frame, rsp.op_ret, op_errno, dict, xdata); if (xdata) dict_unref(xdata); if (dict) dict_unref(dict); return 0; } int client4_0_fgetxattr_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_dict_rsp rsp = { 0, }; call_frame_t *frame = NULL; dict_t *dict = NULL; int ret = 0; int op_errno = EINVAL; xlator_t *this = NULL; dict_t *xdata = NULL; this = THIS; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_dict_rsp); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; op_errno = EINVAL; goto out; } op_errno = gf_error_to_errno(rsp.op_errno); ret = client_post_common_dict(&rsp, &dict, &xdata); if (ret) { op_errno = -ret; goto out; } out: if (rsp.op_ret == -1) { if ((op_errno == ENOTSUP) || (op_errno == ERANGE) || (op_errno == ENODATA) || (op_errno == ENOENT)) { gf_msg_debug(this->name, op_errno, "remote operation failed"); } else { gf_smsg(this->name, GF_LOG_WARNING, op_errno, PC_MSG_REMOTE_OP_FAILED, NULL); } } else { /* This is required as many places, `if (ret)` is checked for syncop_fgetxattr() */ gf_msg_debug(this->name, 0, "resetting op_ret to 0 from %d", rsp.op_ret); rsp.op_ret = 0; } CLIENT_STACK_UNWIND(fgetxattr, frame, rsp.op_ret, op_errno, dict, xdata); if (xdata) dict_unref(xdata); if (dict) dict_unref(dict); return 0; } int client4_0_removexattr_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; gf_loglevel_t loglevel = GF_LOG_NONE; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { /* EPERM/EACCESS is returned some times in case of selinux attributes, or other system attributes which may not be possible to remove from an user process is encountered. we can't treat it as an error */ if ((ENODATA == rsp.op_errno) || (ENOATTR == rsp.op_errno) || (EPERM == rsp.op_errno) || (EACCES == rsp.op_errno)) loglevel = GF_LOG_DEBUG; else loglevel = GF_LOG_WARNING; gf_smsg(THIS->name, loglevel, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(removexattr, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_fremovexattr_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(fremovexattr, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_fsyncdir_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(fsyncdir, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_access_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(access, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_ftruncate_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_2iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &prestat, &poststat, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(ftruncate, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_fstat_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt stat = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_iatt(&rsp, &stat, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(fstat, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &stat, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_inodelk_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, fop_log_level(GF_FOP_INODELK, gf_error_to_errno(rsp.op_errno)), gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(inodelk, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_finodelk_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; xlator_t *this = NULL; dict_t *xdata = NULL; clnt_local_t *local = NULL; frame = myframe; this = frame->this; local = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(this->name, fop_log_level(GF_FOP_FINODELK, gf_error_to_errno(rsp.op_errno)), gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } else if (rsp.op_ret == 0) { if (local->attempt_reopen) client_attempt_reopen(local->fd, this); } CLIENT_STACK_UNWIND(finodelk, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_entrylk_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, fop_log_level(GF_FOP_ENTRYLK, gf_error_to_errno(rsp.op_errno)), gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(entrylk, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_fentrylk_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if ((rsp.op_ret == -1) && (EAGAIN != gf_error_to_errno(rsp.op_errno))) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(fentrylk, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_xattrop_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; dict_t *dict = NULL; gfx_common_dict_rsp rsp = { 0, }; int ret = 0; int op_errno = EINVAL; clnt_local_t *local = NULL; xlator_t *this = NULL; dict_t *xdata = NULL; this = THIS; frame = myframe; local = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_dict_rsp); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; op_errno = EINVAL; goto out; } op_errno = rsp.op_errno; ret = client_post_common_dict(&rsp, &dict, &xdata); if (ret) { op_errno = -ret; goto out; } out: if (rsp.op_ret == -1) { gf_smsg(this->name, fop_log_level(GF_FOP_XATTROP, op_errno), gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, "Path=%s", local->loc.path, "gfid=%s", loc_gfid_utoa(&local->loc), NULL); } else { /* This is required as many places, `if (ret)` is checked for syncop_xattrop() */ gf_msg_debug(this->name, 0, "resetting op_ret to 0 from %d", rsp.op_ret); rsp.op_ret = 0; } CLIENT_STACK_UNWIND(xattrop, frame, rsp.op_ret, gf_error_to_errno(op_errno), dict, xdata); if (xdata) dict_unref(xdata); if (dict) dict_unref(dict); return 0; } int client4_0_fxattrop_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; dict_t *dict = NULL; dict_t *xdata = NULL; gfx_common_dict_rsp rsp = { 0, }; int ret = 0; int op_errno = 0; clnt_local_t *local = NULL; xlator_t *this = NULL; this = THIS; frame = myframe; local = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_dict_rsp); if (ret < 0) { rsp.op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); goto out; } op_errno = rsp.op_errno; ret = client_post_common_dict(&rsp, &dict, &xdata); if (ret) { rsp.op_ret = -1; op_errno = -ret; goto out; } out: if (rsp.op_ret == -1) { gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } else { /* This is required as many places, `if (ret)` is checked for syncop_fxattrop() */ gf_msg_debug(this->name, 0, "resetting op_ret to 0 from %d", rsp.op_ret); rsp.op_ret = 0; if (local->attempt_reopen) client_attempt_reopen(local->fd, this); } CLIENT_STACK_UNWIND(fxattrop, frame, rsp.op_ret, gf_error_to_errno(op_errno), dict, xdata); if (xdata) dict_unref(xdata); if (dict) dict_unref(dict); return 0; } int client4_0_fsetxattr_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; int op_errno = EINVAL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: op_errno = gf_error_to_errno(rsp.op_errno); if (rsp.op_ret == -1) { if (op_errno == ENOTSUP) { gf_msg_debug(THIS->name, op_errno, "remote operation failed"); } else { gf_smsg(THIS->name, GF_LOG_WARNING, rsp.op_errno, PC_MSG_REMOTE_OP_FAILED, NULL); } } CLIENT_STACK_UNWIND(fsetxattr, frame, rsp.op_ret, op_errno, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_fallocate_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_2iatt_rsp rsp = { 0, }; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &prestat, &poststat, &xdata); if (ret < 0) goto out; out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(fallocate, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_discard_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_2iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &prestat, &poststat, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(discard, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_zerofill_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_2iatt_rsp rsp = { 0, }; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &prestat, &poststat, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(zerofill, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_ipc_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(ipc, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_seek_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; struct gfx_seek_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_seek_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(seek, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), rsp.offset, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_setattr_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_2iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &prestat, &poststat, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(setattr, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_fsetattr_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_2iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_2iatt(&rsp, &prestat, &poststat, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(fsetattr, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_create_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; fd_t *fd = NULL; inode_t *inode = NULL; struct iatt stbuf = { 0, }; struct iatt preparent = { 0, }; struct iatt postparent = { 0, }; int32_t ret = -1; clnt_local_t *local = NULL; gfx_create_rsp rsp = { 0, }; dict_t *xdata = NULL; frame = myframe; local = frame->local; fd = local->fd; inode = local->loc.inode; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_create_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_create_v2(&rsp, &stbuf, &preparent, &postparent, local, &xdata); if (ret < 0) goto out; if (-1 != rsp.op_ret) { ret = client_add_fd_to_saved_fds(frame->this, fd, &local->loc, local->flags, rsp.fd, 0); if (ret) { rsp.op_ret = -1; rsp.op_errno = -ret; goto out; } } out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, NULL); } CLIENT_STACK_UNWIND(create, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), fd, inode, &stbuf, &preparent, &postparent, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_lease_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; struct gf_lease lease = { 0, }; gfx_lease_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { gf_smsg(THIS->name, GF_LOG_ERROR, ENOTCONN, PC_MSG_REMOTE_OP_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_lease_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_lease_v2(&rsp, &lease, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(lease, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &lease, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_lk_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; struct gf_flock lock = { 0, }; gfx_lk_rsp rsp = { 0, }; int ret = 0; xlator_t *this = NULL; dict_t *xdata = NULL; clnt_local_t *local = NULL; frame = myframe; local = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_lk_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (rsp.op_ret >= 0) { ret = client_post_lk_v2(&rsp, &lock, &xdata); if (ret < 0) goto out; } if (local->check_reopen) { this = THIS; if (lock.l_type == F_WRLCK) set_fd_reopen_status(this, xdata, FD_REOPEN_NOT_ALLOWED); else set_fd_reopen_status(this, xdata, FD_REOPEN_ALLOWED); } out: if ((rsp.op_ret == -1) && (EAGAIN != gf_error_to_errno(rsp.op_errno))) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(lk, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &lock, xdata); free(rsp.flock.lk_owner.lk_owner_val); if (xdata) dict_unref(xdata); return 0; } int client4_0_readdir_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_readdir_rsp rsp = { 0, }; int32_t ret = 0; clnt_local_t *local = NULL; gf_dirent_t entries; xlator_t *this = NULL; dict_t *xdata = NULL; this = THIS; frame = myframe; local = frame->local; INIT_LIST_HEAD(&entries.list); if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_readdir_rsp_custom); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_readdir_v2(this, &rsp, &entries, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, "remote_fd=%d", local->cmd, NULL); } CLIENT_STACK_UNWIND(readdir, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &entries, xdata); if (rsp.op_ret != -1) { gf_dirent_free(&entries); } if (xdata) dict_unref(xdata); clnt_readdir_rsp_cleanup_v2(&rsp); return 0; } int client4_0_readdirp_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_readdirp_rsp rsp = { 0, }; int32_t ret = 0; clnt_local_t *local = NULL; gf_dirent_t entries; xlator_t *this = NULL; dict_t *xdata = NULL; this = THIS; frame = myframe; local = frame->local; INIT_LIST_HEAD(&entries.list); if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_readdirp_rsp_custom); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_readdirp_v2(this, &rsp, local->fd, &entries, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(readdirp, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &entries, xdata); if (rsp.op_ret != -1) { gf_dirent_free(&entries); } if (xdata) dict_unref(xdata); clnt_readdirp_rsp_cleanup_v2(&rsp); return 0; } int client4_0_rename_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_rename_rsp rsp = { 0, }; struct iatt stbuf = { 0, }; struct iatt preoldparent = { 0, }; struct iatt postoldparent = { 0, }; struct iatt prenewparent = { 0, }; struct iatt postnewparent = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_rename_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } client_post_rename_v2(&rsp, &stbuf, &preoldparent, &postoldparent, &prenewparent, &postnewparent, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(rename, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &stbuf, &preoldparent, &postoldparent, &prenewparent, &postnewparent, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_link_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_3iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt stbuf = { 0, }; struct iatt preparent = { 0, }; struct iatt postparent = { 0, }; int ret = 0; clnt_local_t *local = NULL; inode_t *inode = NULL; dict_t *xdata = NULL; frame = myframe; local = frame->local; inode = local->loc.inode; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_3iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_3iatt(&rsp, &stbuf, &preparent, &postparent, &xdata); out: if (rsp.op_ret == -1) { if (GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, "source=%s", local->loc.path, "target=%s", local->loc2.path, NULL); } } CLIENT_STACK_UNWIND(link, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), inode, &stbuf, &preparent, &postparent, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_opendir_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { clnt_local_t *local = NULL; call_frame_t *frame = NULL; fd_t *fd = NULL; int ret = 0; gfx_open_rsp rsp = { 0, }; dict_t *xdata = NULL; frame = myframe; local = frame->local; fd = local->fd; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } /* open and opendir are two operations dealing with same thing, but separated by fop number only */ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_open_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (-1 != rsp.op_ret) { ret = client_add_fd_to_saved_fds(frame->this, fd, &local->loc, 0, rsp.fd, 1); if (ret) { rsp.op_ret = -1; rsp.op_errno = -ret; goto out; } } ret = xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, fop_log_level(GF_FOP_OPENDIR, gf_error_to_errno(rsp.op_errno)), gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, "gfid=%s", loc_gfid_utoa(&local->loc), NULL); } CLIENT_STACK_UNWIND(opendir, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), fd, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_lookup_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_2iatt_rsp rsp = { 0, }; clnt_local_t *local = NULL; call_frame_t *frame = NULL; int ret = 0; struct iatt stbuf = { 0, }; struct iatt postparent = { 0, }; int op_errno = EINVAL; dict_t *xdata = NULL; inode_t *inode = NULL; frame = myframe; local = frame->local; inode = local->loc.inode; if (-1 == req->rpc_status) { rsp.op_ret = -1; op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; op_errno = EINVAL; goto out; } /* Preserve the op_errno received from the server */ op_errno = gf_error_to_errno(rsp.op_errno); ret = client_post_common_2iatt(&rsp, &stbuf, &postparent, &xdata); if (ret < 0) { /* Don't change the op_errno if the fop failed on server */ if (rsp.op_ret == 0) op_errno = rsp.op_errno; rsp.op_ret = -1; goto out; } if (rsp.op_ret < 0) goto out; if ((!gf_uuid_is_null(inode->gfid)) && (gf_uuid_compare(stbuf.ia_gfid, inode->gfid) != 0)) { gf_msg_debug(frame->this->name, 0, "gfid changed for %s", local->loc.path); rsp.op_ret = -1; op_errno = ESTALE; if (xdata) ret = dict_set_int32_sizen(xdata, "gfid-changed", 1); goto out; } rsp.op_ret = 0; out: /* Restore the correct op_errno to rsp.op_errno */ rsp.op_errno = op_errno; if (rsp.op_ret == -1) { /* any error other than ENOENT */ if (!(local->loc.name && rsp.op_errno == ENOENT) && !(rsp.op_errno == ESTALE)) gf_smsg(THIS->name, GF_LOG_WARNING, rsp.op_errno, PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, "gfid=%s", loc_gfid_utoa(&local->loc), NULL); else gf_msg_trace(THIS->name, 0, "not found on remote " "node"); } CLIENT_STACK_UNWIND(lookup, frame, rsp.op_ret, rsp.op_errno, inode, &stbuf, xdata, &postparent); if (xdata) dict_unref(xdata); return 0; } int client4_0_readv_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; struct iobref *iobref = NULL; struct iovec vector[MAX_IOVEC] = { {0}, }; struct iatt stat = { 0, }; gfx_read_rsp rsp = { 0, }; int ret = 0, rspcount = 0; clnt_local_t *local = NULL; dict_t *xdata = NULL; frame = myframe; local = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_read_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } memset(vector, 0, sizeof(vector)); ret = client_post_readv_v2(&rsp, &iobref, req->rsp_iobref, &stat, vector, &req->rsp[1], &rspcount, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } else if (rsp.op_ret >= 0) { if (local->attempt_reopen) client_attempt_reopen(local->fd, THIS); } CLIENT_STACK_UNWIND(readv, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), vector, rspcount, &stat, iobref, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_release_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; frame = myframe; STACK_DESTROY(frame->root); return 0; } int client4_0_releasedir_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; frame = myframe; STACK_DESTROY(frame->root); return 0; } int client4_0_getactivelk_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_getactivelk_rsp rsp = { 0, }; int32_t ret = 0; lock_migration_info_t locklist; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_getactivelk_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } INIT_LIST_HEAD(&locklist.list); if (rsp.op_ret > 0) { clnt_unserialize_rsp_locklist_v2(&rsp, &locklist); } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(getactivelk, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &locklist, xdata); if (xdata) dict_unref(xdata); clnt_getactivelk_rsp_cleanup_v2(&rsp); return 0; } int client4_0_setactivelk_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_common_rsp rsp = { 0, }; int32_t ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(setactivelk, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_copy_file_range_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_3iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; struct iatt stbuf = { 0, }; struct iatt prestat = { 0, }; struct iatt poststat = { 0, }; int ret = 0; xlator_t *this = NULL; dict_t *xdata = NULL; clnt_local_t *local = NULL; frame = myframe; local = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_3iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = client_post_common_3iatt(&rsp, &stbuf, &prestat, &poststat, &xdata); if (ret < 0) goto out; out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } else if (rsp.op_ret >= 0) { this = THIS; if (local->attempt_reopen) client_attempt_reopen(local->fd, this); if (local->attempt_reopen_out) client_attempt_reopen(local->fd_out, this); } CLIENT_STACK_UNWIND(copy_file_range, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &stbuf, &prestat, &poststat, xdata); if (xdata) dict_unref(xdata); return 0; } int32_t client4_0_releasedir(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_fd_ctx_t *fdctx = NULL; clnt_args_t *args = NULL; int64_t remote_fd = -1; gf_boolean_t destroy = _gf_false; if (!this || !data) goto out; args = data; conf = this->private; pthread_spin_lock(&conf->fd_lock); { fdctx = this_fd_del_ctx(args->fd, this); if (fdctx != NULL) { remote_fd = fdctx->remote_fd; /* fdctx->remote_fd == -1 indicates a reopen attempt in progress. Just mark ->released = 1 and let reopen_cbk handle releasing */ if (remote_fd == -1) { fdctx->released = 1; } else { list_del_init(&fdctx->sfd_pos); destroy = _gf_true; } } } pthread_spin_unlock(&conf->fd_lock); if (destroy) client_fdctx_destroy(this, fdctx); out: return 0; } int32_t client4_0_release(call_frame_t *frame, xlator_t *this, void *data) { int64_t remote_fd = -1; clnt_conf_t *conf = NULL; clnt_fd_ctx_t *fdctx = NULL; clnt_args_t *args = NULL; gf_boolean_t destroy = _gf_false; if (!this || !data) goto out; args = data; conf = this->private; pthread_spin_lock(&conf->fd_lock); { fdctx = this_fd_del_ctx(args->fd, this); if (fdctx != NULL) { remote_fd = fdctx->remote_fd; /* fdctx->remote_fd == -1 indicates a reopen attempt in progress. Just mark ->released = 1 and let reopen_cbk handle releasing */ if (remote_fd == -1) { fdctx->released = 1; } else { list_del_init(&fdctx->sfd_pos); destroy = _gf_true; } } } pthread_spin_unlock(&conf->fd_lock); if (destroy) client_fdctx_destroy(this, fdctx); out: return 0; } int32_t client4_0_lookup(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_local_t *local = NULL; clnt_args_t *args = NULL; gfx_lookup_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; data_t *content = NULL; struct iovec vector[MAX_IOVEC] = { {0}, }; int count = 0; struct iobref *rsp_iobref = NULL; struct iobuf *rsp_iobuf = NULL; struct iovec *rsphdr = NULL; client_payload_t cp; if (!frame || !this || !data) goto unwind; conf = this->private; args = data; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; if (!(args->loc && args->loc->inode)) goto unwind; loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); if (args->xdata) { content = dict_get_sizen(args->xdata, GF_CONTENT_KEY); if (content != NULL) { rsp_iobref = iobref_new(); if (rsp_iobref == NULL) { goto unwind; } /* TODO: what is the size we should send ? */ /* This change very much depends on quick-read changes */ rsp_iobuf = iobuf_get(this->ctx->iobuf_pool); if (rsp_iobuf == NULL) { goto unwind; } iobref_add(rsp_iobref, rsp_iobuf); memset(vector, 0, sizeof(vector)); rsphdr = &vector[0]; rsphdr->iov_base = iobuf_ptr(rsp_iobuf); rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); count = 1; local->iobref = rsp_iobref; iobuf_unref(rsp_iobuf); rsp_iobuf = NULL; rsp_iobref = NULL; } } ret = client_pre_lookup_v2(this, &req, args->loc, args->xdata); if (ret) { op_errno = -ret; goto unwind; } memset(&cp, 0, sizeof(client_payload_t)); cp.rsphdr = rsphdr; cp.rsphdr_cnt = count; cp.rsp_iobref = local->iobref; ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LOOKUP, client4_0_lookup_cbk, &cp, (xdrproc_t)xdr_gfx_lookup_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); if (rsp_iobref) iobref_unref(rsp_iobref); return 0; } int32_t client4_0_stat(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_stat_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_stat_v2(&req, args->loc, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_STAT, client4_0_stat_cbk, NULL, (xdrproc_t)xdr_gfx_stat_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_truncate(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_truncate_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_truncate_v2(&req, args->loc, args->offset, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_TRUNCATE, client4_0_truncate_cbk, NULL, (xdrproc_t)xdr_gfx_truncate_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_ftruncate(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_ftruncate_req req = { { 0, }, }; int op_errno = EINVAL; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_ftruncate_v2(this, &req, args->fd, args->offset, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FTRUNCATE, client4_0_ftruncate_cbk, NULL, (xdrproc_t)xdr_gfx_ftruncate_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_access(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_access_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_access_v2(&req, args->loc, args->mask, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ACCESS, client4_0_access_cbk, NULL, (xdrproc_t)xdr_gfx_access_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(access, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_readlink(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_readlink_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; clnt_local_t *local = NULL; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; ret = client_pre_readlink_v2(&req, args->loc, args->size, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READLINK, client4_0_readlink_cbk, NULL, (xdrproc_t)xdr_gfx_readlink_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(readlink, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_unlink(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_unlink_req req = { { 0, }, }; int ret = 0; int op_errno = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_unlink_v2(&req, args->loc, args->flags, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_UNLINK, client4_0_unlink_cbk, NULL, (xdrproc_t)xdr_gfx_unlink_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_rmdir(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_rmdir_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_rmdir_v2(&req, args->loc, args->flags, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_RMDIR, client4_0_rmdir_cbk, NULL, (xdrproc_t)xdr_gfx_rmdir_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(rmdir, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_symlink(call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_symlink_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; if (!(args->loc && args->loc->parent)) goto unwind; loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); local->loc2.path = gf_strdup(args->linkname); ret = client_pre_symlink_v2(&req, args->loc, args->linkname, args->umask, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SYMLINK, client4_0_symlink_cbk, NULL, (xdrproc_t)xdr_gfx_symlink_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_rename(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_rename_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_rename_v2(&req, args->oldloc, args->newloc, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_RENAME, client4_0_rename_cbk, NULL, (xdrproc_t)xdr_gfx_rename_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_link(call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_link_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; ret = client_pre_link_v2(&req, args->oldloc, args->newloc, args->xdata); if (ret) { op_errno = -ret; goto unwind; } loc_copy(&local->loc, args->oldloc); loc_path(&local->loc, NULL); loc_copy(&local->loc2, args->newloc); loc_path(&local->loc2, NULL); ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LINK, client4_0_link_cbk, NULL, (xdrproc_t)xdr_gfx_link_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_mknod(call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_mknod_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); ret = client_pre_mknod_v2(&req, args->loc, args->mode, args->rdev, args->umask, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_MKNOD, client4_0_mknod_cbk, NULL, (xdrproc_t)xdr_gfx_mknod_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_mkdir(call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_mkdir_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; if (!args->xdata || !dict_get_sizen(args->xdata, "gfid-req")) { op_errno = EPERM; gf_msg_callingfn(this->name, GF_LOG_WARNING, op_errno, PC_MSG_GFID_NULL, "mkdir: %s is received " "without gfid-req %p", args->loc->path, args->xdata); goto unwind; } local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; if (!(args->loc && args->loc->parent)) goto unwind; loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); ret = client_pre_mkdir_v2(&req, args->loc, args->mode, args->umask, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_MKDIR, client4_0_mkdir_cbk, NULL, (xdrproc_t)xdr_gfx_mkdir_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_create(call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_create_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; local->fd = fd_ref(args->fd); local->flags = args->flags; loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); ret = client_pre_create_v2(&req, args->loc, args->fd, args->mode, args->flags, args->umask, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_CREATE, client4_0_create_cbk, NULL, (xdrproc_t)xdr_gfx_create_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_open(call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_open_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; local->flags = args->flags; local->fd = fd_ref(args->fd); loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); ret = client_pre_open_v2(&req, args->loc, args->fd, args->flags, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPEN, client4_0_open_cbk, NULL, (xdrproc_t)xdr_gfx_open_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(open, frame, -1, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_readv(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; clnt_local_t *local = NULL; int op_errno = ESTALE; gfx_read_req req = { { 0, }, }; int ret = 0; struct iovec rsp_vec = { 0, }; struct iobuf *rsp_iobuf = NULL; struct iobref *rsp_iobref = NULL; client_payload_t cp; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_readv_v2(this, &req, args->fd, args->size, args->offset, args->flags, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); if (ret) { op_errno = -ret; goto unwind; } local = frame->local; rsp_iobuf = iobuf_get2(this->ctx->iobuf_pool, args->size); if (rsp_iobuf == NULL) { op_errno = ENOMEM; goto unwind; } rsp_iobref = iobref_new(); if (rsp_iobref == NULL) { op_errno = ENOMEM; goto unwind; } iobref_add(rsp_iobref, rsp_iobuf); rsp_vec.iov_base = iobuf_ptr(rsp_iobuf); rsp_vec.iov_len = iobuf_pagesize(rsp_iobuf); local->iobref = rsp_iobref; iobuf_unref(rsp_iobuf); rsp_iobref = NULL; rsp_iobuf = NULL; if (args->size > rsp_vec.iov_len) { gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, PC_MSG_BIGGER_SIZE, "read-size=%lu", (unsigned long)args->size, "iobuf-size=%lu", (unsigned long)rsp_vec.iov_len, NULL); op_errno = EINVAL; goto unwind; } memset(&cp, 0, sizeof(client_payload_t)); cp.rsp_payload = &rsp_vec; cp.rsp_payload_cnt = 1; cp.rsp_iobref = local->iobref; ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READ, client4_0_readv_cbk, &cp, (xdrproc_t)xdr_gfx_read_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: if (rsp_iobuf) iobuf_unref(rsp_iobuf); CLIENT_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_writev(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_write_req req = { { 0, }, }; int op_errno = ESTALE; int ret = 0; client_payload_t cp; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_writev_v2(this, &req, args->fd, args->size, args->offset, args->flags, &args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); if (ret) { op_errno = -ret; goto unwind; } memset(&cp, 0, sizeof(client_payload_t)); cp.iobref = args->iobref; cp.payload = args->vector; cp.payload_cnt = args->count; ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_WRITE, client4_0_writev_cbk, &cp, (xdrproc_t)xdr_gfx_write_req); if (ret) { /* * If the lower layers fail to submit a request, they'll also * do the unwind for us (see rpc_clnt_submit), so don't unwind * here in such cases. */ gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_flush(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; gfx_flush_req req = { { 0, }, }; clnt_conf_t *conf = NULL; clnt_local_t *local = NULL; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; local->fd = fd_ref(args->fd); lk_owner_copy(&local->owner, &frame->root->lk_owner); ret = client_pre_flush_v2(this, &req, args->fd, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FLUSH, client4_0_flush_cbk, NULL, (xdrproc_t)xdr_gfx_flush_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(flush, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fsync(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; gfx_fsync_req req = { { 0, }, }; clnt_conf_t *conf = NULL; int op_errno = 0; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_fsync_v2(this, &req, args->fd, args->flags, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSYNC, client4_0_fsync_cbk, NULL, (xdrproc_t)xdr_gfx_fsync_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fsync, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fstat(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; gfx_fstat_req req = { { 0, }, }; clnt_conf_t *conf = NULL; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_fstat_v2(this, &req, args->fd, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSTAT, client4_0_fstat_cbk, NULL, (xdrproc_t)xdr_gfx_fstat_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_opendir(call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_opendir_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; local->fd = fd_ref(args->fd); loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); ret = client_pre_opendir_v2(&req, args->loc, args->fd, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPENDIR, client4_0_opendir_cbk, NULL, (xdrproc_t)xdr_gfx_opendir_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(opendir, frame, -1, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fsyncdir(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_fsyncdir_req req = { { 0, }, }; int ret = 0; int32_t op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_fsyncdir_v2(this, &req, args->fd, args->flags, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSYNCDIR, client4_0_fsyncdir_cbk, NULL, (xdrproc_t)xdr_gfx_fsyncdir_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fsyncdir, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_statfs(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_statfs_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_statfs_v2(&req, args->loc, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_STATFS, client4_0_statfs_cbk, NULL, (xdrproc_t)xdr_gfx_statfs_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_setxattr(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_setxattr_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_setxattr_v2(&req, args->loc, args->xattr, args->flags, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SETXATTR, client4_0_setxattr_cbk, NULL, (xdrproc_t)xdr_gfx_setxattr_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.dict.pairs.pairs_val); GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); GF_FREE(req.dict.pairs.pairs_val); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fsetxattr(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_fsetxattr_req req = { { 0, }, }; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_fsetxattr_v2(this, &req, args->fd, args->flags, args->xattr, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSETXATTR, client4_0_fsetxattr_cbk, NULL, (xdrproc_t)xdr_gfx_fsetxattr_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.dict.pairs.pairs_val); GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); GF_FREE(req.dict.pairs.pairs_val); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fgetxattr(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_fgetxattr_req req = { { 0, }, }; int op_errno = ESTALE; int ret = 0; clnt_local_t *local = NULL; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; ret = client_pre_fgetxattr_v2(this, &req, args->fd, args->name, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FGETXATTR, client4_0_fgetxattr_cbk, NULL, (xdrproc_t)xdr_gfx_fgetxattr_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_getxattr(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_getxattr_req req = { { 0, }, }; int ret = 0; int32_t op_ret = -1; int op_errno = ESTALE; clnt_local_t *local = NULL; if (!frame || !this || !data) { op_errno = 0; goto unwind; } args = data; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); if (args->name) local->name = gf_strdup(args->name); conf = this->private; ret = client_pre_getxattr_v2(&req, args->loc, args->name, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_GETXATTR, client4_0_getxattr_cbk, NULL, (xdrproc_t)xdr_gfx_getxattr_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(getxattr, frame, op_ret, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_xattrop(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_xattrop_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; clnt_local_t *local = NULL; if (!frame || !this || !data) goto unwind; args = data; if (!(args->loc && args->loc->inode)) goto unwind; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); conf = this->private; ret = client_pre_xattrop_v2(&req, args->loc, args->xattr, args->flags, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_XATTROP, client4_0_xattrop_cbk, NULL, (xdrproc_t)xdr_gfx_xattrop_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.dict.pairs.pairs_val); GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL); GF_FREE(req.dict.pairs.pairs_val); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fxattrop(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_fxattrop_req req = { { 0, }, }; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_fxattrop_v2(this, &req, args->fd, args->xattr, args->flags, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FXATTROP, client4_0_fxattrop_cbk, NULL, (xdrproc_t)xdr_gfx_fxattrop_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.dict.pairs.pairs_val); GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fxattrop, frame, -1, op_errno, NULL, NULL); GF_FREE(req.dict.pairs.pairs_val); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_removexattr(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_removexattr_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_removexattr_v2(&req, args->loc, args->name, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_REMOVEXATTR, client4_0_removexattr_cbk, NULL, (xdrproc_t)xdr_gfx_removexattr_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fremovexattr(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_fremovexattr_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_fremovexattr_v2(this, &req, args->fd, args->name, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request( this, &req, frame, conf->fops, GFS3_OP_FREMOVEXATTR, client4_0_fremovexattr_cbk, NULL, (xdrproc_t)xdr_gfx_fremovexattr_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fremovexattr, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_lease(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; gfx_lease_req req = { { 0, }, }; clnt_conf_t *conf = NULL; int op_errno = ESTALE; int ret = 0; GF_VALIDATE_OR_GOTO("client", this, unwind); GF_VALIDATE_OR_GOTO(this->name, frame, unwind); GF_VALIDATE_OR_GOTO(this->name, data, unwind); args = data; conf = this->private; ret = client_pre_lease_v2(&req, args->loc, args->lease, args->xdata); if (ret < 0) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LEASE, client4_0_lease_cbk, NULL, (xdrproc_t)xdr_gfx_lease_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(lease, frame, -1, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_lk(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; gfx_lk_req req = { { 0, }, }; dict_t *xdata = NULL; int32_t gf_cmd = 0; clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; ret = client_cmd_to_gf_cmd(args->cmd, &gf_cmd); if (ret) { op_errno = EINVAL; gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, "gf_cmd=%d", gf_cmd, NULL); goto unwind; } ret = dict_get_int32(args->xdata, "fd-reopen-status", &local->check_reopen); if (ret) local->check_reopen = 0; lk_owner_copy(&local->owner, &frame->root->lk_owner); local->cmd = args->cmd; local->fd = fd_ref(args->fd); ret = client_pre_lk_v2(this, &req, args->cmd, args->flock, args->fd, args->xdata); if (ret) { op_errno = -ret; if ((op_errno == EBADF) && (args->flock->l_type == F_UNLCK) && client_is_setlk(local->cmd)) { /*Let it pass*/ } else if (local->check_reopen) { xdata = dict_new(); if (xdata == NULL) { op_errno = ENOMEM; goto unwind; } set_fd_reopen_status(this, xdata, FD_BAD); } goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LK, client4_0_lk_cbk, NULL, (xdrproc_t)xdr_gfx_lk_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(lk, frame, -1, op_errno, NULL, xdata); GF_FREE(req.xdata.pairs.pairs_val); if (xdata) dict_unref(xdata); return 0; } int32_t client4_0_inodelk(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_inodelk_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_inodelk_v2(&req, args->loc, args->cmd, args->flock, args->volume, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_INODELK, client4_0_inodelk_cbk, NULL, (xdrproc_t)xdr_gfx_inodelk_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(inodelk, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_finodelk(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; gfx_finodelk_req req = { { 0, }, }; clnt_conf_t *conf = NULL; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_finodelk_v2(this, &req, args->fd, args->cmd, args->flock, args->volume, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FINODELK, client4_0_finodelk_cbk, NULL, (xdrproc_t)xdr_gfx_finodelk_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(finodelk, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_entrylk(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_entrylk_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_entrylk_v2(&req, args->loc, args->cmd_entrylk, args->type, args->volume, args->basename, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ENTRYLK, client4_0_entrylk_cbk, NULL, (xdrproc_t)xdr_gfx_entrylk_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(entrylk, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fentrylk(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; gfx_fentrylk_req req = { { 0, }, }; clnt_conf_t *conf = NULL; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_fentrylk_v2(this, &req, args->fd, args->cmd_entrylk, args->type, args->volume, args->basename, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FENTRYLK, client4_0_fentrylk_cbk, NULL, (xdrproc_t)xdr_gfx_fentrylk_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fentrylk, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_readdir(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; int64_t remote_fd = -1; clnt_conf_t *conf = NULL; gfx_readdir_req req = { { 0, }, }; gfx_readdir_rsp rsp = { 0, }; clnt_local_t *local = NULL; int op_errno = ESTALE; int ret = 0; int count = 0; struct iobref *rsp_iobref = NULL; struct iobuf *rsp_iobuf = NULL; struct iovec *rsphdr = NULL; struct iovec vector[MAX_IOVEC] = { {0}, }; int readdir_rsp_size = 0; client_payload_t cp; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; readdir_rsp_size = xdr_sizeof((xdrproc_t)xdr_gfx_readdir_rsp_custom, &rsp) + args->size; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; local->cmd = remote_fd; if ((readdir_rsp_size + GLUSTERFS_RPC_REPLY_SIZE + GLUSTERFS_RDMA_MAX_HEADER_SIZE) > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) { rsp_iobref = iobref_new(); if (rsp_iobref == NULL) { goto unwind; } /* TODO: what is the size we should send ? */ /* This iobuf will live for only receiving the response, so not harmful */ rsp_iobuf = iobuf_get(this->ctx->iobuf_pool); if (rsp_iobuf == NULL) { goto unwind; } iobref_add(rsp_iobref, rsp_iobuf); rsphdr = &vector[0]; rsphdr->iov_base = iobuf_ptr(rsp_iobuf); rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); count = 1; local->iobref = rsp_iobref; iobuf_unref(rsp_iobuf); rsp_iobuf = NULL; rsp_iobref = NULL; } ret = client_pre_readdir_v2(this, &req, args->fd, args->size, args->offset, args->xdata); if (ret) { op_errno = -ret; goto unwind; } memset(&cp, 0, sizeof(client_payload_t)); cp.rsphdr = rsphdr; cp.rsphdr_cnt = count; cp.rsp_iobref = rsp_iobref; ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READDIR, client4_0_readdir_cbk, &cp, (xdrproc_t)xdr_gfx_readdir_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: if (rsp_iobref) iobref_unref(rsp_iobref); CLIENT_STACK_UNWIND(readdir, frame, -1, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_readdirp(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; gfx_readdirp_req req = { { 0, }, }; gfx_readdirp_rsp rsp = { 0, }; clnt_conf_t *conf = NULL; int op_errno = ESTALE; int ret = 0; int count = 0; int readdirp_rsp_size = 0; struct iobref *rsp_iobref = NULL; struct iobuf *rsp_iobuf = NULL; struct iovec *rsphdr = NULL; struct iovec vector[MAX_IOVEC] = { {0}, }; clnt_local_t *local = NULL; client_payload_t cp; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; ret = client_pre_readdirp_v2(this, &req, args->fd, args->size, args->offset, args->xdata); if (ret) { op_errno = -ret; goto unwind; } readdirp_rsp_size = xdr_sizeof((xdrproc_t)xdr_gfx_readdirp_rsp_custom, &rsp) + args->size; if ((readdirp_rsp_size + GLUSTERFS_RPC_REPLY_SIZE + GLUSTERFS_RDMA_MAX_HEADER_SIZE) > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) { rsp_iobref = iobref_new(); if (rsp_iobref == NULL) { goto unwind; } /* TODO: what is the size we should send ? */ /* This iobuf will live for only receiving the response, so not harmful */ rsp_iobuf = iobuf_get(this->ctx->iobuf_pool); if (rsp_iobuf == NULL) { goto unwind; } rsphdr = &vector[0]; rsphdr->iov_base = iobuf_ptr(rsp_iobuf); rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); count = 1; local->iobref = rsp_iobref; iobref_add(rsp_iobref, rsp_iobuf); iobuf_unref(rsp_iobuf); rsp_iobuf = NULL; rsp_iobref = NULL; } local->fd = fd_ref(args->fd); memset(&cp, 0, sizeof(client_payload_t)); cp.rsphdr = rsphdr; cp.rsphdr_cnt = count; cp.rsp_iobref = rsp_iobref; ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READDIRP, client4_0_readdirp_cbk, &cp, (xdrproc_t)xdr_gfx_readdirp_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: if (rsp_iobref) iobref_unref(rsp_iobref); GF_FREE(req.xdata.pairs.pairs_val); CLIENT_STACK_UNWIND(readdirp, frame, -1, op_errno, NULL, NULL); return 0; } int32_t client4_0_setattr(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_setattr_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_setattr_v2(&req, args->loc, args->valid, args->stbuf, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SETATTR, client4_0_setattr_cbk, NULL, (xdrproc_t)xdr_gfx_setattr_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(setattr, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fallocate(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_fallocate_req req = { {0}, }; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_fallocate_v2(this, &req, args->fd, args->flags, args->offset, args->size, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FALLOCATE, client4_0_fallocate_cbk, NULL, (xdrproc_t)xdr_gfx_fallocate_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_discard(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_discard_req req = { {0}, }; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_discard_v2(this, &req, args->fd, args->offset, args->size, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_DISCARD, client4_0_discard_cbk, NULL, (xdrproc_t)xdr_gfx_discard_req); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_zerofill(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_zerofill_req req = { {0}, }; int op_errno = ESTALE; int ret = 0; GF_ASSERT(frame); if (!this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_zerofill_v2(this, &req, args->fd, args->offset, args->size, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ZEROFILL, client4_0_zerofill_cbk, NULL, (xdrproc_t)xdr_gfx_zerofill_req); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_ipc(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_ipc_req req = { 0, }; int op_errno = ESTALE; int ret = 0; GF_ASSERT(frame); if (!this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_ipc_v2(&req, args->cmd, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_IPC, client4_0_ipc_cbk, NULL, (xdrproc_t)xdr_gfx_ipc_req); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(ipc, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_seek(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; struct gfx_seek_req req = { { 0, }, }; int op_errno = ESTALE; int ret = 0; GF_ASSERT(frame); if (!this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_seek_v2(this, &req, args->fd, args->offset, args->what, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SEEK, client4_0_seek_cbk, NULL, (xdrproc_t)xdr_gfx_seek_req); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(seek, frame, -1, op_errno, 0, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_getactivelk(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_getactivelk_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; if (!(args->loc && args->loc->inode)) goto unwind; if (!gf_uuid_is_null(args->loc->inode->gfid)) memcpy(req.gfid, args->loc->inode->gfid, 16); else memcpy(req.gfid, args->loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req.gfid)), unwind, op_errno, EINVAL); conf = this->private; dict_to_xdr(args->xdata, &req.xdata); ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_GETACTIVELK, client4_0_getactivelk_cbk, NULL, (xdrproc_t)xdr_gfx_getactivelk_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(getactivelk, frame, -1, op_errno, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_setactivelk(call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_setactivelk_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; if (!frame || !this || !data) goto unwind; args = data; if (!(args->loc && args->loc->inode && args->locklist)) goto unwind; if (!gf_uuid_is_null(args->loc->inode->gfid)) memcpy(req.gfid, args->loc->inode->gfid, 16); else memcpy(req.gfid, args->loc->gfid, 16); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req.gfid)), unwind, op_errno, EINVAL); conf = this->private; dict_to_xdr(args->xdata, &req.xdata); ret = serialize_req_locklist_v2(args->locklist, &req); if (ret) goto unwind; ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SETACTIVELK, client4_0_setactivelk_cbk, NULL, (xdrproc_t)xdr_gfx_setactivelk_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } clnt_setactivelk_req_cleanup_v2(&req); GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(setactivelk, frame, -1, op_errno, NULL); GF_FREE(req.xdata.pairs.pairs_val); clnt_setactivelk_req_cleanup_v2(&req); return 0; } int client4_rchecksum_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; gfx_rchecksum_rsp rsp = { 0, }; int ret = 0; dict_t *xdata = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_rchecksum_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } xdr_to_dict(&rsp.xdata, &xdata); out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(rchecksum, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), rsp.weak_checksum, (uint8_t *)rsp.strong_checksum.strong_checksum_val, xdata); if (rsp.strong_checksum.strong_checksum_val) { /* This is allocated by the libc while decoding RPC msg */ /* Hence no 'GF_FREE', but just 'free' */ free(rsp.strong_checksum.strong_checksum_val); } if (xdata) dict_unref(xdata); return 0; } int32_t client4_namelink_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { int32_t ret = 0; struct iatt prebuf = { 0, }; struct iatt postbuf = { 0, }; dict_t *xdata = NULL; call_frame_t *frame = NULL; gfx_common_2iatt_rsp rsp = { 0, }; frame = myframe; if (req->rpc_status == -1) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); if (ret < 0) { rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (rsp.op_ret != -1) { gfx_stat_to_iattx(&rsp.prestat, &prebuf); gfx_stat_to_iattx(&rsp.poststat, &postbuf); } xdr_to_dict(&rsp.xdata, &xdata); out: CLIENT_STACK_UNWIND(namelink, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), &prebuf, &postbuf, xdata); if (xdata) dict_unref(xdata); return 0; } int32_t client4_icreate_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { int32_t ret = 0; inode_t *inode = NULL; clnt_local_t *local = NULL; struct iatt stbuf = { 0, }; dict_t *xdata = NULL; call_frame_t *frame = NULL; gfx_common_iatt_rsp rsp = { 0, }; frame = myframe; local = frame->local; inode = local->loc.inode; if (req->rpc_status == -1) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_iatt_rsp); if (ret < 0) { rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (rsp.op_ret != -1) gfx_stat_to_iattx(&rsp.stat, &stbuf); xdr_to_dict(&rsp.xdata, &xdata); out: CLIENT_STACK_UNWIND(icreate, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), inode, &stbuf, xdata); if (xdata) dict_unref(xdata); return 0; } int client4_0_put_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfx_common_3iatt_rsp rsp = { 0, }; call_frame_t *frame = NULL; int ret = 0; dict_t *xdata = NULL; clnt_local_t *local = NULL; struct iatt stbuf = { 0, }; struct iatt preparent = { 0, }; struct iatt postparent = { 0, }; inode_t *inode = NULL; frame = myframe; local = frame->local; inode = local->loc.inode; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_3iatt_rsp); if (ret < 0) { gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, NULL); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (-1 != rsp.op_ret) { ret = client_post_common_3iatt(&rsp, &stbuf, &preparent, &postparent, &xdata); if (ret < 0) goto out; } out: if (rsp.op_ret == -1) { gf_smsg(THIS->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); } CLIENT_STACK_UNWIND(put, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), inode, &stbuf, &preparent, &postparent, xdata); if (xdata) dict_unref(xdata); return 0; } int32_t client4_0_namelink(call_frame_t *frame, xlator_t *this, void *data) { int32_t ret = 0; int32_t op_errno = EINVAL; clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; gfx_namelink_req req = { { 0, }, }; GF_ASSERT(frame); args = data; conf = this->private; if (!(args->loc && args->loc->parent)) goto unwind; if (!gf_uuid_is_null(args->loc->parent->gfid)) memcpy(req.pargfid, args->loc->parent->gfid, sizeof(uuid_t)); else memcpy(req.pargfid, args->loc->pargfid, sizeof(uuid_t)); GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(*((uuid_t *)req.pargfid)), unwind, op_errno, EINVAL); req.bname = (char *)args->loc->name; dict_to_xdr(args->xdata, &req.xdata); ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_NAMELINK, client4_namelink_cbk, NULL, (xdrproc_t)xdr_gfx_namelink_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(namelink, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int32_t client4_0_icreate(call_frame_t *frame, xlator_t *this, void *data) { int32_t ret = 0; int32_t op_errno = EINVAL; clnt_conf_t *conf = NULL; clnt_args_t *args = NULL; clnt_local_t *local = NULL; gfx_icreate_req req = { { 0, }, }; GF_ASSERT(frame); args = data; conf = this->private; if (!(args->loc && args->loc->inode)) goto unwind; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; loc_copy(&local->loc, args->loc); req.mode = args->mode; memcpy(req.gfid, args->loc->gfid, sizeof(uuid_t)); op_errno = ESTALE; dict_to_xdr(args->xdata, &req.xdata); ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ICREATE, client4_icreate_cbk, NULL, (xdrproc_t)xdr_gfx_icreate_req); if (ret) goto free_reqdata; GF_FREE(req.xdata.pairs.pairs_val); return 0; free_reqdata: GF_FREE(req.xdata.pairs.pairs_val); unwind: CLIENT_STACK_UNWIND(icreate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int32_t client4_0_put(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_put_req req = { { 0, }, }; int op_errno = ESTALE; int ret = 0; clnt_local_t *local = NULL; client_payload_t cp; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; goto unwind; } frame->local = local; loc_copy(&local->loc, args->loc); loc_path(&local->loc, NULL); ret = client_pre_put_v2(&req, args->loc, args->mode, args->umask, args->flags, args->size, args->offset, args->xattr, args->xdata); if (ret) { op_errno = -ret; goto unwind; } memset(&cp, 0, sizeof(client_payload_t)); cp.iobref = args->iobref; cp.payload = args->vector; cp.payload_cnt = args->count; ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_PUT, client4_0_put_cbk, &cp, (xdrproc_t)xdr_gfx_put_req); if (ret) { /* * If the lower layers fail to submit a request, they'll also * do the unwind for us (see rpc_clnt_submit), so don't unwind * here in such cases. */ gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } return 0; unwind: CLIENT_STACK_UNWIND(put, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t client4_0_copy_file_range(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; clnt_local_t *local = NULL; gfx_copy_file_range_req req = { { 0, }, }; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_copy_file_range_v2(this, &req, args->fd, args->off_in, args->fd_out, args->off_out, args->size, args->flags, &args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_fd_fop_prepare_local(frame, args->fd, req.fd_in); if (ret) { op_errno = -ret; goto unwind; } /* * Since frame->local is allocated in above function call * itself, better to use it (with the assumption that it * has been allocated) directly instead of again calling * client_fd_fop_prepare_local or modifying it, as doing * so requires changes in other places as well. */ local = frame->local; local->fd_out = fd_ref(args->fd_out); local->attempt_reopen_out = client_is_reopen_needed(args->fd_out, this, req.fd_out); ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_COPY_FILE_RANGE, client4_0_copy_file_range_cbk, NULL, (xdrproc_t)xdr_gfx_copy_file_range_req); if (ret) { /* * If the lower layers fail to submit a request, they'll also * do the unwind for us (see rpc_clnt_submit), so don't unwind * here in such cases. */ gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(copy_file_range, frame, -1, op_errno, NULL, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_fsetattr(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; clnt_conf_t *conf = NULL; gfx_fsetattr_req req = { {0}, }; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; ret = client_pre_fsetattr_v2(this, &req, args->fd, args->valid, args->stbuf, args->xdata); if (ret) { op_errno = -ret; goto unwind; } ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSETATTR, client4_0_fsetattr_cbk, NULL, (xdrproc_t)xdr_gfx_fsetattr_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(fsetattr, frame, -1, op_errno, NULL, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } int32_t client4_0_rchecksum(call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; int64_t remote_fd = -1; clnt_conf_t *conf = NULL; gfx_rchecksum_req req = { {0}, }; int op_errno = ESTALE; int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; CLIENT_GET_REMOTE_FD(this, args->fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, GFS3_OP_RCHECKSUM, unwind); req.len = args->len; req.offset = args->offset; req.fd = remote_fd; memcpy(req.gfid, args->fd->inode->gfid, 16); dict_to_xdr(args->xdata, &req.xdata); ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_RCHECKSUM, client4_rchecksum_cbk, NULL, (xdrproc_t)xdr_gfx_rchecksum_req); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); } GF_FREE(req.xdata.pairs.pairs_val); return 0; unwind: CLIENT_STACK_UNWIND(rchecksum, frame, -1, op_errno, 0, NULL, NULL); GF_FREE(req.xdata.pairs.pairs_val); return 0; } /* Used From RPC-CLNT library to log proper name of procedure based on number */ char *clnt4_0_fop_names[GFS3_OP_MAXVALUE] = { [GFS3_OP_NULL] = "NULL", [GFS3_OP_STAT] = "STAT", [GFS3_OP_READLINK] = "READLINK", [GFS3_OP_MKNOD] = "MKNOD", [GFS3_OP_MKDIR] = "MKDIR", [GFS3_OP_UNLINK] = "UNLINK", [GFS3_OP_RMDIR] = "RMDIR", [GFS3_OP_SYMLINK] = "SYMLINK", [GFS3_OP_RENAME] = "RENAME", [GFS3_OP_LINK] = "LINK", [GFS3_OP_TRUNCATE] = "TRUNCATE", [GFS3_OP_OPEN] = "OPEN", [GFS3_OP_READ] = "READ", [GFS3_OP_WRITE] = "WRITE", [GFS3_OP_STATFS] = "STATFS", [GFS3_OP_FLUSH] = "FLUSH", [GFS3_OP_FSYNC] = "FSYNC", [GFS3_OP_SETXATTR] = "SETXATTR", [GFS3_OP_GETXATTR] = "GETXATTR", [GFS3_OP_REMOVEXATTR] = "REMOVEXATTR", [GFS3_OP_OPENDIR] = "OPENDIR", [GFS3_OP_FSYNCDIR] = "FSYNCDIR", [GFS3_OP_ACCESS] = "ACCESS", [GFS3_OP_CREATE] = "CREATE", [GFS3_OP_FTRUNCATE] = "FTRUNCATE", [GFS3_OP_FSTAT] = "FSTAT", [GFS3_OP_LK] = "LK", [GFS3_OP_LOOKUP] = "LOOKUP", [GFS3_OP_READDIR] = "READDIR", [GFS3_OP_INODELK] = "INODELK", [GFS3_OP_FINODELK] = "FINODELK", [GFS3_OP_ENTRYLK] = "ENTRYLK", [GFS3_OP_FENTRYLK] = "FENTRYLK", [GFS3_OP_XATTROP] = "XATTROP", [GFS3_OP_FXATTROP] = "FXATTROP", [GFS3_OP_FGETXATTR] = "FGETXATTR", [GFS3_OP_FSETXATTR] = "FSETXATTR", [GFS3_OP_RCHECKSUM] = "RCHECKSUM", [GFS3_OP_SETATTR] = "SETATTR", [GFS3_OP_FSETATTR] = "FSETATTR", [GFS3_OP_READDIRP] = "READDIRP", [GFS3_OP_RELEASE] = "RELEASE", [GFS3_OP_RELEASEDIR] = "RELEASEDIR", [GFS3_OP_FREMOVEXATTR] = "FREMOVEXATTR", [GFS3_OP_FALLOCATE] = "FALLOCATE", [GFS3_OP_DISCARD] = "DISCARD", [GFS3_OP_ZEROFILL] = "ZEROFILL", [GFS3_OP_IPC] = "IPC", [GFS3_OP_SEEK] = "SEEK", [GFS3_OP_LEASE] = "LEASE", [GFS3_OP_GETACTIVELK] = "GETACTIVELK", [GFS3_OP_SETACTIVELK] = "SETACTIVELK", [GFS3_OP_COMPOUND] = "COMPOUND", [GFS3_OP_ICREATE] = "ICREATE", [GFS3_OP_NAMELINK] = "NAMELINK", }; rpc_clnt_procedure_t clnt4_0_fop_actors[GF_FOP_MAXVALUE] = { [GF_FOP_NULL] = {"NULL", NULL}, [GF_FOP_STAT] = {"STAT", client4_0_stat}, [GF_FOP_READLINK] = {"READLINK", client4_0_readlink}, [GF_FOP_MKNOD] = {"MKNOD", client4_0_mknod}, [GF_FOP_MKDIR] = {"MKDIR", client4_0_mkdir}, [GF_FOP_UNLINK] = {"UNLINK", client4_0_unlink}, [GF_FOP_RMDIR] = {"RMDIR", client4_0_rmdir}, [GF_FOP_SYMLINK] = {"SYMLINK", client4_0_symlink}, [GF_FOP_RENAME] = {"RENAME", client4_0_rename}, [GF_FOP_LINK] = {"LINK", client4_0_link}, [GF_FOP_TRUNCATE] = {"TRUNCATE", client4_0_truncate}, [GF_FOP_OPEN] = {"OPEN", client4_0_open}, [GF_FOP_READ] = {"READ", client4_0_readv}, [GF_FOP_WRITE] = {"WRITE", client4_0_writev}, [GF_FOP_STATFS] = {"STATFS", client4_0_statfs}, [GF_FOP_FLUSH] = {"FLUSH", client4_0_flush}, [GF_FOP_FSYNC] = {"FSYNC", client4_0_fsync}, [GF_FOP_GETXATTR] = {"GETXATTR", client4_0_getxattr}, [GF_FOP_SETXATTR] = {"SETXATTR", client4_0_setxattr}, [GF_FOP_REMOVEXATTR] = {"REMOVEXATTR", client4_0_removexattr}, [GF_FOP_OPENDIR] = {"OPENDIR", client4_0_opendir}, [GF_FOP_FSYNCDIR] = {"FSYNCDIR", client4_0_fsyncdir}, [GF_FOP_ACCESS] = {"ACCESS", client4_0_access}, [GF_FOP_CREATE] = {"CREATE", client4_0_create}, [GF_FOP_FTRUNCATE] = {"FTRUNCATE", client4_0_ftruncate}, [GF_FOP_FSTAT] = {"FSTAT", client4_0_fstat}, [GF_FOP_LK] = {"LK", client4_0_lk}, [GF_FOP_LOOKUP] = {"LOOKUP", client4_0_lookup}, [GF_FOP_READDIR] = {"READDIR", client4_0_readdir}, [GF_FOP_INODELK] = {"INODELK", client4_0_inodelk}, [GF_FOP_FINODELK] = {"FINODELK", client4_0_finodelk}, [GF_FOP_ENTRYLK] = {"ENTRYLK", client4_0_entrylk}, [GF_FOP_FENTRYLK] = {"FENTRYLK", client4_0_fentrylk}, [GF_FOP_XATTROP] = {"XATTROP", client4_0_xattrop}, [GF_FOP_FXATTROP] = {"FXATTROP", client4_0_fxattrop}, [GF_FOP_FGETXATTR] = {"FGETXATTR", client4_0_fgetxattr}, [GF_FOP_FSETXATTR] = {"FSETXATTR", client4_0_fsetxattr}, [GF_FOP_RCHECKSUM] = {"RCHECKSUM", client4_0_rchecksum}, [GF_FOP_SETATTR] = {"SETATTR", client4_0_setattr}, [GF_FOP_FSETATTR] = {"FSETATTR", client4_0_fsetattr}, [GF_FOP_READDIRP] = {"READDIRP", client4_0_readdirp}, [GF_FOP_FALLOCATE] = {"FALLOCATE", client4_0_fallocate}, [GF_FOP_DISCARD] = {"DISCARD", client4_0_discard}, [GF_FOP_ZEROFILL] = {"ZEROFILL", client4_0_zerofill}, [GF_FOP_RELEASE] = {"RELEASE", client4_0_release}, [GF_FOP_RELEASEDIR] = {"RELEASEDIR", client4_0_releasedir}, [GF_FOP_GETSPEC] = {"GETSPEC", client3_getspec}, [GF_FOP_FREMOVEXATTR] = {"FREMOVEXATTR", client4_0_fremovexattr}, [GF_FOP_IPC] = {"IPC", client4_0_ipc}, [GF_FOP_SEEK] = {"SEEK", client4_0_seek}, [GF_FOP_LEASE] = {"LEASE", client4_0_lease}, [GF_FOP_GETACTIVELK] = {"GETACTIVELK", client4_0_getactivelk}, [GF_FOP_SETACTIVELK] = {"SETACTIVELK", client4_0_setactivelk}, [GF_FOP_COMPOUND] = {"COMPOUND", NULL}, [GF_FOP_ICREATE] = {"ICREATE", client4_0_icreate}, [GF_FOP_NAMELINK] = {"NAMELINK", client4_0_namelink}, [GF_FOP_COPY_FILE_RANGE] = {"COPY-FILE-RANGE", client4_0_copy_file_range}, }; rpc_clnt_prog_t clnt4_0_fop_prog = { .progname = "GlusterFS 4.x v1", .prognum = GLUSTER_FOP_PROGRAM, .progver = GLUSTER_FOP_VERSION_v2, .numproc = GLUSTER_FOP_PROCCNT, .proctable = clnt4_0_fop_actors, .procnames = clnt4_0_fop_names, }; glusterfs-11.1/xlators/protocol/client/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467023247 xustar000000000000000030 mtime=1699284279.479069034 30 atime=1699284289.950100573 30 ctime=1699284301.767136165 glusterfs-11.1/xlators/protocol/client/Makefile.in0000664000175100017510000005262514522202467023540 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol/client DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/client/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/client/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/client/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023227 xustar000000000000000030 mtime=1699284265.771027745 30 atime=1699284279.455068962 30 ctime=1699284301.768136168 glusterfs-11.1/xlators/protocol/client/Makefile.am0000664000175100017510000000001614522202451023503 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/protocol/PaxHeaders.9031/server0000644000000000000000000000013114522202515021146 xustar000000000000000030 mtime=1699284301.860136445 29 atime=1699284309.68416001 30 ctime=1699284301.860136445 glusterfs-11.1/xlators/protocol/server/0002775000175100017510000000000014522202515021505 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/server/PaxHeaders.9031/src0000644000000000000000000000013114522202515021735 xustar000000000000000030 mtime=1699284301.912136601 29 atime=1699284309.68416001 30 ctime=1699284301.912136601 glusterfs-11.1/xlators/protocol/server/src/0002775000175100017510000000000014522202515022274 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server-common.h0000644000000000000000000000013214522202451024757 xustar000000000000000030 mtime=1699284265.777027763 30 atime=1699284265.777027763 30 ctime=1699284301.902136571 glusterfs-11.1/xlators/protocol/server/src/server-common.h0000664000175100017510000000525614522202451025246 0ustar00jenkinsjenkins00000000000000#include "server.h" #include "glusterfs3.h" #include #include "server-messages.h" #ifdef BUILD_GNFS #include "xdr-nfs3.h" #endif void server4_post_readlink(gfx_readlink_rsp *rsp, struct iatt *stbuf, const char *buf); void server4_post_statfs(gfx_statfs_rsp *rsp, struct statvfs *stbuf); void server4_post_lk(xlator_t *this, gfx_lk_rsp *rsp, struct gf_flock *lock); int server4_post_readdir(gfx_readdir_rsp *rsp, gf_dirent_t *entries); void server4_post_seek(gfx_seek_rsp *rsp, off_t offset); int server4_post_readdirp(gfx_readdirp_rsp *rsp, gf_dirent_t *entries); void server4_post_rchecksum(gfx_rchecksum_rsp *rsp, uint32_t weak_checksum, uint8_t *strong_checksum); void server4_post_rename(call_frame_t *frame, server_state_t *state, gfx_rename_rsp *rsp, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent); int server4_post_open(call_frame_t *frame, xlator_t *this, gfx_open_rsp *rsp, fd_t *fd); void server4_post_readv(gfx_read_rsp *rsp, struct iatt *stbuf, int op_ret); int server4_post_create(call_frame_t *frame, gfx_create_rsp *rsp, server_state_t *state, xlator_t *this, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent); void server4_post_common_2iatt(gfx_common_2iatt_rsp *rsp, struct iatt *stbuf1, struct iatt *stbuf2); void server4_post_entry_remove(server_state_t *state, gfx_common_2iatt_rsp *rsp, struct iatt *stbuf1, struct iatt *stbuf2); void server4_post_common_3iatt(server_state_t *state, gfx_common_3iatt_rsp *rsp, inode_t *inode, struct iatt *stbuf, struct iatt *pre, struct iatt *post); void server4_post_common_iatt(server_state_t *state, gfx_common_iatt_rsp *rsp, struct iatt *stbuf); void server4_post_lease(gfx_lease_rsp *rsp, struct gf_lease *lease); void server4_post_lookup(gfx_common_2iatt_rsp *rsp, call_frame_t *frame, server_state_t *state, inode_t *inode, struct iatt *stbuf, dict_t *xdata); void server4_post_link(server_state_t *state, gfx_common_3iatt_rsp *rsp, inode_t *inode, struct iatt *stbuf, struct iatt *pre, struct iatt *post); void server4_post_common_3iatt_noinode(gfx_common_3iatt_rsp *rsp, struct iatt *stbuf, struct iatt *prebuf_dst, struct iatt *postbuf_dst); glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server-resolve.c0000644000000000000000000000013114522202451025140 xustar000000000000000030 mtime=1699284265.779027769 30 atime=1699284265.778027766 29 ctime=1699284301.90513658 glusterfs-11.1/xlators/protocol/server/src/server-resolve.c0000664000175100017510000004406014522202451025424 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "server.h" #include "server-helpers.h" #include "server-messages.h" static void server_resolve_all(call_frame_t *frame, server_state_t *state); static int resolve_entry_simple(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve); static int resolve_inode_simple(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve); static void resolve_continue(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve); static int resolve_anonfd_simple(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve); static int resolve_name_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { server_state_t *state = NULL; server_resolve_t *resolve = NULL; inode_t *link_inode = NULL; loc_t *resolve_loc = NULL; state = CALL_STATE(frame); resolve = state->resolve_now; resolve_loc = &resolve->resolve_loc; if (op_ret == -1) { if (op_errno == ENOENT) { gf_msg_debug(this->name, op_errno, "%s/%s: failed to resolve", uuid_utoa(resolve_loc->pargfid), resolve_loc->name); if (resolve->type == RESOLVE_NOT) { do { inode = inode_grep(state->itable, resolve_loc->parent, resolve->bname); if (inode) { gf_msg_debug(this->name, 0, "%s/%s: " "removing stale dentry", uuid_utoa(resolve_loc->pargfid), resolve->bname); inode_unlink(inode, resolve_loc->parent, resolve->bname); } } while (inode); } } else { gf_msg(this->name, GF_LOG_WARNING, op_errno, PS_MSG_GFID_RESOLVE_FAILED, "%s/%s: failed to " "resolve (%s)", uuid_utoa(resolve_loc->pargfid), resolve_loc->name, strerror(op_errno)); } goto out; } link_inode = inode_link(inode, resolve_loc->parent, resolve_loc->name, buf); if (!link_inode) goto out; inode_lookup(link_inode); inode_unref(link_inode); out: loc_wipe(resolve_loc); resolve_continue(frame, state, resolve); return 0; } static int resolve_name(call_frame_t *frame, inode_t *parent, server_state_t *state, server_resolve_t *resolve) { loc_t *resolve_loc = NULL; dict_t *dict = NULL; resolve_loc = &resolve->resolve_loc; resolve_loc->parent = inode_ref(parent); gf_uuid_copy(resolve_loc->pargfid, resolve_loc->parent->gfid); resolve_loc->name = resolve->bname; resolve_loc->inode = server_inode_new(state->itable, resolve_loc->gfid); inode_path(resolve_loc->parent, resolve_loc->name, (char **)&resolve_loc->path); if (state->xdata) { dict = dict_copy_with_ref(state->xdata, NULL); if (!dict) gf_msg(frame->this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY, "BUG: dict allocation failed (pargfid: %s, name: %s), " "still continuing", uuid_utoa(resolve_loc->gfid), resolve_loc->name); } STACK_WIND(frame, resolve_name_cbk, frame->root->client->bound_xl, frame->root->client->bound_xl->fops->lookup, &resolve->resolve_loc, dict); if (dict) dict_unref(dict); return 0; } static int resolve_gfid_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { server_state_t *state = NULL; server_resolve_t *resolve = NULL; inode_t *link_inode = NULL; loc_t *resolve_loc = NULL; state = CALL_STATE(frame); resolve = state->resolve_now; resolve_loc = &resolve->resolve_loc; if (op_ret == -1) { if (op_errno == ENOENT) { gf_msg_debug(this->name, op_errno, "%s: failed to resolve", uuid_utoa(resolve_loc->gfid)); } else { gf_msg(this->name, GF_LOG_WARNING, op_errno, PS_MSG_GFID_RESOLVE_FAILED, "%s: failed to resolve (%s)", uuid_utoa(resolve_loc->gfid), strerror(op_errno)); } loc_wipe(&resolve->resolve_loc); goto out; } link_inode = inode_link(inode, NULL, NULL, buf); if (!link_inode) { loc_wipe(resolve_loc); goto out; } inode_lookup(link_inode); /* wipe the loc only after the inode has been linked to the inode table. Otherwise before inode gets linked to the inode table, inode would have been unrefed (this might have been destroyed if refcount becomes 0, and put back to mempool). So once the inode gets destroyed, inode_link is a redundant operation. But without knowing that the destroyed inode's pointer is saved in the resolved_loc as parent (while constructing loc for resolving the entry) and the inode_new call for resolving the entry will return the same pointer to the inode as the parent (because in reality the inode is a free inode present in cold list of the inode mem-pool). */ loc_wipe(resolve_loc); if (gf_uuid_is_null(resolve->pargfid)) { inode_unref(link_inode); goto out; } resolve_name(frame, link_inode, state, resolve); inode_unref(link_inode); return 0; out: resolve_continue(frame, state, resolve); return 0; } static void resolve_gfid(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve) { loc_t *resolve_loc = NULL; dict_t *xdata = NULL; resolve_loc = &resolve->resolve_loc; if (!gf_uuid_is_null(resolve->pargfid)) gf_uuid_copy(resolve_loc->gfid, resolve->pargfid); else if (!gf_uuid_is_null(resolve->gfid)) gf_uuid_copy(resolve_loc->gfid, resolve->gfid); resolve_loc->inode = server_inode_new(state->itable, resolve_loc->gfid); (void)loc_path(resolve_loc, NULL); if (state->xdata) { xdata = dict_copy_with_ref(state->xdata, NULL); if (!xdata) gf_msg(frame->this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY, "BUG: dict allocation failed (gfid: %s), " "still continuing", uuid_utoa(resolve_loc->gfid)); } STACK_WIND(frame, resolve_gfid_cbk, frame->root->client->bound_xl, frame->root->client->bound_xl->fops->lookup, &resolve->resolve_loc, xdata); if (xdata) dict_unref(xdata); } static void resolve_continue(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve) { int ret = 0; resolve->op_ret = 0; resolve->op_errno = 0; if (resolve->fd_no != -1) { ret = resolve_anonfd_simple(frame, state, resolve); goto out; } else if (!gf_uuid_is_null(resolve->pargfid)) ret = resolve_entry_simple(frame, state, resolve); else if (!gf_uuid_is_null(resolve->gfid)) ret = resolve_inode_simple(frame, state, resolve); if (ret) gf_msg_debug(frame->this->name, 0, "return value of resolve_*_" "simple %d", ret); loc_touchup(state->loc_now, resolve->bname); out: server_resolve_all(frame, state); } /* Check if the requirements are fulfilled by entries in the inode cache itself Return value: <= 0 - simple resolution was decisive and complete (either success or failure) > 0 - indecisive, need to perform deep resolution */ static int resolve_entry_simple(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve) { inode_t *parent = NULL; inode_t *inode = NULL; int ret = 0; parent = inode_find(state->itable, resolve->pargfid); if (!parent) { /* simple resolution is indecisive. need to perform deep resolution */ resolve->op_ret = -1; resolve->op_errno = ESTALE; ret = 1; goto out; } if (parent->ia_type != IA_IFDIR) { /* Parent type should be 'directory', and nothing else */ gf_msg(frame->this->name, GF_LOG_ERROR, EPERM, PS_MSG_GFID_RESOLVE_FAILED, "%s: parent type not directory (%d)", uuid_utoa(parent->gfid), parent->ia_type); resolve->op_ret = -1; resolve->op_errno = EPERM; ret = 1; goto out; } /* expected @parent was found from the inode cache */ gf_uuid_copy(state->loc_now->pargfid, resolve->pargfid); state->loc_now->parent = inode_ref(parent); if (strchr(resolve->bname, '/')) { /* basename should be a string (without '/') in a directory, it can't span multiple levels. This can also lead to resolving outside the parent's tree, which is not allowed */ gf_msg(frame->this->name, GF_LOG_ERROR, EPERM, PS_MSG_GFID_RESOLVE_FAILED, "%s: basename sent by client not allowed", resolve->bname); resolve->op_ret = -1; resolve->op_errno = EPERM; ret = 1; goto out; } state->loc_now->name = resolve->bname; inode = inode_grep(state->itable, parent, resolve->bname); if (!inode) { switch (resolve->type) { case RESOLVE_DONTCARE: case RESOLVE_NOT: ret = 0; break; case RESOLVE_MAY: ret = 2; break; default: resolve->op_ret = -1; resolve->op_errno = ENOENT; ret = 2; break; } goto out; } if (resolve->type == RESOLVE_NOT) { gf_msg_debug(frame->this->name, 0, "inode (pointer: %p gfid:%s found" " for path (%s) while type is RESOLVE_NOT. " "Performing lookup on backend to rule out any " "possible stale dentries in inode table", inode, uuid_utoa(inode->gfid), resolve->path); resolve->op_ret = -1; resolve->op_errno = EEXIST; ret = 1; goto out; } ret = 0; state->loc_now->inode = inode_ref(inode); out: if (parent) inode_unref(parent); if (inode) inode_unref(inode); return ret; } static void server_resolve_entry(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve) { int ret = 0; inode_t *parent = NULL; ret = resolve_entry_simple(frame, state, resolve); if (ret > 0) { if (ret == 2) { parent = inode_ref(state->loc_now->parent); } /*Wipe state->loc_now before calling resolve_xxxx()*/ loc_wipe(state->loc_now); if (parent) { resolve_name(frame, parent, state, resolve); inode_unref(parent); } else { resolve_gfid(frame, state, resolve); } } else { loc_touchup(state->loc_now, resolve->bname); server_resolve_all(frame, state); } } static int resolve_inode_simple(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve) { inode_t *inode = NULL; int ret = 0; inode = inode_find(state->itable, resolve->gfid); if (!inode) { if (resolve->type == RESOLVE_DONTCARE) { gf_uuid_copy(state->loc_now->gfid, resolve->gfid); } else { resolve->op_ret = -1; resolve->op_errno = ESTALE; ret = 1; } goto out; } state->loc_now->inode = inode_ref(inode); gf_uuid_copy(state->loc_now->gfid, resolve->gfid); out: if (inode) inode_unref(inode); return ret; } static void server_resolve_inode(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve) { int ret = 0; loc_t *loc = NULL; ret = resolve_inode_simple(frame, state, resolve); if (ret > 0) { loc = state->loc_now; loc_wipe(loc); resolve_gfid(frame, state, resolve); } else { loc_touchup(state->loc_now, resolve->bname); server_resolve_all(frame, state); } } static int resolve_anonfd_simple(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve) { inode_t *inode = NULL; int ret = 0; inode = inode_find(state->itable, resolve->gfid); if (!inode) { resolve->op_ret = -1; resolve->op_errno = ENOENT; ret = 1; gf_msg_debug("server", 0, "inode for the gfid" "(%s) is not found. anonymous fd creation failed", uuid_utoa(resolve->gfid)); goto out; } if (frame->root->op == GF_FOP_READ || frame->root->op == GF_FOP_WRITE) state->fd = fd_anonymous_with_flags(inode, state->flags); else state->fd = fd_anonymous(inode); out: if (inode) inode_unref(inode); return ret; } static void server_resolve_anonfd(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve) { int ret = 0; loc_t *loc = NULL; ret = resolve_anonfd_simple(frame, state, resolve); if (ret > 0) { loc = state->loc_now; loc_wipe(loc); resolve_gfid(frame, state, resolve); } else { server_resolve_all(frame, state); } } static void server_resolve_fd(call_frame_t *frame, server_state_t *state, server_resolve_t *resolve) { server_ctx_t *serv_ctx = NULL; client_t *client = NULL; uint64_t fd_no; fd_no = resolve->fd_no; if (fd_no == GF_ANON_FD_NO) { server_resolve_anonfd(frame, state, resolve); return; } client = frame->root->client; serv_ctx = server_ctx_get(client, client->this); if (serv_ctx == NULL) { gf_msg("", GF_LOG_INFO, ENOMEM, PS_MSG_NO_MEMORY, "server_ctx_get() failed"); resolve->op_ret = -1; resolve->op_errno = ENOMEM; return; } /* * With copy_file_range, there will be 2 fds to resolve. * This same function is called to resolve both the source * fd and the destination fd. As of now, this function does * not have any mechanism to distinguish between the 2 fds * being resolved except for checking the value of state->fd. * The assumption is that, if source fd the one which is * being resolved here, then state->fd would be NULL. If it * is not NULL, then it is the destination fd which is being * resolved. * This method (provided the above assumption is true) is * to achieve the ability to distinguish between 2 fds with * minimum changes being done to this function. If this way * is not correct, then more changes might be needed. */ if (!state->fd) { state->fd = gf_fd_fdptr_get(serv_ctx->fdtable, fd_no); if (!state->fd) { gf_msg("", GF_LOG_INFO, EBADF, PS_MSG_FD_NOT_FOUND, "fd not " "found in context"); resolve->op_ret = -1; resolve->op_errno = EBADF; } } else { state->fd_out = gf_fd_fdptr_get(serv_ctx->fdtable, fd_no); if (!state->fd_out) { gf_msg("", GF_LOG_INFO, EBADF, PS_MSG_FD_NOT_FOUND, "fd not " "found in context"); resolve->op_ret = -1; resolve->op_errno = EBADF; } } server_resolve_all(frame, state); } static void server_resolve(call_frame_t *frame, server_state_t *state) { server_resolve_t *resolve = NULL; resolve = state->resolve_now; if (resolve->fd_no != -1) { server_resolve_fd(frame, state, resolve); } else if (!gf_uuid_is_null(resolve->pargfid)) { server_resolve_entry(frame, state, resolve); } else if (!gf_uuid_is_null(resolve->gfid)) { server_resolve_inode(frame, state, resolve); } else { if (resolve == &state->resolve) gf_msg(frame->this->name, GF_LOG_WARNING, 0, PS_MSG_INVALID_ENTRY, "no resolution type for %s (%s)", resolve->path, gf_fop_list[frame->root->op]); resolve->op_ret = -1; resolve->op_errno = EINVAL; server_resolve_all(frame, state); } } static void server_resolve_done(call_frame_t *frame, server_state_t *state) { server_print_request(frame); state->resume_fn(frame, frame->root->client->bound_xl); } /* * This function is called multiple times, once per resolving one location/fd. * state->resolve_now is used to decide which location/fd is to be resolved now */ static void server_resolve_all(call_frame_t *frame, server_state_t *state) { if (state->resolve_now == NULL) { state->resolve_now = &state->resolve; state->loc_now = &state->loc; server_resolve(frame, state); } else if (state->resolve_now == &state->resolve) { state->resolve_now = &state->resolve2; state->loc_now = &state->loc2; server_resolve(frame, state); } else if (state->resolve_now == &state->resolve2) { server_resolve_done(frame, state); } else { gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, PS_MSG_INVALID_ENTRY, "Invalid pointer for " "state->resolve_now"); } } void resolve_and_resume(call_frame_t *frame, server_resume_fn_t fn) { server_state_t *state = NULL; state = CALL_STATE(frame); state->resume_fn = fn; server_resolve_all(frame, state); } glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/authenticate.c0000644000000000000000000000013014522202451024632 xustar000000000000000029 mtime=1699284265.77602776 29 atime=1699284265.77602776 30 ctime=1699284301.909136592 glusterfs-11.1/xlators/protocol/server/src/authenticate.c0000664000175100017510000001375514522202451025126 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2007-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include "authenticate.h" #include "server-messages.h" static int init(dict_t *this, char *key, data_t *value, void *data) { void *handle = NULL; char *auth_file = NULL; auth_handle_t *auth_handle = NULL; auth_fn_t authenticate = NULL; int *error = NULL; int ret = 0; /* It gets over written */ error = data; if (!strncasecmp(key, "ip", SLEN("ip"))) { gf_msg("authenticate", GF_LOG_ERROR, 0, PS_MSG_AUTHENTICATE_ERROR, "AUTHENTICATION MODULE " "\"IP\" HAS BEEN REPLACED BY \"ADDR\""); dict_set(this, key, data_from_dynptr(NULL, 0)); /* TODO: 1.3.x backward compatibility */ // *error = -1; // return; key = "addr"; } ret = gf_asprintf(&auth_file, "%s/%s.so", LIBDIR, key); if (-1 == ret) { dict_set(this, key, data_from_dynptr(NULL, 0)); *error = -1; return -1; } handle = dlopen(auth_file, RTLD_LAZY); if (!handle) { gf_msg("authenticate", GF_LOG_ERROR, 0, PS_MSG_AUTHENTICATE_ERROR, "dlopen(%s): %s\n", auth_file, dlerror()); dict_set(this, key, data_from_dynptr(NULL, 0)); GF_FREE(auth_file); *error = -1; return -1; } GF_FREE(auth_file); authenticate = dlsym(handle, "gf_auth"); if (!authenticate) { gf_msg("authenticate", GF_LOG_ERROR, 0, PS_MSG_AUTHENTICATE_ERROR, "dlsym(gf_auth) on %s\n", dlerror()); dict_set(this, key, data_from_dynptr(NULL, 0)); dlclose(handle); *error = -1; return -1; } auth_handle = GF_CALLOC(1, sizeof(*auth_handle), gf_common_mt_auth_handle_t); if (!auth_handle) { dict_set(this, key, data_from_dynptr(NULL, 0)); *error = -1; dlclose(handle); return -1; } auth_handle->vol_opt = GF_CALLOC(1, sizeof(volume_opt_list_t), gf_common_mt_volume_opt_list_t); if (!auth_handle->vol_opt) { dict_set(this, key, data_from_dynptr(NULL, 0)); *error = -1; GF_FREE(auth_handle); dlclose(handle); return -1; } auth_handle->vol_opt->given_opt = dlsym(handle, "options"); if (auth_handle->vol_opt->given_opt == NULL) { gf_msg_debug("authenticate", 0, "volume option validation " "not specified"); } auth_handle->authenticate = authenticate; auth_handle->handle = handle; dict_set(this, key, data_from_dynptr(auth_handle, sizeof(*auth_handle))); return 0; } static int fini(dict_t *this, char *key, data_t *value, void *data) { auth_handle_t *handle = data_to_ptr(value); if (handle) { dlclose(handle->handle); if (handle->vol_opt) { list_del_init(&handle->vol_opt->list); GF_FREE(handle->vol_opt); } } return 0; } static int _gf_auth_option_validate(dict_t *d, char *k, data_t *v, void *tmp) { auth_handle_t *handle = NULL; xlator_t *xl = NULL; int ret = 0; xl = tmp; handle = data_to_ptr(v); if (!handle) return 0; list_add_tail(&(handle->vol_opt->list), &(xl->volume_options)); ret = xlator_options_validate_list(xl, xl->options, handle->vol_opt, NULL); if (ret) { gf_msg("authenticate", GF_LOG_ERROR, 0, PS_MSG_VOL_VALIDATE_FAILED, "volume option validation " "failed"); return -1; } return 0; } int32_t gf_auth_init(xlator_t *xl, dict_t *auth_modules) { int ret = 0; dict_foreach(auth_modules, init, &ret); if (ret) goto out; ret = dict_foreach(auth_modules, _gf_auth_option_validate, xl); out: if (ret) { gf_msg(xl->name, GF_LOG_ERROR, 0, PS_MSG_AUTH_INIT_FAILED, "authentication init failed"); dict_foreach(auth_modules, fini, &ret); ret = -1; } return ret; } typedef struct { dict_t *iparams; dict_t *cparams; int64_t result; } gf_auth_args_t; static int gf_auth_one_method(dict_t *this, char *key, data_t *value, void *data) { gf_auth_args_t *args = data; auth_handle_t *handle = NULL; if (!value) { return 0; } handle = data_to_ptr(value); if (!handle || !handle->authenticate) { return 0; } switch (handle->authenticate(args->iparams, args->cparams)) { case AUTH_ACCEPT: if (args->result != AUTH_REJECT) { args->result = AUTH_ACCEPT; } /* FALLTHROUGH */ default: return 0; case AUTH_REJECT: args->result = AUTH_REJECT; return -1; } } auth_result_t gf_authenticate(dict_t *input_params, dict_t *config_params, dict_t *auth_modules) { char *name = NULL; data_t *peerinfo_data = NULL; gf_auth_args_t args; args.iparams = input_params; args.cparams = config_params; args.result = AUTH_DONT_CARE; dict_foreach(auth_modules, gf_auth_one_method, &args); if (AUTH_DONT_CARE == args.result) { peerinfo_data = dict_get(input_params, "peer-info-name"); if (peerinfo_data) { name = peerinfo_data->data; } gf_msg("auth", GF_LOG_ERROR, 0, PS_MSG_REMOTE_CLIENT_REFUSED, "no authentication module is interested in " "accepting remote-client %s", name); args.result = AUTH_REJECT; } return args.result; } void gf_auth_fini(dict_t *auth_modules) { int32_t dummy; dict_foreach(auth_modules, fini, &dummy); } glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server-rpc-fops_v2.c0000644000000000000000000000013214522202451025622 xustar000000000000000030 mtime=1699284265.779027769 30 atime=1699284265.779027769 30 ctime=1699284301.912136601 glusterfs-11.1/xlators/protocol/server/src/server-rpc-fops_v2.c0000664000175100017510000050235514522202451026113 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2017 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "server.h" #include "server-helpers.h" #include "rpc-common-xdr.h" #include "glusterfs3.h" #include #include "server-messages.h" #include #include "server-common.h" #ifdef BUILD_GNFS #include "xdr-nfs3.h" #endif #define SERVER_REQ_SET_ERROR(req, ret) \ do { \ rpcsvc_request_seterr(req, GARBAGE_ARGS); \ ret = RPCSVC_ACTOR_ERROR; \ } while (0) static int _gf_server_log_setxattr_failure(dict_t *d, char *k, data_t *v, void *tmp) { server_state_t *state = NULL; call_frame_t *frame = NULL; frame = tmp; state = CALL_STATE(frame); gf_msg(THIS->name, GF_LOG_INFO, 0, PS_MSG_SETXATTR_INFO, "%" PRId64 ": SETXATTR %s (%s) ==> %s, client: %s, " "error-xlator: %s", frame->root->unique, state->loc.path, uuid_utoa(state->resolve.gfid), k, STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root)); return 0; } void forget_inode_if_no_dentry(inode_t *inode) { if (!inode) { return; } if (!inode_has_dentry(inode)) inode_forget(inode, 0); return; } static void set_resolve_gfid(client_t *client, uuid_t resolve_gfid, char *on_wire_gfid) { if (client->subdir_mount && __is_root_gfid((unsigned char *)on_wire_gfid)) { /* set the subdir_mount's gfid for proper resolution */ gf_uuid_copy(resolve_gfid, client->subdir_gfid); } else { memcpy(resolve_gfid, on_wire_gfid, 16); } } static int rpc_receive_common(rpcsvc_request_t *req, call_frame_t **fr, server_state_t **st, ssize_t *xdrlen, void *args, void *xdrfn, glusterfs_fop_t fop) { int ret = -1; ssize_t len = 0; len = xdr_to_generic(req->msg[0], args, (xdrproc_t)xdrfn); if (len < 0) { /* failed to decode msg; */ SERVER_REQ_SET_ERROR(req, ret); goto out; } /* Few fops use the xdr size to get the vector sizes */ if (xdrlen) *xdrlen = len; *fr = get_frame_from_request(req); if (!(*fr)) { /* something wrong, mostly no memory */ SERVER_REQ_SET_ERROR(req, ret); goto out; } (*fr)->root->op = fop; *st = CALL_STATE((*fr)); if (!(*fr)->root->client->bound_xl) { /* auth failure, mostly setvolume is not successful */ SERVER_REQ_SET_ERROR(req, ret); goto out; } if (!(*fr)->root->client->bound_xl->itable) { /* inode_table is not allocated successful in server_setvolume */ SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; out: return ret; } /* Callback function section */ int server4_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata) { gfx_statfs_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, PS_MSG_STATFS, "frame=%" PRId64, frame->root->unique, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_statfs(&rsp, buf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_statfs_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xdata, struct iatt *postparent) { rpcsvc_request_t *req = NULL; server_state_t *state = NULL; loc_t fresh_loc = { 0, }; gfx_common_2iatt_rsp rsp = { 0, }; state = CALL_STATE(frame); if (state->is_revalidate == 1 && op_ret == -1) { state->is_revalidate = 2; loc_copy(&fresh_loc, &state->loc); inode_unref(fresh_loc.inode); fresh_loc.inode = server_inode_new(state->itable, fresh_loc.gfid); STACK_WIND(frame, server4_lookup_cbk, frame->root->client->bound_xl, frame->root->client->bound_xl->fops->lookup, &fresh_loc, state->xdata); loc_wipe(&fresh_loc); return 0; } gfx_stat_from_iattx(&rsp.poststat, postparent); dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { if (state->is_revalidate && op_errno == ENOENT) { if (!__is_root_gfid(state->resolve.gfid)) { inode_unlink(state->loc.inode, state->loc.parent, state->loc.name); /** * If the entry is not present, then just * unlinking the associated dentry is not * suffecient. This condition should be * treated as unlink of the entry. So along * with deleting the entry, its also important * to forget the inode for it (if the dentry * being considered was the last dentry). * Otherwise it might lead to inode leak. * It also might lead to wrong decisions being * taken if the future lookups on this inode are * successful since they are able to find the * inode in the inode table (at least gfid based * lookups will be successful, if the lookup * is a soft lookup) */ forget_inode_if_no_dentry(state->loc.inode); } } goto out; } server4_post_lookup(&rsp, frame, state, inode, stbuf, xdata); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); if (op_ret) { if (state->resolve.bname) { gf_smsg(this->name, fop_log_level(GF_FOP_LOOKUP, op_errno), op_errno, PS_MSG_LOOKUP_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s", state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); } else { gf_smsg(this->name, fop_log_level(GF_FOP_LOOKUP, op_errno), op_errno, PS_MSG_LOOKUP_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); } } req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_lease_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_lease *lease, dict_t *xdata) { gfx_lease_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; server_state_t *state = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_LEASE, op_errno), op_errno, PS_MSG_LK_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); } server4_post_lease(&rsp, lease); rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_lease_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { gfx_lk_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; server_state_t *state = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_LK, op_errno), op_errno, PS_MSG_LK_INFO, "frame=%" PRId64, frame->root->unique, "fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_lk(this, &rsp, lock); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_lk_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg(this->name, fop_log_level(GF_FOP_INODELK, op_errno), op_errno, PS_MSG_INODELK_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg(this->name, fop_log_level(GF_FOP_FINODELK, op_errno), op_errno, PS_MSG_INODELK_INFO, "frame=%" PRId64, frame->root->unique, "FINODELK_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg(this->name, fop_log_level(GF_FOP_ENTRYLK, op_errno), op_errno, PS_MSG_ENTRYLK_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_fentrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg(this->name, fop_log_level(GF_FOP_FENTRYLK, op_errno), op_errno, PS_MSG_ENTRYLK_INFO, "frame=%" PRId64, frame->root->unique, "FENTRYLK_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator: %s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; server_state_t *state = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { state = CALL_STATE(frame); gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_ACCESS_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret) { gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique, "RMDIR_pat=%s", (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s", state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_entry_remove(state, &rsp, preparent, postparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { gfx_common_3iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg(this->name, fop_log_level(GF_FOP_MKDIR, op_errno), op_errno, PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique, "MKDIR_path=%s", (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s", state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_3iatt(state, &rsp, inode, stbuf, preparent, postparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_3iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { gfx_common_3iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg(this->name, fop_log_level(GF_FOP_MKNOD, op_errno), op_errno, PS_MSG_MKNOD_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s", state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_3iatt(state, &rsp, inode, stbuf, preparent, postparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_3iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_FSYNCDIR, op_errno), op_errno, PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique, "FSYNCDIR_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { gfx_readdir_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; int ret = 0; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_READDIR, op_errno), op_errno, PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique, "READDIR_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } /* (op_ret == 0) is valid, and means EOF */ if (op_ret) { ret = server4_post_readdir(&rsp, entries); if (ret == -1) { op_ret = -1; op_errno = ENOMEM; goto out; } } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_readdir_rsp_custom); GF_FREE(rsp.xdata.pairs.pairs_val); readdir_rsp_cleanup_v2(&rsp); return 0; } int server4_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { server_state_t *state = NULL; rpcsvc_request_t *req = NULL; gfx_open_rsp rsp = { 0, }; uint64_t fd_no = 0; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_OPENDIR, op_errno), op_errno, PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique, "OPENDIR_path=%s", (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } op_ret = server4_post_open(frame, this, &rsp, fd); if (op_ret) goto out; out: if (op_ret) rsp.fd = fd_no; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_open_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; server_state_t *state = NULL; gf_loglevel_t loglevel = GF_LOG_NONE; dict_to_xdr(xdata, &rsp.xdata); if (op_ret == -1) { state = CALL_STATE(frame); if (ENODATA == op_errno || ENOATTR == op_errno) loglevel = GF_LOG_DEBUG; else loglevel = GF_LOG_INFO; gf_smsg(this->name, loglevel, op_errno, PS_MSG_REMOVEXATTR_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "name=%s", state->name, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; server_state_t *state = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret == -1) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_FREMOVEXATTR, op_errno), op_errno, PS_MSG_REMOVEXATTR_INFO, "frame=%" PRId64, frame->root->unique, "FREMOVEXATTR_fd_no%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "name=%s", state->name, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator: %s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { gfx_common_dict_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; server_state_t *state = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret == -1) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_GETXATTR, op_errno), op_errno, PS_MSG_GETXATTR_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "name=%s", state->name, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } dict_to_xdr(dict, &rsp.dict); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_dict_rsp); GF_FREE(rsp.dict.pairs.pairs_val); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { gfx_common_dict_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret == -1) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_FGETXATTR, op_errno), op_errno, PS_MSG_GETXATTR_INFO, "frame=%" PRId64, frame->root->unique, "FGETXATTR_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "name=%s", state->name, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } dict_to_xdr(dict, &rsp.dict); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_dict_rsp); GF_FREE(rsp.dict.pairs.pairs_val); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; server_state_t *state = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret == -1) { if (op_errno != ENOTSUP) dict_foreach(state->dict, _gf_server_log_setxattr_failure, frame); if (op_errno == ENOTSUP) { gf_msg_debug(THIS->name, op_errno, "Failed"); } else { gf_smsg(THIS->name, GF_LOG_INFO, op_errno, PS_MSG_SETXATTR_INFO, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); } goto out; } if (dict_get_sizen(state->dict, GF_NAMESPACE_KEY)) { /* This inode onwards we will set namespace */ gf_msg(THIS->name, GF_LOG_DEBUG, 0, PS_MSG_SETXATTR_INFO, "client=%s, path=%s", STACK_CLIENT_NAME(frame->root), state->loc.path); inode_set_namespace_inode(state->loc.inode, state->loc.inode); } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; server_state_t *state = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret == -1) { state = CALL_STATE(frame); if (op_errno != ENOTSUP) { dict_foreach(state->dict, _gf_server_log_setxattr_failure, frame); } if (op_errno == ENOTSUP) { gf_msg_debug(THIS->name, op_errno, "Failed"); } else { gf_smsg(THIS->name, GF_LOG_INFO, op_errno, PS_MSG_SETXATTR_INFO, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); } goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { gfx_rename_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; char oldpar_str[50] = { 0, }; char newpar_str[50] = { 0, }; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret == -1) { uuid_utoa_r(state->resolve.pargfid, oldpar_str); uuid_utoa_r(state->resolve2.pargfid, newpar_str); gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_RENAME_INFO, "frame=%" PRId64, frame->root->unique, "loc.path=%s", state->loc.path, "oldpar_str=%s", oldpar_str, "resolve-name=%s", state->resolve.bname, "loc2.path=%s", state->loc2.path, "newpar_str=%s", newpar_str, "resolve2=%s", state->resolve2.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_rename(frame, state, &rsp, stbuf, preoldparent, postoldparent, prenewparent, postnewparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_rename_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret) { gf_smsg(this->name, fop_log_level(GF_FOP_UNLINK, op_errno), op_errno, PS_MSG_LINK_INFO, "frame=%" PRId64, frame->root->unique, "UNLINK_path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s", state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator: %s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } /* TODO: log gfid of the inodes */ gf_msg_trace(frame->root->client->bound_xl->name, 0, "%" PRId64 ": " "UNLINK_CBK %s", frame->root->unique, state->loc.name); server4_post_entry_remove(state, &rsp, preparent, postparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { gfx_common_3iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_LINK_INFO, "frame=%" PRId64, frame->root->unique, "SYMLINK_path= %s", (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s", state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_3iatt(state, &rsp, inode, stbuf, preparent, postparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_3iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { gfx_common_3iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; char gfid_str[50] = { 0, }; char newpar_str[50] = { 0, }; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret) { uuid_utoa_r(state->resolve.gfid, gfid_str); uuid_utoa_r(state->resolve2.pargfid, newpar_str); gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_LINK_INFO, "frame=%" PRId64, frame->root->unique, "LINK_path=%s", state->loc.path, "gfid_str=%s", gfid_str, "newpar_str=%s", newpar_str, "resolve2.bname=%s", state->resolve2.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_link(state, &rsp, inode, stbuf, preparent, postparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_3iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { state = CALL_STATE(frame); gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_TRUNCATE_INFO, "frame=%" PRId64, frame->root->unique, "TRUNCATE_path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_2iatt(&rsp, prebuf, postbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, dict_t *xdata) { gfx_common_iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret) { gf_smsg(this->name, fop_log_level(GF_FOP_FSTAT, op_errno), op_errno, PS_MSG_STAT_INFO, "frame=%" PRId64, frame->root->unique, "FSTAT_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_iatt(state, &rsp, stbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { gfx_common_2iatt_rsp rsp = {0}; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_FTRUNCATE, op_errno), op_errno, PS_MSG_TRUNCATE_INFO, "frame=%" PRId64, frame->root->unique, "FTRUNCATE_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_2iatt(&rsp, prebuf, postbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_FLUSH, op_errno), op_errno, PS_MSG_FLUSH_INFO, "frame=%" PRId64, frame->root->unique, "FLUSH_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator: %s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_FSYNC, op_errno), op_errno, PS_MSG_SYNC_INFO, "frame=%" PRId64, frame->root->unique, "FSYNC_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator: %s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_2iatt(&rsp, prebuf, postbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_WRITE, op_errno), op_errno, PS_MSG_WRITE_INFO, "frame=%" PRId64, frame->root->unique, "WRITEV_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_2iatt(&rsp, prebuf, postbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { gfx_read_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; #ifdef GF_TESTING_IO_XDATA { int ret = 0; if (!xdata) xdata = dict_new(); ret = dict_set_str(xdata, "testing-the-xdata-key", "testing-xdata-value"); } #endif dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_READ, op_errno), op_errno, PS_MSG_READ_INFO, "frame=%" PRId64, frame->root->unique, "READV_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_readv(&rsp, stbuf, op_ret); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, vector, count, iobref, (xdrproc_t)xdr_gfx_read_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_rchecksum_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, uint32_t weak_checksum, uint8_t *strong_checksum, dict_t *xdata) { gfx_rchecksum_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; server_state_t *state = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_RCHECKSUM, op_errno), op_errno, PS_MSG_CHKSUM_INFO, "frame=%" PRId64, frame->root->unique, "RCHECKSUM_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_rchecksum(&rsp, weak_checksum, strong_checksum); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_rchecksum_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { server_state_t *state = NULL; rpcsvc_request_t *req = NULL; gfx_open_rsp rsp = { 0, }; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_OPEN, op_errno), op_errno, PS_MSG_OPEN_INFO, "frame=%" PRId64, frame->root->unique, "OPEN_path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } op_ret = server4_post_open(frame, this, &rsp, fd); if (op_ret) goto out; out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_open_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { server_state_t *state = NULL; rpcsvc_request_t *req = NULL; uint64_t fd_no = 0; gfx_create_rsp rsp = { 0, }; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg( this->name, GF_LOG_INFO, op_errno, PS_MSG_CREATE_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s", state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } /* TODO: log gfid too */ gf_msg_trace(frame->root->client->bound_xl->name, 0, "%" PRId64 ": " "CREATE %s (%s)", frame->root->unique, state->loc.name, uuid_utoa(stbuf->ia_gfid)); op_ret = server4_post_create(frame, &rsp, state, this, fd, inode, stbuf, preparent, postparent); if (op_ret) { op_errno = -op_ret; op_ret = -1; goto out; } out: if (op_ret) rsp.fd = fd_no; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_create_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, const char *buf, struct iatt *stbuf, dict_t *xdata) { gfx_readlink_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_LINK_INFO, "frame=%" PRId64, frame->root->unique, "READLINK_path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_readlink(&rsp, stbuf, buf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); if (!rsp.path) rsp.path = ""; req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_readlink_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, dict_t *xdata) { gfx_common_iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret) { gf_smsg(this->name, fop_log_level(GF_FOP_STAT, op_errno), op_errno, PS_MSG_STAT_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_iatt(state, &rsp, stbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { state = CALL_STATE(frame); gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SETATTR_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_2iatt(&rsp, statpre, statpost); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_FSETATTR, op_errno), op_errno, PS_MSG_SETATTR_INFO, "frame=%" PRId64, "FSETATTR_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_2iatt(&rsp, statpre, statpost); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { gfx_common_dict_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_XATTROP, op_errno), op_errno, PS_MSG_XATTROP_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } dict_to_xdr(dict, &rsp.dict); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_dict_rsp); GF_FREE(rsp.dict.pairs.pairs_val); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { gfx_common_dict_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_FXATTROP, op_errno), op_errno, PS_MSG_XATTROP_INFO, "frame=%" PRId64, frame->root->unique, "FXATTROP_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } dict_to_xdr(dict, &rsp.dict); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_dict_rsp); GF_FREE(rsp.dict.pairs.pairs_val); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { gfx_readdirp_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; int ret = 0; state = CALL_STATE(frame); dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_READDIRP, op_errno), op_errno, PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique, "READDIRP_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } /* (op_ret == 0) is valid, and means EOF */ if (op_ret) { ret = server4_post_readdirp(&rsp, entries); if (ret == -1) { op_ret = -1; op_errno = ENOMEM; goto out; } } gf_link_inodes_from_dirent(state->fd->inode, entries); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_readdirp_rsp_custom); GF_FREE(rsp.xdata.pairs.pairs_val); readdirp_rsp_cleanup_v2(&rsp); return 0; } int server4_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_FALLOCATE, op_errno), op_errno, PS_MSG_ALLOC_INFO, "frame=%" PRId64, frame->root->unique, "FALLOCATE_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_2iatt(&rsp, statpre, statpost); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { state = CALL_STATE(frame); gf_smsg(this->name, fop_log_level(GF_FOP_DISCARD, op_errno), op_errno, PS_MSG_DISCARD_INFO, "frame=%" PRId64, frame->root->unique, "fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator: %s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_2iatt(&rsp, statpre, statpost); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; req = frame->local; state = CALL_STATE(frame); dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { gf_smsg(this->name, fop_log_level(GF_FOP_ZEROFILL, op_errno), op_errno, PS_MSG_ZEROFILL_INFO, "frame=%" PRId64, frame->root->unique, "fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_common_2iatt(&rsp, statpre, statpost); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; req = frame->local; state = CALL_STATE(frame); dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SERVER_IPC_INFO, "frame=%" PRId64, frame->root->unique, "IPC=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata) { struct gfx_seek_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; req = frame->local; state = CALL_STATE(frame); dict_to_xdr(xdata, &rsp.xdata); if (op_ret) { gf_smsg(this->name, fop_log_level(GF_FOP_SEEK, op_errno), op_errno, PS_MSG_SEEK_INFO, "frame=%" PRId64, frame->root->unique, "fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } server4_post_seek(&rsp, offset); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_seek_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } static int server4_setactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { gfx_common_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; state = CALL_STATE(frame); dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SETACTIVELK_INFO, "frame=%" PRId64, frame->root->unique, "path==%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_namelink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { gfx_common_2iatt_rsp rsp = { 0, }; rpcsvc_request_t *req = NULL; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) goto out; gfx_stat_from_iattx(&rsp.prestat, prebuf); gfx_stat_from_iattx(&rsp.poststat, postbuf); /** * no point in linking inode here -- there's no stbuf anyway and a * lookup() for this name entry would be a negative lookup. */ out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_2iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_icreate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xdata) { server_state_t *state = NULL; inode_t *link_inode = NULL; rpcsvc_request_t *req = NULL; gfx_common_iatt_rsp rsp = { 0, }; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_CREATE_INFO, "frame=%" PRId64, frame->root->unique, "ICREATE_gfid=%s", uuid_utoa(state->resolve.gfid), NULL); goto out; } gf_msg_trace(frame->root->client->bound_xl->name, 0, "%" PRId64 ": " "ICREATE [%s]", frame->root->unique, uuid_utoa(stbuf->ia_gfid)); link_inode = inode_link(inode, state->loc.parent, state->loc.name, stbuf); if (!link_inode) { op_ret = -1; op_errno = ENOENT; goto out; } inode_lookup(link_inode); inode_unref(link_inode); gfx_stat_from_iattx(&rsp.stat, stbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_put_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { server_state_t *state = NULL; rpcsvc_request_t *req = NULL; gfx_common_3iatt_rsp rsp = { 0, }; dict_to_xdr(xdata, &rsp.xdata); state = CALL_STATE(frame); if (op_ret < 0) { gf_smsg( this->name, GF_LOG_INFO, op_errno, PS_MSG_PUT_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s", state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } gf_msg_trace(frame->root->client->bound_xl->name, 0, "%" PRId64 ": " "PUT %s (%s)", frame->root->unique, state->loc.name, uuid_utoa(stbuf->ia_gfid)); server4_post_common_3iatt(state, &rsp, inode, stbuf, preparent, postparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_3iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } int server4_copy_file_range_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, struct iatt *prebuf_dst, struct iatt *postbuf_dst, dict_t *xdata) { gfx_common_3iatt_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; char in_gfid[GF_UUID_BUF_SIZE] = {0}; char out_gfid[GF_UUID_BUF_SIZE] = {0}; dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); uuid_utoa_r(state->resolve.gfid, in_gfid); uuid_utoa_r(state->resolve2.gfid, out_gfid); gf_smsg(this->name, fop_log_level(GF_FOP_COPY_FILE_RANGE, op_errno), op_errno, PS_MSG_WRITE_INFO, "frame=%" PRId64, frame->root->unique, "COPY_FILE_RANGE_fd_no=%" PRId64, state->resolve.fd_no, "in_gfid=%s", in_gfid, "resolve2_fd_no=%" PRId64, state->resolve2.fd_no, "out_gfid=%s", out_gfid, "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } /* * server4_post_common_3iatt (ex: used by server4_put_cbk and some * other cbks) also performs inode linking along with copying of 3 * iatt structures to the response. But, for copy_file_range, linking * of inode is not needed. Therefore a new function is used to * construct the response using 3 iatt structures. * @stbuf: iatt or stat of the source file (or fd) * @prebuf_dst: iatt or stat of destination file (or fd) before the fop * @postbuf_dst: iatt or stat of destination file (or fd) after the fop */ server4_post_common_3iatt_noinode(&rsp, stbuf, prebuf_dst, postbuf_dst); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_3iatt_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); return 0; } /* Resume function section */ int server4_rchecksum_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; int op_ret = 0; int op_errno = EINVAL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) { op_ret = state->resolve.op_ret; op_errno = state->resolve.op_errno; goto err; } STACK_WIND(frame, server4_rchecksum_cbk, bound_xl, bound_xl->fops->rchecksum, state->fd, state->offset, state->size, state->xdata); return 0; err: server4_rchecksum_cbk(frame, NULL, frame->this, op_ret, op_errno, 0, NULL, NULL); return 0; } int server4_lease_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_lease_cbk, bound_xl, bound_xl->fops->lease, &state->loc, &state->lease, state->xdata); return 0; err: server4_lease_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_put_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; state->loc.inode = inode_new(state->itable); STACK_WIND(frame, server4_put_cbk, bound_xl, bound_xl->fops->put, &(state->loc), state->mode, state->umask, state->flags, state->payload_vector, state->payload_count, state->offset, state->iobref, state->dict, state->xdata); return 0; err: server4_put_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int server4_lk_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_lk_cbk, bound_xl, bound_xl->fops->lk, state->fd, state->cmd, &state->flock, state->xdata); return 0; err: server4_lk_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_rename_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; int op_ret = 0; int op_errno = 0; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) { op_ret = state->resolve.op_ret; op_errno = state->resolve.op_errno; goto err; } if (state->resolve2.op_ret != 0) { op_ret = state->resolve2.op_ret; op_errno = state->resolve2.op_errno; goto err; } if (state->loc.parent->ns_inode != state->loc2.parent->ns_inode) { /* lets not allow rename across namespaces */ op_ret = -1; op_errno = EXDEV; gf_msg(THIS->name, GF_LOG_ERROR, EXDEV, 0, "%s: rename across different namespaces not supported", state->loc.path); goto err; } STACK_WIND(frame, server4_rename_cbk, bound_xl, bound_xl->fops->rename, &state->loc, &state->loc2, state->xdata); return 0; err: server4_rename_cbk(frame, NULL, frame->this, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int server4_link_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; int op_ret = 0; int op_errno = 0; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) { op_ret = state->resolve.op_ret; op_errno = state->resolve.op_errno; goto err; } if (state->resolve2.op_ret != 0) { op_ret = state->resolve2.op_ret; op_errno = state->resolve2.op_errno; goto err; } if (state->loc.inode->ns_inode != state->loc2.parent->ns_inode) { /* lets not allow linking across namespaces */ op_ret = -1; op_errno = EXDEV; gf_msg(THIS->name, GF_LOG_ERROR, EXDEV, 0, "%s: linking across different namespaces not supported", state->loc.path); goto err; } state->loc2.inode = inode_ref(state->loc.inode); STACK_WIND(frame, server4_link_cbk, bound_xl, bound_xl->fops->link, &state->loc, &state->loc2, state->xdata); return 0; err: server4_link_cbk(frame, NULL, frame->this, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int server4_symlink_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; state->loc.inode = inode_new(state->itable); STACK_WIND(frame, server4_symlink_cbk, bound_xl, bound_xl->fops->symlink, state->name, &state->loc, state->umask, state->xdata); return 0; err: server4_symlink_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int server4_access_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_access_cbk, bound_xl, bound_xl->fops->access, &state->loc, state->mask, state->xdata); return 0; err: server4_access_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_fentrylk_resume(call_frame_t *frame, xlator_t *bound_xl) { GF_UNUSED int ret = -1; server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; if (!state->xdata) state->xdata = dict_new(); if (state->xdata) ret = dict_set_str(state->xdata, "connection-id", frame->root->client->client_uid); STACK_WIND(frame, server4_fentrylk_cbk, bound_xl, bound_xl->fops->fentrylk, state->volume, state->fd, state->name, state->cmd, state->type, state->xdata); return 0; err: server4_fentrylk_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_entrylk_resume(call_frame_t *frame, xlator_t *bound_xl) { GF_UNUSED int ret = -1; server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; if (!state->xdata) state->xdata = dict_new(); if (state->xdata) ret = dict_set_str(state->xdata, "connection-id", frame->root->client->client_uid); STACK_WIND(frame, server4_entrylk_cbk, bound_xl, bound_xl->fops->entrylk, state->volume, &state->loc, state->name, state->cmd, state->type, state->xdata); return 0; err: server4_entrylk_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_finodelk_resume(call_frame_t *frame, xlator_t *bound_xl) { GF_UNUSED int ret = -1; server_state_t *state = NULL; gf_msg_debug(bound_xl->name, 0, "frame %p, xlator %p", frame, bound_xl); state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; if (!state->xdata) state->xdata = dict_new(); if (state->xdata) ret = dict_set_str(state->xdata, "connection-id", frame->root->client->client_uid); STACK_WIND(frame, server4_finodelk_cbk, bound_xl, bound_xl->fops->finodelk, state->volume, state->fd, state->cmd, &state->flock, state->xdata); return 0; err: server4_finodelk_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_inodelk_resume(call_frame_t *frame, xlator_t *bound_xl) { GF_UNUSED int ret = -1; server_state_t *state = NULL; gf_msg_debug(bound_xl->name, 0, "frame %p, xlator %p", frame, bound_xl); state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; if (!state->xdata) state->xdata = dict_new(); if (state->xdata) ret = dict_set_str(state->xdata, "connection-id", frame->root->client->client_uid); STACK_WIND(frame, server4_inodelk_cbk, bound_xl, bound_xl->fops->inodelk, state->volume, &state->loc, state->cmd, &state->flock, state->xdata); return 0; err: server4_inodelk_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_rmdir_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_rmdir_cbk, bound_xl, bound_xl->fops->rmdir, &state->loc, state->flags, state->xdata); return 0; err: server4_rmdir_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_mkdir_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; state->loc.inode = inode_new(state->itable); STACK_WIND(frame, server4_mkdir_cbk, bound_xl, bound_xl->fops->mkdir, &(state->loc), state->mode, state->umask, state->xdata); return 0; err: server4_mkdir_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int server4_mknod_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; state->loc.inode = inode_new(state->itable); STACK_WIND(frame, server4_mknod_cbk, bound_xl, bound_xl->fops->mknod, &(state->loc), state->mode, state->dev, state->umask, state->xdata); return 0; err: server4_mknod_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int server4_fsyncdir_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_fsyncdir_cbk, bound_xl, bound_xl->fops->fsyncdir, state->fd, state->flags, state->xdata); return 0; err: server4_fsyncdir_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_readdir_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; GF_ASSERT(state->fd); STACK_WIND(frame, server4_readdir_cbk, bound_xl, bound_xl->fops->readdir, state->fd, state->size, state->offset, state->xdata); return 0; err: server4_readdir_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_readdirp_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_readdirp_cbk, bound_xl, bound_xl->fops->readdirp, state->fd, state->size, state->offset, state->xdata); return 0; err: server4_readdirp_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_opendir_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; state->fd = fd_create(state->loc.inode, frame->root->pid); if (!state->fd) { gf_smsg("server", GF_LOG_ERROR, 0, PS_MSG_FD_CREATE_FAILED, NULL); goto err; } STACK_WIND(frame, server4_opendir_cbk, bound_xl, bound_xl->fops->opendir, &state->loc, state->fd, state->xdata); return 0; err: server4_opendir_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_statfs_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_statfs_cbk, bound_xl, bound_xl->fops->statfs, &state->loc, state->xdata); return 0; err: server4_statfs_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_removexattr_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; if (dict_get_sizen(state->xdata, GF_NAMESPACE_KEY) || !strncmp(GF_NAMESPACE_KEY, state->name, sizeof(GF_NAMESPACE_KEY))) { gf_msg(bound_xl->name, GF_LOG_ERROR, ENOTSUP, 0, "%s: removal of namespace is not allowed", state->loc.path); state->resolve.op_errno = ENOTSUP; state->resolve.op_ret = -1; goto err; } STACK_WIND(frame, server4_removexattr_cbk, bound_xl, bound_xl->fops->removexattr, &state->loc, state->name, state->xdata); return 0; err: server4_removexattr_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_fremovexattr_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; if (dict_get_sizen(state->xdata, GF_NAMESPACE_KEY) || !strncmp(GF_NAMESPACE_KEY, state->name, sizeof(GF_NAMESPACE_KEY))) { gf_msg(bound_xl->name, GF_LOG_ERROR, ENOTSUP, 0, "%s: removal of namespace is not allowed", uuid_utoa(state->fd->inode->gfid)); state->resolve.op_errno = ENOTSUP; state->resolve.op_ret = -1; goto err; } STACK_WIND(frame, server4_fremovexattr_cbk, bound_xl, bound_xl->fops->fremovexattr, state->fd, state->name, state->xdata); return 0; err: server4_fremovexattr_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_fgetxattr_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_fgetxattr_cbk, bound_xl, bound_xl->fops->fgetxattr, state->fd, state->name, state->xdata); return 0; err: server4_fgetxattr_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_xattrop_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_xattrop_cbk, bound_xl, bound_xl->fops->xattrop, &state->loc, state->flags, state->dict, state->xdata); return 0; err: server4_xattrop_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_fxattrop_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_fxattrop_cbk, bound_xl, bound_xl->fops->fxattrop, state->fd, state->flags, state->dict, state->xdata); return 0; err: server4_fxattrop_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_fsetxattr_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_setxattr_cbk, bound_xl, bound_xl->fops->fsetxattr, state->fd, state->dict, state->flags, state->xdata); return 0; err: server4_fsetxattr_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_unlink_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_unlink_cbk, bound_xl, bound_xl->fops->unlink, &state->loc, state->flags, state->xdata); return 0; err: server4_unlink_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_truncate_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_truncate_cbk, bound_xl, bound_xl->fops->truncate, &state->loc, state->offset, state->xdata); return 0; err: server4_truncate_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_fstat_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_fstat_cbk, bound_xl, bound_xl->fops->fstat, state->fd, state->xdata); return 0; err: server4_fstat_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_setxattr_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_setxattr_cbk, bound_xl, bound_xl->fops->setxattr, &state->loc, state->dict, state->flags, state->xdata); return 0; err: server4_setxattr_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_getxattr_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_getxattr_cbk, bound_xl, bound_xl->fops->getxattr, &state->loc, state->name, state->xdata); return 0; err: server4_getxattr_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_ftruncate_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_ftruncate_cbk, bound_xl, bound_xl->fops->ftruncate, state->fd, state->offset, state->xdata); return 0; err: server4_ftruncate_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_flush_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_flush_cbk, bound_xl, bound_xl->fops->flush, state->fd, state->xdata); return 0; err: server4_flush_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_fsync_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_fsync_cbk, bound_xl, bound_xl->fops->fsync, state->fd, state->flags, state->xdata); return 0; err: server4_fsync_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_writev_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_writev_cbk, bound_xl, bound_xl->fops->writev, state->fd, state->payload_vector, state->payload_count, state->offset, state->flags, state->iobref, state->xdata); return 0; err: server4_writev_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_readv_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_readv_cbk, bound_xl, bound_xl->fops->readv, state->fd, state->size, state->offset, state->flags, state->xdata); return 0; err: server4_readv_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, 0, NULL, NULL, NULL); return 0; } int server4_create_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; state->loc.inode = inode_new(state->itable); state->fd = fd_create(state->loc.inode, frame->root->pid); if (!state->fd) { gf_smsg("server", GF_LOG_ERROR, 0, PS_MSG_FD_CREATE_FAILED, "inode=%s", state->loc.inode ? uuid_utoa(state->loc.inode->gfid) : NULL, NULL); state->resolve.op_ret = -1; state->resolve.op_errno = ENOMEM; goto err; } state->fd->flags = state->flags; STACK_WIND(frame, server4_create_cbk, bound_xl, bound_xl->fops->create, &(state->loc), state->flags, state->mode, state->umask, state->fd, state->xdata); return 0; err: server4_create_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int server4_open_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; state->fd = fd_create(state->loc.inode, frame->root->pid); state->fd->flags = state->flags; STACK_WIND(frame, server4_open_cbk, bound_xl, bound_xl->fops->open, &state->loc, state->flags, state->fd, state->xdata); return 0; err: server4_open_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_readlink_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_readlink_cbk, bound_xl, bound_xl->fops->readlink, &state->loc, state->size, state->xdata); return 0; err: server4_readlink_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_fsetattr_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_fsetattr_cbk, bound_xl, bound_xl->fops->fsetattr, state->fd, &state->stbuf, state->valid, state->xdata); return 0; err: server4_fsetattr_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_setattr_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_setattr_cbk, bound_xl, bound_xl->fops->setattr, &state->loc, &state->stbuf, state->valid, state->xdata); return 0; err: server4_setattr_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_stat_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_stat_cbk, bound_xl, bound_xl->fops->stat, &state->loc, state->xdata); return 0; err: server4_stat_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_lookup_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; dict_t *xdata = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; xdata = state->xdata ? dict_ref(state->xdata) : dict_new(); if (!xdata) { state->resolve.op_ret = -1; state->resolve.op_errno = ENOMEM; goto err; } if (!state->loc.inode) { state->loc.inode = server_inode_new(state->itable, state->loc.gfid); int ret = dict_set_int32(xdata, GF_NAMESPACE_KEY, 1); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, 0, "dict set (namespace) failed (path: %s), continuing", state->loc.path); state->resolve.op_ret = -1; state->resolve.op_errno = ENOMEM; goto err; } if (state->loc.path && (state->loc.path[0] == '<')) { /* This is a lookup on gfid : get full-path */ /* TODO: handle gfid based lookup in a better way. Ref GH PR #1763 */ ret = dict_set_int32(xdata, "get-full-path", 1); if (ret) { gf_msg(THIS->name, GF_LOG_INFO, ENOMEM, 0, "%s: dict set (full-path) failed, continuing", state->loc.path); } } } else { state->is_revalidate = 1; } STACK_WIND(frame, server4_lookup_cbk, bound_xl, bound_xl->fops->lookup, &state->loc, xdata); dict_unref(xdata); return 0; err: server4_lookup_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL, NULL); if (xdata) dict_unref(xdata); return 0; } int server4_fallocate_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_fallocate_cbk, bound_xl, bound_xl->fops->fallocate, state->fd, state->flags, state->offset, state->size, state->xdata); return 0; err: server4_fallocate_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_discard_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_discard_cbk, bound_xl, bound_xl->fops->discard, state->fd, state->offset, state->size, state->xdata); return 0; err: server4_discard_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_zerofill_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_zerofill_cbk, bound_xl, bound_xl->fops->zerofill, state->fd, state->offset, state->size, state->xdata); return 0; err: server4_zerofill_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_seek_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_seek_cbk, bound_xl, bound_xl->fops->seek, state->fd, state->offset, state->what, state->xdata); return 0; err: server4_seek_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, 0, NULL); return 0; } static int server4_getactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, lock_migration_info_t *locklist, dict_t *xdata) { gfx_getactivelk_rsp rsp = { 0, }; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; int ret = 0; state = CALL_STATE(frame); dict_to_xdr(xdata, &rsp.xdata); if (op_ret < 0) { state = CALL_STATE(frame); gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_GETACTIVELK_INFO, "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path, "gfid=%s", uuid_utoa(state->resolve.gfid), "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL); goto out; } /* (op_ret == 0) means there are no locks on the file*/ if (op_ret > 0) { ret = serialize_rsp_locklist_v2(locklist, &rsp); if (ret == -1) { op_ret = -1; op_errno = ENOMEM; goto out; } } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error(op_errno); req = frame->local; server_submit_reply(frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_getactivelk_rsp); GF_FREE(rsp.xdata.pairs.pairs_val); getactivelkinfo_rsp_cleanup_v2(&rsp); return 0; } int server4_getactivelk_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_getactivelk_cbk, bound_xl, bound_xl->fops->getactivelk, &state->loc, state->xdata); return 0; err: server4_getactivelk_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL); return 0; } int server4_setactivelk_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_setactivelk_cbk, bound_xl, bound_xl->fops->setactivelk, &state->loc, &state->locklist, state->xdata); return 0; err: server4_setactivelk_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL); return 0; } int server4_namelink_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; state->loc.inode = inode_new(state->itable); STACK_WIND(frame, server4_namelink_cbk, bound_xl, bound_xl->fops->namelink, &(state->loc), state->xdata); return 0; err: server4_namelink_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_icreate_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; state->loc.inode = inode_new(state->itable); STACK_WIND(frame, server4_icreate_cbk, bound_xl, bound_xl->fops->icreate, &(state->loc), state->mode, state->xdata); return 0; err: server4_icreate_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL); return 0; } int server4_copy_file_range_resume(call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; state = CALL_STATE(frame); if (state->resolve.op_ret != 0) goto err; STACK_WIND(frame, server4_copy_file_range_cbk, bound_xl, bound_xl->fops->copy_file_range, state->fd, state->off_in, state->fd_out, state->off_out, state->size, state->flags, state->xdata); return 0; err: server4_copy_file_range_cbk(frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno, NULL, NULL, NULL, NULL); return 0; } int server4_0_stat(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_stat_req args = { { 0, }, }; int ret = -1; if (!req) return 0; /* Initialize args first, then decode */ ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_stat_req, GF_FOP_STAT); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_stat_resume); out: return ret; } int server4_0_setattr(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_setattr_req args = { { 0, }, }; int ret = -1; if (!req) return 0; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_setattr_req, GF_FOP_SETATTR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); gfx_stat_to_iattx(&args.stbuf, &state->stbuf); state->valid = args.valid; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_setattr_resume); out: return ret; } int server4_0_fallocate(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fallocate_req args = { {0}, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fallocate_req, GF_FOP_FALLOCATE); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->flags = args.flags; state->offset = args.offset; state->size = args.size; memcpy(state->resolve.gfid, args.gfid, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fallocate_resume); out: return ret; } int server4_0_discard(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_discard_req args = { {0}, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_discard_req, GF_FOP_DISCARD); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->offset = args.offset; state->size = args.size; memcpy(state->resolve.gfid, args.gfid, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_discard_resume); out: return ret; } int server4_0_zerofill(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_zerofill_req args = { {0}, }; int ret = -1; int op_errno = 0; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_zerofill_req, GF_FOP_ZEROFILL); if (ret != 0) { op_errno = -1; goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->offset = args.offset; state->size = args.size; memcpy(state->resolve.gfid, args.gfid, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_zerofill_resume); out: if (op_errno) req->rpc_err = GARBAGE_ARGS; return ret; } int server4_0_ipc(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_ipc_req args = { 0, }; int ret = -1; xlator_t *bound_xl = NULL; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_ipc_req, GF_FOP_IPC); if (ret != 0) { goto out; } bound_xl = frame->root->client->bound_xl; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; STACK_WIND(frame, server4_ipc_cbk, bound_xl, bound_xl->fops->ipc, args.op, state->xdata); out: return ret; } int server4_0_seek(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_seek_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_seek_req, GF_FOP_SEEK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->offset = args.offset; state->what = args.what; memcpy(state->resolve.gfid, args.gfid, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_seek_resume); out: return ret; } int server4_0_readlink(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_readlink_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_readlink_req, GF_FOP_READLINK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; memcpy(state->resolve.gfid, args.gfid, 16); state->size = args.size; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_readlink_resume); out: return ret; } int server4_0_create(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_create_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_create_req, GF_FOP_CREATE); if (ret != 0) { goto out; } state->resolve.bname = gf_strdup(args.bname); state->mode = args.mode; state->umask = args.umask; state->flags = gf_flags_to_flags(args.flags); set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid); if (state->flags & O_EXCL) { state->resolve.type = RESOLVE_NOT; } else { state->resolve.type = RESOLVE_DONTCARE; } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_create_resume); out: free(args.bname); return ret; } int server4_0_open(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_open_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_open_req, GF_FOP_OPEN); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; memcpy(state->resolve.gfid, args.gfid, 16); state->flags = gf_flags_to_flags(args.flags); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_open_resume); out: return ret; } int server4_0_readv(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_read_req args = { { 0, }, }; int ret = -1; if (!req) goto out; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_read_req, GF_FOP_READ); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->size = args.size; state->offset = args.offset; state->flags = args.flag; memcpy(state->resolve.gfid, args.gfid, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_readv_resume); out: return ret; } int server4_0_writev(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_write_req args = { { 0, }, }; ssize_t len = 0; int i = 0; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, &len, &args, xdr_gfx_write_req, GF_FOP_WRITE); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->offset = args.offset; state->size = args.size; state->flags = args.flag; state->iobref = iobref_ref(req->iobref); memcpy(state->resolve.gfid, args.gfid, 16); if (len < req->msg[0].iov_len) { state->payload_vector[0].iov_base = (req->msg[0].iov_base + len); state->payload_vector[0].iov_len = req->msg[0].iov_len - len; state->payload_count = 1; } for (i = 1; i < req->count; i++) { state->payload_vector[state->payload_count++] = req->msg[i]; } len = iov_length(state->payload_vector, state->payload_count); GF_ASSERT(state->size == len); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } #ifdef GF_TESTING_IO_XDATA dict_dump_to_log(state->xdata); #endif ret = 0; resolve_and_resume(frame, server4_writev_resume); out: return ret; } #define SERVER4_0_VECWRITE_START 0 #define SERVER4_0_VECWRITE_READING_HDR 1 #define SERVER4_0_VECWRITE_READING_OPAQUE 2 int server4_0_writev_vecsizer(int state, ssize_t *readsize, char *base_addr, char *curr_addr) { ssize_t size = 0; int nextstate = 0; gfx_write_req write_req = { { 0, }, }; XDR xdr; switch (state) { case SERVER4_0_VECWRITE_START: size = xdr_sizeof((xdrproc_t)xdr_gfx_write_req, &write_req); *readsize = size; nextstate = SERVER4_0_VECWRITE_READING_HDR; break; case SERVER4_0_VECWRITE_READING_HDR: size = xdr_sizeof((xdrproc_t)xdr_gfx_write_req, &write_req); xdrmem_create(&xdr, base_addr, size, XDR_DECODE); /* This will fail if there is xdata sent from client, if not, well and good */ xdr_gfx_write_req(&xdr, &write_req); /* need to round off to proper roof (%4), as XDR packing pads the end of opaque object with '0' */ size = gf_roof(write_req.xdata.xdr_size, 4); *readsize = size; if (!size) nextstate = SERVER4_0_VECWRITE_START; else nextstate = SERVER4_0_VECWRITE_READING_OPAQUE; free(write_req.xdata.pairs.pairs_val); break; case SERVER4_0_VECWRITE_READING_OPAQUE: *readsize = 0; nextstate = SERVER4_0_VECWRITE_START; break; } return nextstate; } int server4_0_release(rpcsvc_request_t *req) { client_t *client = NULL; server_ctx_t *serv_ctx = NULL; gfx_release_req args = { { 0, }, }; gfx_common_rsp rsp = { 0, }; int ret = -1; ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gfx_release_req); if (ret < 0) { SERVER_REQ_SET_ERROR(req, ret); goto out; } client = req->trans->xl_private; if (!client) { /* Handshake is not complete yet. */ req->rpc_err = SYSTEM_ERR; goto out; } serv_ctx = server_ctx_get(client, client->this); if (serv_ctx == NULL) { gf_smsg(req->trans->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED, NULL); req->rpc_err = SYSTEM_ERR; goto out; } gf_fd_put(serv_ctx->fdtable, args.fd); server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); ret = 0; out: return ret; } int server4_0_releasedir(rpcsvc_request_t *req) { client_t *client = NULL; server_ctx_t *serv_ctx = NULL; gfx_releasedir_req args = { { 0, }, }; gfx_common_rsp rsp = { 0, }; int ret = -1; ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gfx_release_req); if (ret < 0) { SERVER_REQ_SET_ERROR(req, ret); goto out; } client = req->trans->xl_private; if (!client) { SERVER_REQ_SET_ERROR(req, ret); goto out; } serv_ctx = server_ctx_get(client, client->this); if (serv_ctx == NULL) { gf_smsg(req->trans->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED, NULL); req->rpc_err = SYSTEM_ERR; goto out; } gf_fd_put(serv_ctx->fdtable, args.fd); server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); ret = 0; out: return ret; } int server4_0_fsync(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fsync_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fsync_req, GF_FOP_FSYNC); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->flags = args.data; memcpy(state->resolve.gfid, args.gfid, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fsync_resume); out: return ret; } int server4_0_flush(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_flush_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_flush_req, GF_FOP_FLUSH); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; memcpy(state->resolve.gfid, args.gfid, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_flush_resume); out: return ret; } int server4_0_ftruncate(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_ftruncate_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_ftruncate_req, GF_FOP_FTRUNCATE); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->offset = args.offset; memcpy(state->resolve.gfid, args.gfid, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_ftruncate_resume); out: return ret; } int server4_0_fstat(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fstat_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fstat_req, GF_FOP_FSTAT); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fstat_resume); out: return ret; } int server4_0_truncate(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_truncate_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_truncate_req, GF_FOP_TRUNCATE); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; memcpy(state->resolve.gfid, args.gfid, 16); state->offset = args.offset; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_truncate_resume); out: return ret; } int server4_0_unlink(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_unlink_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_unlink_req, GF_FOP_UNLINK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.bname = gf_strdup(args.bname); set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid); state->flags = args.xflags; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_unlink_resume); out: free(args.bname); return ret; } int server4_0_setxattr(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_setxattr_req args = { { 0, }, }; int32_t ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_setxattr_req, GF_FOP_SETXATTR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->flags = args.flags; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.dict, &state->dict)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } /* There can be some commands hidden in key, check and proceed */ gf_server_check_setxattr_cmd(frame, state->dict); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } /* Let the namespace setting can happen only from special mounts, this should prevent all mounts creating fake namespace. */ if ((frame->root->pid >= 0) && dict_get_sizen(state->dict, GF_NAMESPACE_KEY)) { gf_smsg("server", GF_LOG_ERROR, 0, PS_MSG_SETXATTR_INFO, "path=%s", state->loc.path, "key=%s", GF_NAMESPACE_KEY, NULL); SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_setxattr_resume); out: return ret; } int server4_0_fsetxattr(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fsetxattr_req args = { { 0, }, }; int32_t ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fsetxattr_req, GF_FOP_FSETXATTR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->flags = args.flags; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.dict, &state->dict)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fsetxattr_resume); out: return ret; } int server4_0_fxattrop(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fxattrop_req args = { { 0, }, }; int32_t ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fxattrop_req, GF_FOP_FXATTROP); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->flags = args.flags; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.dict, &state->dict)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fxattrop_resume); out: return ret; } int server4_0_xattrop(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_xattrop_req args = { { 0, }, }; int32_t ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_xattrop_req, GF_FOP_XATTROP); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->flags = args.flags; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.dict, &state->dict)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_xattrop_resume); out: return ret; } int server4_0_getxattr(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_getxattr_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_getxattr_req, GF_FOP_GETXATTR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (args.namelen) { state->name = gf_strdup(args.name); /* There can be some commands hidden in key, check and proceed */ gf_server_check_getxattr_cmd(frame, state->name); } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_getxattr_resume); out: free(args.name); return ret; } int server4_0_fgetxattr(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fgetxattr_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fgetxattr_req, GF_FOP_FGETXATTR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (args.namelen) state->name = gf_strdup(args.name); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fgetxattr_resume); out: free(args.name); return ret; } int server4_0_removexattr(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_removexattr_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_removexattr_req, GF_FOP_REMOVEXATTR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); state->name = gf_strdup(args.name); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_removexattr_resume); out: free(args.name); return ret; } int server4_0_fremovexattr(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fremovexattr_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fremovexattr_req, GF_FOP_FREMOVEXATTR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); state->name = gf_strdup(args.name); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fremovexattr_resume); out: free(args.name); return ret; } int server4_0_opendir(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_opendir_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_opendir_req, GF_FOP_OPENDIR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_opendir_resume); out: return ret; } int server4_0_readdirp(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_readdirp_req args = { { 0, }, }; size_t headers_size = 0; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_readdirp_req, GF_FOP_READDIRP); if (ret != 0) { goto out; } /* FIXME: this should go away when variable sized iobufs are introduced * and transport layer can send msgs bigger than current page-size. */ headers_size = sizeof(struct rpc_msg) + sizeof(gfx_readdir_rsp); if ((frame->this->ctx->page_size < args.size) || ((frame->this->ctx->page_size - args.size) < headers_size)) { state->size = frame->this->ctx->page_size - headers_size; } else { state->size = args.size; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->offset = args.offset; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); /* here, dict itself works as xdata */ if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_readdirp_resume); out: return ret; } int server4_0_readdir(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_readdir_req args = { { 0, }, }; size_t headers_size = 0; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_readdir_req, GF_FOP_READDIR); if (ret != 0) { goto out; } /* FIXME: this should go away when variable sized iobufs are introduced * and transport layer can send msgs bigger than current page-size. */ headers_size = sizeof(struct rpc_msg) + sizeof(gfx_readdir_rsp); if ((frame->this->ctx->page_size < args.size) || ((frame->this->ctx->page_size - args.size) < headers_size)) { state->size = frame->this->ctx->page_size - headers_size; } else { state->size = args.size; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->offset = args.offset; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_readdir_resume); out: return ret; } int server4_0_fsyncdir(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fsyncdir_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fsyncdir_req, GF_FOP_FSYNCDIR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->flags = args.data; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fsyncdir_resume); out: return ret; } int server4_0_mknod(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_mknod_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_mknod_req, GF_FOP_MKNOD); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_NOT; set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid); state->resolve.bname = gf_strdup(args.bname); state->mode = args.mode; state->dev = args.dev; state->umask = args.umask; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_mknod_resume); out: free(args.bname); return ret; } int server4_0_mkdir(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_mkdir_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_mkdir_req, GF_FOP_MKDIR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_NOT; set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid); state->resolve.bname = gf_strdup(args.bname); state->mode = args.mode; state->umask = args.umask; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_mkdir_resume); out: free(args.bname); return ret; } int server4_0_rmdir(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_rmdir_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_rmdir_req, GF_FOP_RMDIR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid); state->resolve.bname = gf_strdup(args.bname); state->flags = args.xflags; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_rmdir_resume); out: free(args.bname); return ret; } int server4_0_inodelk(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_inodelk_req args = { { 0, }, }; int cmd = 0; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_inodelk_req, GF_FOP_INODELK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_EXACT; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); cmd = args.cmd; switch (cmd) { case GF_LK_GETLK: state->cmd = F_GETLK; break; case GF_LK_SETLK: state->cmd = F_SETLK; break; case GF_LK_SETLKW: state->cmd = F_SETLKW; break; } state->type = args.type; state->volume = gf_strdup(args.volume); gf_proto_flock_to_flock(&args.flock, &state->flock); switch (state->type) { case GF_LK_F_RDLCK: state->flock.l_type = F_RDLCK; break; case GF_LK_F_WRLCK: state->flock.l_type = F_WRLCK; break; case GF_LK_F_UNLCK: state->flock.l_type = F_UNLCK; break; } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_inodelk_resume); out: free(args.volume); free(args.flock.lk_owner.lk_owner_val); return ret; } int server4_0_finodelk(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_finodelk_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_finodelk_req, GF_FOP_FINODELK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_EXACT; state->volume = gf_strdup(args.volume); state->resolve.fd_no = args.fd; state->cmd = args.cmd; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); switch (state->cmd) { case GF_LK_GETLK: state->cmd = F_GETLK; break; case GF_LK_SETLK: state->cmd = F_SETLK; break; case GF_LK_SETLKW: state->cmd = F_SETLKW; break; } state->type = args.type; gf_proto_flock_to_flock(&args.flock, &state->flock); switch (state->type) { case GF_LK_F_RDLCK: state->flock.l_type = F_RDLCK; break; case GF_LK_F_WRLCK: state->flock.l_type = F_WRLCK; break; case GF_LK_F_UNLCK: state->flock.l_type = F_UNLCK; break; } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_finodelk_resume); out: free(args.volume); free(args.flock.lk_owner.lk_owner_val); return ret; } int server4_0_entrylk(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_entrylk_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_entrylk_req, GF_FOP_ENTRYLK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_EXACT; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (args.namelen) state->name = gf_strdup(args.name); state->volume = gf_strdup(args.volume); state->cmd = args.cmd; state->type = args.type; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_entrylk_resume); out: free(args.volume); free(args.name); return ret; } int server4_0_fentrylk(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fentrylk_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fentrylk_req, GF_FOP_FENTRYLK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_EXACT; state->resolve.fd_no = args.fd; state->cmd = args.cmd; state->type = args.type; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (args.namelen) state->name = gf_strdup(args.name); state->volume = gf_strdup(args.volume); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fentrylk_resume); out: free(args.volume); free(args.name); return ret; } int server4_0_access(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_access_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_access_req, GF_FOP_ACCESS); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); state->mask = args.mask; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_access_resume); out: return ret; } int server4_0_symlink(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_symlink_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_symlink_req, GF_FOP_SYMLINK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_NOT; set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid); state->resolve.bname = gf_strdup(args.bname); state->name = gf_strdup(args.linkname); state->umask = args.umask; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_symlink_resume); out: free(args.bname); free(args.linkname); return ret; } int server4_0_link(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_link_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_link_req, GF_FOP_LINK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; memcpy(state->resolve.gfid, args.oldgfid, 16); state->resolve2.type = RESOLVE_NOT; state->resolve2.bname = gf_strdup(args.newbname); set_resolve_gfid(frame->root->client, state->resolve2.pargfid, args.newgfid); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_link_resume); out: free(args.newbname); return ret; } int server4_0_rename(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_rename_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_rename_req, GF_FOP_RENAME); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.bname = gf_strdup(args.oldbname); set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.oldgfid); state->resolve2.type = RESOLVE_MAY; state->resolve2.bname = gf_strdup(args.newbname); set_resolve_gfid(frame->root->client, state->resolve2.pargfid, args.newgfid); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_rename_resume); out: free(args.oldbname); free(args.newbname); return ret; } int server4_0_lease(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_lease_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_lease_req, GF_FOP_LEASE); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); gf_proto_lease_to_lease(&args.lease, &state->lease); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_lease_resume); out: return ret; } int server4_0_lk(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_lk_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_lk_req, GF_FOP_LK); if (ret != 0) { goto out; } state->resolve.fd_no = args.fd; state->cmd = args.cmd; state->type = args.type; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); switch (state->cmd) { case GF_LK_GETLK: state->cmd = F_GETLK; break; case GF_LK_SETLK: state->cmd = F_SETLK; break; case GF_LK_SETLKW: state->cmd = F_SETLKW; break; case GF_LK_RESLK_LCK: state->cmd = F_RESLK_LCK; break; case GF_LK_RESLK_LCKW: state->cmd = F_RESLK_LCKW; break; case GF_LK_RESLK_UNLCK: state->cmd = F_RESLK_UNLCK; break; case GF_LK_GETLK_FD: state->cmd = F_GETLK_FD; break; } gf_proto_flock_to_flock(&args.flock, &state->flock); switch (state->type) { case GF_LK_F_RDLCK: state->flock.l_type = F_RDLCK; break; case GF_LK_F_WRLCK: state->flock.l_type = F_WRLCK; break; case GF_LK_F_UNLCK: state->flock.l_type = F_UNLCK; break; default: gf_smsg(frame->root->client->bound_xl->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR, "fd=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s", uuid_utoa(state->fd->inode->gfid), "lock type=" PRId32, state->type, NULL); break; } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_lk_resume); out: free(args.flock.lk_owner.lk_owner_val); return ret; } int server4_0_null(rpcsvc_request_t *req) { gfx_common_rsp rsp = { 0, }; /* Accepted */ rsp.op_ret = 0; server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfx_common_rsp); return 0; } int server4_0_lookup(rpcsvc_request_t *req) { call_frame_t *frame = NULL; server_state_t *state = NULL; gfx_lookup_req args = { { 0, }, }; int ret = -1; GF_VALIDATE_OR_GOTO("server", req, err); ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_lookup_req, GF_FOP_LOOKUP); if (ret != 0) { goto err; } state->resolve.type = RESOLVE_DONTCARE; if (args.bname && strcmp(args.bname, "")) { set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid); state->resolve.bname = gf_strdup(args.bname); } else { set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto err; } ret = 0; resolve_and_resume(frame, server4_lookup_resume); err: free(args.bname); return ret; } int server4_0_statfs(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_statfs_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_statfs_req, GF_FOP_STATFS); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_statfs_resume); out: return ret; } int server4_0_getactivelk(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_getactivelk_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_getactivelk_req, GF_FOP_GETACTIVELK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); /* here, dict itself works as xdata */ if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_getactivelk_resume); out: return ret; } int server4_0_setactivelk(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_setactivelk_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_setactivelk_req, GF_FOP_SETACTIVELK); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid); /* here, dict itself works as xdata */ if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = unserialize_req_locklist_v2(&args, &state->locklist); if (ret) goto out; ret = 0; resolve_and_resume(frame, server4_setactivelk_resume); out: return ret; } int server4_0_namelink(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_namelink_req args = { { 0, }, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_namelink_req, GF_FOP_NAMELINK); if (ret != 0) goto out; state->resolve.bname = gf_strdup(args.bname); memcpy(state->resolve.pargfid, args.pargfid, sizeof(uuid_t)); state->resolve.type = RESOLVE_NOT; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_namelink_resume); out: return ret; } int server4_0_icreate(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_icreate_req args = { { 0, }, }; int ret = -1; uuid_t gfid = { 0, }; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_icreate_req, GF_FOP_ICREATE); if (ret != 0) goto out; memcpy(gfid, args.gfid, sizeof(uuid_t)); state->mode = args.mode; gf_asprintf(&state->resolve.bname, INODE_PATH_FMT, uuid_utoa(gfid)); /* parent is an auxiliary inode number */ memset(state->resolve.pargfid, 0, sizeof(uuid_t)); state->resolve.pargfid[15] = GF_AUXILLARY_PARGFID; state->resolve.type = RESOLVE_NOT; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_icreate_resume); out: return ret; } int server4_0_fsetattr(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_fsetattr_req args = { {0}, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_fsetattr_req, GF_FOP_FSETATTR); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; memcpy(state->resolve.gfid, args.gfid, 16); gfx_stat_to_iattx(&args.stbuf, &state->stbuf); state->valid = args.valid; if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_fsetattr_resume); out: return ret; } int server4_0_rchecksum(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_rchecksum_req args = { {0}, }; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_rchecksum_req, GF_FOP_RCHECKSUM); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MAY; state->resolve.fd_no = args.fd; state->offset = args.offset; state->size = args.len; memcpy(state->resolve.gfid, args.gfid, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_rchecksum_resume); out: return ret; } int server4_0_put(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_put_req args = { { 0, }, }; int ret = -1; ssize_t len = 0; int i = 0; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, &len, &args, xdr_gfx_put_req, GF_FOP_PUT); if (ret != 0) { goto out; } state->resolve.bname = gf_strdup(args.bname); state->mode = args.mode; state->umask = args.umask; state->flags = gf_flags_to_flags(args.flag); state->offset = args.offset; state->size = args.size; state->iobref = iobref_ref(req->iobref); if (len < req->msg[0].iov_len) { state->payload_vector[0].iov_base = (req->msg[0].iov_base + len); state->payload_vector[0].iov_len = req->msg[0].iov_len - len; state->payload_count = 1; } for (i = 1; i < req->count; i++) { state->payload_vector[state->payload_count++] = req->msg[i]; } len = iov_length(state->payload_vector, state->payload_count); GF_ASSERT(state->size == len); set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid); if (state->flags & O_EXCL) { state->resolve.type = RESOLVE_NOT; } else { state->resolve.type = RESOLVE_DONTCARE; } if (xdr_to_dict(&args.xattr, &state->dict)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_put_resume); out: free(args.bname); return ret; } int server4_0_compound(rpcsvc_request_t *req) { int ret = -1; SERVER_REQ_SET_ERROR(req, ret); return ret; } int server4_0_copy_file_range(rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; gfx_copy_file_range_req args = { { 0, }, }; ssize_t len = 0; int ret = -1; if (!req) return ret; ret = rpc_receive_common(req, &frame, &state, &len, &args, xdr_gfx_copy_file_range_req, GF_FOP_COPY_FILE_RANGE); if (ret != 0) { goto out; } state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd_in; state->resolve2.type = RESOLVE_MUST; /*making this resolve must */ state->resolve2.fd_no = args.fd_out; state->off_in = args.off_in; state->off_out = args.off_out; state->size = args.size; state->flags = args.flag; memcpy(state->resolve.gfid, args.gfid1, 16); memcpy(state->resolve2.gfid, args.gfid2, 16); if (xdr_to_dict(&args.xdata, &state->xdata)) { SERVER_REQ_SET_ERROR(req, ret); goto out; } ret = 0; resolve_and_resume(frame, server4_copy_file_range_resume); out: return ret; } int server_null(rpcsvc_request_t *req) { gf_common_rsp rsp = { 0, }; /* Accepted */ rsp.op_ret = 0; server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); return 0; } static rpcsvc_actor_t glusterfs4_0_fop_actors[] = { [GFS3_OP_NULL] = {"NULL", server_null, NULL, GFS3_OP_NULL, 0}, [GFS3_OP_STAT] = {"STAT", server4_0_stat, NULL, GFS3_OP_STAT, 0}, [GFS3_OP_READLINK] = {"READLINK", server4_0_readlink, NULL, GFS3_OP_READLINK, 0}, [GFS3_OP_MKNOD] = {"MKNOD", server4_0_mknod, NULL, GFS3_OP_MKNOD, 0}, [GFS3_OP_MKDIR] = {"MKDIR", server4_0_mkdir, NULL, GFS3_OP_MKDIR, 0}, [GFS3_OP_UNLINK] = {"UNLINK", server4_0_unlink, NULL, GFS3_OP_UNLINK, 0}, [GFS3_OP_RMDIR] = {"RMDIR", server4_0_rmdir, NULL, GFS3_OP_RMDIR, 0}, [GFS3_OP_SYMLINK] = {"SYMLINK", server4_0_symlink, NULL, GFS3_OP_SYMLINK, 0}, [GFS3_OP_RENAME] = {"RENAME", server4_0_rename, NULL, GFS3_OP_RENAME, 0}, [GFS3_OP_LINK] = {"LINK", server4_0_link, NULL, GFS3_OP_LINK, 0}, [GFS3_OP_TRUNCATE] = {"TRUNCATE", server4_0_truncate, NULL, GFS3_OP_TRUNCATE, 0}, [GFS3_OP_OPEN] = {"OPEN", server4_0_open, NULL, GFS3_OP_OPEN, 0}, [GFS3_OP_READ] = {"READ", server4_0_readv, NULL, GFS3_OP_READ, 0}, [GFS3_OP_WRITE] = {"WRITE", server4_0_writev, server4_0_writev_vecsizer, GFS3_OP_WRITE, 0}, [GFS3_OP_STATFS] = {"STATFS", server4_0_statfs, NULL, GFS3_OP_STATFS, 0}, [GFS3_OP_FLUSH] = {"FLUSH", server4_0_flush, NULL, GFS3_OP_FLUSH, 0}, [GFS3_OP_FSYNC] = {"FSYNC", server4_0_fsync, NULL, GFS3_OP_FSYNC, 0}, [GFS3_OP_GETXATTR] = {"GETXATTR", server4_0_getxattr, NULL, GFS3_OP_GETXATTR, 0}, [GFS3_OP_SETXATTR] = {"SETXATTR", server4_0_setxattr, NULL, GFS3_OP_SETXATTR, 0}, [GFS3_OP_REMOVEXATTR] = {"REMOVEXATTR", server4_0_removexattr, NULL, GFS3_OP_REMOVEXATTR, 0}, [GFS3_OP_OPENDIR] = {"OPENDIR", server4_0_opendir, NULL, GFS3_OP_OPENDIR, 0}, [GFS3_OP_FSYNCDIR] = {"FSYNCDIR", server4_0_fsyncdir, NULL, GFS3_OP_FSYNCDIR, 0}, [GFS3_OP_ACCESS] = {"ACCESS", server4_0_access, NULL, GFS3_OP_ACCESS, 0}, [GFS3_OP_CREATE] = {"CREATE", server4_0_create, NULL, GFS3_OP_CREATE, 0}, [GFS3_OP_FTRUNCATE] = {"FTRUNCATE", server4_0_ftruncate, NULL, GFS3_OP_FTRUNCATE, 0}, [GFS3_OP_FSTAT] = {"FSTAT", server4_0_fstat, NULL, GFS3_OP_FSTAT, 0}, [GFS3_OP_LK] = {"LK", server4_0_lk, NULL, GFS3_OP_LK, 0}, [GFS3_OP_LOOKUP] = {"LOOKUP", server4_0_lookup, NULL, GFS3_OP_LOOKUP, 0}, [GFS3_OP_READDIR] = {"READDIR", server4_0_readdir, NULL, GFS3_OP_READDIR, 0}, [GFS3_OP_INODELK] = {"INODELK", server4_0_inodelk, NULL, GFS3_OP_INODELK, 0}, [GFS3_OP_FINODELK] = {"FINODELK", server4_0_finodelk, NULL, GFS3_OP_FINODELK, 0}, [GFS3_OP_ENTRYLK] = {"ENTRYLK", server4_0_entrylk, NULL, GFS3_OP_ENTRYLK, 0}, [GFS3_OP_FENTRYLK] = {"FENTRYLK", server4_0_fentrylk, NULL, GFS3_OP_FENTRYLK, 0}, [GFS3_OP_XATTROP] = {"XATTROP", server4_0_xattrop, NULL, GFS3_OP_XATTROP, 0}, [GFS3_OP_FXATTROP] = {"FXATTROP", server4_0_fxattrop, NULL, GFS3_OP_FXATTROP, 0}, [GFS3_OP_FGETXATTR] = {"FGETXATTR", server4_0_fgetxattr, NULL, GFS3_OP_FGETXATTR, 0}, [GFS3_OP_FSETXATTR] = {"FSETXATTR", server4_0_fsetxattr, NULL, GFS3_OP_FSETXATTR, 0}, [GFS3_OP_RCHECKSUM] = {"RCHECKSUM", server4_0_rchecksum, NULL, GFS3_OP_RCHECKSUM, 0}, [GFS3_OP_SETATTR] = {"SETATTR", server4_0_setattr, NULL, GFS3_OP_SETATTR, 0}, [GFS3_OP_FSETATTR] = {"FSETATTR", server4_0_fsetattr, NULL, GFS3_OP_FSETATTR, 0}, [GFS3_OP_READDIRP] = {"READDIRP", server4_0_readdirp, NULL, GFS3_OP_READDIRP, 0}, [GFS3_OP_RELEASE] = {"RELEASE", server4_0_release, NULL, GFS3_OP_RELEASE, 0}, [GFS3_OP_RELEASEDIR] = {"RELEASEDIR", server4_0_releasedir, NULL, GFS3_OP_RELEASEDIR, 0}, [GFS3_OP_FREMOVEXATTR] = {"FREMOVEXATTR", server4_0_fremovexattr, NULL, GFS3_OP_FREMOVEXATTR, 0}, [GFS3_OP_FALLOCATE] = {"FALLOCATE", server4_0_fallocate, NULL, DRC_NA, GFS3_OP_FALLOCATE, 0}, [GFS3_OP_DISCARD] = {"DISCARD", server4_0_discard, NULL, DRC_NA, GFS3_OP_DISCARD, 0}, [GFS3_OP_ZEROFILL] = {"ZEROFILL", server4_0_zerofill, NULL, DRC_NA, GFS3_OP_ZEROFILL, 0}, [GFS3_OP_IPC] = {"IPC", server4_0_ipc, NULL, DRC_NA, GFS3_OP_IPC, 0}, [GFS3_OP_SEEK] = {"SEEK", server4_0_seek, NULL, DRC_NA, GFS3_OP_SEEK, 0}, [GFS3_OP_LEASE] = {"LEASE", server4_0_lease, NULL, DRC_NA, GFS3_OP_LEASE, 0}, [GFS3_OP_GETACTIVELK] = {"GETACTIVELK", server4_0_getactivelk, NULL, DRC_NA, GFS3_OP_GETACTIVELK, 0}, [GFS3_OP_SETACTIVELK] = {"SETACTIVELK", server4_0_setactivelk, NULL, DRC_NA, GFS3_OP_SETACTIVELK, 0}, [GFS3_OP_COMPOUND] = {"COMPOUND", server4_0_compound, NULL, DRC_NA, GFS3_OP_COMPOUND, 0}, [GFS3_OP_ICREATE] = {"ICREATE", server4_0_icreate, NULL, DRC_NA, GFS3_OP_ICREATE, 0}, [GFS3_OP_NAMELINK] = {"NAMELINK", server4_0_namelink, NULL, DRC_NA, GFS3_OP_NAMELINK, 0}, [GFS3_OP_COPY_FILE_RANGE] = {"COPY-FILE-RANGE", server4_0_copy_file_range, NULL, DRC_NA, GFS3_OP_COPY_FILE_RANGE, 0}, }; struct rpcsvc_program glusterfs4_0_fop_prog = { .progname = "GlusterFS 4.x v1", .prognum = GLUSTER_FOP_PROGRAM, .progver = GLUSTER_FOP_VERSION_v2, .numactors = GLUSTER_FOP_PROCCNT, .actors = glusterfs4_0_fop_actors, .ownthread = _gf_true, }; glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server.h0000644000000000000000000000013214522202451023471 xustar000000000000000030 mtime=1699284265.780027772 30 atime=1699284265.780027772 30 ctime=1699284301.896136553 glusterfs-11.1/xlators/protocol/server/src/server.h0000664000175100017510000001173614522202451023760 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _SERVER_H #define _SERVER_H #include #include "rpcsvc.h" #include "protocol-common.h" #include "server-mem-types.h" #include "glusterfs3.h" #include #include #include "authenticate.h" /* Threading limits for server event threads. */ #define SERVER_MIN_EVENT_THREADS 1 #define SERVER_MAX_EVENT_THREADS 1024 #define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol" typedef enum { INTERNAL_LOCKS = 1, POSIX_LOCKS = 2, } server_lock_flags_t; typedef struct _server_state server_state_t; int server_null(rpcsvc_request_t *req); struct _volfile_ctx { struct _volfile_ctx *next; char *key; uint32_t checksum; }; struct _child_status { struct list_head status_list; char *name; char volume_id[GF_UUID_BUF_SIZE]; gf_boolean_t child_up; }; struct server_conf { rpcsvc_t *rpc; int inode_lru_limit; gf_boolean_t server_manage_gids; /* resolve gids on brick */ gf_boolean_t trace; gf_boolean_t parent_up; gf_boolean_t dync_auth; /* if set authenticate dynamically, * in case if volume set options * (say *.allow | *.reject) are * tweeked */ char *conf_dir; char *volfile_dir; struct _volfile_ctx *volfile; dict_t *auth_modules; struct list_head xprt_list; time_t gid_cache_timeout; struct _child_status *child_status; int event_threads; /* # of event threads * configured */ gf_boolean_t strict_auth_enabled; pthread_mutex_t mutex; gf_lock_t itable_lock; gid_cache_t gid_cache; }; typedef struct server_conf server_conf_t; typedef enum { RESOLVE_MUST = 1, RESOLVE_NOT, RESOLVE_MAY, RESOLVE_DONTCARE, RESOLVE_EXACT } server_resolve_type_t; struct resolve_comp { char *basename; inode_t *inode; }; typedef struct { server_resolve_type_t type; int64_t fd_no; u_char gfid[16]; u_char pargfid[16]; char *path; char *bname; int op_ret; int op_errno; loc_t resolve_loc; } server_resolve_t; typedef int (*server_resume_fn_t)(call_frame_t *frame, xlator_t *bound_xl); void resolve_and_resume(call_frame_t *frame, server_resume_fn_t fn); struct _server_state { rpc_transport_t *xprt; inode_table_t *itable; server_resume_fn_t resume_fn; loc_t loc; loc_t loc2; server_resolve_t resolve; server_resolve_t resolve2; /* used within resolve_and_resume */ loc_t *loc_now; server_resolve_t *resolve_now; struct iatt stbuf; int valid; int32_t flags; /* * this fd is used in all the fd based operations PLUS * as a source fd in copy_file_range */ fd_t *fd; fd_t *fd_out; /* destination fd in copy_file_range */ dict_t *params; struct iovec payload_vector[MAX_IOVEC]; int payload_count; struct iobref *iobref; size_t size; off_t offset; /* * According to the man page of copy_file_range, * the offsets for source and destination file * are of type loff_t. But the type loff_t is * linux specific and is actual a typedef of * off64_t. */ off64_t off_in; /* source offset in copy_file_range */ off64_t off_out; /* destination offset in copy_file_range */ mode_t mode; dev_t dev; int cmd; int type; char *name; int mask; char is_revalidate; dict_t *dict; struct gf_flock flock; const char *volume; dict_t *xdata; mode_t umask; struct gf_lease lease; lock_migration_info_t locklist; struct iovec rsp_vector[MAX_IOVEC]; int rsp_count; gf_seek_what_t what; /* subdir mount */ client_t *client; }; extern struct rpcsvc_program gluster_handshake_prog; extern struct rpcsvc_program glusterfs3_3_fop_prog; extern struct rpcsvc_program glusterfs4_0_fop_prog; typedef struct _server_ctx { gf_lock_t fdtable_lock; fdtable_t *fdtable; } server_ctx_t; typedef struct server_cleanup_xprt_arg { xlator_t *this; char *victim_name; } server_cleanup_xprt_arg_t; int server_submit_reply(call_frame_t *frame, rpcsvc_request_t *req, void *arg, struct iovec *payload, int payloadcount, struct iobref *iobref, xdrproc_t xdrproc); int gf_server_check_setxattr_cmd(call_frame_t *frame, dict_t *dict); int gf_server_check_getxattr_cmd(call_frame_t *frame, const char *name); void forget_inode_if_no_dentry(inode_t *inode); void * server_graph_janitor_threads(void *); server_ctx_t * server_ctx_get(client_t *client, xlator_t *xlator); void server_cleanup(xlator_t *this, server_conf_t *conf); #endif /* !_SERVER_H */ glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server-handshake.c0000644000000000000000000000013214522202451025410 xustar000000000000000030 mtime=1699284265.777027763 30 atime=1699284265.777027763 30 ctime=1699284301.908136589 glusterfs-11.1/xlators/protocol/server/src/server-handshake.c0000664000175100017510000006537714522202451025711 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "server.h" #include "server-helpers.h" #include "rpc-common-xdr.h" #include "glusterfs4-xdr.h" #include #include "glusterfs3.h" #include "authenticate.h" #include "server-messages.h" #include #include #include struct __get_xl_struct { const char *name; xlator_t *reply; }; int gf_compare_client_version(rpcsvc_request_t *req, int fop_prognum, int mgmt_prognum) { int ret = 0; /* TODO: think.. */ return ret; } int server_getspec(rpcsvc_request_t *req) { int32_t ret = 0; int32_t op_errno = ENOENT; gf_getspec_req args = { 0, }; gf_getspec_rsp rsp = { 0, }; struct stat stbuf = { 0, }; char volpath[PATH_MAX] = { 0, }; int32_t spec_fd = -1; xlator_t *this = req->svc->xl; server_conf_t *conf = this->private; gf_boolean_t need_to_free_buffer = _gf_false; ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gf_getspec_req); if (ret < 0) { // failed to decode msg; req->rpc_err = GARBAGE_ARGS; op_errno = EINVAL; rsp.spec = ""; rsp.op_errno = gf_errno_to_error(op_errno); rsp.op_ret = -1; goto out; } /* By default, the behavior is not to return anything if specific option is * not set */ if (!conf->volfile_dir) { ret = -1; op_errno = ENOTSUP; rsp.spec = ""; goto out; } char *volid = args.key; if (strstr(volid, "../")) { op_errno = EINVAL; rsp.spec = "having '../' in volid is not valid"; rsp.op_errno = gf_errno_to_error(op_errno); rsp.op_ret = -1; goto out; } ret = snprintf(volpath, PATH_MAX - 1, "%s/%s.vol", conf->volfile_dir, volid); if (ret == -1) { op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, errno, 0, "failed to copy volfile"); goto out; } ret = sys_stat(volpath, &stbuf); if (ret < 0) { op_errno = errno; goto out; } spec_fd = sys_open(volpath, O_RDONLY, 0); if (spec_fd < 0) { op_errno = errno; gf_msg("glusterd", GF_LOG_ERROR, errno, 0, "Unable to open %s (%s)", volpath, strerror(errno)); goto out; } ret = stbuf.st_size; if (ret > 0) { rsp.spec = MALLOC((ret + 1) * sizeof(char)); if (!rsp.spec) { gf_msg(this->name, GF_LOG_ERROR, errno, 0, "no memory"); ret = -1; goto out; } need_to_free_buffer = _gf_true; ret = sys_read(spec_fd, rsp.spec, ret); if (ret <= 0) { op_errno = errno; } } out: if (spec_fd >= 0) sys_close(spec_fd); rsp.op_ret = ret; if (rsp.op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, 0, "Failed to mount the volume"); } if (op_errno) rsp.op_errno = gf_errno_to_error(op_errno); if (!rsp.spec) rsp.spec = ""; server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_getspec_rsp); free(args.key); if (args.xdata.xdata_val) free(args.xdata.xdata_val); if (need_to_free_buffer) FREE(rsp.spec); if (rsp.xdata.xdata_val) GF_FREE(rsp.xdata.xdata_val); return 0; } static void server_first_lookup_done(rpcsvc_request_t *req, gf_setvolume_rsp *rsp) { server_submit_reply(NULL, req, rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_setvolume_rsp); GF_FREE(rsp->dict.dict_val); GF_FREE(rsp); } static inode_t * do_path_lookup(xlator_t *xl, dict_t *dict, inode_t *parinode, char *basename) { int ret = 0; loc_t loc = { 0, }; uuid_t gfid = { 0, }; struct iatt iatt = { 0, }; inode_t *inode = NULL; loc.parent = inode_ref(parinode); loc_touchup(&loc, basename); loc.inode = inode_new(xl->itable); gf_uuid_generate(gfid); ret = dict_set_gfuuid(dict, "gfid-req", gfid, true); if (ret) { gf_log(xl->name, GF_LOG_ERROR, "failed to set 'gfid-req' for subdir"); goto out; } ret = syncop_lookup(xl, &loc, &iatt, NULL, dict, NULL); if (ret < 0) { gf_log(xl->name, GF_LOG_ERROR, "first lookup on subdir (%s) failed: %s", basename, strerror(errno)); } /* Inode linking is required so that the resolution happens all fine for future fops */ inode = inode_link(loc.inode, loc.parent, loc.name, &iatt); /* Extra ref so the pointer is valid till client is valid */ /* FIXME: not a priority, but this can lead to some inode leaks if subdir is more than 1 level depth. Leak is only per subdir entry, and not dependent on number of connections, so it should be fine for now */ inode_ref(inode); out: loc_wipe(&loc); return inode; } int server_first_lookup(xlator_t *this, client_t *client, dict_t *reply) { loc_t loc = { 0, }; dict_t *dict = NULL; int ret = 0; xlator_t *xl = client->bound_xl; char *msg = NULL; inode_t *inode = NULL; char *bname = NULL; char *str = NULL; char *tmp = NULL; char *saveptr = NULL; loc.path = "/"; loc.name = ""; loc.inode = xl->itable->root; loc.parent = NULL; gf_uuid_copy(loc.gfid, loc.inode->gfid); ret = syncop_lookup(xl, &loc, NULL, NULL, NULL, NULL); if (ret < 0) gf_log(xl->name, GF_LOG_ERROR, "lookup on root failed: %s", strerror(errno)); /* Ignore error from lookup, don't set * failure in rsp->op_ret. lookup on a snapview-server * can fail with ESTALE */ /* TODO-SUBDIR-MOUNT: validate above comment with respect to subdir lookup */ if (client->subdir_mount) { str = tmp = gf_strdup(client->subdir_mount); dict = dict_new(); inode = xl->itable->root; bname = strtok_r(str, "/", &saveptr); while (bname != NULL) { inode = do_path_lookup(xl, dict, inode, bname); if (inode == NULL) { gf_log(this->name, GF_LOG_ERROR, "first lookup on subdir (%s) failed: %s", client->subdir_mount, strerror(errno)); ret = -1; goto fail; } bname = strtok_r(NULL, "/", &saveptr); } /* Can be used in server_resolve() */ gf_uuid_copy(client->subdir_gfid, inode->gfid); client->subdir_inode = inode; } ret = 0; goto out; fail: /* we should say to client, it is not possible to connect */ ret = gf_asprintf(&msg, "subdirectory for mount \"%s\" is not found", client->subdir_mount); if (-1 == ret) { gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_ASPRINTF_FAILED, "asprintf failed while setting error msg"); } ret = dict_set_dynstr(reply, "ERROR", msg); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); ret = -1; out: if (dict) dict_unref(dict); inode_unref(loc.inode); if (tmp) GF_FREE(tmp); return ret; } int server_setvolume(rpcsvc_request_t *req) { gf_setvolume_req args = { { 0, }, }; gf_setvolume_rsp *rsp = NULL; client_t *client = NULL; server_ctx_t *serv_ctx = NULL; server_conf_t *conf = NULL; peer_info_t *peerinfo = NULL; dict_t *reply = NULL; dict_t *config_params = NULL; dict_t *params = NULL; char *name = NULL; char *volume_id = NULL; char *client_uid = NULL; char *clnt_version = NULL; xlator_t *xl = NULL; char *msg = NULL; xlator_t *this = NULL; int32_t ret = -1; int32_t op_ret = -1; int32_t op_errno = EINVAL; uint32_t opversion = 0; rpc_transport_t *xprt = NULL; int32_t fop_version = 0; int32_t mgmt_version = 0; glusterfs_ctx_t *ctx = NULL; struct _child_status *tmp = NULL; char *subdir_mount = NULL; char *client_name = NULL; gf_boolean_t cleanup_starting = _gf_false; gf_boolean_t xlator_in_graph = _gf_true; params = dict_new(); reply = dict_new(); ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gf_setvolume_req); if (ret < 0) { // failed to decode msg; req->rpc_err = GARBAGE_ARGS; goto fail; } ctx = THIS->ctx; this = req->svc->xl; /* this is to ensure config_params is populated with the first brick * details at first place if brick multiplexing is enabled */ config_params = dict_copy_with_ref(this->options, NULL); ret = dict_unserialize(args.dict.dict_val, args.dict.dict_len, ¶ms); if (ret < 0) { ret = dict_set_sizen_str_sizen(reply, "ERROR", "Internal error: failed to unserialize " "request dictionary"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg \"%s\"", "Internal error: failed " "to unserialize request dictionary"); op_ret = -1; op_errno = EINVAL; goto fail; } ret = dict_get_str(params, "remote-subvolume", &name); if (ret < 0) { ret = dict_set_str(reply, "ERROR", "No remote-subvolume option specified"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); op_ret = -1; op_errno = EINVAL; goto fail; } LOCK(&ctx->volfile_lock); { xl = get_xlator_by_name(this, name); if (!xl) { xlator_in_graph = _gf_false; xl = this; } if (ctx->cleanup_starting) { cleanup_starting = _gf_true; op_ret = -1; op_errno = ENOENT; } } UNLOCK(&ctx->volfile_lock); if (!xl || cleanup_starting) { ret = gf_asprintf(&msg, "remote-subvolume \"%s\" is not found", name); if (-1 == ret) { gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_ASPRINTF_FAILED, "asprintf failed while setting error msg"); goto fail; } ret = dict_set_dynstr(reply, "ERROR", msg); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); op_ret = -1; op_errno = ENOENT; goto fail; } config_params = dict_copy_with_ref(xl->options, config_params); conf = this->private; if (conf->parent_up == _gf_false) { /* PARENT_UP indicates that all xlators in graph are inited * successfully */ op_ret = -1; op_errno = EAGAIN; ret = dict_set_str(reply, "ERROR", "xlator graph in server is not initialised " "yet. Try again later"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error: " "xlator graph in server is not " "initialised yet. Try again later"); goto fail; } pthread_mutex_lock(&conf->mutex); list_for_each_entry(tmp, &conf->child_status->status_list, status_list) { if (strcmp(tmp->name, name) == 0) break; } if (!tmp->name) { gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CHILD_STATUS_FAILED, "No xlator %s is found in child status list", name); } else { ret = dict_set_int32(reply, "child_up", tmp->child_up); if (ret < 0) gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_DICT_GET_FAILED, "Failed to set 'child_up' for xlator %s " "in the reply dict", tmp->name); if (!tmp->child_up) { ret = dict_set_str(reply, "ERROR", "Not received child_up for this xlator"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error msg"); gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_CHILD_STATUS_FAILED, "Not received child_up for this xlator %s", name); op_ret = -1; op_errno = EAGAIN; pthread_mutex_unlock(&conf->mutex); goto fail; } } pthread_mutex_unlock(&conf->mutex); ret = dict_get_str(params, "process-uuid", &client_uid); if (ret < 0) { ret = dict_set_str(reply, "ERROR", "UUID not specified"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); op_ret = -1; op_errno = EINVAL; goto fail; } ret = dict_get_str(params, "subdir-mount", &subdir_mount); if (ret < 0) { /* Not a problem at all as the key is optional */ } ret = dict_get_str(params, "process-name", &client_name); if (ret < 0) { client_name = "unknown"; } /* If any value is set, the first element will be non-0. It would be '0', but not '\0' :-) */ if (xl->graph->volume_id[0]) { ret = dict_get_str_sizen(params, "volume-id", &volume_id); if (!ret && strcmp(xl->graph->volume_id, volume_id)) { ret = dict_set_str(reply, "ERROR", "Volume-ID different, possible case " "of same brick re-used in another volume"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error msg"); op_ret = -1; op_errno = EINVAL; goto fail; } ret = dict_set_str(reply, "volume-id", tmp->volume_id); if (ret) gf_msg_debug(this->name, 0, "failed to set 'volume-id'"); } client = gf_client_get(this, &req->cred, client_uid, subdir_mount); if (client == NULL) { op_ret = -1; op_errno = ENOMEM; goto fail; } client->client_name = gf_strdup(client_name); gf_msg_debug(this->name, 0, "Connected to %s", client->client_uid); serv_ctx = server_ctx_get(client, client->this); if (serv_ctx == NULL) { gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " "failed"); goto fail; } pthread_mutex_lock(&conf->mutex); if (xl->cleanup_starting) { cleanup_starting = _gf_true; } else if (req->trans->xl_private != client) { req->trans->xl_private = client; } pthread_mutex_unlock(&conf->mutex); if (cleanup_starting) { op_ret = -1; op_errno = EAGAIN; ret = dict_set_str(reply, "ERROR", "cleanup flag is set for xlator. " " Try again later"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error: " "cleanup flag is set for xlator. " "Try again later"); goto fail; } auth_set_username_passwd(params, config_params, client); if (req->trans->ssl_name) { if (dict_set_str(params, "ssl-name", req->trans->ssl_name) != 0) { gf_msg(this->name, GF_LOG_WARNING, 0, PS_MSG_SSL_NAME_SET_FAILED, "failed to set " "ssl_name %s", req->trans->ssl_name); /* Not fatal, auth will just fail. */ } } ret = dict_get_int32(params, "fops-version", &fop_version); if (ret < 0) { ret = dict_set_str(reply, "ERROR", "No FOP version number specified"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); } ret = dict_get_int32(params, "mgmt-version", &mgmt_version); if (ret < 0) { ret = dict_set_str(reply, "ERROR", "No MGMT version number specified"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); } ret = gf_compare_client_version(req, fop_version, mgmt_version); if (ret != 0) { ret = gf_asprintf(&msg, "version mismatch: client(%d)" " - client-mgmt(%d)", fop_version, mgmt_version); /* get_supported_version (req)); */ if (-1 == ret) { gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_ASPRINTF_FAILED, "asprintf failed while" "setting up error msg"); goto fail; } ret = dict_set_dynstr(reply, "ERROR", msg); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); op_ret = -1; op_errno = EINVAL; goto fail; } peerinfo = &req->trans->peerinfo; if (peerinfo) { ret = dict_set_static_ptr(params, "peer-info", peerinfo); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set " "peer-info"); } ret = dict_get_uint32(params, "opversion", &opversion); if (ret) { gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_OPVERSION_GET_FAILED, "Failed to get client opversion"); } client->opversion = opversion; /* Assign op-version value to the client */ pthread_mutex_lock(&conf->mutex); list_for_each_entry(xprt, &conf->xprt_list, list) { if (strcmp(peerinfo->identifier, xprt->peerinfo.identifier)) continue; xprt->peerinfo.max_op_version = opversion; } pthread_mutex_unlock(&conf->mutex); if (conf->auth_modules == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_AUTH_INIT_FAILED, "Authentication module not initialized"); } ret = dict_get_str(params, "client-version", &clnt_version); if (ret) gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_VERSION_NOT_SET, "client-version not set, may be of older version"); ret = gf_authenticate(params, config_params, conf->auth_modules); if (ret == AUTH_ACCEPT) { /* Store options received from client side */ req->trans->clnt_options = dict_ref(params); gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_ACCEPTED, "accepted client from %s (version: %s) with subvol %s", client->client_uid, (clnt_version) ? clnt_version : "old", name); gf_event(EVENT_CLIENT_CONNECT, "client_uid=%s;" "client_identifier=%s;server_identifier=%s;" "brick_path=%s;subdir_mount=%s", client->client_uid, req->trans->peerinfo.identifier, req->trans->myinfo.identifier, name, subdir_mount); op_ret = 0; client->bound_xl = xl; /* Don't be confused by the below line (like how ERROR can be Success), key checked on client is 'ERROR' and hence we send 'Success' in this key */ ret = dict_set_str(reply, "ERROR", "Success"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); } else { op_ret = -1; if (!xlator_in_graph) { gf_msg(this->name, GF_LOG_ERROR, ENOENT, PS_MSG_AUTHENTICATE_ERROR, "Cannot authenticate client" " from %s %s because brick is not attached in graph", client->client_uid, (clnt_version) ? clnt_version : "old"); op_errno = ENOENT; ret = dict_set_str(reply, "ERROR", "Brick not found"); } else { gf_event(EVENT_CLIENT_AUTH_REJECT, "client_uid=%s;" "client_identifier=%s;server_identifier=%s;" "brick_path=%s", client->client_uid, req->trans->peerinfo.identifier, req->trans->myinfo.identifier, name); gf_msg(this->name, GF_LOG_ERROR, EACCES, PS_MSG_AUTHENTICATE_ERROR, "Cannot authenticate client" " from %s %s", client->client_uid, (clnt_version) ? clnt_version : "old"); op_errno = EACCES; ret = dict_set_str(reply, "ERROR", "Authentication failed"); } if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); goto fail; } if (client->bound_xl == NULL) { ret = dict_set_str(reply, "ERROR", "Check volfile and handshake " "options in protocol/client"); if (ret < 0) gf_msg_debug(this->name, 0, "failed to set error " "msg"); op_ret = -1; op_errno = EACCES; goto fail; } LOCK(&conf->itable_lock); { if (client->bound_xl->itable == NULL) { /* create inode table for this bound_xl, if one doesn't already exist */ gf_msg_trace(this->name, 0, "creating inode table with" " lru_limit=%" PRId32 ", xlator=%s", conf->inode_lru_limit, client->bound_xl->name); /* TODO: what is this ? */ client->bound_xl->itable = inode_table_new(conf->inode_lru_limit, client->bound_xl, 0, 0); } } UNLOCK(&conf->itable_lock); ret = dict_set_str(reply, "process-uuid", this->ctx->process_uuid); if (ret) gf_msg_debug(this->name, 0, "failed to set 'process-uuid'"); /* Insert a dummy key value pair to avoid failure at client side for * clnt-lk-version with older clients. */ ret = dict_set_uint32(reply, "clnt-lk-version", 0); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, PS_MSG_CLIENT_LK_VERSION_ERROR, "failed to set " "'clnt-lk-version'"); } ret = dict_set_uint64(reply, "transport-ptr", ((uint64_t)(long)req->trans)); if (ret) gf_msg_debug(this->name, 0, "failed to set 'transport-ptr'"); fail: /* It is important to validate the lookup on '/' as part of handshake, because if lookup itself can't succeed, we should communicate this to client. Very important in case of subdirectory mounts, where if client is trying to mount a non-existing directory */ if (op_ret >= 0 && client->bound_xl->itable) { if (client->bound_xl->cleanup_starting) { op_ret = -1; op_errno = EAGAIN; ret = dict_set_str(reply, "ERROR", "cleanup flag is set for xlator " "before call first_lookup Try again later"); /* quisce coverity about UNUSED_VALUE ret */ (void)(ret); } else { op_ret = server_first_lookup(this, client, reply); if (op_ret == -1) op_errno = ENOENT; } } rsp = GF_CALLOC(1, sizeof(gf_setvolume_rsp), gf_server_mt_setvolume_rsp_t); GF_ASSERT(rsp); rsp->op_ret = 0; ret = dict_allocate_and_serialize(reply, (char **)&rsp->dict.dict_val, &rsp->dict.dict_len); if (ret != 0) { ret = -1; gf_msg_debug("server-handshake", 0, "failed to serialize reply dict"); op_ret = -1; op_errno = -ret; } rsp->op_ret = op_ret; rsp->op_errno = gf_errno_to_error(op_errno); /* if bound_xl is NULL or something fails, then put the connection * back. Otherwise the connection would have been added to the * list of connections the server is maintaining and might segfault * during statedump when bound_xl of the connection is accessed. */ if (op_ret && !xl && (client != NULL)) { /* We would have set the xl_private of the transport to the * @conn. But if we have put the connection i.e shutting down * the connection, then we should set xl_private to NULL as it * would be pointing to a freed memory and would segfault when * accessed upon getting DISCONNECT. */ gf_client_put(client, NULL); req->trans->xl_private = NULL; } /* Send the response properly */ server_first_lookup_done(req, rsp); free(args.dict.dict_val); dict_unref(params); dict_unref(reply); if (config_params) { /* * This might be null if we couldn't even find the translator * (brick) to copy it from. */ dict_unref(config_params); } return 0; } int server_ping(rpcsvc_request_t *req) { gf_common_rsp rsp = { 0, }; /* Accepted */ rsp.op_ret = 0; server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); return 0; } int server_set_lk_version(rpcsvc_request_t *req) { int ret = -1; gf_set_lk_ver_req args = { 0, }; gf_set_lk_ver_rsp rsp = { 0, }; ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gf_set_lk_ver_req); if (ret < 0) { /* failed to decode msg */ req->rpc_err = GARBAGE_ARGS; goto fail; } rsp.lk_ver = args.lk_ver; fail: server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_set_lk_ver_rsp); free(args.uid); return 0; } static rpcsvc_actor_t gluster_handshake_actors[GF_HNDSK_MAXVALUE] = { [GF_HNDSK_NULL] = {"NULL", server_null, NULL, GF_HNDSK_NULL, DRC_NA, 0}, [GF_HNDSK_SETVOLUME] = {"SETVOLUME", server_setvolume, NULL, GF_HNDSK_SETVOLUME, DRC_NA, 0}, [GF_HNDSK_GETSPEC] = {"GETSPEC", server_getspec, NULL, GF_HNDSK_GETSPEC, DRC_NA, 0}, [GF_HNDSK_PING] = {"PING", server_ping, NULL, GF_HNDSK_PING, DRC_NA, 0}, [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", server_set_lk_version, NULL, GF_HNDSK_SET_LK_VER, DRC_NA, 0}, }; struct rpcsvc_program gluster_handshake_prog = { .progname = "GlusterFS Handshake", .prognum = GLUSTER_HNDSK_PROGRAM, .progver = GLUSTER_HNDSK_VERSION, .actors = gluster_handshake_actors, .numactors = GF_HNDSK_MAXVALUE, }; glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server-messages.h0000644000000000000000000000013214522202451025276 xustar000000000000000030 mtime=1699284265.778027766 30 atime=1699284265.778027766 30 ctime=1699284301.901136568 glusterfs-11.1/xlators/protocol/server/src/server-messages.h0000664000175100017510000002217114522202451025560 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _PS_MESSAGES_H__ #define _PS_MESSAGES_H__ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID( PS, PS_MSG_AUTHENTICATE_ERROR, PS_MSG_VOL_VALIDATE_FAILED, PS_MSG_AUTH_INIT_FAILED, PS_MSG_REMOTE_CLIENT_REFUSED, PS_MSG_GFID_RESOLVE_FAILED, PS_MSG_ANONYMOUS_FD_CREATE_FAILED, PS_MSG_NO_MEMORY, PS_MSG_FD_NOT_FOUND, PS_MSG_INVALID_ENTRY, PS_MSG_GET_UID_FAILED, PS_MSG_UID_NOT_FOUND, PS_MSG_MAPPING_ERROR, PS_MSG_FD_CLEANUP, PS_MSG_SERVER_CTX_GET_FAILED, PS_MSG_FDENTRY_NULL, PS_MSG_DIR_NOT_FOUND, PS_MSG_SERVER_MSG, PS_MSG_DICT_SERIALIZE_FAIL, PS_MSG_RW_STAT, PS_MSG_DICT_GET_FAILED, PS_MSG_LOGIN_ERROR, PS_MSG_REMOUNT_CLIENT_REQD, PS_MSG_DEFAULTING_FILE, PS_MSG_VOL_FILE_OPEN_FAILED, PS_MSG_STAT_ERROR, PS_MSG_SSL_NAME_SET_FAILED, PS_MSG_ASPRINTF_FAILED, PS_MSG_CLIENT_VERSION_NOT_SET, PS_MSG_CLIENT_ACCEPTED, PS_MSG_CLIENT_LK_VERSION_ERROR, PS_MSG_GRACE_TIMER_EXPD, PS_MSG_SERIALIZE_REPLY_FAILED, PS_MSG_AUTH_IP_ERROR, PS_MSG_SKIP_FORMAT_CHK, PS_MSG_INTERNET_ADDR_ERROR, PS_MSG_CLIENT_DISCONNECTING, PS_MSG_GRACE_TIMER_START, PS_MSG_STATEDUMP_PATH_ERROR, PS_MSG_GRP_CACHE_ERROR, PS_MSG_RPC_CONF_ERROR, PS_MSG_TRANSPORT_ERROR, PS_MSG_SUBVOL_NULL, PS_MSG_PARENT_VOL_ERROR, PS_MSG_RPCSVC_CREATE_FAILED, PS_MSG_RPCSVC_LISTENER_CREATE_FAILED, PS_MSG_RPCSVC_NOTIFY, PS_MSG_PGM_REG_FAILED, PS_MSG_ULIMIT_SET_FAILED, PS_MSG_STATFS, PS_MSG_LOOKUP_INFO, PS_MSG_LK_INFO, PS_MSG_LOCK_ERROR, PS_MSG_INODELK_INFO, PS_MSG_ENTRYLK_INFO, PS_MSG_ACCESS_INFO, PS_MSG_DIR_INFO, PS_MSG_MKNOD_INFO, PS_MSG_REMOVEXATTR_INFO, PS_MSG_GETXATTR_INFO, PS_MSG_SETXATTR_INFO, PS_MSG_RENAME_INFO, PS_MSG_LINK_INFO, PS_MSG_TRUNCATE_INFO, PS_MSG_FSTAT_INFO, PS_MSG_FLUSH_INFO, PS_MSG_SYNC_INFO, PS_MSG_WRITE_INFO, PS_MSG_READ_INFO, PS_MSG_CHKSUM_INFO, PS_MSG_OPEN_INFO, PS_MSG_CREATE_INFO, PS_MSG_SETATTR_INFO, PS_MSG_XATTROP_INFO, PS_MSG_ALLOC_INFO, PS_MSG_DISCARD_INFO, PS_MSG_ZEROFILL_INFO, PS_MSG_FD_CREATE_FAILED, PS_MSG_WRONG_STATE, PS_MSG_CONF_DIR_INVALID, PS_MSG_MOUNT_PT_FAIL, PS_MSG_STAT_INFO, PS_MSG_FILE_OP_FAILED, PS_MSG_GRACE_TIMER_CANCELLED, PS_MSG_ENCODE_MSG_FAILED, PS_MSG_REPLY_SUBMIT_FAILED, PS_MSG_RPC_NOTIFY_ERROR, PS_MSG_SERVER_EVENT_UPCALL_FAILED, PS_MSG_SERVER_IPC_INFO, PS_MSG_SEEK_INFO, PS_MSG_COMPOUND_INFO, PS_MSG_CLIENT_OPVERSION_GET_FAILED, PS_MSG_CHILD_STATUS_FAILED, PS_MSG_PUT_INFO, PS_MSG_UNAUTHORIZED_CLIENT, PS_MSG_RECONFIGURE_FAILED, PS_MSG_SET_STATEDUMP_PATH_ERROR, PS_MSG_INIT_GRP_CACHE_ERROR, PS_MSG_RPC_CONFIGURE_FAILED, PS_MSG_TRANSPORT_TYPE_NOT_SET, PS_MSG_GET_TOTAL_AVAIL_TRANSPORT_FAILED, PS_MSG_INVLAID_UPCALL_EVENT, PS_MSG_SERVER_CHILD_EVENT_FAILED, PS_MSG_SETACTIVELK_INFO, PS_MSG_GETACTIVELK_INFO, PS_MSG_WRONG_VALUE, PS_MSG_PASSWORD_NOT_FOUND, PS_MSG_REMOTE_SUBVOL_NOT_SPECIFIED, PS_MSG_NO_MEM); #define PS_MSG_SERIALIZE_REPLY_FAILED_STR "Failed to serialize reply" #define PS_MSG_AUTH_IP_ERROR_STR "assuming 'auth.ip' to be 'auth.addr'" #define PS_MSG_SKIP_FORMAT_CHK_STR "skip format check for non-addr auth option" #define PS_MSG_INTERNET_ADDR_ERROR_STR \ "internet address does not confirm to standards" #define PS_MSG_AUTHENTICATE_ERROR_STR \ "volume defined as subvolume, but no authentication defined for the same" #define PS_MSG_CLIENT_DISCONNECTING_STR "disconnecting connection" #define PS_MSG_DICT_GET_FAILED_STR "failed to get" #define PS_MSG_NO_MEMORY_STR "Memory accounting init failed" #define PS_MSG_INVALID_ENTRY_STR \ "'trace' takes on only boolean values. Neglecting option" #define PS_MSG_STATEDUMP_PATH_ERROR_STR \ "Error while reconfiguring statedump path" #define PS_MSG_GRP_CACHE_ERROR_STR "Failed to reconfigure group cache." #define PS_MSG_RPC_CONF_ERROR_STR "No rpc_conf !!!!" #define PS_MSG_CLIENT_ACCEPTED_STR \ "authorized client, hence we continue with this connection" #define PS_MSG_UNAUTHORIZED_CLIENT_STR \ "unauthorized client, hence terminating the connection" #define PS_MSG_RECONFIGURE_FAILED_STR \ "Failed to reconfigure outstanding-rpc-limit" #define PS_MSG_TRANSPORT_ERROR_STR "Reconfigure not found for transport" #define PS_MSG_SUBVOL_NULL_STR "protocol/server should have subvolume" #define PS_MSG_PARENT_VOL_ERROR_STR \ "protocol/server should not have parent volumes" #define PS_MSG_SET_STATEDUMP_PATH_ERROR_STR "Error setting statedump path" #define PS_MSG_INIT_GRP_CACHE_ERROR_STR "Failed to initialize group cache." #define PS_MSG_RPCSVC_CREATE_FAILED_STR "creation of rpcsvc failed" #define PS_MSG_RPC_CONFIGURE_FAILED_STR \ "Failed to configure outstanding-rpc-limit" #define PS_MSG_TRANSPORT_TYPE_NOT_SET_STR "option transport-type not set" #define PS_MSG_GET_TOTAL_AVAIL_TRANSPORT_FAILED_STR \ "failed to get total number of available tranpsorts" #define PS_MSG_RPCSVC_LISTENER_CREATE_FAILED_STR "creation of listener failed" #define PS_MSG_RPCSVC_NOTIFY_STR "registration of notify with rpcsvc failed" #define PS_MSG_PGM_REG_FAILED_STR "registration of program failed" #define PS_MSG_ULIMIT_SET_FAILED_STR "WARNING: Failed to set 'ulimit -n 1M'" #define PS_MSG_FD_NOT_FOUND_STR "Failed to set max open fd to 64k" #define PS_MSG_VOL_FILE_OPEN_FAILED_STR \ "volfile-id argument not given. This is mandatory argument, defaulting " \ "to 'gluster'" #define PS_MSG_INVLAID_UPCALL_EVENT_STR "Received invalid upcall event" #define PS_MSG_CHILD_STATUS_FAILED_STR "No xlator is found in child status list" #define PS_MSG_SERVER_EVENT_UPCALL_FAILED_STR \ "server_process_event_upcall failed" #define PS_MSG_SERVER_CHILD_EVENT_FAILED_STR "server_process_child_event failed" #define PS_MSG_STATFS_STR "STATFS" #define PS_MSG_LOOKUP_INFO_STR "LOOKUP info" #define PS_MSG_LK_INFO_STR "LEASE info" #define PS_MSG_INODELK_INFO_STR "INODELK info" #define PS_MSG_DIR_INFO_STR "MKDIR info" #define PS_MSG_MKNOD_INFO_STR "MKNOD info" #define PS_MSG_REMOVEXATTR_INFO_STR "REMOVEXATTR info" #define PS_MSG_GETXATTR_INFO_STR "GETXATTR info" #define PS_MSG_SETXATTR_INFO_STR "SETXATTR info" #define PS_MSG_RENAME_INFO_STR "RENAME inf" #define PS_MSG_LINK_INFO_STR "LINK info" #define PS_MSG_TRUNCATE_INFO_STR "TRUNCATE info" #define PS_MSG_STAT_INFO_STR "STAT info" #define PS_MSG_FLUSH_INFO_STR "FLUSH info" #define PS_MSG_SYNC_INFO_STR "SYNC info" #define PS_MSG_WRITE_INFO_STR "WRITE info" #define PS_MSG_READ_INFO_STR "READ info" #define PS_MSG_CHKSUM_INFO_STR "CHKSUM info" #define PS_MSG_OPEN_INFO_STR "OPEN info" #define PS_MSG_XATTROP_INFO_STR "XATTROP info" #define PS_MSG_ALLOC_INFO_STR "ALLOC info" #define PS_MSG_DISCARD_INFO_STR "DISCARD info" #define PS_MSG_ZEROFILL_INFO_STR "ZEROFILL info" #define PS_MSG_SERVER_IPC_INFO_STR "IPC info" #define PS_MSG_SEEK_INFO_STR "SEEK info" #define PS_MSG_SETACTIVELK_INFO_STR "SETACTIVELK info" #define PS_MSG_CREATE_INFO_STR "CREATE info" #define PS_MSG_PUT_INFO_STR "PUT info" #define PS_MSG_FD_CREATE_FAILED_STR "could not create the fd" #define PS_MSG_GETACTIVELK_INFO_STR "GETACTIVELK info" #define PS_MSG_ENTRYLK_INFO_STR "ENTRYLK info" #define PS_MSG_ACCESS_INFO_STR "ACCESS info" #define PS_MSG_SETATTR_INFO_STR "SETATTR info" #define PS_MSG_SERVER_CTX_GET_FAILED_STR "server_ctx_get() failed" #define PS_MSG_LOCK_ERROR_STR "Unknown lock type" #define PS_MSG_GET_UID_FAILED_STR "getpwuid_r failed" #define PS_MSG_UID_NOT_FOUND_STR "getpwuid_r found nothing" #define PS_MSG_MAPPING_ERROR_STR "could not map to group list" #define PS_MSG_FD_CLEANUP_STR "fd cleanup" #define PS_MSG_FDENTRY_NULL_STR "no fdentry to clean" #define PS_MSG_DIR_NOT_FOUND_STR "Directory doesnot exist" #define PS_MSG_CONF_DIR_INVALID_STR "invalid conf_dir" #define PS_MSG_SERVER_MSG_STR "server msg" #define PS_MSG_DICT_SERIALIZE_FAIL_STR "failed to serialize reply dict" #define PS_MSG_MOUNT_PT_FAIL_STR "mount point fail" #define PS_MSG_RW_STAT_STR "stat" #define PS_MSG_PASSWORD_NOT_FOUND_STR "password not found, returning DONT-CARE" #define PS_MSG_REMOTE_SUBVOL_NOT_SPECIFIED_STR "remote-subvolume not specified" #define PS_MSG_LOGIN_ERROR_STR "wrong password for user" #define PS_MSG_NO_MEM_STR "No memory" #endif /* !_PS_MESSAGES_H__ */ glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server-common.c0000644000000000000000000000013114522202451024751 xustar000000000000000030 mtime=1699284265.777027763 29 atime=1699284265.77602776 30 ctime=1699284301.911136598 glusterfs-11.1/xlators/protocol/server/src/server-common.c0000664000175100017510000002626314522202451025242 0ustar00jenkinsjenkins00000000000000#include "server.h" #include "glusterfs3.h" #include #include "server-messages.h" #include "server-helpers.h" #ifdef BUILD_GNFS #include "xdr-nfs3.h" #endif /* Version 4 helpers */ void server4_post_readlink(gfx_readlink_rsp *rsp, struct iatt *stbuf, const char *buf) { gfx_stat_from_iattx(&rsp->buf, stbuf); rsp->path = (char *)buf; } void server4_post_common_3iatt(server_state_t *state, gfx_common_3iatt_rsp *rsp, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent) { inode_t *link_inode = NULL; gfx_stat_from_iattx(&rsp->stat, stbuf); if (state->client->subdir_mount && !gf_uuid_compare(preparent->ia_gfid, state->client->subdir_gfid)) { /* This is very important as when we send iatt of root-inode, fuse/client expect the gfid to be 1, along with inode number. As for subdirectory mount, we use inode table which is shared by everyone, but make sure we send fops only from subdir and below, we have to alter inode gfid and send it to client */ static uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; preparent->ia_ino = 1; postparent->ia_ino = 1; gf_uuid_copy(preparent->ia_gfid, gfid); gf_uuid_copy(postparent->ia_gfid, gfid); } gfx_stat_from_iattx(&rsp->preparent, preparent); gfx_stat_from_iattx(&rsp->postparent, postparent); link_inode = inode_link(inode, state->loc.parent, state->loc.name, stbuf); inode_lookup(link_inode); inode_unref(link_inode); } void server4_post_common_3iatt_noinode(gfx_common_3iatt_rsp *rsp, struct iatt *stbuf, struct iatt *prebuf_dst, struct iatt *postbuf_dst) { gfx_stat_from_iattx(&rsp->stat, stbuf); gfx_stat_from_iattx(&rsp->preparent, prebuf_dst); gfx_stat_from_iattx(&rsp->postparent, postbuf_dst); } void server4_post_common_2iatt(gfx_common_2iatt_rsp *rsp, struct iatt *prebuf, struct iatt *postbuf) { gfx_stat_from_iattx(&rsp->prestat, prebuf); gfx_stat_from_iattx(&rsp->poststat, postbuf); } void server4_post_entry_remove(server_state_t *state, gfx_common_2iatt_rsp *rsp, struct iatt *prebuf, struct iatt *postbuf) { inode_unlink(state->loc.inode, state->loc.parent, state->loc.name); /* parent should not be found for directories after * inode_unlink, since directories cannot have * hardlinks. */ forget_inode_if_no_dentry(state->loc.inode); gfx_stat_from_iattx(&rsp->prestat, prebuf); gfx_stat_from_iattx(&rsp->poststat, postbuf); } void server4_post_statfs(gfx_statfs_rsp *rsp, struct statvfs *stbuf) { gf_statfs_from_statfs(&rsp->statfs, stbuf); } void server4_post_common_iatt(server_state_t *state, gfx_common_iatt_rsp *rsp, struct iatt *stbuf) { if (state->client->subdir_mount && !gf_uuid_compare(stbuf->ia_gfid, state->client->subdir_gfid)) { /* This is very important as when we send iatt of root-inode, fuse/client expect the gfid to be 1, along with inode number. As for subdirectory mount, we use inode table which is shared by everyone, but make sure we send fops only from subdir and below, we have to alter inode gfid and send it to client */ static uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; stbuf->ia_ino = 1; gf_uuid_copy(stbuf->ia_gfid, gfid); } gfx_stat_from_iattx(&rsp->stat, stbuf); } void server4_post_lk(xlator_t *this, gfx_lk_rsp *rsp, struct gf_flock *lock) { switch (lock->l_type) { case F_RDLCK: lock->l_type = GF_LK_F_RDLCK; break; case F_WRLCK: lock->l_type = GF_LK_F_WRLCK; break; case F_UNLCK: lock->l_type = GF_LK_F_UNLCK; break; default: gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR, "Unknown lock type: %" PRId32 "!", lock->l_type); break; } gf_proto_flock_from_flock(&rsp->flock, lock); } int server4_post_readdir(gfx_readdir_rsp *rsp, gf_dirent_t *entries) { int ret = 0; ret = serialize_rsp_dirent_v2(entries, rsp); return ret; } void server4_post_seek(gfx_seek_rsp *rsp, off_t offset) { rsp->offset = offset; } int server4_post_readdirp(gfx_readdirp_rsp *rsp, gf_dirent_t *entries) { int ret = 0; ret = serialize_rsp_direntp_v2(entries, rsp); return ret; } void server4_post_rchecksum(gfx_rchecksum_rsp *rsp, uint32_t weak_checksum, uint8_t *strong_checksum) { rsp->weak_checksum = weak_checksum; /* When the length encoding changes, update the change in posix code also. */ rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum; rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH; rsp->flags = 1; /* Indicates SHA256 TYPE */ } void server4_post_rename(call_frame_t *frame, server_state_t *state, gfx_rename_rsp *rsp, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent) { inode_t *tmp_inode = NULL; stbuf->ia_type = state->loc.inode->ia_type; /* TODO: log gfid of the inodes */ gf_msg_trace(frame->root->client->bound_xl->name, 0, "%" PRId64 ": " "RENAME_CBK %s ==> %s", frame->root->unique, state->loc.name, state->loc2.name); /* Before renaming the inode, we have to get the inode for the * destination entry (i.e. inode with state->loc2.parent as * parent and state->loc2.name as name). If it exists, then * unlink that inode, and send forget on that inode if the * unlinked entry is the last entry. In case of fuse client * the fuse kernel module itself sends the forget on the * unlinked inode. */ tmp_inode = inode_grep(state->loc.inode->table, state->loc2.parent, state->loc2.name); if (tmp_inode) { inode_unlink(tmp_inode, state->loc2.parent, state->loc2.name); forget_inode_if_no_dentry(tmp_inode); inode_unref(tmp_inode); } inode_rename(state->itable, state->loc.parent, state->loc.name, state->loc2.parent, state->loc2.name, state->loc.inode, stbuf); gfx_stat_from_iattx(&rsp->stat, stbuf); gfx_stat_from_iattx(&rsp->preoldparent, preoldparent); gfx_stat_from_iattx(&rsp->postoldparent, postoldparent); gfx_stat_from_iattx(&rsp->prenewparent, prenewparent); gfx_stat_from_iattx(&rsp->postnewparent, postnewparent); } int server4_post_open(call_frame_t *frame, xlator_t *this, gfx_open_rsp *rsp, fd_t *fd) { server_ctx_t *serv_ctx = NULL; uint64_t fd_no = 0; serv_ctx = server_ctx_get(frame->root->client, this); if (serv_ctx == NULL) { gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " "failed"); return -1; } fd_bind(fd); fd_ref(fd); fd_no = gf_fd_unused_get(serv_ctx->fdtable, fd); rsp->fd = fd_no; return 0; } void server4_post_readv(gfx_read_rsp *rsp, struct iatt *stbuf, int op_ret) { gfx_stat_from_iattx(&rsp->stat, stbuf); rsp->size = op_ret; } int server4_post_create(call_frame_t *frame, gfx_create_rsp *rsp, server_state_t *state, xlator_t *this, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent) { server_ctx_t *serv_ctx = NULL; inode_t *link_inode = NULL; uint64_t fd_no = 0; int op_errno = 0; link_inode = inode_link(inode, state->loc.parent, state->loc.name, stbuf); if (!link_inode) { op_errno = ENOENT; goto out; } if (link_inode != inode) { /* VERY racy code (if used anywhere else) -- don't do this without understanding */ inode_ctx_merge(fd, fd->inode, link_inode); inode_unref(fd->inode); fd->inode = inode_ref(link_inode); } inode_lookup(link_inode); inode_unref(link_inode); serv_ctx = server_ctx_get(frame->root->client, this); if (serv_ctx == NULL) { gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " "failed"); goto out; } fd_bind(fd); fd_ref(fd); fd_no = gf_fd_unused_get(serv_ctx->fdtable, fd); if ((fd_no > UINT64_MAX) || (fd == 0)) { op_errno = errno; } rsp->fd = fd_no; gfx_stat_from_iattx(&rsp->stat, stbuf); gfx_stat_from_iattx(&rsp->preparent, preparent); gfx_stat_from_iattx(&rsp->postparent, postparent); return 0; out: return -op_errno; } /*TODO: Handle revalidate path */ void server4_post_lookup(gfx_common_2iatt_rsp *rsp, call_frame_t *frame, server_state_t *state, inode_t *inode, struct iatt *stbuf, dict_t *xdata) { inode_t *root_inode = NULL; inode_t *link_inode = NULL; static uuid_t rootgfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; root_inode = frame->root->client->bound_xl->itable->root; if (!__is_root_gfid(inode->gfid)) { link_inode = inode_link(inode, state->loc.parent, state->loc.name, stbuf); if (link_inode) { if (dict_get_sizen(xdata, GF_NAMESPACE_KEY)) { inode_set_namespace_inode(link_inode, link_inode); } inode_lookup(link_inode); inode_unref(link_inode); } } if ((inode == root_inode) || (state->client->subdir_mount && (inode == state->client->subdir_inode))) { /* we just looked up root ("/") OR subdir mount directory, which is root ('/') in client */ /* This is very important as when we send iatt of root-inode, fuse/client expect the gfid to be 1, along with inode number. As for subdirectory mount, we use inode table which is shared by everyone, but make sure we send fops only from subdir and below, we have to alter inode gfid and send it to client */ stbuf->ia_ino = 1; gf_uuid_copy(stbuf->ia_gfid, rootgfid); if (inode->ia_type == 0) inode->ia_type = stbuf->ia_type; } gfx_stat_from_iattx(&rsp->prestat, stbuf); } void server4_post_lease(gfx_lease_rsp *rsp, struct gf_lease *lease) { gf_proto_lease_from_lease(&rsp->lease, lease); } void server4_post_link(server_state_t *state, gfx_common_3iatt_rsp *rsp, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent) { inode_t *link_inode = NULL; gfx_stat_from_iattx(&rsp->stat, stbuf); gfx_stat_from_iattx(&rsp->preparent, preparent); gfx_stat_from_iattx(&rsp->postparent, postparent); link_inode = inode_link(inode, state->loc2.parent, state->loc2.name, stbuf); inode_lookup(link_inode); inode_unref(link_inode); } glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467024066 xustar000000000000000030 mtime=1699284279.613069438 30 atime=1699284290.020100784 30 ctime=1699284301.893136544 glusterfs-11.1/xlators/protocol/server/src/Makefile.in0000664000175100017510000006407714522202467024363 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol/server/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(server_la_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" "$(DESTDIR)$(server_ladir)" LTLIBRARIES = $(xlator_LTLIBRARIES) am__DEPENDENCIES_1 = server_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la $(am__DEPENDENCIES_1) am_server_la_OBJECTS = server.lo server-resolve.lo server-helpers.lo \ server-handshake.lo authenticate.lo server-common.lo \ server-rpc-fops_v2.lo server_la_OBJECTS = $(am_server_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = server_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(server_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_server_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(server_la_SOURCES) DIST_SOURCES = $(server_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(server_la_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = server.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol server_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la $(LIB_DL) server_la_SOURCES = server.c server-resolve.c server-helpers.c \ server-handshake.c authenticate.c server-common.c \ server-rpc-fops_v2.c server_la_HEADERS = server.h server-helpers.h server-mem-types.h \ authenticate.h server-messages.h server-common.h server_ladir = $(includedir)/glusterfs/server AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -DCONFDIR=\"$(sysconfdir)/glusterfs\" \ -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \ -I$(top_srcdir)/rpc/rpc-transport/socket/src \ -I$(top_srcdir)/xlators/protocol/lib/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/glusterfsd/src AM_CFLAGS = -Wall $(GF_CFLAGS) \ -DDATADIR=\"$(localstatedir)\" CLEANFILES = *~ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/server/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/server/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } server.la: $(server_la_OBJECTS) $(server_la_DEPENDENCIES) $(EXTRA_server_la_DEPENDENCIES) $(AM_V_CCLD)$(server_la_LINK) $(am_server_la_rpath) $(server_la_OBJECTS) $(server_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/authenticate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server-handshake.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server-resolve.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server-rpc-fops_v2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-server_laHEADERS: $(server_la_HEADERS) @$(NORMAL_INSTALL) @list='$(server_la_HEADERS)'; test -n "$(server_ladir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(server_ladir)'"; \ $(MKDIR_P) "$(DESTDIR)$(server_ladir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(server_ladir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(server_ladir)" || exit $$?; \ done uninstall-server_laHEADERS: @$(NORMAL_UNINSTALL) @list='$(server_la_HEADERS)'; test -n "$(server_ladir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(server_ladir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)" "$(DESTDIR)$(server_ladir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-server_laHEADERS install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-server_laHEADERS uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-server_laHEADERS \ install-strip install-xlatorLTLIBRARIES installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-server_laHEADERS \ uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server-helpers.c0000644000000000000000000000013214522202451025124 xustar000000000000000030 mtime=1699284265.778027766 30 atime=1699284265.777027763 30 ctime=1699284301.907136586 glusterfs-11.1/xlators/protocol/server/src/server-helpers.c0000664000175100017510000010070414522202451025405 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "server.h" #include "server-helpers.h" #include "server-messages.h" #include #include #include "server-common.h" #include #include /* based on nfs_fix_aux_groups() */ static int gid_resolve(server_conf_t *conf, call_stack_t *root) { int ret = 0; struct passwd mypw; char mystrs[1024]; struct passwd *result; gid_t *mygroups = NULL; gid_list_t gl; int ngroups; const gid_list_t *agl; agl = gid_cache_lookup(&conf->gid_cache, root->uid, 0, 0); if (agl) { root->ngrps = agl->gl_count; if (root->ngrps > 0) { ret = call_stack_alloc_groups(root, agl->gl_count); if (ret == 0) { memcpy(root->groups, agl->gl_list, sizeof(gid_t) * agl->gl_count); } } gid_cache_release(&conf->gid_cache, agl); return ret; } ret = getpwuid_r(root->uid, &mypw, mystrs, sizeof(mystrs), &result); if (ret != 0) { gf_smsg("gid-cache", GF_LOG_ERROR, errno, PS_MSG_GET_UID_FAILED, "uid=%u", root->uid, NULL); return -1; } if (!result) { gf_smsg("gid-cache", GF_LOG_ERROR, 0, PS_MSG_UID_NOT_FOUND, "uid=%u", root->uid, NULL); return -1; } gf_msg_trace("gid-cache", 0, "mapped %u => %s", root->uid, result->pw_name); ngroups = gf_getgrouplist(result->pw_name, root->gid, &mygroups); if (ngroups == -1) { gf_smsg("gid-cache", GF_LOG_ERROR, 0, PS_MSG_MAPPING_ERROR, "pw_name=%s", result->pw_name, "root->ngtps=%d", root->ngrps, NULL); return -1; } root->ngrps = (uint16_t)ngroups; /* setup a full gid_list_t to add it to the gid_cache */ gl.gl_id = root->uid; gl.gl_uid = root->uid; gl.gl_gid = root->gid; gl.gl_count = root->ngrps; gl.gl_list = GF_MALLOC(root->ngrps * sizeof(gid_t), gf_common_mt_groups_t); if (gl.gl_list) memcpy(gl.gl_list, mygroups, sizeof(gid_t) * root->ngrps); else { GF_FREE(mygroups); return -1; } if (root->ngrps > 0) { call_stack_set_groups(root, root->ngrps, &mygroups); } if (gid_cache_add(&conf->gid_cache, &gl) != 1) GF_FREE(gl.gl_list); return ret; } static int server_decode_groups(call_frame_t *frame, rpcsvc_request_t *req) { int i = 0; if (call_stack_alloc_groups(frame->root, req->auxgidcount) != 0) return -1; frame->root->ngrps = req->auxgidcount; if (frame->root->ngrps == 0) return 0; /* ngrps cannot be bigger than USHRT_MAX(65535) */ if (frame->root->ngrps > GF_MAX_AUX_GROUPS) return -1; for (; i < frame->root->ngrps; ++i) frame->root->groups[i] = req->auxgids[i]; return 0; } void server_resolve_wipe(server_resolve_t *resolve) { GF_FREE((void *)resolve->path); GF_FREE((void *)resolve->bname); loc_wipe(&resolve->resolve_loc); } void free_state(server_state_t *state) { if (state->fd) { fd_unref(state->fd); state->fd = NULL; } if (state->params) { dict_unref(state->params); state->params = NULL; } if (state->iobref) { iobref_unref(state->iobref); state->iobref = NULL; } if (state->dict) { dict_unref(state->dict); state->dict = NULL; } if (state->xdata) { dict_unref(state->xdata); state->xdata = NULL; } GF_FREE((void *)state->volume); GF_FREE((void *)state->name); loc_wipe(&state->loc); loc_wipe(&state->loc2); server_resolve_wipe(&state->resolve); server_resolve_wipe(&state->resolve2); /* Call rpc_trnasport_unref to avoid crashes at last after free all resources because of server_rpc_notify (for transport destroy) call's xlator_mem_cleanup if all xprt are destroyed that internally call's inode_table_destroy. */ if (state->xprt) { rpc_transport_unref(state->xprt); state->xprt = NULL; } GF_FREE(state); } static int server_connection_cleanup_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { int32_t ret = -1; fd_t *fd = NULL; client_t *client = NULL; uint64_t fd_cnt = 0; xlator_t *victim = NULL; server_conf_t *conf = NULL; xlator_t *serv_xl = NULL; rpc_transport_t *xprt = NULL; rpc_transport_t *xp_next = NULL; int32_t detach = (long)cookie; gf_boolean_t xprt_found = _gf_false; GF_VALIDATE_OR_GOTO("server", this, out); GF_VALIDATE_OR_GOTO("server", frame, out); fd = frame->local; client = frame->root->client; serv_xl = frame->this; conf = serv_xl->private; fd_unref(fd); frame->local = NULL; if (client) victim = client->bound_xl; if (victim) { fd_cnt = GF_ATOMIC_DEC(client->fd_cnt); if (!fd_cnt && conf && detach) { pthread_mutex_lock(&conf->mutex); { list_for_each_entry_safe(xprt, xp_next, &conf->xprt_list, list) { if (!xprt->xl_private) continue; if (xprt->xl_private == client) { xprt_found = _gf_true; break; } } } pthread_mutex_unlock(&conf->mutex); if (xprt_found) { rpc_transport_unref(xprt); } } } gf_client_unref(client); STACK_DESTROY(frame->root); ret = 0; out: return ret; } static int do_fd_cleanup(xlator_t *this, client_t *client, fdentry_t *fdentries, int fd_count, int32_t detach) { fd_t *fd = NULL; int i = 0, ret = -1; call_frame_t *tmp_frame = NULL; xlator_t *bound_xl = NULL; char *path = NULL; GF_VALIDATE_OR_GOTO("server", this, out); GF_VALIDATE_OR_GOTO("server", fdentries, out); bound_xl = client->bound_xl; for (i = 0; i < fd_count; i++) { fd = fdentries[i].fd; if (fd != NULL) { tmp_frame = create_frame(this, this->ctx->pool); if (tmp_frame == NULL) { goto out; } tmp_frame->root->type = GF_OP_TYPE_FOP; GF_ASSERT(fd->inode); ret = inode_path(fd->inode, NULL, &path); if (ret > 0) { gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_FD_CLEANUP, "path=%s", path, NULL); GF_FREE(path); } else { gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_FD_CLEANUP, "inode-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); } tmp_frame->local = fd; tmp_frame->root->pid = 0; gf_client_ref(client); tmp_frame->root->client = client; memset(&tmp_frame->root->lk_owner, 0, sizeof(gf_lkowner_t)); STACK_WIND_COOKIE(tmp_frame, server_connection_cleanup_flush_cbk, (void *)(long)detach, bound_xl, bound_xl->fops->flush, fd, NULL); } } GF_FREE(fdentries); ret = 0; out: return ret; } int server_connection_cleanup(xlator_t *this, client_t *client, int32_t flags, gf_boolean_t *fd_exist) { server_ctx_t *serv_ctx = NULL; fdentry_t *fdentries = NULL; uint32_t fd_count = 0; int cd_ret = 0; int ret = 0; xlator_t *bound_xl = NULL; int i = 0; fd_t *fd = NULL; uint64_t fd_cnt = 0; int32_t detach = 0; GF_VALIDATE_OR_GOTO("server", this, out); GF_VALIDATE_OR_GOTO(this->name, client, out); GF_VALIDATE_OR_GOTO(this->name, flags, out); serv_ctx = server_ctx_get(client, client->this); if (serv_ctx == NULL) { gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED, NULL); goto out; } LOCK(&serv_ctx->fdtable_lock); { if (serv_ctx->fdtable && (flags & POSIX_LOCKS)) fdentries = gf_fd_fdtable_get_all_fds(serv_ctx->fdtable, &fd_count); } UNLOCK(&serv_ctx->fdtable_lock); if (client->bound_xl == NULL) goto out; if (flags & INTERNAL_LOCKS) { cd_ret = gf_client_disconnect(client); } if (fdentries != NULL) { /* Loop to configure fd_count on victim brick */ bound_xl = client->bound_xl; if (bound_xl) { for (i = 0; i < fd_count; i++) { fd = fdentries[i].fd; if (!fd) continue; fd_cnt++; } if (fd_cnt) { if (fd_exist) (*fd_exist) = _gf_true; GF_ATOMIC_ADD(client->fd_cnt, fd_cnt); } } /* If fd_exist is not NULL it means function is invoke by server_rpc_notify at the time of getting DISCONNECT notification */ if (fd_exist) detach = 1; gf_msg_debug(this->name, 0, "Performing cleanup on %d " "fdentries", fd_count); ret = do_fd_cleanup(this, client, fdentries, fd_count, detach); } else gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_FDENTRY_NULL, NULL); if (cd_ret || ret) ret = -1; out: return ret; } static call_frame_t * server_alloc_frame(rpcsvc_request_t *req, client_t *client) { call_frame_t *frame = NULL; server_state_t *state = NULL; frame = create_frame(client->this, req->svc->ctx->pool); if (!frame) goto out; state = GF_CALLOC(1, sizeof(*state), gf_server_mt_state_t); if (caa_unlikely(!state)) { STACK_DESTROY(frame->root); frame = NULL; goto out; } if (client->bound_xl) state->itable = client->bound_xl->itable; state->xprt = rpc_transport_ref(req->trans); state->resolve.fd_no = -1; state->resolve2.fd_no = -1; frame->root->state = state; /* which socket */ frame->root->type = GF_OP_TYPE_FOP; frame->this = client->this; out: return frame; } call_frame_t * get_frame_from_request(rpcsvc_request_t *req) { call_frame_t *frame = NULL; client_t *client = NULL; client_t *tmp_client = NULL; xlator_t *this = NULL; server_conf_t *priv = NULL; clienttable_t *clienttable = NULL; unsigned int i = 0; rpc_transport_t *trans = NULL; server_state_t *state = NULL; GF_VALIDATE_OR_GOTO("server", req, out); trans = req->trans; GF_VALIDATE_OR_GOTO("server", trans, out); GF_VALIDATE_OR_GOTO("server", req->svc, out); GF_VALIDATE_OR_GOTO("server", req->svc->ctx, out); client = trans->xl_private; GF_VALIDATE_OR_GOTO("server", client, out); frame = server_alloc_frame(req, client); if (!frame) goto out; frame->root->op = req->procnum; this = trans->xl; priv = this->private; clienttable = this->ctx->clienttable; for (i = 0; i < clienttable->max_clients; i++) { tmp_client = clienttable->cliententries[i].client; if (client == tmp_client) { /* For nfs clients the server processes will be running within the trusted storage pool machines. So if we do not do root-squashing and all-squashing for nfs servers, thinking that its a trusted client, then root-squashing and all-squashing won't work for nfs clients. */ if (req->pid == NFS_PID) { RPC_AUTH_ROOT_SQUASH(req); RPC_AUTH_ALL_SQUASH(req); goto after_squash; } /* for non trusted clients username and password would not have been set. So for non trusted clients (i.e clients not from the same machine as the brick, and clients from outside the storage pool) do the root-squashing and all-squashing. TODO: If any client within the storage pool (i.e mounting within a machine from the pool but using other machine's ip/hostname from the same pool) is present treat it as a trusted client */ else if (!client->auth.username) { RPC_AUTH_ROOT_SQUASH(req); RPC_AUTH_ALL_SQUASH(req); goto after_squash; } /* Problem: If we just check whether the client is trusted client and do not do root squashing and all squashing for them, then for smb clients and UFO clients root squashing and all squashing will never happen as they use the fuse mounts done within the trusted pool (i.e they are trusted clients). Solution: To fix it, do root squashing and all squashing for trusted clients also. If one wants to have a client within the storage pool for which root-squashing does not happen, then the client has to be mounted with --no-root-squash option. But for defrag client and gsyncd client do not do root-squashing and all-squashing. */ else if (req->pid != GF_CLIENT_PID_NO_ROOT_SQUASH && req->pid != GF_CLIENT_PID_GSYNCD && req->pid != GF_CLIENT_PID_DEFRAG && req->pid != GF_CLIENT_PID_SELF_HEALD && req->pid != GF_CLIENT_PID_QUOTA_MOUNT) { RPC_AUTH_ROOT_SQUASH(req); RPC_AUTH_ALL_SQUASH(req); goto after_squash; } } } after_squash: /* Add a ref for this fop */ gf_client_ref(client); frame->root->uid = req->uid; frame->root->gid = req->gid; frame->root->pid = req->pid; frame->root->client = client; lk_owner_copy(&frame->root->lk_owner, &req->lk_owner); if (priv->server_manage_gids) gid_resolve(priv, frame->root); else server_decode_groups(frame, req); memcpy(&frame->root->identifier, trans->peerinfo.identifier, UNIX_PATH_MAX); /* more fields, for the clients which are 3.x series this will be 0 */ frame->root->flags = req->flags; frame->root->ctime = req->ctime; frame->local = req; state = CALL_STATE(frame); state->client = client; out: return frame; } int server_build_config(xlator_t *this, server_conf_t *conf) { data_t *data = NULL; int ret = -1; struct stat buf = { 0, }; GF_VALIDATE_OR_GOTO("server", this, out); GF_VALIDATE_OR_GOTO("server", conf, out); ret = dict_get_int32(this->options, "inode-lru-limit", &conf->inode_lru_limit); if (ret < 0) { conf->inode_lru_limit = 16384; } data = dict_get(this->options, "trace"); if (data) { ret = gf_string2boolean(data->data, &conf->trace); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_INVALID_ENTRY, NULL); } } data = dict_get(this->options, "config-directory"); if (data) { /* Check whether the specified directory exists, or directory specified is non standard */ ret = sys_stat(data->data, &buf); if ((ret != 0) || !S_ISDIR(buf.st_mode)) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_DIR_NOT_FOUND, "data=%s", data->data, NULL); ret = -1; goto out; } /* Make sure that conf-dir doesn't contain ".." in path */ if ((gf_strstr(data->data, "/", "..")) == -1) { ret = -1; gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_CONF_DIR_INVALID, "data=%s", data->data, NULL); goto out; } conf->conf_dir = gf_strdup(data->data); } ret = 0; out: return ret; } void print_caller(char *str, int size, call_frame_t *frame) { server_state_t *state = NULL; GF_VALIDATE_OR_GOTO("server", str, out); GF_VALIDATE_OR_GOTO("server", frame, out); state = CALL_STATE(frame); snprintf(str, size, " Callid=%" PRId64 ", Client=%s", frame->root->unique, state->xprt->peerinfo.identifier); out: return; } void server_print_resolve(char *str, int size, server_resolve_t *resolve) { int filled = 0; GF_VALIDATE_OR_GOTO("server", str, out); if (!resolve) { snprintf(str, size, ""); return; } filled += snprintf(str + filled, size - filled, " Resolve={"); if (resolve->fd_no != -1) filled += snprintf(str + filled, size - filled, "fd=%" PRId64 ",", (uint64_t)resolve->fd_no); if (resolve->bname) filled += snprintf(str + filled, size - filled, "bname=%s,", resolve->bname); if (resolve->path) filled += snprintf(str + filled, size - filled, "path=%s", resolve->path); snprintf(str + filled, size - filled, "}"); out: return; } void server_print_loc(char *str, int size, loc_t *loc) { int filled = 0; GF_VALIDATE_OR_GOTO("server", str, out); if (!loc) { snprintf(str, size, ""); return; } filled += snprintf(str + filled, size - filled, " Loc={"); if (loc->path) filled += snprintf(str + filled, size - filled, "path=%s,", loc->path); if (loc->inode) filled += snprintf(str + filled, size - filled, "inode=%p,", loc->inode); if (loc->parent) filled += snprintf(str + filled, size - filled, "parent=%p", loc->parent); snprintf(str + filled, size - filled, "}"); out: return; } void server_print_params(char *str, int size, server_state_t *state) { int filled = 0; GF_VALIDATE_OR_GOTO("server", str, out); filled += snprintf(str + filled, size - filled, " Params={"); if (state->fd) filled += snprintf(str + filled, size - filled, "fd=%p,", state->fd); if (state->valid) filled += snprintf(str + filled, size - filled, "valid=%d,", state->valid); if (state->flags) filled += snprintf(str + filled, size - filled, "flags=%d,", state->flags); if (state->size) filled += snprintf(str + filled, size - filled, "size=%zu,", state->size); if (state->offset) filled += snprintf(str + filled, size - filled, "offset=%" PRId64 ",", state->offset); if (state->cmd) filled += snprintf(str + filled, size - filled, "cmd=%d,", state->cmd); if (state->type) filled += snprintf(str + filled, size - filled, "type=%d,", state->type); if (state->name) filled += snprintf(str + filled, size - filled, "name=%s,", state->name); if (state->mask) filled += snprintf(str + filled, size - filled, "mask=%d,", state->mask); if (state->volume) filled += snprintf(str + filled, size - filled, "volume=%s,", state->volume); /* FIXME snprintf (str + filled, size - filled, "bound_xl=%s}", state->client->bound_xl->name); */ out: return; } int server_resolve_is_empty(server_resolve_t *resolve) { if (resolve->fd_no != -1) return 0; if (resolve->path != 0) return 0; if (resolve->bname != 0) return 0; return 1; } void server_print_reply(call_frame_t *frame, int op_ret, int op_errno) { server_conf_t *conf = NULL; server_state_t *state = NULL; xlator_t *this = NULL; char caller[512]; char fdstr[32]; char *op = "UNKNOWN"; GF_VALIDATE_OR_GOTO("server", frame, out); this = frame->this; conf = this->private; GF_VALIDATE_OR_GOTO("server", conf, out); GF_VALIDATE_OR_GOTO("server", conf->trace, out); state = CALL_STATE(frame); print_caller(caller, 256, frame); switch (frame->root->type) { case GF_OP_TYPE_FOP: op = (char *)gf_fop_list[frame->root->op]; break; default: op = ""; } fdstr[0] = '\0'; if (state->fd) snprintf(fdstr, 32, " fd=%p", state->fd); gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SERVER_MSG, "op=%s", op, "caller=%s", caller, "op_ret=%d", op_ret, "op_errno=%d", op_errno, "fdstr=%s", fdstr, NULL); out: return; } void server_print_request(call_frame_t *frame) { server_conf_t *conf = NULL; xlator_t *this = NULL; server_state_t *state = NULL; char *op = "UNKNOWN"; char resolve_vars[256]; char resolve2_vars[256]; char loc_vars[256]; char loc2_vars[256]; char other_vars[512]; char caller[512]; GF_VALIDATE_OR_GOTO("server", frame, out); this = frame->this; conf = this->private; GF_VALIDATE_OR_GOTO("server", conf, out); if (!conf->trace) goto out; state = CALL_STATE(frame); memset(resolve_vars, '\0', 256); memset(resolve2_vars, '\0', 256); memset(loc_vars, '\0', 256); memset(loc2_vars, '\0', 256); memset(other_vars, '\0', 256); print_caller(caller, 256, frame); if (!server_resolve_is_empty(&state->resolve)) { server_print_resolve(resolve_vars, 256, &state->resolve); server_print_loc(loc_vars, 256, &state->loc); } if (!server_resolve_is_empty(&state->resolve2)) { server_print_resolve(resolve2_vars, 256, &state->resolve2); server_print_loc(loc2_vars, 256, &state->loc2); } server_print_params(other_vars, 512, state); switch (frame->root->type) { case GF_OP_TYPE_FOP: op = (char *)gf_fop_list[frame->root->op]; break; default: op = ""; break; } gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_MSG, "op=%s", op, "caller=%s", caller, "resolve_vars=%s", resolve_vars, "loc_vars=%s", loc_vars, "resolve2_vars=%s", resolve2_vars, "loc2_vars=%s", loc2_vars, "other_vars=%s", other_vars, NULL); out: return; } int serialize_rsp_direntp_v2(gf_dirent_t *entries, gfx_readdirp_rsp *rsp) { gf_dirent_t *entry = NULL; gfx_dirplist *trav = NULL; gfx_dirplist *prev = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("server", entries, out); GF_VALIDATE_OR_GOTO("server", rsp, out); list_for_each_entry(entry, &entries->list, list) { trav = GF_CALLOC(1, sizeof(*trav), gf_server_mt_dirent_rsp_t); if (!trav) goto out; trav->d_ino = entry->d_ino; trav->d_off = entry->d_off; trav->d_len = entry->d_len; trav->d_type = entry->d_type; trav->name = entry->d_name; gfx_stat_from_iattx(&trav->stat, &entry->d_stat); dict_to_xdr(entry->dict, &trav->dict); if (prev) prev->nextentry = trav; else rsp->reply = trav; prev = trav; trav = NULL; } ret = 0; out: GF_FREE(trav); return ret; } int serialize_rsp_dirent_v2(gf_dirent_t *entries, gfx_readdir_rsp *rsp) { gf_dirent_t *entry = NULL; gfx_dirlist *trav = NULL; gfx_dirlist *prev = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("server", rsp, out); GF_VALIDATE_OR_GOTO("server", entries, out); list_for_each_entry(entry, &entries->list, list) { trav = GF_CALLOC(1, sizeof(*trav), gf_server_mt_dirent_rsp_t); if (!trav) goto out; trav->d_ino = entry->d_ino; trav->d_off = entry->d_off; trav->d_len = entry->d_len; trav->d_type = entry->d_type; trav->name = entry->d_name; if (prev) prev->nextentry = trav; else rsp->reply = trav; prev = trav; } ret = 0; out: return ret; } int readdir_rsp_cleanup_v2(gfx_readdir_rsp *rsp) { gfx_dirlist *prev = NULL; gfx_dirlist *trav = NULL; trav = rsp->reply; prev = trav; while (trav) { trav = trav->nextentry; GF_FREE(prev); prev = trav; } return 0; } int readdirp_rsp_cleanup_v2(gfx_readdirp_rsp *rsp) { gfx_dirplist *prev = NULL; gfx_dirplist *trav = NULL; trav = rsp->reply; prev = trav; while (trav) { trav = trav->nextentry; GF_FREE(prev->dict.pairs.pairs_val); GF_FREE(prev); prev = trav; } return 0; } static int common_rsp_locklist(lock_migration_info_t *locklist, gfs3_locklist **reply) { lock_migration_info_t *tmp = NULL; gfs3_locklist *trav = NULL; gfs3_locklist *prev = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("server", locklist, out); list_for_each_entry(tmp, &locklist->list, list) { /* TODO: move to GF_MALLOC() */ trav = GF_CALLOC(1, sizeof(*trav), gf_server_mt_lock_mig_t); if (!trav) goto out; switch (tmp->flock.l_type) { case F_RDLCK: tmp->flock.l_type = GF_LK_F_RDLCK; break; case F_WRLCK: tmp->flock.l_type = GF_LK_F_WRLCK; break; case F_UNLCK: tmp->flock.l_type = GF_LK_F_UNLCK; break; default: gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR, "lock_type=%" PRId32, tmp->flock.l_type, NULL); break; } gf_proto_flock_from_flock(&trav->flock, &tmp->flock); trav->lk_flags = tmp->lk_flags; trav->client_uid = tmp->client_uid; if (prev) prev->nextentry = trav; else *reply = trav; prev = trav; trav = NULL; } ret = 0; out: GF_FREE(trav); return ret; } int serialize_rsp_locklist_v2(lock_migration_info_t *locklist, gfx_getactivelk_rsp *rsp) { int ret = 0; GF_VALIDATE_OR_GOTO("server", rsp, out); ret = common_rsp_locklist(locklist, &rsp->reply); out: return ret; } int getactivelkinfo_rsp_cleanup_v2(gfx_getactivelk_rsp *rsp) { gfs3_locklist *prev = NULL; gfs3_locklist *trav = NULL; trav = rsp->reply; prev = trav; while (trav) { trav = trav->nextentry; GF_FREE(prev); prev = trav; } return 0; } int gf_server_check_getxattr_cmd(call_frame_t *frame, const char *key) { server_conf_t *conf = NULL; rpc_transport_t *xprt = NULL; conf = frame->this->private; if (!conf) return 0; if (fnmatch("*list*mount*point*", key, 0) == 0) { /* list all the client protocol connecting to this process */ pthread_mutex_lock(&conf->mutex); { list_for_each_entry(xprt, &conf->xprt_list, list) { gf_smsg("mount-point-list", GF_LOG_INFO, 0, PS_MSG_MOUNT_PT_FAIL, "identifier=%s", xprt->peerinfo.identifier, NULL); } } pthread_mutex_unlock(&conf->mutex); } /* Add more options/keys here */ return 0; } int gf_server_check_setxattr_cmd(call_frame_t *frame, dict_t *dict) { server_conf_t *conf = NULL; rpc_transport_t *xprt = NULL; uint64_t total_read = 0; uint64_t total_write = 0; conf = frame->this->private; if (!conf || !dict) return 0; if (dict_foreach_fnmatch(dict, "*io*stat*dump", dict_null_foreach_fn, NULL) > 0) { list_for_each_entry(xprt, &conf->xprt_list, list) { total_read += xprt->total_bytes_read; total_write += xprt->total_bytes_write; } gf_smsg("stats", GF_LOG_INFO, 0, PS_MSG_RW_STAT, "total-read=%" PRIu64, total_read, "total-write=%" PRIu64, total_write, NULL); } return 0; } server_ctx_t * server_ctx_get(client_t *client, xlator_t *xlator) { void *tmp = NULL; server_ctx_t *ctx = NULL; server_ctx_t *setted_ctx = NULL; tmp = client_ctx_get(client, xlator); ctx = tmp; if (ctx != NULL) goto out; ctx = GF_CALLOC(1, sizeof(server_ctx_t), gf_server_mt_server_conf_t); if (ctx == NULL) goto out; ctx->fdtable = gf_fd_fdtable_alloc(); if (ctx->fdtable == NULL) { GF_FREE(ctx); ctx = NULL; goto out; } LOCK_INIT(&ctx->fdtable_lock); setted_ctx = client_ctx_set(client, xlator, ctx); if (ctx != setted_ctx) { LOCK_DESTROY(&ctx->fdtable_lock); GF_FREE(ctx->fdtable); GF_FREE(ctx); ctx = setted_ctx; } out: return ctx; } int auth_set_username_passwd(dict_t *input_params, dict_t *config_params, client_t *client) { int ret = 0; data_t *allow_user = NULL; data_t *passwd_data = NULL; char *username = NULL; char *password = NULL; char *brick_name = NULL; char *searchstr = NULL; char *username_str = NULL; char *tmp = NULL; char *username_cpy = NULL; ret = dict_get_str(input_params, "username", &username); if (ret) { gf_msg_debug("auth/login", 0, "username not found, returning " "DONT-CARE"); /* For non trusted clients username and password will not be there. So don't reject the client. */ ret = 0; goto out; } ret = dict_get_str(input_params, "password", &password); if (ret) { gf_smsg("auth/login", GF_LOG_WARNING, 0, PS_MSG_PASSWORD_NOT_FOUND, NULL); goto out; } ret = dict_get_str(input_params, "remote-subvolume", &brick_name); if (ret) { gf_smsg("auth/login", GF_LOG_ERROR, 0, PS_MSG_REMOTE_SUBVOL_NOT_SPECIFIED, NULL); ret = -1; goto out; } ret = gf_asprintf(&searchstr, "auth.login.%s.allow", brick_name); if (-1 == ret) { ret = 0; goto out; } allow_user = dict_get(config_params, searchstr); GF_FREE(searchstr); if (allow_user) { username_cpy = gf_strdup(allow_user->data); if (!username_cpy) goto out; username_str = strtok_r(username_cpy, " ,", &tmp); while (username_str) { if (!fnmatch(username_str, username, 0)) { ret = gf_asprintf(&searchstr, "auth.login.%s.password", username); if (-1 == ret) goto out; passwd_data = dict_get(config_params, searchstr); GF_FREE(searchstr); if (!passwd_data) { gf_smsg("auth/login", GF_LOG_ERROR, 0, PS_MSG_LOGIN_ERROR, NULL); ret = -1; goto out; } ret = strcmp(data_to_str(passwd_data), password); if (!ret) { client->auth.username = gf_strdup(username); client->auth.passwd = gf_strdup(password); } else { gf_smsg("auth/login", GF_LOG_ERROR, 0, PS_MSG_LOGIN_ERROR, "username=%s", username, NULL); } break; } username_str = strtok_r(NULL, " ,", &tmp); } } out: GF_FREE(username_cpy); return ret; } inode_t * server_inode_new(inode_table_t *itable, uuid_t gfid) { if (__is_root_gfid(gfid)) return itable->root; else return inode_new(itable); } int unserialize_req_locklist_v2(gfx_setactivelk_req *req, lock_migration_info_t *lmi) { struct gfs3_locklist *trav = NULL; lock_migration_info_t *temp = NULL; int ret = -1; trav = req->request; INIT_LIST_HEAD(&lmi->list); while (trav) { /* TODO: move to GF_MALLOC() */ temp = GF_CALLOC(1, sizeof(*lmi), gf_common_mt_lock_mig); if (temp == NULL) { gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_NO_MEM, NULL); goto out; } INIT_LIST_HEAD(&temp->list); gf_proto_flock_to_flock(&trav->flock, &temp->flock); temp->lk_flags = trav->lk_flags; temp->client_uid = gf_strdup(trav->client_uid); list_add_tail(&temp->list, &lmi->list); trav = trav->nextentry; } ret = 0; out: return ret; } glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server-helpers.h0000644000000000000000000000013214522202451025131 xustar000000000000000030 mtime=1699284265.778027766 30 atime=1699284265.778027766 30 ctime=1699284301.897136556 glusterfs-11.1/xlators/protocol/server/src/server-helpers.h0000664000175100017510000000335214522202451025413 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _SERVER_HELPERS_H #define _SERVER_HELPERS_H #include #define CALL_STATE(frame) ((server_state_t *)frame->root->state) void free_state(server_state_t *state); void server_print_request(call_frame_t *frame); call_frame_t * get_frame_from_request(rpcsvc_request_t *req); int server_connection_cleanup(xlator_t *this, struct _client *client, int32_t flags, gf_boolean_t *fd_exist); int server_build_config(xlator_t *this, server_conf_t *conf); int readdirp_rsp_cleanup_v2(gfx_readdirp_rsp *rsp); int readdir_rsp_cleanup_v2(gfx_readdir_rsp *rsp); int auth_set_username_passwd(dict_t *input_params, dict_t *config_params, struct _client *client); server_ctx_t * server_ctx_get(client_t *client, xlator_t *xlator); int server_process_event_upcall(xlator_t *this, void *data); inode_t * server_inode_new(inode_table_t *itable, uuid_t gfid); int serialize_rsp_locklist_v2(lock_migration_info_t *locklist, gfx_getactivelk_rsp *rsp); int getactivelkinfo_rsp_cleanup_v2(gfx_getactivelk_rsp *rsp); int unserialize_req_locklist_v2(gfx_setactivelk_req *req, lock_migration_info_t *lmi); int serialize_rsp_dirent_v2(gf_dirent_t *entries, gfx_readdir_rsp *rsp); int serialize_rsp_direntp_v2(gf_dirent_t *entries, gfx_readdirp_rsp *rsp); #endif /* !_SERVER_HELPERS_H */ glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013014522202451024044 xustar000000000000000029 mtime=1699284265.77602776 29 atime=1699284279.57406932 30 ctime=1699284301.894136547 glusterfs-11.1/xlators/protocol/server/src/Makefile.am0000664000175100017510000000217414522202451024331 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = server.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol server_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la $(LIB_DL) server_la_SOURCES = server.c server-resolve.c server-helpers.c \ server-handshake.c authenticate.c server-common.c \ server-rpc-fops_v2.c server_la_HEADERS = server.h server-helpers.h server-mem-types.h \ authenticate.h server-messages.h server-common.h server_ladir = $(includedir)/glusterfs/server AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -DCONFDIR=\"$(sysconfdir)/glusterfs\" \ -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \ -I$(top_srcdir)/rpc/rpc-transport/socket/src \ -I$(top_srcdir)/xlators/protocol/lib/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/glusterfsd/src AM_CFLAGS = -Wall $(GF_CFLAGS) \ -DDATADIR=\"$(localstatedir)\" CLEANFILES = *~ glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server-mem-types.h0000644000000000000000000000013214522202451025407 xustar000000000000000030 mtime=1699284265.778027766 30 atime=1699284265.778027766 30 ctime=1699284301.898136559 glusterfs-11.1/xlators/protocol/server/src/server-mem-types.h0000664000175100017510000000136614522202451025674 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __SERVER_MEM_TYPES_H__ #define __SERVER_MEM_TYPES_H__ #include enum gf_server_mem_types_ { gf_server_mt_server_conf_t = gf_common_mt_end + 1, gf_server_mt_state_t, gf_server_mt_dirent_rsp_t, gf_server_mt_setvolume_rsp_t, gf_server_mt_lock_mig_t, gf_server_mt_child_status, gf_server_mt_end, }; #endif /* __SERVER_MEM_TYPES_H__ */ glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/server.c0000644000000000000000000000013214522202451023464 xustar000000000000000030 mtime=1699284265.780027772 30 atime=1699284265.779027769 30 ctime=1699284301.904136577 glusterfs-11.1/xlators/protocol/server/src/server.c0000664000175100017510000017272714522202451023763 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "socket.h" #include "server.h" #include "server-helpers.h" #include #include #include "authenticate.h" #include #include #include #include "server-messages.h" #include "rpc-clnt.h" rpcsvc_cbk_program_t server_cbk_prog = { .progname = "Gluster Callback", .prognum = GLUSTER_CBK_PROGRAM, .progver = GLUSTER_CBK_VERSION, }; struct iobuf * gfs_serialize_reply(rpcsvc_request_t *req, void *arg, struct iovec *outmsg, xdrproc_t xdrproc) { struct iobuf *iob = NULL; ssize_t retlen = 0; ssize_t xdr_size = 0; GF_VALIDATE_OR_GOTO("server", req, ret); /* First, get the io buffer into which the reply in arg will * be serialized. */ if (arg && xdrproc) { xdr_size = xdr_sizeof(xdrproc, arg); iob = iobuf_get2(req->svc->ctx->iobuf_pool, xdr_size); if (!iob) { gf_msg_callingfn(THIS->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY, "Failed to get iobuf"); goto ret; }; iobuf_to_iovec(iob, outmsg); /* Use the given serializer to translate the give C structure in arg * to XDR format which will be written into the buffer in outmsg. */ /* retlen is used to received the error since size_t is unsigned and we * need -1 for error notification during encoding. */ retlen = xdr_serialize_generic(*outmsg, arg, xdrproc); if (retlen == -1) { /* Failed to Encode 'GlusterFS' msg in RPC is not exactly failure of RPC return values.. client should get notified about this, so there are no missing frames */ gf_msg_callingfn("", GF_LOG_ERROR, 0, PS_MSG_ENCODE_MSG_FAILED, "Failed to encode message"); req->rpc_err = GARBAGE_ARGS; retlen = 0; } } outmsg->iov_len = retlen; ret: return iob; } int server_submit_reply(call_frame_t *frame, rpcsvc_request_t *req, void *arg, struct iovec *payload, int payloadcount, struct iobref *iobref, xdrproc_t xdrproc) { struct iobuf *iob = NULL; int ret = -1; struct iovec rsp = { 0, }; server_state_t *state = NULL; char new_iobref = 0; client_t *client = NULL; GF_VALIDATE_OR_GOTO("server", req, ret); if (frame) { state = CALL_STATE(frame); frame->local = NULL; client = frame->root->client; } if (!iobref) { iobref = iobref_new(); if (!iobref) { goto ret; } new_iobref = 1; } iob = gfs_serialize_reply(req, arg, &rsp, xdrproc); if (!iob) { gf_smsg("", GF_LOG_ERROR, 0, PS_MSG_SERIALIZE_REPLY_FAILED, NULL); goto ret; } iobref_add(iobref, iob); /* Then, submit the message for transmission. */ ret = rpcsvc_submit_generic(req, &rsp, 1, payload, payloadcount, iobref); /* TODO: this is demo purpose only */ /* ret = rpcsvc_callback_submit (req->svc, req->trans, req->prog, GF_CBK_NULL, &rsp, 1); */ iobuf_unref(iob); if (ret == -1) { gf_msg_callingfn("", GF_LOG_ERROR, 0, PS_MSG_REPLY_SUBMIT_FAILED, "Reply submission failed"); if (frame && client) { server_connection_cleanup(frame->this, client, INTERNAL_LOCKS | POSIX_LOCKS, NULL); } else { gf_msg_callingfn("", GF_LOG_ERROR, 0, PS_MSG_REPLY_SUBMIT_FAILED, "Reply submission failed"); /* TODO: Failure of open(dir), create, inodelk, entrylk or lk fops send failure must be handled specially. */ } goto ret; } ret = 0; ret: if (client) gf_client_unref(client); if (frame) STACK_DESTROY(frame->root); if (new_iobref) iobref_unref(iobref); if (state) free_state(state); return ret; } int server_priv_to_dict(xlator_t *this, dict_t *dict, char *brickname) { server_conf_t *conf = NULL; rpc_transport_t *xprt = NULL; peer_info_t *peerinfo = NULL; char key[32] = { 0, }; int keylen; int count = 0; int ret = -1; GF_VALIDATE_OR_GOTO(THIS->name, this, out); GF_VALIDATE_OR_GOTO(THIS->name, dict, out); conf = this->private; if (!conf) return 0; // TODO: Dump only specific info to dict pthread_mutex_lock(&conf->mutex); { list_for_each_entry(xprt, &conf->xprt_list, list) { if ((xprt->xl_private) && (xprt->xl_private->bound_xl) && (xprt->xl_private->bound_xl->name) && (brickname) && (!strcmp(brickname, xprt->xl_private->bound_xl->name))) { peerinfo = &xprt->peerinfo; keylen = snprintf(key, sizeof(key), "client%d.hostname", count); ret = dict_set_strn(dict, key, keylen, peerinfo->identifier); if (ret) goto unlock; snprintf(key, sizeof(key), "client%d.bytesread", count); ret = dict_set_uint64(dict, key, xprt->total_bytes_read); if (ret) goto unlock; snprintf(key, sizeof(key), "client%d.byteswrite", count); ret = dict_set_uint64(dict, key, xprt->total_bytes_write); if (ret) goto unlock; snprintf(key, sizeof(key), "client%d.opversion", count); ret = dict_set_uint32(dict, key, peerinfo->max_op_version); if (ret) goto unlock; keylen = snprintf(key, sizeof(key), "client%d.name", count); ret = dict_set_strn(dict, key, keylen, xprt->xl_private->client_name); if (ret) goto unlock; count++; } } } unlock: pthread_mutex_unlock(&conf->mutex); if (ret) goto out; ret = dict_set_int32_sizen(dict, "clientcount", count); out: return ret; } int server_priv(xlator_t *this) { server_conf_t *conf = NULL; rpc_transport_t *xprt = NULL; char key[GF_DUMP_MAX_BUF_LEN] = { 0, }; uint64_t total_read = 0; uint64_t total_write = 0; int32_t ret = -1; GF_VALIDATE_OR_GOTO("server", this, out); conf = this->private; if (!conf) return 0; gf_proc_dump_build_key(key, "xlator.protocol.server", "priv"); gf_proc_dump_add_section("%s", key); ret = pthread_mutex_trylock(&conf->mutex); if (ret != 0) goto out; { list_for_each_entry(xprt, &conf->xprt_list, list) { total_read += xprt->total_bytes_read; total_write += xprt->total_bytes_write; } } pthread_mutex_unlock(&conf->mutex); gf_proc_dump_build_key(key, "server", "total-bytes-read"); gf_proc_dump_write(key, "%" PRIu64, total_read); gf_proc_dump_build_key(key, "server", "total-bytes-write"); gf_proc_dump_write(key, "%" PRIu64, total_write); rpcsvc_statedump(conf->rpc); ret = 0; out: if (ret) gf_proc_dump_write("Unable to print priv", "(Lock acquisition failed) %s", this ? this->name : "server"); return ret; } static int get_auth_types(dict_t *this, char *key, data_t *value, void *data) { dict_t *auth_dict = NULL; char *saveptr = NULL; char *tmp = NULL; char *key_cpy = NULL; int32_t ret = -1; GF_VALIDATE_OR_GOTO("server", this, out); GF_VALIDATE_OR_GOTO("server", key, out); GF_VALIDATE_OR_GOTO("server", data, out); auth_dict = data; key_cpy = gf_strdup(key); GF_VALIDATE_OR_GOTO("server", key_cpy, out); tmp = strtok_r(key_cpy, ".", &saveptr); ret = strcmp(tmp, "auth"); if (ret == 0) { tmp = strtok_r(NULL, ".", &saveptr); if (strcmp(tmp, "ip") == 0) { /* TODO: backward compatibility, remove when newer versions are available */ tmp = "addr"; gf_smsg("server", GF_LOG_WARNING, 0, PS_MSG_AUTH_IP_ERROR, NULL); } ret = dict_set_dynptr(auth_dict, tmp, NULL, 0); if (ret < 0) { gf_msg_debug("server", 0, "failed to " "dict_set_dynptr"); } } GF_FREE(key_cpy); out: return 0; } int _check_for_auth_option(dict_t *d, char *k, data_t *v, void *tmp) { int ret = 0; xlator_t *xl = NULL; char *tail = NULL; xl = tmp; tail = strtail(k, "auth."); if (!tail) goto out; if (strncmp(tail, "addr.", 5) != 0) { gf_smsg(xl->name, GF_LOG_TRACE, 0, PS_MSG_SKIP_FORMAT_CHK, "option=%s", k, NULL); goto out; } /* fast fwd through module type */ tail = strchr(tail, '.'); if (!tail) goto out; tail++; tail = strtail(tail, xl->name); if (!tail) goto out; if (*tail == '.') { /* when we are here, the key is checked for * valid auth.allow. * Now we verify the ip address */ ret = xlator_option_validate_addr_list(xl, "auth-*", v->data, NULL, NULL); if (ret) gf_smsg(xl->name, GF_LOG_ERROR, 0, PS_MSG_INTERNET_ADDR_ERROR, "data=%s", v->data, NULL); } out: return ret; } int validate_auth_options(xlator_t *this, dict_t *dict) { int error = -1; xlator_list_t *trav = NULL; GF_VALIDATE_OR_GOTO("server", this, out); GF_VALIDATE_OR_GOTO("server", dict, out); trav = this->children; while (trav) { error = dict_foreach(dict, _check_for_auth_option, trav->xlator); if (-1 == error) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_AUTHENTICATE_ERROR, "name=%s", trav->xlator->name, NULL); break; } trav = trav->next; } out: return error; } void server_call_xlator_mem_cleanup(xlator_t *this, char *victim_name) { pthread_t th_id = { 0, }; int th_ret = -1; server_cleanup_xprt_arg_t *arg = NULL; if (!victim_name) return; gf_log(this->name, GF_LOG_INFO, "Create graph janitor thread for brick %s", victim_name); arg = calloc(1, sizeof(*arg)); arg->this = this; arg->victim_name = strdup(victim_name); if (!arg->victim_name) { gf_smsg(this->name, GF_LOG_CRITICAL, ENOMEM, LG_MSG_NO_MEMORY, "Memory allocation is failed"); free(arg); return; } th_ret = gf_thread_create_detached(&th_id, server_graph_janitor_threads, arg, "graphjanitor"); if (th_ret) { gf_log(this->name, GF_LOG_ERROR, "graph janitor Thread" " creation is failed for brick %s", victim_name); free(arg->victim_name); free(arg); } } int server_rpc_notify(rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, void *data) { gf_boolean_t detached = _gf_false; xlator_t *this = NULL; rpc_transport_t *trans = NULL; server_conf_t *conf = NULL; client_t *client = NULL; char *auth_path = NULL; int ret = -1; char *xlator_name = NULL; uint64_t xprtrefcount = 0; gf_boolean_t fd_exist = _gf_false; this = xl; trans = data; if (!this || !data || !this->ctx || !this->ctx->active) { gf_msg_callingfn("server", GF_LOG_WARNING, 0, PS_MSG_RPC_NOTIFY_ERROR, "Calling rpc_notify without initializing"); goto out; } conf = this->private; switch (event) { case RPCSVC_EVENT_ACCEPT: { /* Have a structure per new connection */ /* TODO: Should we create anything here at all ? * / client->conn = create_server_conn_state (this, trans); if (!client->conn) goto out; trans->protocol_private = client->conn; */ pthread_mutex_lock(&conf->mutex); rpc_transport_ref(trans); list_add_tail(&trans->list, &conf->xprt_list); pthread_mutex_unlock(&conf->mutex); break; } case RPCSVC_EVENT_DISCONNECT: /* A DISCONNECT event could come without an ACCEPT event * happening for this transport. This happens when the server is * expecting encrypted connections by the client tries to * connect unecnrypted */ if (list_empty(&trans->list)) { break; } /* Set the disconnect_progress flag to 1 to avoid races during brick detach while brick mux is enabled */ GF_ATOMIC_INIT(trans->disconnect_progress, 1); /* transport has to be removed from the list upon disconnect * irrespective of whether lock self heal is off or on, since * new transport will be created upon reconnect. */ pthread_mutex_lock(&conf->mutex); client = trans->xl_private; if (!client) list_del_init(&trans->list); pthread_mutex_unlock(&conf->mutex); if (!client) goto unref_transport; gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_DISCONNECTING, "client-uid=%s", client->client_uid, NULL); ret = dict_get_str_sizen(this->options, "auth-path", &auth_path); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PS_MSG_DICT_GET_FAILED, "type=auth-path", NULL); auth_path = NULL; } gf_client_ref(client); gf_client_put(client, &detached); if (detached) { server_connection_cleanup( this, client, INTERNAL_LOCKS | POSIX_LOCKS, &fd_exist); gf_event(EVENT_CLIENT_DISCONNECT, "client_uid=%s;" "client_identifier=%s;server_identifier=%s;" "brick_path=%s", client->client_uid, trans->peerinfo.identifier, trans->myinfo.identifier, auth_path); } /* * gf_client_unref will be done while handling * RPC_EVENT_TRANSPORT_DESTROY */ unref_transport: /* rpc_transport_unref() causes a RPCSVC_EVENT_TRANSPORT_DESTROY * to be called in blocking manner * So no code should ideally be after this unref, Call * rpc_transport_unref only while cleanup_starting flag is not set * otherwise transport_unref will be call by either * server_connection_cleanup_flush_cbk or server_submit_reply at the * time of freeing state */ if (!client || !detached || !fd_exist) rpc_transport_unref(trans); break; case RPCSVC_EVENT_TRANSPORT_DESTROY: pthread_mutex_lock(&conf->mutex); client = trans->xl_private; list_del_init(&trans->list); pthread_mutex_unlock(&conf->mutex); if (!client) break; if (client->bound_xl && client->bound_xl->cleanup_starting) { xprtrefcount = GF_ATOMIC_GET(client->bound_xl->xprtrefcnt); if (xprtrefcount > 0) { xprtrefcount = GF_ATOMIC_DEC(client->bound_xl->xprtrefcnt); if (xprtrefcount == 0) xlator_name = gf_strdup(client->bound_xl->name); } } gf_client_unref(client); if (xlator_name) { server_call_xlator_mem_cleanup(this, xlator_name); GF_FREE(xlator_name); } trans->xl_private = NULL; break; default: break; } ret = 0; out: /* Only case when ret == -1 is the initial validation */ return ret; } int glusterfs_ctx_pool_destroy(glusterfs_ctx_t *ctx) { call_pool_t *pool = NULL; int ret = 0; if (ctx == NULL) return 0; /* Free the memory pool */ if (ctx->dict_pool) mem_pool_destroy(ctx->dict_pool); if (ctx->dict_data_pool) mem_pool_destroy(ctx->dict_data_pool); if (ctx->logbuf_pool) mem_pool_destroy(ctx->logbuf_pool); pool = ctx->pool; if (pool) { if (pool->frame_mem_pool) mem_pool_destroy(pool->frame_mem_pool); if (pool->stack_mem_pool) mem_pool_destroy(pool->stack_mem_pool); LOCK_DESTROY(&pool->lock); GF_FREE(pool); } /* Free the event pool */ ret = gf_event_pool_destroy(ctx->event_pool); /* Free the iobuf pool */ iobuf_pool_destroy(ctx->iobuf_pool); GF_FREE(ctx->process_uuid); GF_FREE(ctx->cmd_args.volfile_id); GF_FREE(ctx->cmd_args.process_name); LOCK_DESTROY(&ctx->lock); pthread_mutex_destroy(&ctx->notify_lock); pthread_cond_destroy(&ctx->notify_cond); GF_FREE(ctx->statedump_path); FREE(ctx); return ret; } void * server_graph_janitor_threads(void *data) { xlator_t *victim = NULL; xlator_t *this = NULL; server_conf_t *conf = NULL; glusterfs_ctx_t *ctx = NULL; char *victim_name = NULL; server_cleanup_xprt_arg_t *arg = NULL; gf_boolean_t victim_found = _gf_false; gf_boolean_t destroy_ctx = _gf_false; xlator_list_t **trav_p = NULL; xlator_t *top = NULL; uint32_t parent_down = 0; struct rpc_clnt *rpc = NULL; GF_ASSERT(data); arg = data; this = arg->this; victim_name = arg->victim_name; THIS = arg->this; conf = this->private; ctx = THIS->ctx; GF_VALIDATE_OR_GOTO(this->name, ctx, out); top = this->ctx->active->first; LOCK(&ctx->volfile_lock); for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) { victim = (*trav_p)->xlator; if (victim->cleanup_starting && strcmp(victim->name, victim_name) == 0) { parent_down = victim->parent_down; victim->parent_down = 1; if (!parent_down) victim_found = _gf_true; break; } } if (victim_found) glusterfs_delete_volfile_checksum(ctx, victim->volfile_id); UNLOCK(&ctx->volfile_lock); if (!victim_found) { gf_log(this->name, GF_LOG_ERROR, "victim brick %s is not" " found in graph", victim_name); goto out; } default_notify(victim, GF_EVENT_PARENT_DOWN, victim); if (victim->notify_down) { gf_log(THIS->name, GF_LOG_INFO, "Start call fini for brick" " %s stack", victim->name); xlator_mem_cleanup(victim); LOCK(&ctx->volfile_lock); { if (!top->children && !ctx->destroy_ctx) { ctx->destroy_ctx = _gf_true; destroy_ctx = _gf_true; } } UNLOCK(&ctx->volfile_lock); rpcsvc_autoscale_threads(ctx, conf->rpc, -1); } out: free(arg->victim_name); free(arg); if (destroy_ctx) { gf_log(THIS->name, GF_LOG_INFO, "Going to Cleanup ctx pool memory and exit the process %s", ctx->cmdlinestr); syncenv_destroy(ctx->env); ctx->env = NULL; gf_event_dispatch_destroy(ctx->event_pool); if (ctx->mgmt) { rpc = ctx->mgmt; rpc_clnt_connection_cleanup(&rpc->conn); rpc_clnt_unref(rpc); } server_cleanup(this, conf); glusterfs_ctx_pool_destroy(ctx); } return NULL; } int32_t server_mem_acct_init(xlator_t *this) { int ret = -1; GF_VALIDATE_OR_GOTO("server", this, out); ret = xlator_mem_acct_init(this, gf_server_mt_end); if (ret != 0) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY, NULL); return ret; } out: return ret; } static int _delete_auth_opt(dict_t *this, char *key, data_t *value, void *data) { char *auth_option_pattern[] = { "auth.addr.*.allow", "auth.addr.*.reject", "auth.login.*.allow", "auth.login.*.password", "auth.login.*.ssl-allow", NULL}; int i = 0; for (i = 0; auth_option_pattern[i]; i++) { if (fnmatch(auth_option_pattern[i], key, 0) == 0) { dict_del(this, key); break; } } return 0; } static int _copy_auth_opt(dict_t *unused, char *key, data_t *value, void *xl_dict) { char *auth_option_pattern[] = { "auth.addr.*.allow", "auth.addr.*.reject", "auth.login.*.allow", "auth.login.*.password", "auth.login.*.ssl-allow", NULL}; int i = 0; for (i = 0; auth_option_pattern[i]; i++) { if (fnmatch(auth_option_pattern[i], key, 0) == 0) { dict_set((dict_t *)xl_dict, key, value); break; } } return 0; } int server_check_event_threads(xlator_t *this, server_conf_t *conf, int32_t new) { struct event_pool *pool = this->ctx->event_pool; int target; target = new + pool->auto_thread_count; conf->event_threads = new; if (target == pool->eventthreadcount) { return 0; } return gf_event_reconfigure_threads(pool, target); } int server_reconfigure(xlator_t *this, dict_t *options) { server_conf_t *conf = NULL; rpcsvc_t *rpc_conf; rpcsvc_listener_t *listeners; rpc_transport_t *xprt = NULL; rpc_transport_t *xp_next = NULL; int inode_lru_limit; gf_boolean_t trace; data_t *data; int ret = 0; char *statedump_path = NULL; int32_t new_nthread = 0; char *auth_path = NULL; char *xprt_path = NULL; xlator_t *oldTHIS; xlator_t *kid; /* * Since we're not a fop, we can't really count on THIS being set * correctly, and it needs to be or else GF_OPTION_RECONF won't work * (because it won't find our options list). This is another thing * that "just happened" to work before multiplexing, but now we need to * handle it more explicitly. */ oldTHIS = THIS; THIS = this; conf = this->private; if (!conf) { gf_msg_callingfn(this->name, GF_LOG_DEBUG, EINVAL, PS_MSG_INVALID_ENTRY, "conf == null!!!"); goto out; } /* * For some of the auth/rpc stuff, we need to operate on the correct * child, but for other stuff we need to operate on the server * translator itself. */ kid = NULL; if (dict_get_str_sizen(options, "auth-path", &auth_path) == 0) { kid = get_xlator_by_name(this, auth_path); } if (!kid) { kid = this; } if (dict_get_int32_sizen(options, "inode-lru-limit", &inode_lru_limit) == 0) { conf->inode_lru_limit = inode_lru_limit; gf_msg_trace(this->name, 0, "Reconfigured inode-lru-limit to " "%d", conf->inode_lru_limit); /* traverse through the xlator graph. For each xlator in the graph check whether it is a bound_xl or not (bound_xl means the xlator will have its itable pointer set). If so, then set the lru limit for the itable. */ xlator_foreach(this, xlator_set_inode_lru_limit, &inode_lru_limit); } data = dict_get_sizen(options, "trace"); if (data) { ret = gf_string2boolean(data->data, &trace); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_INVALID_ENTRY, NULL); ret = -1; goto out; } conf->trace = trace; gf_msg_trace(this->name, 0, "Reconfigured trace to %d", conf->trace); } GF_OPTION_RECONF("statedump-path", statedump_path, options, path, do_auth); if (!statedump_path) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_STATEDUMP_PATH_ERROR, NULL); goto do_auth; } gf_path_strip_trailing_slashes(statedump_path); GF_FREE(this->ctx->statedump_path); this->ctx->statedump_path = gf_strdup(statedump_path); /* if the option is not set, we should fall back to NULL value */ GF_FREE(conf->volfile_dir); conf->volfile_dir = NULL; statedump_path = NULL; GF_OPTION_RECONF("volspec-directory", statedump_path, options, path, do_auth); if (statedump_path) { gf_path_strip_trailing_slashes(statedump_path); conf->volfile_dir = gf_strdup(statedump_path); if (!conf->volfile_dir) { ret = -1; goto out; } } do_auth: if (conf->auth_modules) gf_auth_fini(conf->auth_modules); else conf->auth_modules = dict_new(); dict_foreach(options, get_auth_types, conf->auth_modules); ret = validate_auth_options(kid, options); if (ret == -1) { /* logging already done in validate_auth_options function. */ goto out; } dict_foreach(kid->options, _delete_auth_opt, NULL); dict_foreach(options, _copy_auth_opt, kid->options); ret = gf_auth_init(kid, conf->auth_modules); if (ret) { dict_unref(conf->auth_modules); goto out; } GF_OPTION_RECONF("manage-gids", conf->server_manage_gids, options, bool, do_rpc); GF_OPTION_RECONF("gid-timeout", conf->gid_cache_timeout, options, time, do_rpc); if (gid_cache_reconf(&conf->gid_cache, conf->gid_cache_timeout) < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_GRP_CACHE_ERROR, NULL); goto do_rpc; } do_rpc: rpc_conf = conf->rpc; if (!rpc_conf) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_RPC_CONF_ERROR, NULL); goto out; } ret = rpcsvc_auth_reconf(rpc_conf, options); if (ret == -1) { gf_log(GF_RPCSVC, GF_LOG_ERROR, "Failed to reconfigure authentication"); goto out; } GF_OPTION_RECONF("strict-auth-accept", conf->strict_auth_enabled, options, bool, out); GF_OPTION_RECONF("dynamic-auth", conf->dync_auth, options, bool, out); if (conf->dync_auth) { pthread_mutex_lock(&conf->mutex); { /* * Disconnecting will (usually) drop the last ref, * which will cause the transport to be unlinked and * freed while we're still traversing, which will cause * us to crash unless we use list_for_each_entry_safe. */ list_for_each_entry_safe(xprt, xp_next, &conf->xprt_list, list) { /* check for client authorization */ if (!xprt->clnt_options) { /* If clnt_options dictionary is null, * which means for this transport * server_setvolume was not called. * * So here we can skip authentication * because server_setvolume will do * gf_authenticate. * */ continue; } /* * Make sure we're only operating on * connections that are relevant to the brick * we're reconfiguring. */ if (dict_get_str_sizen(xprt->clnt_options, "remote-subvolume", &xprt_path) != 0) { continue; } if (strcmp(xprt_path, auth_path) != 0) { continue; } ret = gf_authenticate(xprt->clnt_options, options, conf->auth_modules); if (ret == AUTH_ACCEPT) { gf_smsg(kid->name, GF_LOG_TRACE, 0, PS_MSG_CLIENT_ACCEPTED, NULL); } else { gf_event(EVENT_CLIENT_AUTH_REJECT, "client_uid=%s;" "client_identifier=%s;" "server_identifier=%s;" "brick_path=%s", xprt->xl_private->client_uid, xprt->peerinfo.identifier, xprt->myinfo.identifier, auth_path); gf_smsg(this->name, GF_LOG_INFO, EACCES, PS_MSG_UNAUTHORIZED_CLIENT, "peerinfo-identifier=%s", xprt->peerinfo.identifier, NULL); rpc_transport_disconnect(xprt, _gf_false); } } } pthread_mutex_unlock(&conf->mutex); } ret = rpcsvc_set_outstanding_rpc_limit( rpc_conf, options, RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_RECONFIGURE_FAILED, NULL); goto out; } list_for_each_entry(listeners, &(rpc_conf->listeners), list) { if (listeners->trans != NULL) { if (listeners->trans->reconfigure) listeners->trans->reconfigure(listeners->trans, options); else gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_TRANSPORT_ERROR, NULL); } } /* * Update: * We don't need to reset auto_thread_count since it has been derived * out of the total bricks attached. We can reconfigure event threads * but not auto threads. */ GF_OPTION_RECONF("event-threads", new_nthread, options, int32, out); ret = server_check_event_threads(this, conf, new_nthread); if (ret) goto out; out: THIS = oldTHIS; gf_msg_debug("", 0, "returning %d", ret); return ret; } static int32_t client_destroy_cbk(xlator_t *this, client_t *client) { void *tmp = NULL; server_ctx_t *ctx = NULL; tmp = client_ctx_del(client, this); ctx = tmp; if (ctx == NULL) return 0; gf_fd_fdtable_destroy(ctx->fdtable); LOCK_DESTROY(&ctx->fdtable_lock); GF_FREE(ctx); return 0; } int32_t server_dump_metrics(xlator_t *this, int fd) { rpc_transport_t *xprt = NULL; server_conf_t *conf = NULL; client_t *client = NULL; conf = this->private; pthread_mutex_lock(&conf->mutex); list_for_each_entry(xprt, &conf->xprt_list, list) { client = xprt->xl_private; if (!client) continue; dprintf(fd, "%s.total.rpc.%s.bytes_read %" PRIu64 "\n", this->name, client->client_uid, xprt->total_bytes_read); dprintf(fd, "%s.total.rpc.%s.bytes_write %" PRIu64 "\n", this->name, client->client_uid, xprt->total_bytes_write); dprintf(fd, "%s.total.rpc.%s.outstanding %d\n", this->name, client->client_uid, xprt->outstanding_rpc_count); } pthread_mutex_unlock(&conf->mutex); return 0; } void server_cleanup(xlator_t *this, server_conf_t *conf) { if (!this || !conf) return; LOCK_DESTROY(&conf->itable_lock); pthread_mutex_destroy(&conf->mutex); if (this->ctx->event_pool) { /* Free the event pool */ (void)gf_event_pool_destroy(this->ctx->event_pool); } if (dict_get_sizen(this->options, "config-directory")) { GF_FREE(conf->conf_dir); conf->conf_dir = NULL; } if (conf->child_status) { GF_FREE(conf->child_status); conf->child_status = NULL; } if (this->ctx->statedump_path) { GF_FREE(this->ctx->statedump_path); this->ctx->statedump_path = NULL; } if (conf->auth_modules) { gf_auth_fini(conf->auth_modules); dict_unref(conf->auth_modules); } if (conf->rpc) { (void)rpcsvc_destroy(conf->rpc); conf->rpc = NULL; } GF_FREE(conf); this->private = NULL; } int server_init(xlator_t *this) { int32_t ret = -1; server_conf_t *conf = NULL; char *transport_type = NULL; char *statedump_path = NULL; int total_transport = 0; GF_VALIDATE_OR_GOTO("init", this, err); if (this->children == NULL) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_SUBVOL_NULL, NULL); goto err; } if (this->parents != NULL) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_PARENT_VOL_ERROR, NULL); goto err; } conf = GF_CALLOC(1, sizeof(server_conf_t), gf_server_mt_server_conf_t); GF_VALIDATE_OR_GOTO(this->name, conf, err); INIT_LIST_HEAD(&conf->xprt_list); pthread_mutex_init(&conf->mutex, NULL); LOCK_INIT(&conf->itable_lock); /* Set event threads to the configured default */ GF_OPTION_INIT("event-threads", conf->event_threads, int32, err); ret = server_check_event_threads(this, conf, conf->event_threads); if (ret) goto err; ret = server_build_config(this, conf); if (ret) goto err; /* Volfile server */ ret = dict_get_str_sizen(this->options, "config-directory", &conf->conf_dir); if (ret) conf->conf_dir = CONFDIR; conf->child_status = GF_CALLOC(1, sizeof(struct _child_status), gf_server_mt_child_status); INIT_LIST_HEAD(&conf->child_status->status_list); GF_OPTION_INIT("statedump-path", statedump_path, path, err); if (statedump_path) { gf_path_strip_trailing_slashes(statedump_path); this->ctx->statedump_path = gf_strdup(statedump_path); } else { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_SET_STATEDUMP_PATH_ERROR, NULL); ret = -1; goto err; } statedump_path = NULL; GF_OPTION_INIT("volspec-directory", statedump_path, path, err); if (statedump_path) { gf_path_strip_trailing_slashes(statedump_path); conf->volfile_dir = gf_strdup(statedump_path); if (!conf->volfile_dir) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_SET_STATEDUMP_PATH_ERROR, NULL); ret = -1; goto err; } } /* Authentication modules */ conf->auth_modules = dict_new(); GF_VALIDATE_OR_GOTO(this->name, conf->auth_modules, err); dict_foreach(this->options, get_auth_types, conf->auth_modules); ret = validate_auth_options(this, this->options); if (ret == -1) { /* logging already done in validate_auth_options function. */ goto err; } ret = gf_auth_init(this, conf->auth_modules); if (ret) { dict_unref(conf->auth_modules); conf->auth_modules = NULL; goto err; } ret = dict_get_str_boolean(this->options, "manage-gids", _gf_false); if (ret == -1) { conf->server_manage_gids = _gf_false; } else { conf->server_manage_gids = ret; } GF_OPTION_INIT("gid-timeout", conf->gid_cache_timeout, time, err); if (gid_cache_init(&conf->gid_cache, conf->gid_cache_timeout) < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_INIT_GRP_CACHE_ERROR, NULL); goto err; } ret = dict_get_str_boolean(this->options, "strict-auth-accept", _gf_false); if (ret == -1) conf->strict_auth_enabled = _gf_false; else conf->strict_auth_enabled = ret; ret = dict_get_str_boolean(this->options, "dynamic-auth", _gf_true); if (ret == -1) conf->dync_auth = _gf_true; else conf->dync_auth = ret; /* RPC related */ conf->rpc = rpcsvc_init(this, this->ctx, this->options, 0); if (conf->rpc == NULL) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_RPCSVC_CREATE_FAILED, NULL); ret = -1; goto err; } ret = rpcsvc_set_outstanding_rpc_limit( conf->rpc, this->options, RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_RPC_CONFIGURE_FAILED, NULL); goto err; } /* * This is the only place where we want secure_srvr to reflect * the data-plane setting. */ this->ctx->secure_srvr = MGMT_SSL_COPY_IO; ret = dict_get_str_sizen(this->options, "transport-type", &transport_type); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_TRANSPORT_TYPE_NOT_SET, NULL); ret = -1; goto err; } total_transport = rpc_transport_count(transport_type); if (total_transport <= 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_GET_TOTAL_AVAIL_TRANSPORT_FAILED, NULL); ret = -1; goto err; } ret = dict_set_int32_sizen(this->options, "notify-poller-death", 1); ret = rpcsvc_create_listeners(conf->rpc, this->options, this->name); if (ret < 1) { gf_smsg(this->name, GF_LOG_WARNING, 0, PS_MSG_RPCSVC_LISTENER_CREATE_FAILED, NULL); if (ret != -EADDRINUSE) ret = -1; goto err; } else if (ret < total_transport) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_RPCSVC_LISTENER_CREATE_FAILED, "number=%d", "continuing with succeeded transport", (total_transport - ret), NULL); } ret = rpcsvc_register_notify(conf->rpc, server_rpc_notify, this); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PS_MSG_RPCSVC_NOTIFY, NULL); goto err; } glusterfs4_0_fop_prog.options = this->options; ret = rpcsvc_program_register(conf->rpc, &glusterfs4_0_fop_prog, _gf_true); if (ret) { gf_log(this->name, GF_LOG_WARNING, "registration of program (name:%s, prognum:%d, " "progver:%d) failed", glusterfs4_0_fop_prog.progname, glusterfs4_0_fop_prog.prognum, glusterfs4_0_fop_prog.progver); goto err; } gluster_handshake_prog.options = this->options; ret = rpcsvc_program_register(conf->rpc, &gluster_handshake_prog, _gf_false); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, PS_MSG_PGM_REG_FAILED, "name=%s", gluster_handshake_prog.progname, "prognum=%d", gluster_handshake_prog.prognum, "progver=%d", gluster_handshake_prog.progver, NULL); rpcsvc_program_unregister(conf->rpc, &glusterfs4_0_fop_prog); goto err; } gf_set_nofile(1048576, 65536); if (!this->ctx->cmd_args.volfile_id) { /* In some use cases this is a valid case, but document this to be annoying log in that case */ gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_VOL_FILE_OPEN_FAILED, NULL); this->ctx->cmd_args.volfile_id = gf_strdup("gluster"); } FIRST_CHILD(this)->volfile_id = gf_strdup(this->ctx->cmd_args.volfile_id); this->private = conf; return 0; err: if (this != NULL) { this->fini(this); } server_cleanup(this, conf); return -1; } void server_fini(xlator_t *this) { #if 0 server_conf_t *conf = NULL; conf = this->private; if (conf) { if (conf->rpc) { /* TODO: memory leak here, have to free RPC */ /* if (conf->rpc->conn) { rpcsvc_conn_destroy (conf->rpc->conn); } rpcsvc_fini (conf->rpc); */ ; } if (conf->auth_modules) dict_unref (conf->auth_modules); GF_FREE (conf->volfile_dir); GF_FREE (conf); } this->private = NULL; #endif return; } int server_process_event_upcall(xlator_t *this, void *data) { int ret = -1; server_conf_t *conf = NULL; client_t *client = NULL; char *client_uid = NULL; struct gf_upcall *upcall_data = NULL; void *up_req = NULL; rpc_transport_t *xprt = NULL; enum gf_cbk_procnum cbk_procnum = GF_CBK_NULL; gfs3_cbk_cache_invalidation_req gf_c_req = { 0, }; gfs3_recall_lease_req gf_recall_lease = { { 0, }, }; gfs4_inodelk_contention_req gf_inodelk_contention = { {0}, }; gfs4_entrylk_contention_req gf_entrylk_contention = { {0}, }; xdrproc_t xdrproc; gf_boolean_t xprt_found = _gf_false; GF_VALIDATE_OR_GOTO(this->name, data, out); conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); upcall_data = (struct gf_upcall *)data; client_uid = upcall_data->client_uid; /* client_uid could be NULL if the upcall was intended for a server's * child xlator (so no client_uid available) but it hasn't handled * the notification. For this reason we silently ignore any upcall * request with a NULL client_uid, but -1 will be returned. */ if (client_uid == NULL) { gf_msg_debug(this->name, 0, "NULL client_uid for an upcall request"); goto out; } switch (upcall_data->event_type) { case GF_UPCALL_CACHE_INVALIDATION: ret = gf_proto_cache_invalidation_from_upcall(this, &gf_c_req, upcall_data); if (ret < 0) goto out; up_req = &gf_c_req; cbk_procnum = GF_CBK_CACHE_INVALIDATION; xdrproc = (xdrproc_t)xdr_gfs3_cbk_cache_invalidation_req; break; case GF_UPCALL_RECALL_LEASE: ret = gf_proto_recall_lease_from_upcall(this, &gf_recall_lease, upcall_data); if (ret < 0) goto out; up_req = &gf_recall_lease; cbk_procnum = GF_CBK_RECALL_LEASE; xdrproc = (xdrproc_t)xdr_gfs3_recall_lease_req; break; case GF_UPCALL_INODELK_CONTENTION: ret = gf_proto_inodelk_contention_from_upcall( this, &gf_inodelk_contention, upcall_data); if (ret < 0) goto out; up_req = &gf_inodelk_contention; cbk_procnum = GF_CBK_INODELK_CONTENTION; xdrproc = (xdrproc_t)xdr_gfs4_inodelk_contention_req; break; case GF_UPCALL_ENTRYLK_CONTENTION: ret = gf_proto_entrylk_contention_from_upcall( this, &gf_entrylk_contention, upcall_data); if (ret < 0) goto out; up_req = &gf_entrylk_contention; cbk_procnum = GF_CBK_ENTRYLK_CONTENTION; xdrproc = (xdrproc_t)xdr_gfs4_entrylk_contention_req; break; default: gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_INVLAID_UPCALL_EVENT, "event-type=%d", upcall_data->event_type, NULL); goto out; } pthread_mutex_lock(&conf->mutex); { list_for_each_entry(xprt, &conf->xprt_list, list) { client = xprt->xl_private; /* 'client' is not atomically added during xprt entry * addition to the list. */ if (!client || strcmp(client->client_uid, client_uid)) continue; /* Avoid upcall notification to client if disconnect is in progress */ if (GF_ATOMIC_GET(xprt->disconnect_progress)) continue; xprt_found = _gf_true; rpc_transport_ref(xprt); break; } } pthread_mutex_unlock(&conf->mutex); if (xprt_found) { ret = rpcsvc_request_submit(conf->rpc, xprt, &server_cbk_prog, cbk_procnum, up_req, this->ctx, xdrproc); rpc_transport_unref(xprt); if (ret < 0) { gf_msg_debug(this->name, 0, "Failed to send " "upcall to client:%s upcall " "event:%d", client_uid, upcall_data->event_type); } } out: GF_FREE((gf_c_req.xdata).xdata_val); GF_FREE((gf_recall_lease.xdata).xdata_val); GF_FREE((gf_inodelk_contention.xdata).xdata_val); GF_FREE((gf_entrylk_contention.xdata).xdata_val); return ret; } int server_process_child_event(xlator_t *this, int32_t event, void *data, enum gf_cbk_procnum cbk_procnum) { int ret = -1; server_conf_t *conf = NULL; rpc_transport_t *xprt = NULL; xlator_t *victim = NULL; struct _child_status *tmp = NULL; GF_VALIDATE_OR_GOTO(this->name, data, out); conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); victim = data; pthread_mutex_lock(&conf->mutex); { if (cbk_procnum == GF_CBK_CHILD_UP) { list_for_each_entry(tmp, &conf->child_status->status_list, status_list) { if (tmp->name == NULL) break; if (strcmp(tmp->name, victim->name) == 0) break; } if (tmp->name) { tmp->child_up = _gf_true; } else { tmp = GF_CALLOC(1, sizeof(struct _child_status), gf_server_mt_child_status); INIT_LIST_HEAD(&tmp->status_list); tmp->name = gf_strdup(victim->name); tmp->child_up = _gf_true; memcpy(tmp->volume_id, victim->graph->volume_id, GF_UUID_BUF_SIZE); list_add_tail(&tmp->status_list, &conf->child_status->status_list); } } if (cbk_procnum == GF_CBK_CHILD_DOWN) { list_for_each_entry(tmp, &conf->child_status->status_list, status_list) { if (strcmp(tmp->name, victim->name) == 0) { tmp->child_up = _gf_false; break; } } if (!tmp->name) gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_CHILD_STATUS_FAILED, "name=%s", victim->name, NULL); } list_for_each_entry(xprt, &conf->xprt_list, list) { if (!xprt->xl_private) { continue; } if (xprt->xl_private->bound_xl == data) { rpcsvc_callback_submit(conf->rpc, xprt, &server_cbk_prog, cbk_procnum, NULL, 0, NULL); } } } pthread_mutex_unlock(&conf->mutex); ret = 0; out: return ret; } int server_notify(xlator_t *this, int32_t event, void *data, ...) { int ret = -1; server_conf_t *conf = NULL; rpc_transport_t *xprt = NULL; rpc_transport_t *xp_next = NULL; xlator_t *victim = NULL; xlator_t *top = NULL; xlator_t *travxl = NULL; xlator_list_t **trav_p = NULL; struct _child_status *tmp = NULL; gf_boolean_t victim_found = _gf_false; glusterfs_ctx_t *ctx = NULL; gf_boolean_t xprt_found = _gf_false; uint64_t totxprt = 0; uint64_t totdisconnect = 0; char *victim_name = NULL; GF_VALIDATE_OR_GOTO(THIS->name, this, out); conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); victim = data; ctx = THIS->ctx; switch (event) { case GF_EVENT_UPCALL: { GF_VALIDATE_OR_GOTO(this->name, data, out); ret = server_process_event_upcall(this, data); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_SERVER_EVENT_UPCALL_FAILED, NULL); goto out; } break; } case GF_EVENT_PARENT_UP: { conf->parent_up = _gf_true; default_notify(this, event, data); break; } case GF_EVENT_CHILD_UP: { ret = server_process_child_event(this, event, data, GF_CBK_CHILD_UP); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_SERVER_CHILD_EVENT_FAILED, NULL); goto out; } default_notify(this, event, data); break; } case GF_EVENT_CHILD_DOWN: { if (victim->cleanup_starting) { victim->notify_down = 1; gf_log(this->name, GF_LOG_INFO, "Getting CHILD_DOWN event for brick %s", victim->name); } ret = server_process_child_event(this, event, data, GF_CBK_CHILD_DOWN); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_SERVER_CHILD_EVENT_FAILED, NULL); goto out; } default_notify(this, event, data); break; } case GF_EVENT_CLEANUP: victim_name = gf_strdup(victim->name); if (!victim_name) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY, NULL); goto out; } pthread_mutex_lock(&conf->mutex); /* Calculate total no. of xprt available in list for this brick xlator */ list_for_each_entry_safe(xprt, xp_next, &conf->xprt_list, list) { if (!xprt->xl_private) { continue; } if (GF_ATOMIC_GET(xprt->disconnect_progress)) continue; if (xprt->xl_private->bound_xl == data) { totxprt++; } } list_for_each_entry(tmp, &conf->child_status->status_list, status_list) { if (strcmp(tmp->name, victim_name) == 0) { tmp->child_up = _gf_false; GF_ATOMIC_INIT(victim->xprtrefcnt, totxprt); break; } } /* * Disconnecting will (usually) drop the last ref, which will * cause the transport to be unlinked and freed while we're * still traversing, which will cause us to crash unless we use * list_for_each_entry_safe. */ list_for_each_entry_safe(xprt, xp_next, &conf->xprt_list, list) { if (!xprt->xl_private) { continue; } if (GF_ATOMIC_GET(xprt->disconnect_progress)) continue; if (xprt->xl_private->bound_xl == data) { gf_log(this->name, GF_LOG_INFO, "disconnecting %s", xprt->peerinfo.identifier); xprt_found = _gf_true; totdisconnect++; rpc_transport_disconnect(xprt, _gf_false); } } if (totxprt > totdisconnect) GF_ATOMIC_SUB(victim->xprtrefcnt, (totxprt - totdisconnect)); pthread_mutex_unlock(&conf->mutex); if (this->ctx->active) { top = this->ctx->active->first; LOCK(&ctx->volfile_lock); for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) { travxl = (*trav_p)->xlator; if (!travxl->call_cleanup && strcmp(travxl->name, victim_name) == 0) { victim_found = _gf_true; break; } } if (victim_found) glusterfs_delete_volfile_checksum(ctx, victim->volfile_id); UNLOCK(&ctx->volfile_lock); rpc_clnt_mgmt_pmap_signout(ctx, victim_name); if (!xprt_found && victim_found) { server_call_xlator_mem_cleanup(this, victim_name); } } GF_FREE(victim_name); break; case GF_EVENT_SIGHUP: if (conf->volfile_dir) { pthread_mutex_lock(&conf->mutex); { list_for_each_entry(xprt, &conf->xprt_list, list) { /* TODO: optimize by sending signal to only those who * fetched data once */ rpcsvc_callback_submit(conf->rpc, xprt, &server_cbk_prog, GF_CBK_FETCHSPEC, NULL, 0, NULL); } } pthread_mutex_unlock(&conf->mutex); } default_notify(this, event, data); break; default: default_notify(this, event, data); break; } ret = 0; out: return ret; } struct xlator_fops server_fops; struct xlator_cbks server_cbks = { .client_destroy = client_destroy_cbk, }; struct xlator_dumpops server_dumpops = { .priv = server_priv, .fd = gf_client_dump_fdtables, .inode = gf_client_dump_inodes, .priv_to_dict = server_priv_to_dict, .fd_to_dict = gf_client_dump_fdtables_to_dict, .inode_to_dict = gf_client_dump_inodes_to_dict, }; struct volume_options server_options[] = { {.key = {"transport-type"}, .value = {"rpc", "rpc-over-rdma", "tcp", "socket", "ib-verbs", "unix", "ib-sdp", "tcp/server", "ib-verbs/server", "rdma", "rdma*([ \t]),*([ \t])socket", "rdma*([ \t]),*([ \t])tcp", "tcp*([ \t]),*([ \t])rdma", "socket*([ \t]),*([ \t])rdma"}, .type = GF_OPTION_TYPE_STR, .default_value = "{{ volume.transport }}"}, { .key = {"transport.listen-backlog"}, .type = GF_OPTION_TYPE_INT, .default_value = "10", }, { .key = {"volume-filename.*"}, .type = GF_OPTION_TYPE_PATH, }, { .key = {"transport.tcp-user-timeout"}, .type = GF_OPTION_TYPE_TIME, .min = 0, .max = 1013, .default_value = TOSTRING(GF_NETWORK_TIMEOUT), }, { .key = {"transport.*"}, .type = GF_OPTION_TYPE_ANY, }, {.key = {"inode-lru-limit"}, .type = GF_OPTION_TYPE_INT, .min = 0, .max = 1048576, .default_value = "16384", .description = "Specifies the limit on the number of inodes " "in the lru list of the inode cache.", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"trace"}, .type = GF_OPTION_TYPE_BOOL}, { .key = {"config-directory", "conf-dir"}, .type = GF_OPTION_TYPE_PATH, }, {.key = {"rpc-auth-allow-insecure", "allow-insecure"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"root-squash"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "Map requests from uid/gid 0 to the anonymous " "uid/gid. Note that this does not apply to any other " "uids or gids that might be equally sensitive, such " "as user bin or group staff.", .op_version = {2}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"all-squash"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "Map requests from any uid/gid to the anonymous " "uid/gid. Note that this does not apply to any other " "uids or gids that might be equally sensitive, such " "as user bin or group staff.", .op_version = {GD_OP_VERSION_6_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"anonuid"}, .type = GF_OPTION_TYPE_INT, .default_value = "65534", /* RPC_NOBODY_UID */ .min = 0, .max = (uint32_t)-1, .description = "value of the uid used for the anonymous " "user/nfsnobody when root-squash/all-squash is enabled.", .op_version = {3}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"anongid"}, .type = GF_OPTION_TYPE_INT, .default_value = "65534", /* RPC_NOBODY_GID */ .min = 0, .max = (uint32_t)-1, .description = "value of the gid used for the anonymous " "user/nfsnobody when root-squash/all-squash is enabled.", .op_version = {3}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"statedump-path"}, .type = GF_OPTION_TYPE_PATH, .default_value = DEFAULT_VAR_RUN_DIRECTORY, .description = "Specifies directory in which gluster should save its" " statedumps.", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"tcp-window-size"}, .type = GF_OPTION_TYPE_SIZET, .min = GF_MIN_SOCKET_WINDOW_SIZE, .max = GF_MAX_SOCKET_WINDOW_SIZE, .description = "Specifies the window size for tcp socket.", .op_version = {1}, .flags = OPT_FLAG_SETTABLE}, /* The following two options are defined in addr.c, redifined here * * for the sake of validation during volume set from cli */ {.key = {"auth.addr.*.allow", "auth.allow"}, .setkey = "auth.addr.{{ brick.path }}.allow", .default_value = "*", .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .description = "Allow a comma separated list of addresses and/or " "hostnames to connect to the server. Option " "auth.reject overrides this option. By default, all " "connections are allowed."}, {.key = {"auth.addr.*.reject", "auth.reject"}, .setkey = "auth.addr.{{ brick.path }}.reject", .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .description = "Reject a comma separated list of addresses and/or " "hostnames to connect to the server. This option " "overrides the auth.allow option. By default, all" " connections are allowed."}, {.key = {"ssl-allow"}, .setkey = "auth.login.{{ brick.path }}.ssl-allow", .default_value = "*", .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .description = "Allow a comma separated list of common names (CN) of" "the clients that are allowed to access the server." "By default, all TLS authenticated clients are" "allowed to access the server."}, /* This is not a valid path w.r.t daemons, hence it's string */ {.key = {"auth-path"}, .type = GF_OPTION_TYPE_STR, .default_value = "{{ brick.path }}"}, {.key = {"rpc.outstanding-rpc-limit"}, .type = GF_OPTION_TYPE_INT, .min = RPCSVC_MIN_OUTSTANDING_RPC_LIMIT, .max = RPCSVC_MAX_OUTSTANDING_RPC_LIMIT, .default_value = TOSTRING(RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT), .description = "Parameter to throttle the number of incoming RPC " "requests from a client. 0 means no limit (can " "potentially run out of memory)", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_GLOBAL}, {.key = {"manage-gids"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "Resolve groups on the server-side.", .op_version = {GD_OP_VERSION_3_6_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"gid-timeout"}, .type = GF_OPTION_TYPE_INT, .default_value = "300", .description = "Timeout in seconds for the cached groups to expire.", .op_version = {GD_OP_VERSION_3_6_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"event-threads"}, .type = GF_OPTION_TYPE_INT, .min = SERVER_MIN_EVENT_THREADS, .max = SERVER_MAX_EVENT_THREADS, .default_value = TOSTRING(STARTING_EVENT_THREADS), .description = "Specifies the number of event threads to execute in " "parallel. Larger values would help process responses " "faster, depending on available processing power.", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE}, {.key = {"dynamic-auth"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "When 'on' perform dynamic authentication of volume " "options in order to allow/terminate client " "transport connection immediately in response to " "*.allow | *.reject volume set options.", .op_version = {GD_OP_VERSION_3_7_5}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"strict-auth-accept"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "strict-auth-accept reject connection with out" "a valid username and password."}, /* As we append '${volid}.vol' at the end of this path, no systemfiles would be exposed through this option */ {.key = {"volspec-directory", "volfile-path"}, .type = GF_OPTION_TYPE_PATH, .default_value = NULL}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = server_init, .fini = server_fini, .notify = server_notify, .reconfigure = server_reconfigure, .mem_acct_init = server_mem_acct_init, .dump_metrics = server_dump_metrics, .op_version = {1}, /* Present from the initial version */ .dumpops = &server_dumpops, .fops = &server_fops, .cbks = &server_cbks, .options = server_options, .identifier = "server", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/protocol/server/src/PaxHeaders.9031/authenticate.h0000644000000000000000000000013014522202451024637 xustar000000000000000029 mtime=1699284265.77602776 29 atime=1699284265.77602776 30 ctime=1699284301.900136565 glusterfs-11.1/xlators/protocol/server/src/authenticate.h0000664000175100017510000000206714522202451025125 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2007-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _AUTHENTICATE_H #define _AUTHENTICATE_H #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include typedef enum { AUTH_ACCEPT, AUTH_REJECT, AUTH_DONT_CARE } auth_result_t; typedef auth_result_t (*auth_fn_t)(dict_t *input_params, dict_t *config_params); typedef struct { void *handle; auth_fn_t authenticate; volume_opt_list_t *vol_opt; } auth_handle_t; int32_t gf_auth_init(xlator_t *xl, dict_t *auth_modules); void gf_auth_fini(dict_t *auth_modules); auth_result_t gf_authenticate(dict_t *, dict_t *, dict_t *); #endif /* _AUTHENTICATE_H */ glusterfs-11.1/xlators/protocol/server/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467023277 xustar000000000000000030 mtime=1699284279.563069287 30 atime=1699284289.995100708 30 ctime=1699284301.854136427 glusterfs-11.1/xlators/protocol/server/Makefile.in0000664000175100017510000005262514522202467023570 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol/server DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/server/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/server/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/server/PaxHeaders.9031/Makefile.am0000644000000000000000000000013014522202451023255 xustar000000000000000029 mtime=1699284265.77602776 30 atime=1699284279.539069215 29 ctime=1699284301.85513643 glusterfs-11.1/xlators/protocol/server/Makefile.am0000664000175100017510000000001614522202451023533 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/protocol/PaxHeaders.9031/auth0000644000000000000000000000013214522202515020602 xustar000000000000000030 mtime=1699284301.665135857 30 atime=1699284309.685160013 30 ctime=1699284301.665135857 glusterfs-11.1/xlators/protocol/auth/0002775000175100017510000000000014522202515021140 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/auth/PaxHeaders.9031/login0000644000000000000000000000013014522202515021710 xustar000000000000000029 mtime=1699284301.69913596 30 atime=1699284309.685160013 29 ctime=1699284301.69913596 glusterfs-11.1/xlators/protocol/auth/login/0002775000175100017510000000000014522202515022250 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/auth/login/PaxHeaders.9031/src0000644000000000000000000000013214522202515022501 xustar000000000000000030 mtime=1699284301.736136071 30 atime=1699284309.685160013 30 ctime=1699284301.736136071 glusterfs-11.1/xlators/protocol/auth/login/src/0002775000175100017510000000000014522202515023037 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/auth/login/src/PaxHeaders.9031/login.c0000644000000000000000000000013214522202451024031 xustar000000000000000030 mtime=1699284265.771027745 30 atime=1699284265.771027745 30 ctime=1699284301.736136071 glusterfs-11.1/xlators/protocol/auth/login/src/login.c0000664000175100017510000001647414522202451024324 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "authenticate.h" /* Note on strict_auth * - Strict auth kicks in when authentication is using the username, password * in the volfile to login * - If enabled, auth is rejected if the username and password is not matched * or is not present * - When using SSL names, this is automatically strict, and allows only those * names that are present in the allow list, IOW strict auth checking has no * implication when using SSL names */ auth_result_t gf_auth(dict_t *input_params, dict_t *config_params) { auth_result_t result = AUTH_DONT_CARE; int ret = 0; data_t *allow_user = NULL; data_t *username_data = NULL; data_t *passwd_data = NULL; data_t *password_data = NULL; char *username = NULL; char *password = NULL; char *brick_name = NULL; char *searchstr = NULL; char *username_str = NULL; char *tmp = NULL; char *username_cpy = NULL; gf_boolean_t using_ssl = _gf_false; gf_boolean_t strict_auth = _gf_false; username_data = dict_get(input_params, "ssl-name"); if (username_data) { gf_log("auth/login", GF_LOG_INFO, "connecting user name: %s", username_data->data); using_ssl = _gf_true; } else { ret = dict_get_str_boolean(config_params, "strict-auth-accept", _gf_false); if (ret == -1) strict_auth = _gf_false; else strict_auth = ret; username_data = dict_get(input_params, "username"); if (!username_data) { if (strict_auth) { gf_log("auth/login", GF_LOG_DEBUG, "username not found, strict auth" " configured returning REJECT"); result = AUTH_REJECT; } else { gf_log("auth/login", GF_LOG_DEBUG, "username not found, returning" " DONT-CARE"); } goto out; } password_data = dict_get(input_params, "password"); if (!password_data) { if (strict_auth) { gf_log("auth/login", GF_LOG_DEBUG, "password not found, strict auth" " configured returning REJECT"); result = AUTH_REJECT; } else { gf_log("auth/login", GF_LOG_WARNING, "password not found, returning" " DONT-CARE"); } goto out; } password = data_to_str(password_data); } username = data_to_str(username_data); brick_name = data_to_str(dict_get(input_params, "remote-subvolume")); if (!brick_name) { gf_log("auth/login", GF_LOG_ERROR, "remote-subvolume not specified"); result = AUTH_REJECT; goto out; } ret = gf_asprintf(&searchstr, "auth.login.%s.%s", brick_name, using_ssl ? "ssl-allow" : "allow"); if (-1 == ret) { gf_log("auth/login", GF_LOG_ERROR, "asprintf failed while setting search string, " "returning REJECT"); result = AUTH_REJECT; goto out; } allow_user = dict_get(config_params, searchstr); GF_FREE(searchstr); if (allow_user) { gf_log("auth/login", GF_LOG_INFO, "allowed user names: %s", allow_user->data); /* * There's a subtle difference between SSL and non-SSL behavior * if we can't match anything in the "while" loop below. * Intuitively, we should AUTH_REJECT if there's no match. * However, existing code depends on allowing untrusted users * to connect with *no credentials at all* by falling through * the loop. They're still distinguished from trusted users * who do provide a valid username and password (in fact that's * pretty much the only thing we use non-SSL login auth for), * but they are allowed to connect. It's wrong, but it's not * worth changing elsewhere. Therefore, we do the sane thing * only for SSL here. * * For SSL, if there's a list *you must be on it*. Note that * if there's no list we don't care. In that case (and the * ssl-allow=* case as well) authorization is effectively * disabled, though authentication and encryption are still * active. * * Read NOTE on strict_auth above. */ if (using_ssl || strict_auth) { result = AUTH_REJECT; } username_cpy = gf_strdup(allow_user->data); if (!username_cpy) goto out; username_str = strtok_r(username_cpy, " ,", &tmp); /* * We have to match a user's *authenticated* name to one in the * list. If we're using SSL, they're already authenticated. * Otherwise, they need a matching password to complete the * process. */ while (username_str) { if (!fnmatch(username_str, username, 0)) { if (using_ssl) { result = AUTH_ACCEPT; break; } ret = gf_asprintf(&searchstr, "auth.login.%s.password", username); if (-1 == ret) { gf_log("auth/login", GF_LOG_WARNING, "asprintf failed while setting search string"); goto out; } passwd_data = dict_get(config_params, searchstr); GF_FREE(searchstr); if (!passwd_data) { gf_log("auth/login", GF_LOG_ERROR, "wrong username/password combination"); result = AUTH_REJECT; goto out; } result = !((strcmp(data_to_str(passwd_data), password)) ? AUTH_ACCEPT : AUTH_REJECT); if (result == AUTH_REJECT) gf_log("auth/login", GF_LOG_ERROR, "wrong password for user %s", username); break; } username_str = strtok_r(NULL, " ,", &tmp); } } out: GF_FREE(username_cpy); return result; } struct volume_options options[] = { { .key = {"auth.login.*.allow"}, .type = GF_OPTION_TYPE_ANY, .default_value = "*", .description = "Username to be allowed access to the volume", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {}, /* option_validation_fn validate_fn; */ }, { .key = {"auth.login.*.password"}, .type = GF_OPTION_TYPE_ANY, .default_value = "*", .description = "Password for the allowed username", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {}, /* option_validation_fn validate_fn; */ }, {.key = {NULL}}}; glusterfs-11.1/xlators/protocol/auth/login/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467024631 xustar000000000000000030 mtime=1699284279.444068929 30 atime=1699284289.928100506 30 ctime=1699284301.733136062 glusterfs-11.1/xlators/protocol/auth/login/src/Makefile.in0000664000175100017510000005672114522202467025123 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol/auth/login/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(authdir)" LTLIBRARIES = $(auth_LTLIBRARIES) login_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_login_la_OBJECTS = login.lo login_la_OBJECTS = $(am_login_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = login_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(login_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(login_la_SOURCES) DIST_SOURCES = $(login_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ auth_LTLIBRARIES = login.la authdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/auth login_la_LDFLAGS = -module $(GF_XLATOR_LDFLAGS) login_la_SOURCES = login.c login_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/protocol/server/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/auth/login/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/auth/login/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-authLTLIBRARIES: $(auth_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(auth_LTLIBRARIES)'; test -n "$(authdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(authdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(authdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(authdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(authdir)"; \ } uninstall-authLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(auth_LTLIBRARIES)'; test -n "$(authdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(authdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(authdir)/$$f"; \ done clean-authLTLIBRARIES: -test -z "$(auth_LTLIBRARIES)" || rm -f $(auth_LTLIBRARIES) @list='$(auth_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } login.la: $(login_la_OBJECTS) $(login_la_DEPENDENCIES) $(EXTRA_login_la_DEPENDENCIES) $(AM_V_CCLD)$(login_la_LINK) -rpath $(authdir) $(login_la_OBJECTS) $(login_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/login.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(authdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-authLTLIBRARIES clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-authLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-authLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-authLTLIBRARIES clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-authLTLIBRARIES install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-authLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/auth/login/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024611 xustar000000000000000030 mtime=1699284265.771027745 30 atime=1699284279.407068817 30 ctime=1699284301.735136068 glusterfs-11.1/xlators/protocol/auth/login/src/Makefile.am0000664000175100017510000000065514522202451025076 0ustar00jenkinsjenkins00000000000000auth_LTLIBRARIES = login.la authdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/auth login_la_LDFLAGS = -module $(GF_XLATOR_LDFLAGS) login_la_SOURCES = login.c login_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/protocol/server/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) glusterfs-11.1/xlators/protocol/auth/login/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467024042 xustar000000000000000030 mtime=1699284279.396068784 30 atime=1699284289.903100431 30 ctime=1699284301.693135942 glusterfs-11.1/xlators/protocol/auth/login/Makefile.in0000664000175100017510000005264114522202467024331 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol/auth/login DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/auth/login/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/auth/login/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/auth/login/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024022 xustar000000000000000030 mtime=1699284265.770027742 30 atime=1699284279.372068712 30 ctime=1699284301.695135948 glusterfs-11.1/xlators/protocol/auth/login/Makefile.am0000664000175100017510000000001614522202451024276 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/protocol/auth/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202467022731 xustar000000000000000030 mtime=1699284279.280068435 29 atime=1699284289.83310022 30 ctime=1699284301.585135616 glusterfs-11.1/xlators/protocol/auth/Makefile.in0000664000175100017510000005262614522202467023224 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol/auth DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = addr login all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/auth/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/auth/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/auth/PaxHeaders.9031/addr0000644000000000000000000000013014522202515021512 xustar000000000000000029 mtime=1699284301.62613574 30 atime=1699284309.685160013 29 ctime=1699284301.62613574 glusterfs-11.1/xlators/protocol/auth/addr/0002775000175100017510000000000014522202515022052 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/auth/addr/PaxHeaders.9031/src0000644000000000000000000000013214522202515022303 xustar000000000000000030 mtime=1699284301.662135848 30 atime=1699284309.685160013 30 ctime=1699284301.662135848 glusterfs-11.1/xlators/protocol/auth/addr/src/0002775000175100017510000000000014522202515022641 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/protocol/auth/addr/src/PaxHeaders.9031/addr.c0000644000000000000000000000013214522202451023435 xustar000000000000000030 mtime=1699284265.770027742 30 atime=1699284265.770027742 30 ctime=1699284301.662135848 glusterfs-11.1/xlators/protocol/auth/addr/src/addr.c0000664000175100017510000002316514522202451023723 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "authenticate.h" #include #include "rpc-transport.h" #define ENTRY_DELIMITER "," #define ADDR_DELIMITER "|" #define PRIVILEGED_PORT_CEILING 1024 #ifndef AF_INET_SDP #define AF_INET_SDP 27 #endif /* An option for subdir validation be like below */ /* 1. '*' 2. '192.168.*' 3. ' 4. '!10.10.1*' (Today as per the code, if negate is set on one entry, its never reset) 5. '192.168.1.*, 10.1.10.*';168.168.2.* =/dir;* =/another-dir' */ int compare_addr_and_update(char *option_str, char *peer_addr, char *subvol, char *delimiter, auth_result_t *result, auth_result_t status) { char *addr_str = NULL; char *tmp = NULL; char negate = 0; char match = 0; int length = 0; int ret = 0; addr_str = strtok_r(option_str, delimiter, &tmp); while (addr_str) { gf_log(subvol, GF_LOG_INFO, "%s = \"%s\", received addr = \"%s\"", (status == AUTH_ACCEPT) ? "allowed" : "rejected", addr_str, peer_addr); if (addr_str[0] == '!') { negate = 1; addr_str++; } length = strlen(addr_str); if ((addr_str[0] != '*') && valid_host_name(addr_str, length)) { match = gf_is_same_address(addr_str, peer_addr); if (match) { *result = status; goto out; } } else { if (strstr(addr_str, "/")) { match = gf_is_ip_in_net(addr_str, peer_addr); if (negate ? !match : match) { *result = status; goto out; } } else { match = fnmatch(addr_str, peer_addr, 0); if (negate ? match : !match) { *result = status; goto out; } } } addr_str = strtok_r(NULL, delimiter, &tmp); } ret = -1; out: return ret; } void parse_entries_and_compare(char *option_str, char *peer_addr, char *subvol, char *subdir, auth_result_t *result, auth_result_t status) { char *entry = NULL; char *entry_cpy = NULL; char *directory = NULL; char *entries = NULL; char *addr_str = NULL; char *addr = NULL; char *tmp = NULL; char *tmpdir = NULL; int ret = 0; if (!subdir) { gf_log(subvol, GF_LOG_WARNING, "subdir entry not present, not performing any operation."); goto out; } entries = gf_strdup(option_str); if (!entries) goto out; if (entries[0] != '/' && !strchr(entries, '(')) { /* Backward compatible option */ ret = compare_addr_and_update(entries, peer_addr, subvol, ",", result, status); goto out; } entry = strtok_r(entries, ENTRY_DELIMITER, &tmp); while (entry) { entry_cpy = gf_strdup(entry); if (!entry_cpy) { goto out; } directory = strtok_r(entry_cpy, "(", &tmpdir); if (directory[0] != '/') goto out; /* send second portion, after ' =' if directory matches */ if (strcmp(subdir, directory)) goto next_entry; addr_str = strtok_r(NULL, ")", &tmpdir); if (!addr_str) goto out; addr = gf_strdup(addr_str); if (!addr) goto out; gf_log(subvol, GF_LOG_INFO, "Found an entry for dir %s (%s)," " performing validation", subdir, addr); ret = compare_addr_and_update(addr, peer_addr, subvol, ADDR_DELIMITER, result, status); if (ret == 0) { break; } GF_FREE(addr); addr = NULL; next_entry: entry = strtok_r(NULL, ENTRY_DELIMITER, &tmp); GF_FREE(entry_cpy); entry_cpy = NULL; } out: GF_FREE(entries); GF_FREE(entry_cpy); GF_FREE(addr); } auth_result_t gf_auth(dict_t *input_params, dict_t *config_params) { auth_result_t result = AUTH_DONT_CARE; int ret = 0; char *name = NULL; char *searchstr = NULL; peer_info_t *peer_info = NULL; data_t *peer_info_data = NULL; data_t *allow_addr = NULL; data_t *reject_addr = NULL; char *service = NULL; uint16_t peer_port = 0; char peer_addr[UNIX_PATH_MAX] = { 0, }; char *type = NULL; gf_boolean_t allow_insecure = _gf_false; char *subdir = NULL; name = data_to_str(dict_get(input_params, "remote-subvolume")); if (!name) { gf_log("authenticate/addr", GF_LOG_DEBUG, "remote-subvolume not specified"); goto out; } ret = gf_asprintf(&searchstr, "auth.addr.%s.allow", name); if (-1 == ret) { gf_log("auth/addr", GF_LOG_DEBUG, "asprintf failed while setting search string"); goto out; } allow_addr = dict_get(config_params, searchstr); GF_FREE(searchstr); ret = gf_asprintf(&searchstr, "auth.addr.%s.reject", name); if (-1 == ret) { gf_log("auth/addr", GF_LOG_ERROR, "asprintf failed while setting search string"); goto out; } reject_addr = dict_get(config_params, searchstr); GF_FREE(searchstr); if (!allow_addr) { /* TODO: backward compatibility */ ret = gf_asprintf(&searchstr, "auth.ip.%s.allow", name); if (-1 == ret) { gf_log("auth/addr", GF_LOG_ERROR, "asprintf failed while setting search string"); goto out; } allow_addr = dict_get(config_params, searchstr); GF_FREE(searchstr); } if (!(allow_addr || reject_addr)) { gf_log("auth/addr", GF_LOG_DEBUG, "none of the options auth.addr.%s.allow or " "auth.addr.%s.reject specified, returning auth_dont_care", name, name); goto out; } peer_info_data = dict_get(input_params, "peer-info"); if (!peer_info_data) { gf_log("auth/addr", GF_LOG_ERROR, "peer-info not present"); goto out; } ret = dict_get_str(input_params, "subdir-mount", &subdir); if (ret) { subdir = "/"; } peer_info = data_to_ptr(peer_info_data); switch (((struct sockaddr *)&peer_info->sockaddr)->sa_family) { case AF_INET_SDP: case AF_INET: case AF_INET6: strcpy(peer_addr, peer_info->identifier); service = strrchr(peer_addr, ':'); *service = '\0'; service++; ret = dict_get_str(config_params, "rpc-auth-allow-insecure", &type); if (ret == 0) { ret = gf_string2boolean(type, &allow_insecure); if (ret < 0) { gf_log("auth/addr", GF_LOG_WARNING, "rpc-auth-allow-insecure option %s " "is not a valid bool option", type); goto out; } } peer_port = atoi(service); if (peer_port >= PRIVILEGED_PORT_CEILING && !allow_insecure) { gf_log("auth/addr", GF_LOG_ERROR, "client is bound to port %d which is not privileged", peer_port); result = AUTH_REJECT; goto out; } break; case AF_UNIX: strcpy(peer_addr, peer_info->identifier); break; default: gf_log("authenticate/addr", GF_LOG_ERROR, "unknown address family %d", ((struct sockaddr *)&peer_info->sockaddr)->sa_family); goto out; } if (reject_addr) { parse_entries_and_compare(reject_addr->data, peer_addr, name, subdir, &result, AUTH_REJECT); if (result == AUTH_REJECT) goto out; } if (allow_addr) { parse_entries_and_compare(allow_addr->data, peer_addr, name, subdir, &result, AUTH_ACCEPT); } out: return result; } struct volume_options options[] = { { .key = {"auth.addr.*.allow"}, .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .default_value = "*", .description = "List of addresses to be allowed to access volume", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {}, /* option_validation_fn validate_fn; */ }, { .key = {"auth.addr.*.reject"}, .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .default_value = "*", .description = "List of addresses to be rejected to access volume", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {}, /* option_validation_fn validate_fn; */ }, /* Backward compatibility */ { .key = {"auth.ip.*.allow"}, .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .default_value = "*", .description = "List of addresses to be allowed to access volume", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {}, /* option_validation_fn validate_fn; */ }, {.key = {NULL}}}; glusterfs-11.1/xlators/protocol/auth/addr/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467024433 xustar000000000000000030 mtime=1699284279.362068682 30 atime=1699284289.879100359 30 ctime=1699284301.659135839 glusterfs-11.1/xlators/protocol/auth/addr/src/Makefile.in0000664000175100017510000005673614522202467024733 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol/auth/addr/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(authdir)" LTLIBRARIES = $(auth_LTLIBRARIES) addr_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_addr_la_OBJECTS = addr.lo addr_la_OBJECTS = $(am_addr_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = addr_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(addr_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(addr_la_SOURCES) DIST_SOURCES = $(addr_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ auth_LTLIBRARIES = addr.la authdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/auth addr_la_LDFLAGS = -module $(GF_XLATOR_LDFLAGS) addr_la_SOURCES = addr.c addr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/protocol/server/src \ -I$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ \ -I$(top_srcdir)/rpc/rpc-lib/src/ AM_CFLAGS = -Wall $(GF_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/auth/addr/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/auth/addr/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-authLTLIBRARIES: $(auth_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(auth_LTLIBRARIES)'; test -n "$(authdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(authdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(authdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(authdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(authdir)"; \ } uninstall-authLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(auth_LTLIBRARIES)'; test -n "$(authdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(authdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(authdir)/$$f"; \ done clean-authLTLIBRARIES: -test -z "$(auth_LTLIBRARIES)" || rm -f $(auth_LTLIBRARIES) @list='$(auth_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } addr.la: $(addr_la_OBJECTS) $(addr_la_DEPENDENCIES) $(EXTRA_addr_la_DEPENDENCIES) $(AM_V_CCLD)$(addr_la_LINK) -rpath $(authdir) $(addr_la_OBJECTS) $(addr_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addr.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(authdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-authLTLIBRARIES clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-authLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-authLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-authLTLIBRARIES clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-authLTLIBRARIES install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-authLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/auth/addr/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451024412 xustar000000000000000030 mtime=1699284265.770027742 29 atime=1699284279.32506857 30 ctime=1699284301.660135842 glusterfs-11.1/xlators/protocol/auth/addr/src/Makefile.am0000664000175100017510000000071614522202451024676 0ustar00jenkinsjenkins00000000000000auth_LTLIBRARIES = addr.la authdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/auth addr_la_LDFLAGS = -module $(GF_XLATOR_LDFLAGS) addr_la_SOURCES = addr.c addr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/protocol/server/src \ -I$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ \ -I$(top_srcdir)/rpc/rpc-lib/src/ AM_CFLAGS = -Wall $(GF_CFLAGS) glusterfs-11.1/xlators/protocol/auth/addr/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202467023643 xustar000000000000000029 mtime=1699284279.31506854 30 atime=1699284289.855100287 30 ctime=1699284301.619135719 glusterfs-11.1/xlators/protocol/auth/addr/Makefile.in0000664000175100017510000005263614522202467024137 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol/auth/addr DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/auth/addr/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/auth/addr/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/auth/addr/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023624 xustar000000000000000030 mtime=1699284265.770027742 30 atime=1699284279.291068468 30 ctime=1699284301.621135725 glusterfs-11.1/xlators/protocol/auth/addr/Makefile.am0000664000175100017510000000001614522202451024100 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/protocol/auth/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451022712 xustar000000000000000030 mtime=1699284265.770027742 30 atime=1699284279.256068363 30 ctime=1699284301.587135623 glusterfs-11.1/xlators/protocol/auth/Makefile.am0000664000175100017510000000002514522202451023166 0ustar00jenkinsjenkins00000000000000SUBDIRS = addr login glusterfs-11.1/xlators/protocol/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467021771 xustar000000000000000030 mtime=1699284279.246068332 30 atime=1699284289.814100163 30 ctime=1699284301.550135511 glusterfs-11.1/xlators/protocol/Makefile.in0000664000175100017510000005261714522202467022263 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/protocol DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = auth client server all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/protocol/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/protocol/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/protocol/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451021750 xustar000000000000000030 mtime=1699284265.770027742 29 atime=1699284279.22206826 30 ctime=1699284301.551135514 glusterfs-11.1/xlators/protocol/Makefile.am0000664000175100017510000000003514522202451022226 0ustar00jenkinsjenkins00000000000000SUBDIRS = auth client server glusterfs-11.1/xlators/PaxHeaders.9031/system0000644000000000000000000000013214522202522017322 xustar000000000000000030 mtime=1699284306.703151031 30 atime=1699284309.685160013 30 ctime=1699284306.703151031 glusterfs-11.1/xlators/system/0002775000175100017510000000000014522202522017660 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/system/PaxHeaders.9031/posix-acl0000644000000000000000000000013214522202522021221 xustar000000000000000030 mtime=1699284306.741151146 30 atime=1699284309.685160013 30 ctime=1699284306.741151146 glusterfs-11.1/xlators/system/posix-acl/0002775000175100017510000000000014522202522021557 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/system/posix-acl/PaxHeaders.9031/src0000644000000000000000000000013214522202522022010 xustar000000000000000030 mtime=1699284306.787151284 30 atime=1699284309.685160013 30 ctime=1699284306.787151284 glusterfs-11.1/xlators/system/posix-acl/src/0002775000175100017510000000000014522202522022346 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/system/posix-acl/src/PaxHeaders.9031/posix-acl-messages.h0000644000000000000000000000013214522202451025743 xustar000000000000000030 mtime=1699284265.789027799 30 atime=1699284265.789027799 30 ctime=1699284306.784151275 glusterfs-11.1/xlators/system/posix-acl/src/posix-acl-messages.h0000664000175100017510000000157414522202451026231 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _POSIX_ACL_MESSAGES_H_ #define _POSIX_ACL_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(POSIX_ACL, POSIX_ACL_MSG_EACCES); #endif /* !_POSIX_ACL_MESSAGES_H_ */ glusterfs-11.1/xlators/system/posix-acl/src/PaxHeaders.9031/posix-acl-xattr.c0000644000000000000000000000013214522202451025271 xustar000000000000000030 mtime=1699284265.789027799 30 atime=1699284265.789027799 30 ctime=1699284306.787151284 glusterfs-11.1/xlators/system/posix-acl/src/posix-acl-xattr.c0000664000175100017510000000777114522202451025564 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2011-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #ifdef __FreeBSD__ #include #else #include #endif #include #include "posix-acl.h" #include "posix-acl-xattr.h" int posix_ace_cmp(const void *val1, const void *val2) { const struct posix_ace *ace1 = NULL; const struct posix_ace *ace2 = NULL; int ret = 0; ace1 = val1; ace2 = val2; ret = (ace1->tag - ace2->tag); if (!ret) ret = (ace1->id - ace2->id); return ret; } void posix_acl_normalize(xlator_t *this, struct posix_acl *acl) { qsort(acl->entries, acl->count, sizeof(struct posix_ace *), posix_ace_cmp); } struct posix_acl * posix_acl_from_xattr(xlator_t *this, const char *xattr_buf, int xattr_size) { struct posix_acl_xattr_header *header = NULL; struct posix_acl_xattr_entry *entry = NULL; struct posix_acl *acl = NULL; struct posix_ace *ace = NULL; int size = 0; int count = 0; int i = 0; size = xattr_size; if (size < sizeof(*header)) return NULL; size -= sizeof(*header); if (size % sizeof(*entry)) return NULL; count = size / sizeof(*entry); header = (struct posix_acl_xattr_header *)(xattr_buf); entry = (struct posix_acl_xattr_entry *)(header + 1); if (header->version != htole32(POSIX_ACL_XATTR_VERSION)) return NULL; acl = posix_acl_new(this, count); if (!acl) return NULL; ace = acl->entries; for (i = 0; i < count; i++) { ace->tag = le16toh(entry->tag); ace->perm = le16toh(entry->perm); switch (ace->tag) { case POSIX_ACL_USER_OBJ: case POSIX_ACL_MASK: case POSIX_ACL_OTHER: ace->id = POSIX_ACL_UNDEFINED_ID; break; case POSIX_ACL_GROUP: case POSIX_ACL_USER: case POSIX_ACL_GROUP_OBJ: ace->id = le32toh(entry->id); break; default: goto err; } ace++; entry++; } posix_acl_normalize(this, acl); return acl; err: posix_acl_destroy(this, acl); return NULL; } int posix_acl_to_xattr(xlator_t *this, struct posix_acl *acl, char *xattr_buf, int xattr_size) { int size = 0; struct posix_acl_xattr_header *header = NULL; struct posix_acl_xattr_entry *entry = NULL; struct posix_ace *ace = NULL; int i = 0; size = sizeof(*header) + (acl->count * sizeof(*entry)); if (xattr_size < size) return size; header = (struct posix_acl_xattr_header *)(xattr_buf); entry = (struct posix_acl_xattr_entry *)(header + 1); ace = acl->entries; header->version = htole32(POSIX_ACL_XATTR_VERSION); for (i = 0; i < acl->count; i++) { entry->tag = htole16(ace->tag); entry->perm = htole16(ace->perm); switch (ace->tag) { case POSIX_ACL_USER: case POSIX_ACL_GROUP: entry->id = htole32(ace->id); break; default: entry->id = POSIX_ACL_UNDEFINED_ID; break; } ace++; entry++; } return 0; } int posix_acl_matches_xattr(xlator_t *this, struct posix_acl *acl, const char *buf, int size) { struct posix_acl *acl2 = NULL; int ret = 1; acl2 = posix_acl_from_xattr(this, buf, size); if (!acl2) return 0; if (acl->count != acl2->count) { ret = 0; goto out; } if (memcmp(acl->entries, acl2->entries, (acl->count * sizeof(struct posix_ace)))) ret = 0; out: posix_acl_destroy(this, acl2); return ret; } glusterfs-11.1/xlators/system/posix-acl/src/PaxHeaders.9031/posix-acl-mem-types.h0000644000000000000000000000013214522202451026054 xustar000000000000000030 mtime=1699284265.789027799 30 atime=1699284265.789027799 30 ctime=1699284306.782151269 glusterfs-11.1/xlators/system/posix-acl/src/posix-acl-mem-types.h0000664000175100017510000000130614522202451026333 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __POSIX_ACL_MEM_TYPES_H__ #define __POSIX_ACL_MEM_TYPES_H__ #include typedef enum gf_posix_acl_mem_types_ { gf_posix_acl_mt_ctx_t = gf_common_mt_end + 1, gf_posix_acl_mt_posix_ace_t, gf_posix_acl_mt_char, gf_posix_acl_mt_conf_t, gf_posix_acl_mt_end } gf_posix_acl_mem_types_t; #endif glusterfs-11.1/xlators/system/posix-acl/src/PaxHeaders.9031/posix-acl-xattr.h0000644000000000000000000000013214522202451025276 xustar000000000000000030 mtime=1699284265.789027799 30 atime=1699284265.789027799 30 ctime=1699284306.781151266 glusterfs-11.1/xlators/system/posix-acl/src/posix-acl-xattr.h0000664000175100017510000000145314522202451025560 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2011-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _POSIX_ACL_XATTR_H #define _POSIX_ACL_XATTR_H #include "posix-acl.h" #include struct posix_acl * posix_acl_from_xattr(xlator_t *this, const char *buf, int size); int posix_acl_to_xattr(xlator_t *this, struct posix_acl *acl, char *buf, int size); int posix_acl_matches_xattr(xlator_t *this, struct posix_acl *acl, const char *buf, int size); #endif /* !_POSIX_ACL_XATTR_H */ glusterfs-11.1/xlators/system/posix-acl/src/PaxHeaders.9031/posix-acl.h0000644000000000000000000000013114522202451024135 xustar000000000000000030 mtime=1699284265.790027802 30 atime=1699284265.789027799 29 ctime=1699284306.77915126 glusterfs-11.1/xlators/system/posix-acl/src/posix-acl.h0000664000175100017510000000201714522202451024415 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2011-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _POSIX_ACL_H #define _POSIX_ACL_H struct posix_acl * posix_acl_new(xlator_t *this, int entry_count); struct posix_acl * posix_acl_ref(xlator_t *this, struct posix_acl *acl); void posix_acl_unref(xlator_t *this, struct posix_acl *acl); void posix_acl_destroy(xlator_t *this, struct posix_acl *acl); struct posix_acl_ctx * posix_acl_ctx_get(inode_t *inode, xlator_t *this); int posix_acl_get(inode_t *inode, xlator_t *this, struct posix_acl **acl_access_p, struct posix_acl **acl_default_p); int posix_acl_set(inode_t *inode, xlator_t *this, struct posix_acl *acl_access, struct posix_acl *acl_default); #endif /* !_POSIX_ACL_H */ glusterfs-11.1/xlators/system/posix-acl/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467024142 xustar000000000000000030 mtime=1699284279.851070155 30 atime=1699284291.506105259 30 ctime=1699284306.775151248 glusterfs-11.1/xlators/system/posix-acl/src/Makefile.in0000664000175100017510000006066514522202467024436 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/system/posix-acl/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) posix_acl_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_posix_acl_la_OBJECTS = posix-acl.lo posix-acl-xattr.lo posix_acl_la_OBJECTS = $(am_posix_acl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = posix_acl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(posix_acl_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(posix_acl_la_SOURCES) DIST_SOURCES = $(posix_acl_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = posix-acl.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/system posix_acl_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) posix_acl_la_SOURCES = posix-acl.c posix-acl-xattr.c posix_acl_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = posix-acl.h posix-acl-xattr.h posix-acl-mem-types.h \ posix-acl-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) AM_LDFLAGS = -L$(xlatordir) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/system/posix-acl/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/system/posix-acl/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } posix-acl.la: $(posix_acl_la_OBJECTS) $(posix_acl_la_DEPENDENCIES) $(EXTRA_posix_acl_la_DEPENDENCIES) $(AM_V_CCLD)$(posix_acl_la_LINK) -rpath $(xlatordir) $(posix_acl_la_OBJECTS) $(posix_acl_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix-acl-xattr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix-acl.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-exec-local install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip install-xlatorLTLIBRARIES installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-local \ uninstall-xlatorLTLIBRARIES access-control-compat: mkdir -p $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features rm -rf $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features/access-control.so ln -s ../system/posix-acl.so $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features/access-control.so install-exec-local: access-control-compat uninstall-local: rm -f $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features/access-control.so # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/system/posix-acl/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451024121 xustar000000000000000030 mtime=1699284265.789027799 29 atime=1699284279.81307004 30 ctime=1699284306.777151254 glusterfs-11.1/xlators/system/posix-acl/src/Makefile.am0000664000175100017510000000201114522202451024373 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = posix-acl.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/system posix_acl_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) posix_acl_la_SOURCES = posix-acl.c posix-acl-xattr.c posix_acl_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = posix-acl.h posix-acl-xattr.h posix-acl-mem-types.h \ posix-acl-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) AM_LDFLAGS = -L$(xlatordir) CLEANFILES = access-control-compat: mkdir -p $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features rm -rf $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features/access-control.so ln -s ../system/posix-acl.so $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features/access-control.so install-exec-local: access-control-compat uninstall-local: rm -f $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features/access-control.so glusterfs-11.1/xlators/system/posix-acl/src/PaxHeaders.9031/posix-acl.c0000644000000000000000000000013214522202451024131 xustar000000000000000030 mtime=1699284265.789027799 30 atime=1699284265.789027799 30 ctime=1699284306.785151278 glusterfs-11.1/xlators/system/posix-acl/src/posix-acl.c0000664000175100017510000015777614522202451024437 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2011-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "posix-acl.h" #include "posix-acl-xattr.h" #include "posix-acl-mem-types.h" #include "posix-acl-messages.h" #define UINT64(ptr) ((uint64_t)((long)(ptr))) #define PTR(num) ((void *)((long)(num))) int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_posix_acl_mt_end); if (ret != 0) { gf_log(this->name, GF_LOG_ERROR, "Memory accounting init" "failed"); return ret; } return ret; } static uid_t r00t(void) { struct posix_acl_conf *conf = NULL; conf = THIS->private; return conf->super_uid; } static int allowed_xattr(const char *key) { if (!key) return 0; if (strcmp(POSIX_ACL_ACCESS_XATTR, key) == 0) return 1; if (strcmp(POSIX_ACL_DEFAULT_XATTR, key) == 0) return 1; if (strcmp(GF_POSIX_ACL_ACCESS, key) == 0) return 1; if (strcmp(GF_POSIX_ACL_DEFAULT, key) == 0) return 1; return 0; } int frame_is_user(call_frame_t *frame, uid_t uid) { return (frame->root->uid == uid); } int frame_is_super_user(call_frame_t *frame) { int ret; ret = frame_is_user(frame, r00t()); if (!ret) ret = frame_is_user(frame, 0); return ret; } int frame_in_group(call_frame_t *frame, gid_t gid) { int i = 0; if (frame->root->gid == gid) return 1; for (i = 0; i < frame->root->ngrps; i++) if (frame->root->groups[i] == gid) return 1; return 0; } mode_t posix_acl_access_set_mode(struct posix_acl *acl, struct posix_acl_ctx *ctx) { struct posix_ace *ace = NULL; struct posix_ace *group_ce = NULL; struct posix_ace *mask_ce = NULL; int count = 0; int i = 0; mode_t mode = 0; int mask = 0; count = acl->count; ace = acl->entries; for (i = 0; i < count; i++) { switch (ace->tag) { case POSIX_ACL_USER_OBJ: mask |= S_IRWXU; mode |= (ace->perm << 6); break; case POSIX_ACL_GROUP_OBJ: group_ce = ace; break; case POSIX_ACL_MASK: mask_ce = ace; break; case POSIX_ACL_OTHER: mask |= S_IRWXO; mode |= (ace->perm); break; } ace++; } if (mask_ce) { mask |= S_IRWXG; mode |= (mask_ce->perm << 3); } else { if (!group_ce) goto out; mask |= S_IRWXG; mode |= (group_ce->perm << 3); } out: ctx->perm = (ctx->perm & ~mask) | mode; return mode; } static int sticky_permits(call_frame_t *frame, inode_t *parent, inode_t *inode) { struct posix_acl_ctx *par = NULL; struct posix_acl_ctx *ctx = NULL; if ((0 > frame->root->pid) || frame_is_super_user(frame)) return 1; par = posix_acl_ctx_get(parent, frame->this); if (par == NULL) return 0; ctx = posix_acl_ctx_get(inode, frame->this); if (ctx == NULL) return 0; if (!(par->perm & S_ISVTX)) return 1; if (frame_is_user(frame, par->uid)) return 1; if (frame_is_user(frame, ctx->uid)) return 1; return 0; } static gf_boolean_t _does_acl_exist(struct posix_acl *acl) { if (acl && (acl->count > POSIX_ACL_MINIMAL_ACE_COUNT)) return _gf_true; return _gf_false; } static void posix_acl_get_acl_string(call_frame_t *frame, struct posix_acl *acl, char **acl_str) { int i = 0; size_t size_acl = 0; size_t offset = 0; struct posix_ace *ace = NULL; char tmp_str[1024] = {0}; #define NON_GRP_FMT "(tag:%" PRIu16 ",perm:%" PRIu16 ",id:%" PRIu32 ")" #define GRP_FMT "(tag:%" PRIu16 ",perm:%" PRIu16 ",id:%" PRIu32 ",in-groups:%d)" if (!_does_acl_exist(acl)) goto out; ace = acl->entries; for (i = 0; i < acl->count; i++) { if (ace->tag != POSIX_ACL_GROUP) { size_acl += snprintf(tmp_str, sizeof tmp_str, NON_GRP_FMT, ace->tag, ace->perm, ace->id); } else { size_acl += snprintf(tmp_str, sizeof tmp_str, GRP_FMT, ace->tag, ace->perm, ace->id, frame_in_group(frame, ace->id)); } ace++; } *acl_str = GF_CALLOC(1, size_acl + 1, gf_posix_acl_mt_char); if (!*acl_str) goto out; ace = acl->entries; for (i = 0; i < acl->count; i++) { if (ace->tag != POSIX_ACL_GROUP) { offset += snprintf(*acl_str + offset, size_acl - offset, NON_GRP_FMT, ace->tag, ace->perm, ace->id); } else { offset += snprintf(*acl_str + offset, size_acl - offset, GRP_FMT, ace->tag, ace->perm, ace->id, frame_in_group(frame, ace->id)); } ace++; } out: return; } static void posix_acl_log_permit_denied(call_frame_t *frame, inode_t *inode, int want, struct posix_acl_ctx *ctx, struct posix_acl *acl) { char *acl_str = NULL; client_t *client = NULL; if (!frame || !inode || !ctx || !frame->root) goto out; client = frame->root->client; posix_acl_get_acl_string(frame, acl, &acl_str); gf_msg(frame->this->name, GF_LOG_INFO, EACCES, POSIX_ACL_MSG_EACCES, "client: %s, gfid: %s, req(uid:%d,gid:%d,perm:%d," "ngrps:%" PRIu16 "), ctx(uid:%d,gid:%d,in-groups:%d,perm:%d%d%d," "updated-fop:%s, acl:%s)", client ? client->client_uid : "-", uuid_utoa(inode->gfid), frame->root->uid, frame->root->gid, want, frame->root->ngrps, ctx->uid, ctx->gid, frame_in_group(frame, ctx->gid), (ctx->perm & S_IRWXU) >> 6, (ctx->perm & S_IRWXG) >> 3, ctx->perm & S_IRWXO, gf_fop_string(ctx->fop), acl_str ? acl_str : "-"); out: GF_FREE(acl_str); return; } static int acl_permits(call_frame_t *frame, inode_t *inode, int want) { int verdict = 0; struct posix_acl *acl = NULL; struct posix_ace *ace = NULL; struct posix_acl_ctx *ctx = NULL; struct posix_acl_conf *conf = NULL; int i = 0; int perm = 0; int found = 0; int acl_present = 0; conf = frame->this->private; if ((0 > frame->root->pid) || frame_is_super_user(frame)) goto green; ctx = posix_acl_ctx_get(inode, frame->this); if (!ctx) goto red; posix_acl_get(inode, frame->this, &acl, NULL); if (!acl) { acl = posix_acl_ref(frame->this, conf->minimal_acl); } ace = acl->entries; if (_does_acl_exist(acl)) acl_present = 1; for (i = 0; i < acl->count; i++) { switch (ace->tag) { case POSIX_ACL_USER_OBJ: perm = ((ctx->perm & S_IRWXU) >> 6); if (frame_is_user(frame, ctx->uid)) goto perm_check; break; case POSIX_ACL_USER: perm = ace->perm; if (frame_is_user(frame, ace->id)) goto mask_check; break; case POSIX_ACL_GROUP_OBJ: if (acl_present) perm = ace->perm; else perm = ((ctx->perm & S_IRWXG) >> 3); if (frame_in_group(frame, ctx->gid)) { found = 1; if ((perm & want) == want) goto mask_check; } break; case POSIX_ACL_GROUP: perm = ace->perm; if (frame_in_group(frame, ace->id)) { found = 1; if ((perm & want) == want) goto mask_check; } break; case POSIX_ACL_MASK: break; case POSIX_ACL_OTHER: perm = (ctx->perm & S_IRWXO); if (!found) goto perm_check; /* fall through */ default: goto red; } ace++; } mask_check: ace = acl->entries; for (i = 0; i < acl->count; i++, ace++) { if (ace->tag != POSIX_ACL_MASK) continue; if ((ace->perm & perm & want) == want) { goto green; } goto red; } perm_check: if ((perm & want) == want) { goto green; } else { goto red; } green: verdict = 1; goto out; red: verdict = 0; posix_acl_log_permit_denied(frame, inode, want, ctx, acl); out: if (acl) posix_acl_unref(frame->this, acl); return verdict; } struct posix_acl_ctx * __posix_acl_ctx_get(inode_t *inode, xlator_t *this, gf_boolean_t create) { struct posix_acl_ctx *ctx = NULL; uint64_t int_ctx = 0; int ret = 0; ret = __inode_ctx_get(inode, this, &int_ctx); if ((ret == 0) && (int_ctx)) return PTR(int_ctx); if (create == _gf_false) return NULL; ctx = GF_CALLOC(1, sizeof(*ctx), gf_posix_acl_mt_ctx_t); if (!ctx) return NULL; ret = __inode_ctx_put(inode, this, UINT64(ctx)); if (ret) { GF_FREE(ctx); ctx = NULL; } return ctx; } struct posix_acl_ctx * posix_acl_ctx_new(inode_t *inode, xlator_t *this) { struct posix_acl_ctx *ctx = NULL; if (inode == NULL) { gf_log_callingfn(this->name, GF_LOG_WARNING, "inode is NULL"); return NULL; } LOCK(&inode->lock); { ctx = __posix_acl_ctx_get(inode, this, _gf_true); } UNLOCK(&inode->lock); if (ctx == NULL) gf_log_callingfn(this->name, GF_LOG_ERROR, "creating inode ctx" "failed for %s", uuid_utoa(inode->gfid)); return ctx; } struct posix_acl_ctx * posix_acl_ctx_get(inode_t *inode, xlator_t *this) { struct posix_acl_ctx *ctx = NULL; if (inode == NULL) { gf_log_callingfn(this->name, GF_LOG_WARNING, "inode is NULL"); return NULL; } LOCK(&inode->lock); { ctx = __posix_acl_ctx_get(inode, this, _gf_false); } UNLOCK(&inode->lock); if (ctx == NULL) gf_log_callingfn(this->name, GF_LOG_ERROR, "inode ctx is NULL " "for %s", uuid_utoa(inode->gfid)); return ctx; } int __posix_acl_set_specific(inode_t *inode, xlator_t *this, gf_boolean_t is_access, struct posix_acl *acl) { int ret = 0; struct posix_acl_ctx *ctx = NULL; ctx = posix_acl_ctx_get(inode, this); if (!ctx) { ret = -1; goto out; } if (is_access) ctx->acl_access = acl; else ctx->acl_default = acl; out: return ret; } int __posix_acl_set(inode_t *inode, xlator_t *this, struct posix_acl *acl_access, struct posix_acl *acl_default) { int ret = 0; struct posix_acl_ctx *ctx = NULL; ctx = posix_acl_ctx_get(inode, this); if (!ctx) goto out; ctx->acl_access = acl_access; ctx->acl_default = acl_default; out: return ret; } int __posix_acl_get(inode_t *inode, xlator_t *this, struct posix_acl **acl_access_p, struct posix_acl **acl_default_p) { int ret = 0; struct posix_acl_ctx *ctx = NULL; ctx = posix_acl_ctx_get(inode, this); if (!ctx) goto out; if (acl_access_p) *acl_access_p = ctx->acl_access; if (acl_default_p) *acl_default_p = ctx->acl_default; out: return ret; } struct posix_acl * posix_acl_new(xlator_t *this, int entrycnt) { struct posix_acl *acl = NULL; struct posix_ace *ace = NULL; acl = GF_CALLOC(1, sizeof(*acl) + (entrycnt * sizeof(*ace)), gf_posix_acl_mt_posix_ace_t); if (!acl) return NULL; acl->count = entrycnt; posix_acl_ref(this, acl); return acl; } void posix_acl_destroy(xlator_t *this, struct posix_acl *acl) { GF_FREE(acl); return; } struct posix_acl * posix_acl_ref(xlator_t *this, struct posix_acl *acl) { struct posix_acl_conf *conf = NULL; conf = this->private; LOCK(&conf->acl_lock); { acl->refcnt++; } UNLOCK(&conf->acl_lock); return acl; } struct posix_acl * posix_acl_dup(xlator_t *this, struct posix_acl *acl) { struct posix_acl *dup = NULL; dup = posix_acl_new(this, acl->count); if (!dup) return NULL; memcpy(dup->entries, acl->entries, sizeof(struct posix_ace) * acl->count); return dup; } void posix_acl_unref(xlator_t *this, struct posix_acl *acl) { struct posix_acl_conf *conf = NULL; int refcnt = 0; conf = this->private; if (!conf) goto out; LOCK(&conf->acl_lock); { refcnt = --acl->refcnt; } UNLOCK(&conf->acl_lock); out: if (!refcnt) posix_acl_destroy(this, acl); } int posix_acl_set_specific(inode_t *inode, xlator_t *this, struct posix_acl *acl, gf_boolean_t is_access) { int ret = 0; int oldret = 0; struct posix_acl *old_acl = NULL; struct posix_acl_conf *conf = NULL; conf = this->private; LOCK(&conf->acl_lock); { if (is_access) oldret = __posix_acl_get(inode, this, &old_acl, NULL); else oldret = __posix_acl_get(inode, this, NULL, &old_acl); if (acl) acl->refcnt++; ret = __posix_acl_set_specific(inode, this, is_access, acl); } UNLOCK(&conf->acl_lock); if (!oldret && old_acl) { posix_acl_unref(this, old_acl); } return ret; } int posix_acl_set(inode_t *inode, xlator_t *this, struct posix_acl *acl_access, struct posix_acl *acl_default) { int ret = 0; int oldret = 0; struct posix_acl *old_access = NULL; struct posix_acl *old_default = NULL; struct posix_acl_conf *conf = NULL; conf = this->private; LOCK(&conf->acl_lock); { oldret = __posix_acl_get(inode, this, &old_access, &old_default); if (acl_access) acl_access->refcnt++; if (acl_default) acl_default->refcnt++; ret = __posix_acl_set(inode, this, acl_access, acl_default); } UNLOCK(&conf->acl_lock); if (oldret == 0) { if (old_access) posix_acl_unref(this, old_access); if (old_default) posix_acl_unref(this, old_default); } return ret; } int posix_acl_get(inode_t *inode, xlator_t *this, struct posix_acl **acl_access_p, struct posix_acl **acl_default_p) { struct posix_acl_conf *conf = NULL; struct posix_acl *acl_access = NULL; struct posix_acl *acl_default = NULL; int ret = 0; conf = this->private; LOCK(&conf->acl_lock); { ret = __posix_acl_get(inode, this, &acl_access, &acl_default); if (ret != 0) goto unlock; if (acl_access && acl_access_p) acl_access->refcnt++; if (acl_default && acl_default_p) acl_default->refcnt++; } unlock: UNLOCK(&conf->acl_lock); if (acl_access_p) *acl_access_p = acl_access; if (acl_default_p) *acl_default_p = acl_default; return ret; } mode_t posix_acl_inherit_mode(struct posix_acl *acl, mode_t modein) { struct posix_ace *ace = NULL; int count = 0; int i = 0; mode_t newmode = 0; mode_t mode = 0; struct posix_ace *mask_ce = NULL; struct posix_ace *group_ce = NULL; newmode = mode = modein; count = acl->count; ace = acl->entries; for (i = 0; i < count; i++) { switch (ace->tag) { case POSIX_ACL_USER_OBJ: ace->perm &= (mode >> 6) | ~S_IRWXO; mode &= (ace->perm << 6) | ~S_IRWXU; break; case POSIX_ACL_GROUP_OBJ: group_ce = ace; break; case POSIX_ACL_MASK: mask_ce = ace; break; case POSIX_ACL_OTHER: ace->perm &= (mode) | ~S_IRWXO; mode &= (ace->perm) | ~S_IRWXO; break; } ace++; } if (mask_ce) { mask_ce->perm &= (mode >> 3) | ~S_IRWXO; mode &= (mask_ce->perm << 3) | ~S_IRWXG; } else if (group_ce) { group_ce->perm &= (mode >> 3) | ~S_IRWXO; mode &= (group_ce->perm << 3) | ~S_IRWXG; } newmode = ((modein & (S_IFMT | S_ISUID | S_ISGID | S_ISVTX)) | (mode & (S_IRWXU | S_IRWXG | S_IRWXO))); return newmode; } mode_t posix_acl_inherit(xlator_t *this, loc_t *loc, dict_t *params, mode_t mode, int32_t umask, int is_dir) { int ret = 0; struct posix_acl *par_default = NULL; struct posix_acl *acl_default = NULL; struct posix_acl *acl_access = NULL; struct posix_acl_ctx *ctx = NULL; char *xattr_default = NULL; char *xattr_access = NULL; int size_default = 0; int size_access = 0; mode_t retmode = 0; int16_t tmp_mode = 0; mode_t client_umask = 0; retmode = mode; client_umask = umask; ret = dict_get_int16(params, "umask", &tmp_mode); if (ret == 0) { client_umask = (mode_t)tmp_mode; dict_del(params, "umask"); ret = dict_get_int16(params, "mode", &tmp_mode); if (ret == 0) { retmode = (mode_t)tmp_mode; dict_del(params, "mode"); } else { gf_log(this->name, GF_LOG_ERROR, "client sent umask, but not the original mode"); } } ret = posix_acl_get(loc->parent, this, NULL, &par_default); if (!par_default) goto out; ctx = posix_acl_ctx_new(loc->inode, this); acl_access = posix_acl_dup(this, par_default); if (!acl_access) goto out; client_umask = 0; // No umask if we inherit an ACL retmode = posix_acl_inherit_mode(acl_access, retmode); ctx->perm = retmode; size_access = posix_acl_to_xattr(this, acl_access, NULL, 0); xattr_access = GF_CALLOC(1, size_access, gf_posix_acl_mt_char); if (!xattr_access) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = -1; goto out; } posix_acl_to_xattr(this, acl_access, xattr_access, size_access); ret = dict_set_bin(params, POSIX_ACL_ACCESS_XATTR, xattr_access, size_access); if (ret) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); GF_FREE(xattr_access); ret = -1; goto out; } if (!is_dir) goto set; acl_default = posix_acl_ref(this, par_default); size_default = posix_acl_to_xattr(this, acl_default, NULL, 0); xattr_default = GF_CALLOC(1, size_default, gf_posix_acl_mt_char); if (!xattr_default) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = -1; goto out; } posix_acl_to_xattr(this, acl_default, xattr_default, size_default); ret = dict_set_bin(params, POSIX_ACL_DEFAULT_XATTR, xattr_default, size_default); if (ret) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); GF_FREE(xattr_default); ret = -1; goto out; } set: ret = posix_acl_set(loc->inode, this, acl_access, acl_default); if (ret != 0) goto out; out: retmode &= ~client_umask; if (par_default) posix_acl_unref(this, par_default); if (acl_access) posix_acl_unref(this, acl_access); if (acl_default) posix_acl_unref(this, acl_default); return retmode; } mode_t posix_acl_inherit_dir(xlator_t *this, loc_t *loc, dict_t *params, mode_t mode, int32_t umask) { mode_t retmode = 0; retmode = posix_acl_inherit(this, loc, params, mode, umask, 1); return retmode; } mode_t posix_acl_inherit_file(xlator_t *this, loc_t *loc, dict_t *params, mode_t mode, int32_t umask) { mode_t retmode = 0; retmode = posix_acl_inherit(this, loc, params, mode, umask, 0); return retmode; } int posix_acl_ctx_update(inode_t *inode, xlator_t *this, struct iatt *buf, glusterfs_fop_t fop) { struct posix_acl_ctx *ctx = NULL; struct posix_acl *acl = NULL; struct posix_ace *ace = NULL; struct posix_ace *mask_ce = NULL; struct posix_ace *group_ce = NULL; int ret = 0; int i = 0; if (!buf || !buf->ia_ctime) { /* No need to update ctx if buf is empty */ gf_log_callingfn(this->name, GF_LOG_DEBUG, "iatt struct is empty (%d)", fop); goto out; } LOCK(&inode->lock); { ctx = __posix_acl_ctx_get(inode, this, _gf_true); if (!ctx) { ret = -1; goto unlock; } ctx->uid = buf->ia_uid; ctx->gid = buf->ia_gid; ctx->perm = st_mode_from_ia(buf->ia_prot, buf->ia_type); ctx->fop = fop; acl = ctx->acl_access; if (!_does_acl_exist(acl)) goto unlock; /* This is an extended ACL (not minimal acl). In case we are only refreshing from iatt and not ACL xattrs (for e.g. from postattributes of setattr() call, we need to update the corresponding ACEs as well. */ ace = acl->entries; for (i = 0; i < acl->count; i++) { switch (ace->tag) { case POSIX_ACL_USER_OBJ: ace->perm = (ctx->perm & S_IRWXU) >> 6; break; case POSIX_ACL_USER: case POSIX_ACL_GROUP: break; case POSIX_ACL_GROUP_OBJ: group_ce = ace; break; case POSIX_ACL_MASK: mask_ce = ace; break; case POSIX_ACL_OTHER: ace->perm = (ctx->perm & S_IRWXO); break; } ace++; } if (mask_ce) mask_ce->perm = (ctx->perm & S_IRWXG) >> 3; else if (group_ce) group_ce->perm = (ctx->perm & S_IRWXG) >> 3; else ret = -1; } unlock: UNLOCK(&inode->lock); out: return ret; } int posix_acl_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, dict_t *xattr, struct iatt *postparent) { struct posix_acl *acl_access = NULL; struct posix_acl *acl_default = NULL; struct posix_acl *old_access = NULL; struct posix_acl *old_default = NULL; struct posix_acl_ctx *ctx = NULL; data_t *data = NULL; int ret = 0; dict_t *my_xattr = NULL; if (op_ret != 0) goto unwind; ctx = posix_acl_ctx_new(inode, this); if (!ctx) { op_ret = -1; op_errno = ENOMEM; goto unwind; } ret = posix_acl_get(inode, this, &old_access, &old_default); if (xattr == NULL) goto acl_set; data = dict_get(xattr, POSIX_ACL_ACCESS_XATTR); if (!data) goto acl_default; if (old_access && posix_acl_matches_xattr(this, old_access, data->data, data->len)) { acl_access = posix_acl_ref(this, old_access); } else { acl_access = posix_acl_from_xattr(this, data->data, data->len); } acl_default: data = dict_get(xattr, POSIX_ACL_DEFAULT_XATTR); if (!data) goto acl_set; if (old_default && posix_acl_matches_xattr(this, old_default, data->data, data->len)) { acl_default = posix_acl_ref(this, old_default); } else { acl_default = posix_acl_from_xattr(this, data->data, data->len); } acl_set: posix_acl_ctx_update(inode, this, buf, GF_FOP_LOOKUP); ret = posix_acl_set(inode, this, acl_access, acl_default); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set ACL in context"); unwind: my_xattr = frame->local; frame->local = NULL; STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xattr, postparent); if (acl_access) posix_acl_unref(this, acl_access); if (acl_default) posix_acl_unref(this, acl_default); if (old_access) posix_acl_unref(this, old_access); if (old_default) posix_acl_unref(this, old_default); if (my_xattr) dict_unref(my_xattr); return 0; } int posix_acl_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr) { int ret = 0; dict_t *my_xattr = NULL; if (!loc->parent) /* lookup of / is always permitted */ goto green; if (acl_permits(frame, loc->parent, POSIX_ACL_EXECUTE)) goto green; else goto red; green: if (xattr) { my_xattr = dict_ref(xattr); } else { my_xattr = dict_new(); } ret = dict_set_int8(my_xattr, POSIX_ACL_ACCESS_XATTR, 0); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set key %s", POSIX_ACL_ACCESS_XATTR); ret = dict_set_int8(my_xattr, POSIX_ACL_DEFAULT_XATTR, 0); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set key %s", POSIX_ACL_DEFAULT_XATTR); frame->local = my_xattr; STACK_WIND(frame, posix_acl_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, my_xattr); return 0; red: STACK_UNWIND_STRICT(lookup, frame, -1, EACCES, NULL, NULL, NULL, NULL); return 0; } int posix_acl_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int mask, dict_t *xdata) { int op_ret = 0; int op_errno = 0; int perm = 0; int mode = 0; int is_fuse_call = 0; is_fuse_call = __is_fuse_call(frame); if (mask & R_OK) perm |= POSIX_ACL_READ; if (mask & W_OK) perm |= POSIX_ACL_WRITE; if (mask & X_OK) perm |= POSIX_ACL_EXECUTE; if (!mask) { goto unwind; } if (!perm) { op_ret = -1; op_errno = EINVAL; goto unwind; } if (is_fuse_call) { mode = acl_permits(frame, loc->inode, perm); if (mode) { op_ret = 0; op_errno = 0; } else { op_ret = -1; op_errno = EACCES; } } else { if (perm & POSIX_ACL_READ) { if (acl_permits(frame, loc->inode, POSIX_ACL_READ)) mode |= POSIX_ACL_READ; } if (perm & POSIX_ACL_WRITE) { if (acl_permits(frame, loc->inode, POSIX_ACL_WRITE)) mode |= POSIX_ACL_WRITE; } if (perm & POSIX_ACL_EXECUTE) { if (acl_permits(frame, loc->inode, POSIX_ACL_EXECUTE)) mode |= POSIX_ACL_EXECUTE; } } unwind: if (is_fuse_call) STACK_UNWIND_STRICT(access, frame, op_ret, op_errno, NULL); else STACK_UNWIND_STRICT(access, frame, 0, mode, NULL); return 0; } int posix_acl_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t off, dict_t *xdata) { struct posix_acl_ctx *ctx = NULL; if (acl_permits(frame, loc->inode, POSIX_ACL_WRITE)) goto green; /* NFS does a truncate through SETATTR, the owner does not need write * permissions for this. Group permissions and root are checked above. */ else if (frame->root->pid == NFS_PID) { ctx = posix_acl_ctx_get(loc->inode, frame->this); if (ctx && frame_is_user(frame, ctx->uid)) goto green; } /* fail by default */ STACK_UNWIND_STRICT(truncate, frame, -1, EACCES, NULL, NULL, NULL); return 0; green: STACK_WIND(frame, default_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, off, xdata); return 0; } int posix_acl_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, fd_t *fd, dict_t *xdata) { int perm = 0; switch (flags & O_ACCMODE) { case O_RDONLY: perm = POSIX_ACL_READ; /* If O_FMODE_EXEC is present, its good enough to have '--x' perm, and its not covered in O_ACCMODE bits */ if (flags & O_FMODE_EXEC) perm = POSIX_ACL_EXECUTE; break; case O_WRONLY: perm = POSIX_ACL_WRITE; break; case O_RDWR: perm = POSIX_ACL_READ | POSIX_ACL_WRITE; break; } if (flags & (O_TRUNC | O_APPEND)) perm |= POSIX_ACL_WRITE; if (acl_permits(frame, loc->inode, perm)) goto green; else goto red; green: STACK_WIND(frame, default_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; red: STACK_UNWIND_STRICT(open, frame, -1, EACCES, NULL, NULL); return 0; } int posix_acl_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { if (__is_fuse_call(frame)) goto green; if (acl_permits(frame, fd->inode, POSIX_ACL_READ)) goto green; else goto red; green: STACK_WIND(frame, default_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; red: STACK_UNWIND_STRICT(readv, frame, -1, EACCES, NULL, 0, NULL, NULL, NULL); return 0; } int posix_acl_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { if (__is_fuse_call(frame)) goto green; if (acl_permits(frame, fd->inode, POSIX_ACL_WRITE)) goto green; else goto red; green: STACK_WIND(frame, default_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; red: STACK_UNWIND_STRICT(writev, frame, -1, EACCES, NULL, NULL, NULL); return 0; } int posix_acl_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { if (__is_fuse_call(frame)) goto green; if (acl_permits(frame, fd->inode, POSIX_ACL_WRITE)) goto green; else goto red; green: STACK_WIND(frame, default_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; red: STACK_UNWIND_STRICT(ftruncate, frame, -1, EACCES, NULL, NULL, NULL); return 0; } int posix_acl_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { if (acl_permits(frame, loc->inode, POSIX_ACL_READ)) goto green; else goto red; green: STACK_WIND(frame, default_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); return 0; red: STACK_UNWIND_STRICT(opendir, frame, -1, EACCES, NULL, NULL); return 0; } int posix_acl_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { if (op_ret != 0) goto unwind; posix_acl_ctx_update(inode, this, buf, GF_FOP_MKDIR); unwind: STACK_UNWIND_STRICT(mkdir, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int posix_acl_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { mode_t newmode = 0; newmode = mode; if (acl_permits(frame, loc->parent, POSIX_ACL_WRITE | POSIX_ACL_EXECUTE)) goto green; else goto red; green: newmode = posix_acl_inherit_dir(this, loc, xdata, mode, umask); STACK_WIND(frame, posix_acl_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, newmode, umask, xdata); return 0; red: STACK_UNWIND_STRICT(mkdir, frame, -1, EACCES, NULL, NULL, NULL, NULL, NULL); return 0; } int posix_acl_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { if (op_ret != 0) goto unwind; posix_acl_ctx_update(inode, this, buf, GF_FOP_MKNOD); unwind: STACK_UNWIND_STRICT(mknod, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int posix_acl_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { mode_t newmode = 0; newmode = mode; if (acl_permits(frame, loc->parent, POSIX_ACL_WRITE | POSIX_ACL_EXECUTE)) goto green; else goto red; green: newmode = posix_acl_inherit_file(this, loc, xdata, mode, umask); STACK_WIND(frame, posix_acl_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, newmode, rdev, umask, xdata); return 0; red: STACK_UNWIND_STRICT(mknod, frame, -1, EACCES, NULL, NULL, NULL, NULL, NULL); return 0; } int posix_acl_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { if (op_ret != 0) goto unwind; posix_acl_ctx_update(inode, this, buf, GF_FOP_CREATE); unwind: STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent, xdata); return 0; } int posix_acl_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { mode_t newmode = 0; newmode = mode; if (acl_permits(frame, loc->parent, POSIX_ACL_WRITE | POSIX_ACL_EXECUTE)) goto green; else goto red; green: newmode = posix_acl_inherit_file(this, loc, xdata, mode, umask); STACK_WIND(frame, posix_acl_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, newmode, umask, fd, xdata); return 0; red: STACK_UNWIND_STRICT(create, frame, -1, EACCES, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int posix_acl_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { if (op_ret != 0) goto unwind; posix_acl_ctx_update(inode, this, buf, GF_FOP_SYMLINK); unwind: STACK_UNWIND_STRICT(symlink, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int posix_acl_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { if (acl_permits(frame, loc->parent, POSIX_ACL_WRITE | POSIX_ACL_EXECUTE)) goto green; else goto red; green: STACK_WIND(frame, posix_acl_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkname, loc, umask, xdata); return 0; red: STACK_UNWIND_STRICT(symlink, frame, -1, EACCES, NULL, NULL, NULL, NULL, NULL); return 0; } int posix_acl_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { if (!sticky_permits(frame, loc->parent, loc->inode)) goto red; if (acl_permits(frame, loc->parent, POSIX_ACL_WRITE | POSIX_ACL_EXECUTE)) goto green; else goto red; green: STACK_WIND(frame, default_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; red: STACK_UNWIND_STRICT(unlink, frame, -1, EACCES, NULL, NULL, NULL); return 0; } int posix_acl_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { if (!sticky_permits(frame, loc->parent, loc->inode)) goto red; if (acl_permits(frame, loc->parent, POSIX_ACL_WRITE | POSIX_ACL_EXECUTE)) goto green; else goto red; green: STACK_WIND(frame, default_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); return 0; red: STACK_UNWIND_STRICT(rmdir, frame, -1, EACCES, NULL, NULL, NULL); return 0; } int posix_acl_rename(call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new, dict_t *xdata) { if (!acl_permits(frame, old->parent, POSIX_ACL_WRITE)) goto red; if (!acl_permits(frame, new->parent, POSIX_ACL_WRITE)) goto red; if (!sticky_permits(frame, old->parent, old->inode)) goto red; if (new->inode) { if (!sticky_permits(frame, new->parent, new->inode)) goto red; } STACK_WIND(frame, default_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, old, new, xdata); return 0; red: STACK_UNWIND_STRICT(rename, frame, -1, EACCES, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int posix_acl_link(call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new, dict_t *xdata) { struct posix_acl_ctx *ctx = NULL; int op_errno = 0; ctx = posix_acl_ctx_get(old->inode, this); if (!ctx) { op_errno = EIO; goto red; } if (!acl_permits(frame, new->parent, POSIX_ACL_WRITE)) { op_errno = EACCES; goto red; } if (!sticky_permits(frame, new->parent, new->inode)) { op_errno = EACCES; goto red; } STACK_WIND(frame, default_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, old, new, xdata); return 0; red: STACK_UNWIND_STRICT(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int posix_acl_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { if (acl_permits(frame, fd->inode, POSIX_ACL_READ)) goto green; else goto red; green: STACK_WIND(frame, default_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, fd, size, offset, xdata); return 0; red: STACK_UNWIND_STRICT(readdir, frame, -1, EACCES, NULL, NULL); return 0; } int posix_acl_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata) { gf_dirent_t *entry = NULL; struct posix_acl *acl_access = NULL; struct posix_acl *acl_default = NULL; struct posix_acl_ctx *ctx = NULL; data_t *data = NULL; int ret = 0; if (op_ret <= 0) goto unwind; list_for_each_entry(entry, &entries->list, list) { /* Update the inode ctx */ if (!entry->dict || !entry->inode) continue; ctx = posix_acl_ctx_new(entry->inode, this); if (!ctx) { op_ret = -1; op_errno = ENOMEM; goto unwind; } ret = posix_acl_get(entry->inode, this, &acl_access, &acl_default); data = dict_get(entry->dict, POSIX_ACL_ACCESS_XATTR); if (!data) goto acl_default; if (acl_access && posix_acl_matches_xattr(this, acl_access, data->data, data->len)) goto acl_default; if (acl_access) posix_acl_unref(this, acl_access); acl_access = posix_acl_from_xattr(this, data->data, data->len); acl_default: data = dict_get(entry->dict, POSIX_ACL_DEFAULT_XATTR); if (!data) goto acl_set; if (acl_default && posix_acl_matches_xattr(this, acl_default, data->data, data->len)) goto acl_set; if (acl_default) posix_acl_unref(this, acl_default); acl_default = posix_acl_from_xattr(this, data->data, data->len); acl_set: posix_acl_ctx_update(entry->inode, this, &entry->d_stat, GF_FOP_READDIRP); ret = posix_acl_set(entry->inode, this, acl_access, acl_default); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set ACL in context"); if (acl_access) posix_acl_unref(this, acl_access); if (acl_default) posix_acl_unref(this, acl_default); } unwind: STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata); return 0; } int posix_acl_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *dict) { int ret = 0; dict_t *alloc_dict = NULL; if (acl_permits(frame, fd->inode, POSIX_ACL_READ)) goto green; else goto red; green: if (!dict) dict = alloc_dict = dict_new(); if (dict) { ret = dict_set_int8(dict, POSIX_ACL_ACCESS_XATTR, 0); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set key %s", POSIX_ACL_ACCESS_XATTR); ret = dict_set_int8(dict, POSIX_ACL_DEFAULT_XATTR, 0); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set key %s", POSIX_ACL_DEFAULT_XATTR); } STACK_WIND(frame, posix_acl_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); if (alloc_dict) dict_unref(alloc_dict); return 0; red: STACK_UNWIND_STRICT(readdirp, frame, -1, EACCES, NULL, NULL); return 0; } int setattr_scrutiny(call_frame_t *frame, inode_t *inode, struct iatt *buf, int valid) { struct posix_acl_ctx *ctx = NULL; if (frame_is_super_user(frame)) return 0; ctx = posix_acl_ctx_get(inode, frame->this); if (!ctx) return EIO; if (valid & GF_SET_ATTR_MODE) { /* The effective UID of the calling process must match the owner of the file, or the process must be privileged */ if (!frame_is_user(frame, ctx->uid)) return EPERM; /* If the calling process is not privileged (Linux: does not have the CAP_FSETID capability), and the group of the file does not match the effective group ID of the process or one of its supplementary group IDs, the S_ISGID bit will be turned off, but this will not cause an error to be returned. */ if (!frame_in_group(frame, ctx->gid)) buf->ia_prot.sgid = 0; } if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { /* Changing timestamps is permitted when: either the process has appropri? ate privileges, or the effective user ID equals the user ID of the file, or times is NULL and the process has write permission for the file. */ if (!frame_is_user(frame, ctx->uid) && !acl_permits(frame, inode, POSIX_ACL_WRITE)) return EACCES; } if (valid & GF_SET_ATTR_UID) { if ((!frame_is_super_user(frame)) && (buf->ia_uid != ctx->uid)) return EPERM; } if (valid & GF_SET_ATTR_GID) { if (!frame_is_user(frame, ctx->uid)) return EPERM; if (!frame_in_group(frame, buf->ia_gid)) return EPERM; } return 0; } int posix_acl_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *inode = NULL; inode = frame->local; frame->local = NULL; if (op_ret != 0) goto unwind; posix_acl_ctx_update(inode, this, postbuf, GF_FOP_SETATTR); unwind: STACK_UNWIND_STRICT(setattr, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int posix_acl_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *buf, int valid, dict_t *xdata) { int op_errno = 0; op_errno = setattr_scrutiny(frame, loc->inode, buf, valid); if (op_errno) goto red; frame->local = loc->inode; STACK_WIND(frame, posix_acl_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, buf, valid, xdata); return 0; red: STACK_UNWIND_STRICT(setattr, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int posix_acl_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *inode = NULL; inode = frame->local; frame->local = NULL; if (op_ret != 0) goto unwind; posix_acl_ctx_update(inode, this, postbuf, GF_FOP_FSETATTR); unwind: STACK_UNWIND_STRICT(fsetattr, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int posix_acl_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *buf, int valid, dict_t *xdata) { int op_errno = 0; op_errno = setattr_scrutiny(frame, fd->inode, buf, valid); if (op_errno) goto red; frame->local = fd->inode; STACK_WIND(frame, posix_acl_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, buf, valid, xdata); return 0; red: STACK_UNWIND_STRICT(fsetattr, frame, -1, EACCES, NULL, NULL, NULL); return 0; } int setxattr_scrutiny(call_frame_t *frame, inode_t *inode, dict_t *xattr) { struct posix_acl_ctx *ctx = NULL; int found = 0; if (frame_is_super_user(frame)) return 0; ctx = posix_acl_ctx_get(inode, frame->this); if (!ctx) return EIO; if (dict_get(xattr, POSIX_ACL_ACCESS_XATTR) || dict_get(xattr, POSIX_ACL_DEFAULT_XATTR) || dict_get(xattr, GF_POSIX_ACL_ACCESS) || dict_get(xattr, GF_POSIX_ACL_DEFAULT)) { found = 1; if (!frame_is_user(frame, ctx->uid)) return EPERM; } if (!found && !acl_permits(frame, inode, POSIX_ACL_WRITE)) return EACCES; return 0; } struct posix_acl * posix_acl_xattr_update(xlator_t *this, inode_t *inode, dict_t *xattr, char *name, struct posix_acl *old) { struct posix_acl *acl = NULL; data_t *data = NULL; data = dict_get(xattr, name); if (data) { acl = posix_acl_from_xattr(this, data->data, data->len); } if (!acl && old) acl = posix_acl_ref(this, old); return acl; } int posix_acl_setxattr_update(xlator_t *this, inode_t *inode, dict_t *xattr) { struct posix_acl *acl_access = NULL; struct posix_acl *acl_default = NULL; struct posix_acl *old_access = NULL; struct posix_acl *old_default = NULL; struct posix_acl_ctx *ctx = NULL; int ret = 0; ctx = posix_acl_ctx_get(inode, this); if (!ctx) return -1; ret = posix_acl_get(inode, this, &old_access, &old_default); acl_access = posix_acl_xattr_update(this, inode, xattr, POSIX_ACL_ACCESS_XATTR, old_access); acl_default = posix_acl_xattr_update(this, inode, xattr, POSIX_ACL_DEFAULT_XATTR, old_default); ret = posix_acl_set(inode, this, acl_access, acl_default); if (acl_access && acl_access != old_access) { posix_acl_access_set_mode(acl_access, ctx); } if (acl_access) posix_acl_unref(this, acl_access); if (acl_default) posix_acl_unref(this, acl_default); if (old_access) posix_acl_unref(this, old_access); if (old_default) posix_acl_unref(this, old_default); return ret; } /* * * Posix acl can be set using other xattr such as GF_POSIX_ACL_ACCESS/ * GF_POSIX_ACL_DEFAULT which requires to update the context of * access-control translator */ int handling_other_acl_related_xattr(xlator_t *this, inode_t *inode, dict_t *xattr) { struct posix_acl *acl = NULL; struct posix_acl_ctx *ctx = NULL; data_t *data = NULL; int ret = 0; if (!this || !xattr || !inode) goto out; data = dict_get(xattr, POSIX_ACL_ACCESS_XATTR); if (data) { acl = posix_acl_from_xattr(this, data->data, data->len); if (!acl) { ret = -1; goto out; } ret = posix_acl_set_specific(inode, this, acl, _gf_true); if (ret) goto out; ctx = posix_acl_ctx_get(inode, this); if (!ctx) { ret = -1; goto out; } posix_acl_access_set_mode(acl, ctx); posix_acl_unref(this, acl); acl = NULL; } data = dict_get(xattr, POSIX_ACL_DEFAULT_XATTR); if (data) { acl = posix_acl_from_xattr(this, data->data, data->len); if (!acl) { ret = -1; goto out; } ret = posix_acl_set_specific(inode, this, acl, _gf_false); } out: if (acl) posix_acl_unref(this, acl); return ret; } int posix_acl_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { /* * Update the context of posix_acl_translator, if any of * POSIX_ACL_*_XATTR set in the call back */ handling_other_acl_related_xattr(this, (inode_t *)cookie, xdata); STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); return 0; } int posix_acl_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr, int flags, dict_t *xdata) { int op_errno = 0; op_errno = setxattr_scrutiny(frame, loc->inode, xattr); if (op_errno != 0) goto red; if (dict_get(xattr, POSIX_ACL_ACCESS_XATTR) || dict_get(xattr, POSIX_ACL_DEFAULT_XATTR)) posix_acl_setxattr_update(this, loc->inode, xattr); /* * inode is required in call back function to update the context * this translator */ STACK_WIND_COOKIE(frame, posix_acl_setxattr_cbk, loc->inode, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, xattr, flags, xdata); return 0; red: STACK_UNWIND_STRICT(setxattr, frame, -1, op_errno, NULL); return 0; } int posix_acl_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xattr, int flags, dict_t *xdata) { int op_errno = 0; op_errno = setxattr_scrutiny(frame, fd->inode, xattr); if (op_errno != 0) goto red; if (dict_get(xattr, POSIX_ACL_ACCESS_XATTR) || dict_get(xattr, POSIX_ACL_DEFAULT_XATTR)) posix_acl_setxattr_update(this, fd->inode, xattr); STACK_WIND(frame, default_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, xattr, flags, xdata); return 0; red: STACK_UNWIND_STRICT(fsetxattr, frame, -1, op_errno, NULL); return 0; } int posix_acl_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { if (allowed_xattr(name)) goto green; if (acl_permits(frame, loc->inode, POSIX_ACL_READ)) goto green; else goto red; green: STACK_WIND(frame, default_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); return 0; red: STACK_UNWIND_STRICT(getxattr, frame, -1, EACCES, NULL, NULL); return 0; } int posix_acl_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { if (allowed_xattr(name)) goto green; if (acl_permits(frame, fd->inode, POSIX_ACL_READ)) goto green; else goto red; green: STACK_WIND(frame, default_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); return 0; red: STACK_UNWIND_STRICT(fgetxattr, frame, -1, EACCES, NULL, NULL); return 0; } int posix_acl_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { struct posix_acl_ctx *ctx = NULL; int op_errno = EACCES; if (frame_is_super_user(frame)) goto green; ctx = posix_acl_ctx_get(loc->inode, this); if (!ctx) { op_errno = EIO; goto red; } if (allowed_xattr(name)) { if (!frame_is_user(frame, ctx->uid)) { op_errno = EPERM; goto red; } } if (acl_permits(frame, loc->inode, POSIX_ACL_WRITE)) goto green; else goto red; green: STACK_WIND(frame, default_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; red: STACK_UNWIND_STRICT(removexattr, frame, -1, op_errno, NULL); return 0; } int posix_acl_forget(xlator_t *this, inode_t *inode) { struct posix_acl_ctx *ctx = NULL; ctx = posix_acl_ctx_get(inode, this); if (!ctx) goto out; if (ctx->acl_access) posix_acl_unref(this, ctx->acl_access); if (ctx->acl_default) posix_acl_unref(this, ctx->acl_default); GF_FREE(ctx); out: return 0; } int reconfigure(xlator_t *this, dict_t *options) { struct posix_acl_conf *conf = NULL; conf = this->private; GF_OPTION_RECONF("super-uid", conf->super_uid, options, uint32, err); return 0; err: return -1; } int init(xlator_t *this) { struct posix_acl_conf *conf = NULL; struct posix_acl *minacl = NULL; struct posix_ace *minace = NULL; conf = GF_CALLOC(1, sizeof(*conf), gf_posix_acl_mt_conf_t); if (!conf) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); return -1; } LOCK_INIT(&conf->acl_lock); this->private = conf; minacl = posix_acl_new(this, 3); if (!minacl) return -1; minace = minacl->entries; minace[0].tag = POSIX_ACL_USER_OBJ; minace[1].tag = POSIX_ACL_GROUP_OBJ; minace[2].tag = POSIX_ACL_OTHER; conf->minimal_acl = minacl; GF_OPTION_INIT("super-uid", conf->super_uid, uint32, err); return 0; err: return -1; } void fini(xlator_t *this) { struct posix_acl_conf *conf = NULL; struct posix_acl *minacl = NULL; conf = this->private; if (!conf) return; this->private = NULL; minacl = conf->minimal_acl; LOCK(&conf->acl_lock); { conf->minimal_acl = NULL; } UNLOCK(&conf->acl_lock); LOCK_DESTROY(&conf->acl_lock); GF_FREE(minacl); GF_FREE(conf); return; } struct xlator_fops fops = { .lookup = posix_acl_lookup, .open = posix_acl_open, #if FD_MODE_CHECK_IS_IMPLEMENTED .readv = posix_acl_readv, .writev = posix_acl_writev, .ftruncate = posix_acl_ftruncate, .fsetattr = posix_acl_fsetattr, .fsetxattr = posix_acl_fsetxattr, .fgetxattr = posix_acl_fgetxattr, #endif .access = posix_acl_access, .truncate = posix_acl_truncate, .mkdir = posix_acl_mkdir, .mknod = posix_acl_mknod, .create = posix_acl_create, .symlink = posix_acl_symlink, .unlink = posix_acl_unlink, .rmdir = posix_acl_rmdir, .rename = posix_acl_rename, .link = posix_acl_link, .opendir = posix_acl_opendir, .readdir = posix_acl_readdir, .readdirp = posix_acl_readdirp, .setattr = posix_acl_setattr, .setxattr = posix_acl_setxattr, .getxattr = posix_acl_getxattr, .removexattr = posix_acl_removexattr, }; struct xlator_cbks cbks = {.forget = posix_acl_forget}; struct volume_options options[] = { { .key = {"super-uid"}, .type = GF_OPTION_TYPE_INT, .default_value = "0", .description = "UID to be treated as super user's id instead of 0", }, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "access-control", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/system/posix-acl/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467023353 xustar000000000000000030 mtime=1699284279.802070007 30 atime=1699284291.486105199 30 ctime=1699284306.736151131 glusterfs-11.1/xlators/system/posix-acl/Makefile.in0000664000175100017510000005263014522202467023640 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/system/posix-acl DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/system/posix-acl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/system/posix-acl/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/system/posix-acl/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023333 xustar000000000000000030 mtime=1699284265.788027796 30 atime=1699284279.778069935 30 ctime=1699284306.738151137 glusterfs-11.1/xlators/system/posix-acl/Makefile.am0000664000175100017510000000001614522202451023607 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/system/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202467021454 xustar000000000000000030 mtime=1699284279.768069905 30 atime=1699284291.466105139 30 ctime=1699284306.698151016 glusterfs-11.1/xlators/system/Makefile.in0000664000175100017510000005260014522202467021736 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/system DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = posix-acl all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/system/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/system/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/system/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451021434 xustar000000000000000030 mtime=1699284265.788027796 30 atime=1699284279.744069832 30 ctime=1699284306.700151022 glusterfs-11.1/xlators/system/Makefile.am0000664000175100017510000000002314522202451021706 0ustar00jenkinsjenkins00000000000000SUBDIRS = posix-aclglusterfs-11.1/xlators/PaxHeaders.9031/cluster0000644000000000000000000000013214522202515017461 xustar000000000000000030 mtime=1699284301.244134589 30 atime=1699284309.685160013 30 ctime=1699284301.244134589 glusterfs-11.1/xlators/cluster/0002775000175100017510000000000014522202515020017 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/cluster/PaxHeaders.9031/dht0000644000000000000000000000013214522202515020240 xustar000000000000000030 mtime=1699284301.172134372 30 atime=1699284309.685160013 30 ctime=1699284301.172134372 glusterfs-11.1/xlators/cluster/dht/0002775000175100017510000000000014522202515020576 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/cluster/dht/PaxHeaders.9031/src0000644000000000000000000000013014522202515021025 xustar000000000000000029 mtime=1699284301.24113458 30 atime=1699284309.685160013 29 ctime=1699284301.24113458 glusterfs-11.1/xlators/cluster/dht/src/0002775000175100017510000000000014522202515021365 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-layout.c0000644000000000000000000000013214522202451023341 xustar000000000000000030 mtime=1699284265.626027308 30 atime=1699284265.625027305 30 ctime=1699284301.219134514 glusterfs-11.1/xlators/cluster/dht/src/dht-layout.c0000664000175100017510000004343314522202451023627 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-common.h" #include "unittest/unittest.h" #define layout_base_size (sizeof(dht_layout_t)) #define layout_entry_size (sizeof((dht_layout_t *)NULL)->list[0]) #define layout_size(cnt) (layout_base_size + (cnt * layout_entry_size)) dht_layout_t * dht_layout_new(xlator_t *this, int cnt) { dht_layout_t *layout = NULL; dht_conf_t *conf = NULL; REQUIRE(NULL != this); REQUIRE(cnt >= 0); conf = this->private; layout = GF_CALLOC(1, layout_size(cnt), gf_dht_mt_dht_layout_t); if (!layout) { goto out; } layout->type = DHT_HASH_TYPE_DM; layout->cnt = cnt; if (conf) { layout->spread_cnt = conf->dir_spread_cnt; layout->gen = conf->gen; } GF_ATOMIC_INIT(layout->ref, 1); ENSURE(NULL != layout); ENSURE(layout->type == DHT_HASH_TYPE_DM); ENSURE(layout->cnt == cnt); ENSURE(GF_ATOMIC_GET(layout->ref) == 1); out: return layout; } dht_layout_t * dht_layout_get(xlator_t *this, inode_t *inode) { dht_layout_t *layout = NULL; (void)dht_inode_ctx_layout_get(inode, this, &layout); return layout; } int dht_layout_set(xlator_t *this, inode_t *inode, dht_layout_t *layout) { dht_conf_t *conf = NULL; int ret = -1; conf = this->private; if (!conf || !layout) goto out; ret = dht_inode_ctx_layout_set(inode, this, layout); out: return ret; } void dht_layout_unref(dht_layout_t *layout) { int ref = 0; if (!layout || layout->preset) return; ref = GF_ATOMIC_DEC(layout->ref); if (!ref) GF_FREE(layout); } dht_layout_t * dht_layout_ref(dht_layout_t *layout) { if (layout->preset) return layout; GF_ATOMIC_INC(layout->ref); return layout; } xlator_t * dht_layout_search(xlator_t *this, dht_layout_t *layout, const char *name) { uint32_t hash = 0; xlator_t *subvol = NULL; int i = 0; int ret = 0; ret = dht_hash_compute(this, layout->type, name, &hash); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_COMPUTE_HASH_FAILED, "type=%d", layout->type, "name=%s", name, NULL); goto out; } for (i = 0; i < layout->cnt; i++) { if (layout->list[i].start <= hash && layout->list[i].stop >= hash) { subvol = layout->list[i].xlator; break; } } if (!subvol) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "hash-value=0x%x", hash, NULL); } out: return subvol; } dht_layout_t * dht_layout_for_subvol(xlator_t *this, xlator_t *subvol) { dht_conf_t *conf = NULL; dht_layout_t *layout = NULL; int i = 0; conf = this->private; if (!conf) goto out; for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == subvol) { layout = conf->file_layouts[i]; break; } } out: return layout; } int dht_layouts_init(xlator_t *this, dht_conf_t *conf) { dht_layout_t *layout = NULL; int i = 0; int ret = -1; if (!conf) goto out; conf->file_layouts = GF_CALLOC(conf->subvolume_cnt, sizeof(dht_layout_t *), gf_dht_mt_dht_layout_t); if (!conf->file_layouts) { goto out; } for (i = 0; i < conf->subvolume_cnt; i++) { layout = dht_layout_new(this, 1); if (!layout) { goto out; } layout->preset = 1; layout->list[0].xlator = conf->subvolumes[i]; conf->file_layouts[i] = layout; } ret = 0; out: return ret; } int dht_disk_layout_extract(xlator_t *this, dht_layout_t *layout, int pos, int32_t **disk_layout_p) { int ret = -1; int32_t *disk_layout = NULL; disk_layout = GF_CALLOC(5, sizeof(int), gf_dht_mt_int32_t); if (!disk_layout) { goto out; } disk_layout[0] = htobe32(layout->list[pos].commit_hash); disk_layout[1] = htobe32(layout->type); disk_layout[2] = htobe32(layout->list[pos].start); disk_layout[3] = htobe32(layout->list[pos].stop); if (disk_layout_p) *disk_layout_p = disk_layout; else GF_FREE(disk_layout); ret = 0; out: return ret; } int dht_disk_layout_extract_for_subvol(xlator_t *this, dht_layout_t *layout, xlator_t *subvol, int32_t **disk_layout_p) { int i = 0; for (i = 0; i < layout->cnt; i++) { if (layout->list[i].xlator == subvol) break; } if (i == layout->cnt) return -1; return dht_disk_layout_extract(this, layout, i, disk_layout_p); } static int dht_disk_layout_merge(xlator_t *this, dht_layout_t *layout, int pos, void *disk_layout_raw, int disk_layout_len) { int type = 0; int start_off = 0; int stop_off = 0; int commit_hash = 0; int disk_layout[4]; if (!disk_layout_raw) { gf_smsg(this->name, GF_LOG_CRITICAL, 0, DHT_MSG_LAYOUT_MERGE_FAILED, NULL); return -1; } GF_ASSERT(disk_layout_len == sizeof(disk_layout)); memcpy(disk_layout, disk_layout_raw, disk_layout_len); type = be32toh(disk_layout[1]); switch (type) { case DHT_HASH_TYPE_DM_USER: gf_msg_debug(this->name, 0, "found user-set layout"); layout->type = type; /* Fall through. */ case DHT_HASH_TYPE_DM: break; default: gf_smsg(this->name, GF_LOG_CRITICAL, 0, DHT_MSG_INVALID_DISK_LAYOUT, "layout=%d", disk_layout[1], NULL); return -1; } commit_hash = be32toh(disk_layout[0]); start_off = be32toh(disk_layout[2]); stop_off = be32toh(disk_layout[3]); layout->list[pos].commit_hash = commit_hash; layout->list[pos].start = start_off; layout->list[pos].stop = stop_off; gf_msg_trace(this->name, 0, "merged to layout: 0x%x - 0x%x (hash 0x%x, type %d) from %s", start_off, stop_off, commit_hash, type, layout->list[pos].xlator->name); return 0; } int dht_layout_merge(xlator_t *this, dht_layout_t *layout, xlator_t *subvol, int op_ret, int op_errno, dict_t *xattr) { int i = 0; int ret = -1; int err = -1; void *disk_layout_raw = NULL; int disk_layout_len = 0; dht_conf_t *conf = this->private; if (op_ret != 0) { err = op_errno; } if (!layout) goto out; for (i = 0; i < layout->cnt; i++) { if (layout->list[i].xlator == NULL) { layout->list[i].err = err; layout->list[i].xlator = subvol; break; } } if (op_ret != 0) { ret = 0; goto out; } if (xattr) { /* during lookup and not mkdir */ ret = dict_get_ptr_and_len(xattr, conf->xattr_name, &disk_layout_raw, &disk_layout_len); } if (ret != 0) { layout->list[i].err = 0; gf_msg_trace(this->name, 0, "Missing disk layout on %s. err = %d", subvol->name, err); ret = 0; goto out; } ret = dht_disk_layout_merge(this, layout, i, disk_layout_raw, disk_layout_len); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_MERGE_FAILED, "subvolume=%s", subvol->name, NULL); goto out; } if (layout->commit_hash == 0) { layout->commit_hash = layout->list[i].commit_hash; } else if (layout->commit_hash != layout->list[i].commit_hash) { layout->commit_hash = DHT_LAYOUT_HASH_INVALID; } layout->list[i].err = 0; out: return ret; } void dht_layout_range_swap(dht_layout_t *layout, int i, int j) { uint32_t start_swap = 0; uint32_t stop_swap = 0; start_swap = layout->list[i].start; stop_swap = layout->list[i].stop; layout->list[i].start = layout->list[j].start; layout->list[i].stop = layout->list[j].stop; layout->list[j].start = start_swap; layout->list[j].stop = stop_swap; } gf_boolean_t dht_is_subvol_in_layout(dht_layout_t *layout, xlator_t *xlator) { int i = 0; for (i = 0; i < layout->cnt; i++) { /* Check if xlator is already part of layout, and layout is * non-zero. */ if (!strcmp(layout->list[i].xlator->name, xlator->name)) { if (layout->list[i].start != layout->list[i].stop) return _gf_true; break; } } return _gf_false; } static int dht_layout_entry_cmp(const void *p, const void *q) { const dht_layout_entry_t *x = p, *y = q; int64_t diff = 0; if (!y->start && !y->stop) diff = (int64_t)x->stop - (int64_t)y->stop; else diff = (int64_t)x->start - (int64_t)y->start; return (diff == 0 ? 0 : (diff < 0 ? -1 : 1)); } static int dht_layout_entry_cmp_volname(const void *p, const void *q) { const dht_layout_entry_t *x = p, *y = q; return strcmp(x->xlator->name, y->xlator->name); } void dht_layout_sort(dht_layout_t *layout) { qsort(layout->list, layout->cnt, sizeof(dht_layout_entry_t), dht_layout_entry_cmp); } void dht_layout_sort_volname(dht_layout_t *layout) { qsort(layout->list, layout->cnt, sizeof(dht_layout_entry_t), dht_layout_entry_cmp_volname); } void dht_layout_anomalies(xlator_t *this, loc_t *loc, dht_layout_t *layout, uint32_t *holes_p, uint32_t *overlaps_p, uint32_t *missing_p, uint32_t *down_p, uint32_t *misc_p, uint32_t *no_space_p) { uint32_t missing = 0; uint32_t down = 0; uint32_t misc = 0; uint32_t hole_cnt = 0; uint32_t overlap_cnt = 0; int i = 0; uint32_t prev_stop = 0; uint32_t last_stop = 0; char is_virgin = 1; uint32_t no_space = 0; /* This function scans through the layout spread of a directory to check if there are any anomalies. Prior to calling this function the layout entries should be sorted in the ascending order. If the layout entry has err != 0 then increment the corresponding anomaly. else if (start of the current layout entry > stop + 1 of previous non erroneous layout entry) then it indicates a hole in the layout if (start of the current layout entry < stop + 1 of previous non erroneous layout entry) then it indicates an overlap in the layout */ last_stop = layout->list[0].start - 1; prev_stop = last_stop; for (i = 0; i < layout->cnt; i++) { switch (layout->list[i].err) { case -1: case ENOENT: case ESTALE: missing++; continue; case ENOTCONN: down++; continue; case ENOSPC: no_space++; continue; case 0: /* if err == 0 and start == stop, then it is a non misc++; * participating subvolume(spread-cnt). Then, do not * check for anomalies. If start != stop, then treat it * as misc err */ if (layout->list[i].start == layout->list[i].stop) { continue; } break; default: misc++; continue; } is_virgin = 0; if ((prev_stop + 1) < layout->list[i].start) { hole_cnt++; } if ((prev_stop + 1) > layout->list[i].start) { overlap_cnt++; } prev_stop = layout->list[i].stop; } if ((last_stop - prev_stop) || is_virgin) hole_cnt++; if (holes_p) *holes_p = hole_cnt; if (overlaps_p) *overlaps_p = overlap_cnt; if (missing_p) *missing_p = missing; if (down_p) *down_p = down; if (misc_p) *misc_p = misc; if (no_space_p) *no_space_p = no_space; } int dht_layout_missing_dirs(dht_layout_t *layout) { int i = 0, missing = 0; if (layout == NULL) goto out; for (i = 0; i < layout->cnt; i++) { if ((layout->list[i].err == ENOENT) || ((layout->list[i].err == -1) && (layout->list[i].start == 0) && (layout->list[i].stop == 0))) { missing++; } } out: return missing; } int dht_layout_normalize(xlator_t *this, loc_t *loc, dht_layout_t *layout) { int ret = 0; uint32_t holes = 0; uint32_t overlaps = 0; uint32_t missing = 0; uint32_t down = 0; uint32_t misc = 0, missing_dirs = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; dht_layout_sort(layout); gf_uuid_unparse(loc->gfid, gfid); dht_layout_anomalies(this, loc, layout, &holes, &overlaps, &missing, &down, &misc, NULL); if (holes || overlaps) { if (missing == layout->cnt) { gf_msg_debug(this->name, 0, "Directory %s looked up first time" " gfid = %s", loc->path, gfid); } else { gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_ANOMALIES_INFO, "path=%s", loc->path, "gfid=%s", gfid, "holes=%d", holes, "overlaps=%d", overlaps, NULL); } ret = -1; } if (ret >= 0) { missing_dirs = dht_layout_missing_dirs(layout); /* TODO During DHT selfheal rewrite (almost) find a better place * to detect this - probably in dht_layout_anomalies() */ if (missing_dirs > 0) ret += missing_dirs; } return ret; } int dht_dir_has_layout(dict_t *xattr, char *name) { void *disk_layout_raw = NULL; return dict_get_ptr(xattr, name, &disk_layout_raw); } int dht_layout_dir_mismatch(xlator_t *this, dht_layout_t *layout, xlator_t *subvol, loc_t *loc, dict_t *xattr) { int idx = 0; int pos = -1; int ret = 0; int err = 0; int dict_ret = 0; int32_t disk_layout[4]; void *disk_layout_raw = NULL; uint32_t start_off = -1; uint32_t stop_off = -1; uint32_t commit_hash = -1; dht_conf_t *conf = this->private; char gfid[GF_UUID_BUF_SIZE] = {0}; if (loc && loc->inode) gf_uuid_unparse(loc->inode->gfid, gfid); for (idx = 0; idx < layout->cnt; idx++) { if (layout->list[idx].xlator == subvol) { pos = idx; break; } } if (pos == -1) { if (loc) { gf_msg_debug(this->name, 0, "%s - no layout info for subvolume %s", loc ? loc->path : "path not found", subvol->name); } ret = 1; goto out; } err = layout->list[pos].err; if (!xattr) { if (err == 0) { if (loc) { gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_XATTR_DICT_NULL, "path=%s", loc->path, NULL); } else { gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_XATTR_DICT_NULL, "path not found", NULL); } ret = -1; } goto out; } dict_ret = dict_get_ptr(xattr, conf->xattr_name, &disk_layout_raw); if (dict_ret < 0) { if (err == 0 && layout->list[pos].stop) { if (loc) { gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_DISK_LAYOUT_MISSING, "path=%s", loc->path, "gfid=%s", gfid, NULL); } else { gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_DISK_LAYOUT_MISSING, "path not found" "gfid=%s", gfid, NULL); } ret = -1; } goto out; } memcpy(disk_layout, disk_layout_raw, sizeof(disk_layout)); start_off = be32toh(disk_layout[2]); stop_off = be32toh(disk_layout[3]); commit_hash = be32toh(disk_layout[0]); if ((layout->list[pos].start != start_off) || (layout->list[pos].stop != stop_off) || (layout->list[pos].commit_hash != commit_hash)) { gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_INFO, "subvol=%s", layout->list[pos].xlator->name, "inode-layout:start=0x%x", layout->list[pos].start, "inode-layout:stop=0x%x", layout->list[pos].stop, "layout-commit-hash=0x%x; ", layout->list[pos].commit_hash, "disk-layout:start-off=0x%x", start_off, "disk-layout:top-off=0x%x", stop_off, "commit-hash=0x%x", commit_hash, NULL); ret = 1; } else { ret = 0; } out: return ret; } int dht_layout_preset(xlator_t *this, xlator_t *subvol, inode_t *inode) { dht_layout_t *layout = NULL; int ret = -1; dht_conf_t *conf = NULL; conf = this->private; if (!conf) goto out; layout = dht_layout_for_subvol(this, subvol); if (!layout) { gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_NO_LAYOUT_INFO, "subvolume=%s", subvol ? subvol->name : "", NULL); ret = -1; goto out; } gf_msg_debug(this->name, 0, "file = %s, subvol = %s", uuid_utoa(inode->gfid), subvol ? subvol->name : ""); ret = dht_inode_ctx_layout_set(inode, this, layout); out: return ret; } int dht_layout_index_for_subvol(dht_layout_t *layout, xlator_t *subvol) { int i = 0, ret = -1; for (i = 0; i < layout->cnt; i++) { if (layout->list[i].xlator == subvol) { ret = i; break; } } return ret; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/nufa.c0000644000000000000000000000013014522202451022176 xustar000000000000000029 mtime=1699284265.63002732 29 atime=1699284265.63002732 30 ctime=1699284301.239134574 glusterfs-11.1/xlators/cluster/dht/src/nufa.c0000664000175100017510000004304614522202451022466 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-common.h" /* TODO: all 'TODO's in dht.c holds good */ extern struct volume_options dht_options[]; int nufa_local_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { xlator_t *subvol = NULL; char is_linkfile = 0; char is_dir = 0; dht_conf_t *conf = NULL; dht_local_t *local = NULL; loc_t *loc = NULL; int i = 0; xlator_t *prev = NULL; int call_cnt = 0; int ret = 0; conf = this->private; prev = cookie; local = frame->local; loc = &local->loc; if (ENTRY_MISSING(op_ret, op_errno)) { if (conf->search_unhashed) { local->op_errno = ENOENT; dht_lookup_everywhere(frame, this, loc); return 0; } } if (op_ret == -1) goto out; is_linkfile = check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name); is_dir = check_is_dir(inode, stbuf, xattr); if (!is_dir && !is_linkfile) { /* non-directory and not a linkfile */ ret = dht_layout_preset(this, prev, inode); if (ret < 0) { gf_msg_debug(this->name, 0, "could not set pre-set layout for subvol" " %s", prev->name); op_ret = -1; op_errno = EINVAL; goto err; } goto out; } if (is_dir) { call_cnt = conf->subvolume_cnt; local->call_cnt = call_cnt; local->inode = inode_ref(inode); local->xattr = dict_ref(xattr); local->op_ret = 0; local->op_errno = 0; local->layout = dht_layout_new(this, conf->subvolume_cnt); if (!local->layout) { op_ret = -1; op_errno = ENOMEM; goto err; } for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, dht_lookup_dir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, &local->loc, local->xattr_req); } } if (is_linkfile) { subvol = dht_linkfile_subvol(this, inode, stbuf, xattr); if (!subvol) { gf_msg_debug(this->name, 0, "linkfile has no link subvolume. path=%s", loc->path); dht_lookup_everywhere(frame, this, loc); return 0; } STACK_WIND_COOKIE(frame, dht_lookup_linkfile_cbk, subvol, subvol, subvol->fops->lookup, &local->loc, local->xattr_req); } return 0; out: if (!local->hashed_subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", local->loc.path); local->op_errno = ENOENT; dht_lookup_everywhere(frame, this, loc); return 0; } STACK_WIND_COOKIE(frame, dht_lookup_cbk, local->hashed_subvol, local->hashed_subvol, local->hashed_subvol->fops->lookup, &local->loc, local->xattr_req); return 0; err: DHT_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, stbuf, xattr, postparent); return 0; } int nufa_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { xlator_t *hashed_subvol = NULL; xlator_t *subvol = NULL; dht_local_t *local = NULL; dht_conf_t *conf = NULL; int ret = -1; int op_errno = -1; dht_layout_t *layout = NULL; int i = 0; int call_cnt = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(loc->path, err); conf = this->private; local = dht_local_init(frame, loc, NULL, GF_FOP_LOOKUP); if (!local) { op_errno = ENOMEM; goto err; } if (xattr_req) { local->xattr_req = dict_ref(xattr_req); } else { local->xattr_req = dict_new(); } hashed_subvol = dht_subvol_get_hashed(this, &local->loc); local->hashed_subvol = hashed_subvol; if (is_revalidate(loc)) { layout = local->layout; if (!layout) { gf_msg_debug(this->name, 0, "revalidate lookup without cache. " "path=%s", loc->path); op_errno = EINVAL; goto err; } if (layout->gen && (layout->gen < conf->gen)) { gf_msg_debug(this->name, 0, "incomplete layout failure for path=%s", loc->path); dht_layout_unref(local->layout); goto do_fresh_lookup; } local->inode = inode_ref(loc->inode); local->call_cnt = layout->cnt; call_cnt = local->call_cnt; /* NOTE: we don't require 'trusted.glusterfs.dht.linkto' attribute, * revalidates directly go to the cached-subvolume. */ ret = dict_set_uint32(local->xattr_req, conf->xattr_name, 4 * 4); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dict value."); op_errno = -1; goto err; } for (i = 0; i < layout->cnt; i++) { subvol = layout->list[i].xlator; STACK_WIND_COOKIE(frame, dht_revalidate_cbk, subvol, subvol, subvol->fops->lookup, loc, local->xattr_req); if (!--call_cnt) break; } } else { do_fresh_lookup: ret = dict_set_uint32(local->xattr_req, conf->xattr_name, 4 * 4); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dict value."); op_errno = -1; goto err; } ret = dict_set_uint32(local->xattr_req, conf->link_xattr_name, 256); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dict value."); op_errno = -1; goto err; } /* Send it to only local volume */ STACK_WIND_COOKIE( frame, nufa_local_lookup_cbk, ((xlator_t *)conf->private), ((xlator_t *)conf->private), ((xlator_t *)conf->private)->fops->lookup, loc, local->xattr_req); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } int nufa_create_linkfile_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (op_ret == -1) goto err; STACK_WIND_COOKIE(frame, dht_create_cbk, local->cached_subvol, local->cached_subvol, local->cached_subvol->fops->create, &local->loc, local->flags, local->mode, local->umask, local->fd, local->params); return 0; err: DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int nufa_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *params) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; xlator_t *subvol = NULL; xlator_t *avail_subvol = NULL; int op_errno = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); conf = this->private; dht_get_du_info(frame, this, loc); local = dht_local_init(frame, loc, fd, GF_FOP_CREATE); if (!local) { op_errno = ENOMEM; goto err; } subvol = dht_subvol_get_hashed(this, loc); if (!subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", loc->path); op_errno = ENOENT; goto err; } avail_subvol = conf->private; if (dht_is_subvol_filled(this, (xlator_t *)conf->private)) { avail_subvol = dht_free_disk_available_subvol( this, (xlator_t *)conf->private, local); } if (subvol != avail_subvol) { /* create a link file instead of actual file */ local->params = dict_ref(params); local->mode = mode; local->flags = flags; local->umask = umask; local->cached_subvol = avail_subvol; dht_linkfile_create(frame, nufa_create_linkfile_create_cbk, this, avail_subvol, subvol, loc); return 0; } gf_msg_trace(this->name, 0, "creating %s on %s", loc->path, subvol->name); STACK_WIND_COOKIE(frame, dht_create_cbk, subvol, subvol, subvol->fops->create, loc, flags, mode, umask, fd, params); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int nufa_mknod_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (!local || !local->cached_subvol) { op_errno = EINVAL; op_ret = -1; goto err; } if (op_ret >= 0) { STACK_WIND_COOKIE( frame, dht_newfile_cbk, (void *)local->cached_subvol, local->cached_subvol, local->cached_subvol->fops->mknod, &local->loc, local->mode, local->rdev, local->umask, local->params); return 0; } err: WIPE(postparent); WIPE(preparent); DHT_STACK_UNWIND(link, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); return 0; } int nufa_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *params) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; xlator_t *subvol = NULL; xlator_t *avail_subvol = NULL; int op_errno = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); conf = this->private; dht_get_du_info(frame, this, loc); local = dht_local_init(frame, loc, NULL, GF_FOP_MKNOD); if (!local) { op_errno = ENOMEM; goto err; } subvol = dht_subvol_get_hashed(this, loc); if (!subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", loc->path); op_errno = ENOENT; goto err; } /* Consider the disksize in consideration */ avail_subvol = conf->private; if (dht_is_subvol_filled(this, (xlator_t *)conf->private)) { avail_subvol = dht_free_disk_available_subvol( this, (xlator_t *)conf->private, local); } if (avail_subvol != subvol) { /* Create linkfile first */ local->params = dict_ref(params); local->mode = mode; local->umask = umask; local->rdev = rdev; local->cached_subvol = avail_subvol; dht_linkfile_create(frame, nufa_mknod_linkfile_cbk, this, avail_subvol, subvol, loc); return 0; } gf_msg_trace(this->name, 0, "creating %s on %s", loc->path, subvol->name); STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)subvol, subvol, subvol->fops->mknod, loc, mode, rdev, umask, params); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } gf_boolean_t same_first_part(char *str1, char term1, char *str2, char term2) { gf_boolean_t ended1; gf_boolean_t ended2; for (;;) { ended1 = ((*str1 == '\0') || (*str1 == term1)); ended2 = ((*str2 == '\0') || (*str2 == term2)); if (ended1 && ended2) { return _gf_true; } if (ended1 || ended2 || (*str1 != *str2)) { return _gf_false; } ++str1; ++str2; } } typedef struct nufa_args { xlator_t *this; char *volname; gf_boolean_t addr_match; } nufa_args_t; static void nufa_find_local_brick(xlator_t *xl, void *data) { nufa_args_t *args = data; xlator_t *this = args->this; char *local_volname = args->volname; gf_boolean_t addr_match = args->addr_match; char *brick_host = NULL; dht_conf_t *conf = this->private; int ret = -1; /*This means a local subvol was already found. We pick the first brick * that is local*/ if (conf->private) return; if (strcmp(xl->name, local_volname) == 0) { conf->private = xl; gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, "Using specified subvol %s", local_volname); return; } if (!addr_match) return; ret = dict_get_str(xl->options, "remote-host", &brick_host); if ((ret == 0) && (gf_is_same_address(local_volname, brick_host) || gf_is_local_addr(brick_host))) { conf->private = xl; gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, "Using the first local " "subvol %s", xl->name); return; } } static void nufa_to_dht(xlator_t *this) { GF_ASSERT(this); GF_ASSERT(this->fops); this->fops->lookup = dht_lookup; this->fops->create = dht_create; this->fops->mknod = dht_mknod; } int nufa_find_local_subvol(xlator_t *this, void (*fn)(xlator_t *each, void *data), void *data) { int ret = -1; dht_conf_t *conf = this->private; xlator_list_t *trav = NULL; xlator_t *parent = NULL; xlator_t *candidate = NULL; xlator_foreach_depth_first(this, fn, data); if (!conf->private) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_BRICK_ERROR, "Couldn't find a local " "brick"); return -1; } candidate = conf->private; trav = candidate->parents; while (trav) { parent = trav->xlator; if (strcmp(parent->type, "cluster/nufa") == 0) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, "Found local subvol, " "%s", candidate->name); ret = 0; conf->private = candidate; break; } candidate = parent; trav = parent->parents; } return ret; } int nufa_init(xlator_t *this) { data_t *data = NULL; char *local_volname = NULL; int ret = -1; gf_boolean_t addr_match = _gf_false; nufa_args_t args = { 0, }; ret = dht_init(this); if (ret) { return ret; } if ((data = dict_get(this->options, "local-volume-name"))) { local_volname = data->data; } else { addr_match = _gf_true; local_volname = gf_gethostname(); } args.this = this; args.volname = local_volname; args.addr_match = addr_match; ret = nufa_find_local_subvol(this, nufa_find_local_brick, &args); if (ret) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, "Unable to find local subvolume, switching " "to dht mode"); nufa_to_dht(this); } return 0; } dht_methods_t dht_methods = { .migration_get_dst_subvol = dht_migration_get_dst_subvol, .layout_search = dht_layout_search, }; struct xlator_fops fops = { .lookup = nufa_lookup, .create = nufa_create, .mknod = nufa_mknod, .stat = dht_stat, .fstat = dht_fstat, .truncate = dht_truncate, .ftruncate = dht_ftruncate, .access = dht_access, .readlink = dht_readlink, .setxattr = dht_setxattr, .getxattr = dht_getxattr, .removexattr = dht_removexattr, .open = dht_open, .readv = dht_readv, .writev = dht_writev, .flush = dht_flush, .fsync = dht_fsync, .statfs = dht_statfs, .lk = dht_lk, .opendir = dht_opendir, .readdir = dht_readdir, .readdirp = dht_readdirp, .fsyncdir = dht_fsyncdir, .symlink = dht_symlink, .unlink = dht_unlink, .link = dht_link, .mkdir = dht_mkdir, .rmdir = dht_rmdir, .rename = dht_rename, .inodelk = dht_inodelk, .finodelk = dht_finodelk, .entrylk = dht_entrylk, .fentrylk = dht_fentrylk, .xattrop = dht_xattrop, .fxattrop = dht_fxattrop, .setattr = dht_setattr, }; struct xlator_cbks cbks = {.forget = dht_forget}; extern int32_t mem_acct_init(xlator_t *this); xlator_api_t xlator_api = { .init = nufa_init, .fini = dht_fini, .notify = dht_notify, .reconfigure = dht_reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = dht_options, .identifier = "nufa", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-inode-read.c0000644000000000000000000000013214522202451024033 xustar000000000000000030 mtime=1699284265.625027305 30 atime=1699284265.625027305 30 ctime=1699284301.233134556 glusterfs-11.1/xlators/cluster/dht/src/dht-inode-read.c0000664000175100017510000013370214522202451024320 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-common.h" static int dht_access2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_readv2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_attr2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_open2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_flush2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_lk2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_fsync2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_common_xattrop2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = 0; local = frame->local; prev = cookie; local->op_errno = op_errno; if ((op_ret == -1) && !dht_inode_missing(op_errno)) { gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } /* Update ctx if the fd has been opened on the target*/ if (!op_ret && (local->call_cnt == 1)) { dht_fd_ctx_set(this, fd, prev); goto out; } if (!op_ret || (local->call_cnt != 1)) goto out; /* rebalance would have happened */ local->rebalance.target_op_fn = dht_open2; ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; out: DHT_STACK_UNWIND(open, frame, op_ret, op_errno, local->fd, xdata); return 0; } static int dht_open2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int op_errno = EINVAL; if (!frame || !frame->local) goto out; local = frame->local; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This DHT layer is not migrating the file */ DHT_STACK_UNWIND(open, frame, -1, local->op_errno, NULL, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; STACK_WIND_COOKIE(frame, dht_open_cbk, subvol, subvol, subvol->fops->open, &local->loc, local->rebalance.flags, local->fd, local->xattr_req); return 0; out: DHT_STACK_UNWIND(open, frame, -1, op_errno, NULL, NULL); return 0; } int dht_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, fd_t *fd, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, loc, fd, GF_FOP_OPEN); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); local->rebalance.flags = flags; local->call_cnt = 1; STACK_WIND_COOKIE(frame, dht_open_cbk, subvol, subvol, subvol->fops->open, loc, flags, fd, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(open, frame, -1, op_errno, NULL, NULL); return 0; } int dht_file_attr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *stbuf, dict_t *xdata) { xlator_t *subvol1 = 0; xlator_t *subvol2 = 0; dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = -1; inode_t *inode = NULL; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", cookie, out); local = frame->local; prev = cookie; if ((local->fop == GF_FOP_FSTAT) && dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if ((op_ret == -1) && !dht_inode_missing(op_errno)) { local->op_errno = op_errno; gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if (local->call_cnt != 1) goto out; local->op_errno = op_errno; local->op_ret = op_ret; /* Check if the rebalance phase2 is true */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(stbuf)) { local->rebalance.target_op_fn = dht_attr2; dht_set_local_rebalance(this, local, NULL, NULL, stbuf, xdata); inode = (local->fd) ? local->fd->inode : local->loc.inode; dht_inode_ctx_get_mig_info(this, inode, &subvol1, &subvol2); if (dht_mig_info_is_invalid(local->cached_subvol, subvol1, subvol2)) { /* Phase 2 of migration */ ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } else { /* it is a non-fd op or it is an fd based Fop and opened on the dst.*/ if (local->fd && !dht_fd_open_on_dst(this, local->fd, subvol2)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } else { dht_attr2(subvol2, frame, 0); return 0; } } } out: DHT_STRIP_PHASE1_FLAGS(stbuf); DHT_STACK_UNWIND(stat, frame, op_ret, op_errno, stbuf, xdata); err: return 0; } static int dht_attr2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int op_errno = EINVAL; local = frame->local; if (!local) goto out; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(stat, frame, local->op_ret, op_errno, &local->rebalance.postbuf, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; if (local->fop == GF_FOP_FSTAT) { STACK_WIND_COOKIE(frame, dht_file_attr_cbk, subvol, subvol, subvol->fops->fstat, local->fd, local->xattr_req); } else { STACK_WIND_COOKIE(frame, dht_file_attr_cbk, subvol, subvol, subvol->fops->stat, &local->loc, local->xattr_req); } return 0; out: DHT_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL); return 0; } static int dht_attr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *stbuf, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; local = frame->local; prev = cookie; LOCK(&frame->lock); { if (op_ret == -1) { local->op_errno = op_errno; UNLOCK(&frame->lock); gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto post_unlock; } dht_iatt_merge(this, &local->stbuf, stbuf); local->op_ret = 0; } UNLOCK(&frame->lock); post_unlock: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { DHT_STACK_UNWIND(stat, frame, local->op_ret, local->op_errno, &local->stbuf, xdata); } return 0; } int dht_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; dht_layout_t *layout = NULL; int i = 0; int call_cnt = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(loc->path, err); local = dht_local_init(frame, loc, NULL, GF_FOP_STAT); if (!local) { op_errno = ENOMEM; goto err; } layout = local->layout; if (!layout) { gf_msg_debug(this->name, 0, "no layout for path=%s", loc->path); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); if (IA_ISREG(loc->inode->ia_type)) { local->call_cnt = 1; subvol = local->cached_subvol; STACK_WIND_COOKIE(frame, dht_file_attr_cbk, subvol, subvol, subvol->fops->stat, loc, xdata); return 0; } local->call_cnt = call_cnt = layout->cnt; for (i = 0; i < call_cnt; i++) { subvol = layout->list[i].xlator; STACK_WIND_COOKIE(frame, dht_attr_cbk, subvol, subvol, subvol->fops->stat, loc, xdata); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL); return 0; } int dht_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; dht_layout_t *layout = NULL; int i = 0; int call_cnt = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_FSTAT); if (!local) { op_errno = ENOMEM; goto err; } layout = local->layout; if (!layout) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "no layout for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); if (IA_ISREG(fd->inode->ia_type)) { local->call_cnt = 1; subvol = local->cached_subvol; STACK_WIND_COOKIE(frame, dht_file_attr_cbk, subvol, subvol, subvol->fops->fstat, fd, xdata); return 0; } local->call_cnt = call_cnt = layout->cnt; for (i = 0; i < call_cnt; i++) { subvol = layout->list[i].xlator; STACK_WIND_COOKIE(frame, dht_attr_cbk, subvol, subvol, subvol->fops->fstat, fd, xdata); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, NULL); return 0; } int dht_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iovec *vector, int count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { dht_local_t *local = NULL; int ret = 0; xlator_t *src_subvol = 0; xlator_t *dst_subvol = 0; local = frame->local; if (!local) { op_ret = -1; op_errno = EINVAL; goto out; } /* This is already second try, no need for re-check */ if (local->call_cnt != 1) goto out; if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if ((op_ret == -1) && !dht_inode_missing(op_errno)) goto out; local->op_errno = op_errno; if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(stbuf)) { local->op_ret = op_ret; local->rebalance.target_op_fn = dht_readv2; dht_set_local_rebalance(this, local, NULL, NULL, stbuf, xdata); /* File would be migrated to other node */ ret = dht_inode_ctx_get_mig_info(this, local->fd->inode, &src_subvol, &dst_subvol); if (dht_mig_info_is_invalid(local->cached_subvol, src_subvol, dst_subvol) || !dht_fd_open_on_dst(this, local->fd, dst_subvol)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } else { /* value is already set in fd_ctx, that means no need to check for whether its complete or not. */ dht_readv2(dst_subvol, frame, 0); return 0; } } out: DHT_STRIP_PHASE1_FLAGS(stbuf); DHT_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, stbuf, iobref, xdata); return 0; } static int dht_readv2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int op_errno = EINVAL; local = frame->local; if (!local) goto out; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(readv, frame, local->op_ret, op_errno, NULL, 0, &local->rebalance.postbuf, NULL, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; STACK_WIND(frame, dht_readv_cbk, subvol, subvol->fops->readv, local->fd, local->rebalance.size, local->rebalance.offset, local->rebalance.flags, local->xattr_req); return 0; out: DHT_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); return 0; } int dht_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, uint32_t flags, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_READ); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); local->rebalance.offset = off; local->rebalance.size = size; local->rebalance.flags = flags; local->call_cnt = 1; STACK_WIND(frame, dht_readv_cbk, subvol, subvol->fops->readv, local->fd, local->rebalance.size, local->rebalance.offset, local->rebalance.flags, local->xattr_req); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); return 0; } static int dht_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { int ret = -1; dht_local_t *local = NULL; xlator_t *subvol = NULL; xlator_t *prev = NULL; local = frame->local; prev = cookie; if (!prev) goto out; if (local->call_cnt != 1) goto out; if ((op_ret == -1) && ((op_errno == ENOTCONN) || dht_inode_missing(op_errno)) && IA_ISDIR(local->loc.inode->ia_type)) { subvol = dht_subvol_next_available(this, prev); if (!subvol) goto out; /* check if we are done with visiting every node */ if (subvol == local->cached_subvol) { goto out; } STACK_WIND_COOKIE(frame, dht_access_cbk, subvol, subvol, subvol->fops->access, &local->loc, local->rebalance.flags, NULL); return 0; } if ((op_ret == -1) && dht_inode_missing(op_errno) && !(IA_ISDIR(local->loc.inode->ia_type))) { /* File would be migrated to other node */ local->op_errno = op_errno; local->rebalance.target_op_fn = dht_access2; ret = dht_rebalance_complete_check(frame->this, frame); if (!ret) return 0; } out: DHT_STACK_UNWIND(access, frame, op_ret, op_errno, xdata); return 0; } static int dht_access2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int op_errno = EINVAL; local = frame->local; if (!local) goto out; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(access, frame, -1, op_errno, NULL); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; STACK_WIND_COOKIE(frame, dht_access_cbk, subvol, subvol, subvol->fops->access, &local->loc, local->rebalance.flags, local->xattr_req); return 0; out: DHT_STACK_UNWIND(access, frame, -1, op_errno, NULL); return 0; } int dht_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(loc->path, err); local = dht_local_init(frame, loc, NULL, GF_FOP_ACCESS); if (!local) { op_errno = ENOMEM; goto err; } local->rebalance.flags = mask; local->call_cnt = 1; subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", loc->path); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); STACK_WIND_COOKIE(frame, dht_access_cbk, subvol, subvol, subvol->fops->access, loc, mask, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(access, frame, -1, op_errno, NULL); return 0; } int dht_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *subvol = 0; int ret = 0; local = frame->local; local->op_errno = op_errno; if (local->call_cnt != 1) goto out; if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } local->rebalance.target_op_fn = dht_flush2; local->op_ret = op_ret; local->op_errno = op_errno; /* If context is set, then send flush() it to the destination */ dht_inode_ctx_get_mig_info(this, local->fd->inode, NULL, &subvol); if (subvol && dht_fd_open_on_dst(this, local->fd, subvol)) { dht_flush2(subvol, frame, 0); return 0; } if (op_errno == EREMOTE) { ret = dht_rebalance_complete_check(this, frame); if (!ret) { return 0; } } out: DHT_STACK_UNWIND(flush, frame, op_ret, op_errno, xdata); return 0; } static int dht_flush2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if ((frame == NULL) || (frame->local == NULL)) goto out; local = frame->local; op_errno = local->op_errno; if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ STACK_WIND(frame, dht_flush_cbk, subvol, subvol->fops->flush, local->fd, local->xattr_req); return 0; out: DHT_STACK_UNWIND(flush, frame, -1, op_errno, NULL); return 0; } int dht_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_FLUSH); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); local->call_cnt = 1; STACK_WIND(frame, dht_flush_cbk, subvol, subvol->fops->flush, fd, local->xattr_req); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(flush, frame, -1, op_errno, NULL); return 0; } int dht_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = -1; inode_t *inode = NULL; xlator_t *src_subvol = 0; xlator_t *dst_subvol = 0; local = frame->local; prev = cookie; local->op_errno = op_errno; if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if (op_ret == -1 && !dht_inode_missing(op_errno)) { gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if (local->call_cnt != 1) { if (local->stbuf.ia_blocks) { dht_iatt_merge(this, postbuf, &local->stbuf); dht_iatt_merge(this, prebuf, &local->prebuf); } goto out; } local->op_ret = op_ret; inode = local->fd->inode; local->rebalance.target_op_fn = dht_fsync2; dht_set_local_rebalance(this, local, NULL, prebuf, postbuf, xdata); if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(postbuf)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* Check if the rebalance phase1 is true */ if (IS_DHT_MIGRATION_PHASE1(postbuf)) { dht_iatt_merge(this, &local->stbuf, postbuf); dht_iatt_merge(this, &local->prebuf, prebuf); dht_inode_ctx_get_mig_info(this, inode, &src_subvol, &dst_subvol); if (dht_mig_info_is_invalid(local->cached_subvol, src_subvol, dst_subvol) || !dht_fd_open_on_dst(this, local->fd, dst_subvol)) { ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } else { dht_fsync2(dst_subvol, frame, 0); return 0; } } out: DHT_STRIP_PHASE1_FLAGS(postbuf); DHT_STRIP_PHASE1_FLAGS(prebuf); DHT_STACK_UNWIND(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } static int dht_fsync2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if ((frame == NULL) || (frame->local == NULL)) goto out; local = frame->local; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(fsync, frame, local->op_ret, op_errno, &local->rebalance.prebuf, &local->rebalance.postbuf, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ STACK_WIND_COOKIE(frame, dht_fsync_cbk, subvol, subvol, subvol->fops->fsync, local->fd, local->rebalance.flags, local->xattr_req); return 0; out: DHT_STACK_UNWIND(fsync, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_FSYNC); if (!local) { op_errno = ENOMEM; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); local->call_cnt = 1; local->rebalance.flags = datasync; subvol = local->cached_subvol; STACK_WIND_COOKIE(frame, dht_fsync_cbk, subvol, subvol, subvol->fops->fsync, local->fd, local->rebalance.flags, local->xattr_req); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fsync, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* TODO: for 'lk()' call, we need some other special error, may be ESTALE to indicate that lock migration happened on the fd, so we can consider it as phase 2 of migration */ static int dht_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct gf_flock *flock, dict_t *xdata) { dht_local_t *local = NULL; int ret = -1; xlator_t *subvol = NULL; local = frame->local; if (!local) { op_ret = -1; op_errno = EINVAL; goto out; } if (local->call_cnt != 1) goto out; local->rebalance.target_op_fn = dht_lk2; local->op_ret = op_ret; local->op_errno = op_errno; if (xdata) local->rebalance.xdata = dict_ref(xdata); if (op_errno == EREMOTE) { dht_inode_ctx_get_mig_info(this, local->fd->inode, NULL, &subvol); if (subvol && dht_fd_open_on_dst(this, local->fd, subvol)) { dht_lk2(subvol, frame, 0); return 0; } else { ret = dht_rebalance_complete_check(this, frame); if (!ret) { return 0; } } } out: dht_lk_inode_unref(frame, op_ret); DHT_STACK_UNWIND(lk, frame, op_ret, op_errno, flock, xdata); return 0; } static int dht_lk2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if ((frame == NULL) || (frame->local == NULL)) goto out; local = frame->local; op_errno = local->op_errno; if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ STACK_WIND(frame, dht_lk_cbk, subvol, subvol->fops->lk, local->fd, local->rebalance.lock_cmd, &local->rebalance.flock, local->xattr_req); return 0; out: DHT_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL); return 0; } int dht_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int cmd, struct gf_flock *flock, dict_t *xdata) { xlator_t *lock_subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_LK); if (!local) { op_errno = ENOMEM; goto err; } local->lock_type = flock->l_type; lock_subvol = dht_get_lock_subvolume(this, flock, local); if (!lock_subvol) { gf_msg_debug(this->name, 0, "no lock subvolume for path=%p", fd); op_errno = EINVAL; goto err; } /* local->cached_subvol = lock_subvol; ret = dht_check_and_open_fd_on_subvol (this, frame); if (ret) goto err; */ if (xdata) local->xattr_req = dict_ref(xdata); gf_flock_copy(&local->rebalance.flock, flock); local->rebalance.lock_cmd = cmd; local->call_cnt = 1; STACK_WIND(frame, dht_lk_cbk, lock_subvol, lock_subvol->fops->lk, fd, cmd, flock, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL); return 0; } static int dht_lease_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct gf_lease *lease, dict_t *xdata) { DHT_STACK_UNWIND(lease, frame, op_ret, op_errno, lease, xdata); return 0; } int dht_lease(call_frame_t *frame, xlator_t *this, loc_t *loc, struct gf_lease *lease, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); subvol = dht_subvol_get_cached(this, loc->inode); if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", loc->path); op_errno = EINVAL; goto err; } /* TODO: for rebalance, we need to preserve the fop arguments */ STACK_WIND(frame, dht_lease_cbk, subvol, subvol->fops->lease, loc, lease, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(lease, frame, -1, op_errno, NULL, NULL); return 0; } /* Symlinks are currently not migrated, so no need for any check here */ static int dht_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, const char *path, struct iatt *stbuf, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (op_ret == -1) goto err; if (!local) { op_ret = -1; op_errno = EINVAL; } err: DHT_STRIP_PHASE1_FLAGS(stbuf); DHT_STACK_UNWIND(readlink, frame, op_ret, op_errno, path, stbuf, xdata); return 0; } int dht_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(loc->path, err); local = dht_local_init(frame, loc, NULL, GF_FOP_READLINK); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", loc->path); op_errno = EINVAL; goto err; } STACK_WIND(frame, dht_readlink_cbk, subvol, subvol->fops->readlink, loc, size, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(readlink, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* Get both DHT_IATT_IN_XDATA_KEY and DHT_MODE_IN_XDATA_KEY * Use DHT_MODE_IN_XDATA_KEY if available, else fall back to * DHT_IATT_IN_XDATA_KEY * This will return a dummy iatt with only the mode and type set */ static int dht_read_iatt_from_xdata(dict_t *xdata, struct iatt *stbuf) { int ret = -1; int32_t mode = 0; ret = dict_get_int32(xdata, DHT_MODE_IN_XDATA_KEY, &mode); if (ret) { ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf); } else { stbuf->ia_prot = ia_prot_from_st_mode(mode); stbuf->ia_type = ia_type_from_st_mode(mode); } return ret; } int dht_common_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { dht_local_t *local = NULL; call_frame_t *call_frame = NULL; xlator_t *prev = NULL; xlator_t *src_subvol = NULL; xlator_t *dst_subvol = NULL; struct iatt stbuf = { 0, }; int ret = -1; inode_t *inode = NULL; local = frame->local; call_frame = cookie; prev = call_frame->this; local->op_errno = op_errno; if ((op_ret == -1) && !dht_inode_missing(op_errno)) { gf_msg_debug(this->name, op_errno, "subvolume %s returned -1.", prev->name); goto out; } if (local->call_cnt != 1) goto out; if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } ret = dht_read_iatt_from_xdata(xdata, &stbuf); if ((!op_ret) && (ret)) { /* This is a potential problem and can cause corruption * with sharding. * Oh well. We tried. */ goto out; } local->op_ret = op_ret; local->rebalance.target_op_fn = dht_common_xattrop2; if (xdata) local->rebalance.xdata = dict_ref(xdata); if (dict) local->rebalance.dict = dict_ref(dict); /* Phase 2 of migration */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(&stbuf)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* Check if the rebalance phase1 is true */ if (IS_DHT_MIGRATION_PHASE1(&stbuf)) { inode = local->loc.inode ? local->loc.inode : local->fd->inode; dht_inode_ctx_get_mig_info(this, inode, &src_subvol, &dst_subvol); if (dht_mig_info_is_invalid(local->cached_subvol, src_subvol, dst_subvol) || !dht_fd_open_on_dst(this, local->fd, dst_subvol)) { ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } else { dht_common_xattrop2(dst_subvol, frame, 0); return 0; } } out: if (local->fop == GF_FOP_XATTROP) { DHT_STACK_UNWIND(xattrop, frame, op_ret, op_errno, dict, xdata); } else { DHT_STACK_UNWIND(fxattrop, frame, op_ret, op_errno, dict, xdata); } return 0; } static int dht_common_xattrop2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if ((frame == NULL) || (frame->local == NULL)) goto out; local = frame->local; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ if (local->fop == GF_FOP_XATTROP) { DHT_STACK_UNWIND(xattrop, frame, local->op_ret, op_errno, local->rebalance.dict, local->rebalance.xdata); } else { DHT_STACK_UNWIND(fxattrop, frame, local->op_ret, op_errno, local->rebalance.dict, local->rebalance.xdata); } return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ if (local->fop == GF_FOP_XATTROP) { STACK_WIND(frame, dht_common_xattrop_cbk, subvol, subvol->fops->xattrop, &local->loc, local->rebalance.flags, local->rebalance.xattr, local->xattr_req); } else { STACK_WIND(frame, dht_common_xattrop_cbk, subvol, subvol->fops->fxattrop, local->fd, local->rebalance.flags, local->rebalance.xattr, local->xattr_req); } return 0; out: /* If local is unavailable we could be unwinding the wrong * function here */ if (local && (local->fop == GF_FOP_XATTROP)) { DHT_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL); } else { DHT_STACK_UNWIND(fxattrop, frame, -1, op_errno, NULL, NULL); } return 0; } static int dht_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { DHT_STACK_UNWIND(xattrop, frame, op_ret, op_errno, dict, xdata); return 0; } /* Set both DHT_IATT_IN_XDATA_KEY and DHT_MODE_IN_XDATA_KEY * Use DHT_MODE_IN_XDATA_KEY if available. Else fall back to * DHT_IATT_IN_XDATA_KEY */ static int dht_request_iatt_in_xdata(dict_t *xattr_req) { int ret = -1; ret = dict_set_int8(xattr_req, DHT_MODE_IN_XDATA_KEY, 1); ret = dict_set_int8(xattr_req, DHT_IATT_IN_XDATA_KEY, 1); /* At least one call succeeded */ return ret; } int dht_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; int ret = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); local = dht_local_init(frame, loc, NULL, GF_FOP_XATTROP); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for gfid=%s", uuid_utoa(loc->inode->gfid)); op_errno = EINVAL; goto err; } /* Todo : Handle dirs as well. At the moment the only xlator above dht * that uses xattrop is sharding and that is only for files */ if (IA_ISDIR(loc->inode->ia_type)) { STACK_WIND(frame, dht_xattrop_cbk, subvol, subvol->fops->xattrop, loc, flags, dict, xdata); } else { local->xattr_req = xdata ? dict_ref(xdata) : dict_new(); local->call_cnt = 1; local->rebalance.xattr = dict_ref(dict); local->rebalance.flags = flags; ret = dht_request_iatt_in_xdata(local->xattr_req); if (ret) { gf_msg_debug(this->name, 0, "Failed to set dictionary key %s file=%s", DHT_IATT_IN_XDATA_KEY, loc->path); } STACK_WIND(frame, dht_common_xattrop_cbk, subvol, subvol->fops->xattrop, loc, local->rebalance.flags, local->rebalance.xattr, local->xattr_req); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL); return 0; } static int dht_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { DHT_STACK_UNWIND(fxattrop, frame, op_ret, op_errno, dict, xdata); return 0; } int dht_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; int ret = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); subvol = dht_subvol_get_cached(this, fd->inode); if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } local = dht_local_init(frame, NULL, fd, GF_FOP_FXATTROP); if (!local) { op_errno = ENOMEM; goto err; } /* Todo : Handle dirs as well. At the moment the only xlator above dht * that uses xattrop is sharding and that is only for files */ if (IA_ISDIR(fd->inode->ia_type)) { STACK_WIND(frame, dht_fxattrop_cbk, subvol, subvol->fops->fxattrop, fd, flags, dict, xdata); } else { local->xattr_req = xdata ? dict_ref(xdata) : dict_new(); local->call_cnt = 1; local->rebalance.xattr = dict_ref(dict); local->rebalance.flags = flags; ret = dht_request_iatt_in_xdata(local->xattr_req); if (ret) { gf_msg_debug(this->name, 0, "Failed to set dictionary key %s fd=%p", DHT_IATT_IN_XDATA_KEY, fd); } STACK_WIND(frame, dht_common_xattrop_cbk, subvol, subvol->fops->fxattrop, fd, local->rebalance.flags, local->rebalance.xattr, local->xattr_req); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fxattrop, frame, -1, op_errno, NULL, NULL); return 0; } /* Currently no translators on top of 'distribute' will be using * below fops, hence not implementing 'migration' related checks */ static int dht_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_lk_inode_unref(frame, op_ret); DHT_STACK_UNWIND(inodelk, frame, op_ret, op_errno, xdata); return 0; } int32_t dht_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { xlator_t *lock_subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); local = dht_local_init(frame, loc, NULL, GF_FOP_INODELK); if (!local) { op_errno = ENOMEM; goto err; } local->lock_type = lock->l_type; lock_subvol = dht_get_lock_subvolume(this, lock, local); if (!lock_subvol) { gf_msg_debug(this->name, 0, "no lock subvolume for path=%s", loc->path); op_errno = EINVAL; goto err; } local->call_cnt = 1; STACK_WIND(frame, dht_inodelk_cbk, lock_subvol, lock_subvol->fops->inodelk, volume, loc, cmd, lock, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(inodelk, frame, -1, op_errno, NULL); return 0; } int dht_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; int ret = 0; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); local = frame->local; if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } out: dht_lk_inode_unref(frame, op_ret); DHT_STACK_UNWIND(finodelk, frame, op_ret, op_errno, xdata); return 0; } int dht_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { xlator_t *lock_subvol = NULL; dht_local_t *local = NULL; int op_errno = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_INODELK); if (!local) { op_errno = ENOMEM; goto err; } local->call_cnt = 1; local->lock_type = lock->l_type; lock_subvol = dht_get_lock_subvolume(this, lock, local); if (!lock_subvol) { gf_msg_debug(this->name, 0, "no lock subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } /* local->cached_subvol = lock_subvol; ret = dht_check_and_open_fd_on_subvol (this, frame); if (ret) goto err; */ gf_flock_copy(&local->rebalance.flock, lock); local->rebalance.lock_cmd = cmd; local->key = gf_strdup(volume); if (xdata) local->xattr_req = dict_ref(xdata); STACK_WIND(frame, dht_finodelk_cbk, lock_subvol, lock_subvol->fops->finodelk, volume, fd, cmd, lock, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(finodelk, frame, -1, op_errno, NULL); return 0; } static int dht_seek2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int op_errno = EINVAL; off_t offset = 0; if (!frame) goto out; local = frame->local; op_errno = local->op_errno; offset = local->rebalance.offset; if (we_are_not_migrating(ret)) { /* This DHT layer is not migrating the file */ DHT_STACK_UNWIND(seek, frame, -1, local->op_errno, 0, NULL); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; STACK_WIND_COOKIE(frame, dht_seek_cbk, subvol, subvol, subvol->fops->seek, local->fd, offset, local->rebalance.flags, local->xattr_req); return 0; out: DHT_STACK_UNWIND(seek, frame, -1, op_errno, 0, NULL); return 0; } int dht_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, off_t offset, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = 0; local = frame->local; prev = cookie; /* lseek fails with EBADF if dht has not yet opened the fd * on the cached subvol. This could happen if the file was migrated * and a lookup updated the cached subvol in the inode ctx. * We only check once as this could be a valid bad fd error. */ if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } local->op_errno = op_errno; if ((op_ret == -1) && !dht_inode_missing(op_errno)) { gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if ((op_ret == -1) && ((op_errno == ENXIO) || (op_errno == EOVERFLOW))) goto out; if (!op_ret || (local->call_cnt != 1)) goto out; /* rebalance would have happened */ local->rebalance.target_op_fn = dht_seek2; ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; out: DHT_STACK_UNWIND(seek, frame, op_ret, op_errno, offset, xdata); return 0; } int dht_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { xlator_t *subvol = NULL; dht_local_t *local = NULL; int op_errno = EINVAL; local = dht_local_init(frame, NULL, fd, GF_FOP_SEEK); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); local->rebalance.offset = offset; local->rebalance.flags = what; local->call_cnt = 1; STACK_WIND_COOKIE(frame, dht_seek_cbk, subvol, subvol, subvol->fops->seek, fd, local->rebalance.offset, local->rebalance.flags, local->xattr_req); return 0; err: DHT_STACK_UNWIND(seek, frame, -1, op_errno, offset, xdata); return 0; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht.c0000644000000000000000000000013014522202451022024 xustar000000000000000029 mtime=1699284265.63002732 29 atime=1699284265.63002732 30 ctime=1699284301.237134568 glusterfs-11.1/xlators/cluster/dht/src/dht.c0000664000175100017510000000661114522202451022311 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-common.h" struct xlator_fops dht_pt_fops = { /* we need to keep mkdir to make sure we have layout on new directory */ .mkdir = dht_pt_mkdir, .getxattr = dht_pt_getxattr, .fgetxattr = dht_pt_fgetxattr, /* required to trace fop properly in changelog */ .rename = dht_pt_rename, /* FIXME: commenting the '.lookup()' below made some of the failing tests to pass. I would remove the below line, but keeping it here as a reminder for people to check for issues if they find concerns with DHT pass-through logic */ /* .lookup = dht_lookup, .readdir = dht_readdir, .readdirp = dht_readdirp, */ /* Keeping above as commented, mainly to support the usecase of a gluster volume getting to 1x(anytype), due to remove-brick (shrinking) exercise. In that case, we would need above fops to be available, so we can handle the case of dangling linkto files (if any) */ }; struct xlator_fops fops = { .ipc = dht_ipc, .lookup = dht_lookup, .mknod = dht_mknod, .create = dht_create, .open = dht_open, .statfs = dht_statfs, .opendir = dht_opendir, .readdir = dht_readdir, .readdirp = dht_readdirp, .fsyncdir = dht_fsyncdir, .symlink = dht_symlink, .unlink = dht_unlink, .link = dht_link, .mkdir = dht_mkdir, .rmdir = dht_rmdir, .rename = dht_rename, .entrylk = dht_entrylk, .fentrylk = dht_fentrylk, /* Inode read operations */ .stat = dht_stat, .fstat = dht_fstat, .access = dht_access, .readlink = dht_readlink, .getxattr = dht_getxattr, .fgetxattr = dht_fgetxattr, .readv = dht_readv, .flush = dht_flush, .fsync = dht_fsync, .inodelk = dht_inodelk, .finodelk = dht_finodelk, .lk = dht_lk, .lease = dht_lease, .seek = dht_seek, /* Inode write operations */ .fremovexattr = dht_fremovexattr, .removexattr = dht_removexattr, .setxattr = dht_setxattr, .fsetxattr = dht_fsetxattr, .truncate = dht_truncate, .ftruncate = dht_ftruncate, .writev = dht_writev, .xattrop = dht_xattrop, .fxattrop = dht_fxattrop, .setattr = dht_setattr, .fsetattr = dht_fsetattr, .fallocate = dht_fallocate, .discard = dht_discard, .zerofill = dht_zerofill, }; struct xlator_dumpops dumpops = { .priv = dht_priv_dump, .inodectx = dht_inodectx_dump, }; struct xlator_cbks cbks = { .release = dht_release, // .releasedir = dht_releasedir, .forget = dht_forget, }; extern int32_t mem_acct_init(xlator_t *this); extern struct volume_options dht_options[]; xlator_api_t xlator_api = { .init = dht_init, .fini = dht_fini, .notify = dht_notify, .reconfigure = dht_reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = dht_options, .identifier = "distribute", .pass_through_fops = &dht_pt_fops, .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-common.c0000644000000000000000000000013214522202451023314 xustar000000000000000030 mtime=1699284265.623027299 30 atime=1699284265.621027293 30 ctime=1699284301.230134547 glusterfs-11.1/xlators/cluster/dht/src/dht-common.c0000664000175100017510000127775714522202451023625 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ /* TODO: add NS locking */ #include "libxlator.h" #include "dht-common.h" #include "dht-lock.h" #include #include #include "glusterfs/compat-errno.h" // for ENODATA on BSD #include #include #include #include static int dht_rmdir_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata); static int dht_link2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_set_dir_xattr_req(xlator_t *this, loc_t *loc, dict_t *xattr_req); static int dht_lookup_everywhere_done(call_frame_t *frame, xlator_t *this); static int dht_common_mark_mdsxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata); static int dht_rmdir_unlock(call_frame_t *frame, xlator_t *this); static const char *dht_dbg_vxattrs[] = {DHT_DBG_HASHED_SUBVOL_PATTERN, NULL}; /* Check the xdata to make sure EBADF has been set by client xlator */ int32_t dht_check_remote_fd_failed_error(dht_local_t *local, int op_ret, int op_errno) { if (op_ret == -1 && (op_errno == EBADF || op_errno == EBADFD) && !(local->fd_checked)) { return 1; } return 0; } /* Sets the blocks and size values to fixed values. This is to be called * only for dirs. The caller is responsible for checking the type */ int32_t dht_set_fixed_dir_stat(struct iatt *stat) { if (stat) { stat->ia_blocks = DHT_DIR_STAT_BLOCKS; stat->ia_size = DHT_DIR_STAT_SIZE; return 0; } return -1; } /* Return true if key exists in array */ static gf_boolean_t dht_match_xattr(const char *key) { char **xattrs_to_heal = get_xattrs_to_heal(); return gf_get_index_by_elem(xattrs_to_heal, (char *)key) >= 0; } static int dht_aggregate_quota_xattr(dict_t *dst, char *key, data_t *value) { int ret = -1; quota_meta_t *meta_dst = NULL; quota_meta_t *meta_src = NULL; int64_t *size = NULL; int64_t dst_dir_count = 0; int64_t src_dir_count = 0; if (value == NULL) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_DATA_NULL, "data value is NULL"); ret = -1; goto out; } ret = dict_get_bin(dst, key, (void **)&meta_dst); if (ret < 0) { meta_dst = GF_CALLOC(1, sizeof(quota_meta_t), gf_common_quota_meta_t); if (meta_dst == NULL) { gf_msg("dht", GF_LOG_WARNING, ENOMEM, DHT_MSG_NO_MEMORY, "Memory allocation failed"); ret = -1; goto out; } ret = dict_set_bin(dst, key, meta_dst, sizeof(quota_meta_t)); if (ret < 0) { gf_msg("dht", GF_LOG_WARNING, EINVAL, DHT_MSG_DICT_SET_FAILED, "dht aggregate dict set failed"); GF_FREE(meta_dst); ret = -1; goto out; } } if (value->len > sizeof(int64_t)) { meta_src = data_to_bin(value); meta_dst->size = htobe64(be64toh(meta_dst->size) + be64toh(meta_src->size)); meta_dst->file_count = htobe64(be64toh(meta_dst->file_count) + be64toh(meta_src->file_count)); if (value->len > (2 * sizeof(int64_t))) { dst_dir_count = be64toh(meta_dst->dir_count); src_dir_count = be64toh(meta_src->dir_count); if (src_dir_count > dst_dir_count) meta_dst->dir_count = meta_src->dir_count; } else { meta_dst->dir_count = 0; } } else { size = data_to_bin(value); meta_dst->size = htobe64(be64toh(meta_dst->size) + be64toh(*size)); } ret = 0; out: return ret; } static int add_opt(char **optsp, const char *opt) { char *newopts = NULL; unsigned oldsize = 0; unsigned newsize = 0; if (*optsp == NULL) newopts = gf_strdup(opt); else { oldsize = strlen(*optsp); newsize = oldsize + 1 + strlen(opt) + 1; newopts = GF_REALLOC(*optsp, newsize); if (newopts) sprintf(newopts + oldsize, ",%s", opt); } if (newopts == NULL) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, "Error to add choices in buffer in add_opt"); return -1; } *optsp = newopts; return 0; } /* Return Choice list from Split brain status */ static char * getChoices(const char *value) { int i = 0; char *ptr = NULL; char *tok = NULL; char *result = NULL; char *newval = NULL; ptr = strstr(value, "Choices:"); if (!ptr) { result = ptr; goto out; } newval = gf_strdup(ptr); if (!newval) { result = newval; goto out; } tok = strtok(newval, ":"); if (!tok) { result = tok; goto out; } while (tok) { i++; if (i == 2) break; tok = strtok(NULL, ":"); } result = gf_strdup(tok); out: if (newval) GF_FREE(newval); return result; } /* This function prepare a list of choices for key (replica.split-brain-status) in case of metadata split brain only on the basis of key-value passed to this function. After prepare the list of choices it update the same key in dict with this value to reflect the same in replica.split-brain-status attr for file. */ static int dht_aggregate_split_brain_xattr(dict_t *dst, char *key, data_t *value) { int ret = 0; char *oldvalue = NULL; char *old_choice = NULL; char *new_choice = NULL; char *full_choice = NULL; char *status = NULL; if (value == NULL) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_DATA_NULL, "GF_AFR_SBRAIN_STATUS value is NULL"); ret = -1; goto out; } ret = dict_get_str(dst, key, &oldvalue); if (ret) goto out; /* skip code that is irrelevant if !oldvalue */ if (!oldvalue) goto out; if (strstr(oldvalue, "not")) { gf_msg_debug("dht", 0, "Need to update split-brain status in dict"); ret = -1; goto out; } if (strstr(oldvalue, "metadata-split-brain:yes") && (strstr(oldvalue, "data-split-brain:no"))) { if (strstr(value->data, "not")) { gf_msg_debug("dht", 0, "No need to update split-brain status"); ret = 0; goto out; } if (strstr(value->data, "yes") && (strncmp(oldvalue, value->data, strlen(oldvalue)))) { old_choice = getChoices(oldvalue); if (!old_choice) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, "Error to get choices"); ret = -1; goto out; } ret = add_opt(&full_choice, old_choice); if (ret) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, "Error to add choices"); ret = -1; goto out; } new_choice = getChoices(value->data); if (!new_choice) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, "Error to get choices"); ret = -1; goto out; } ret = add_opt(&full_choice, new_choice); if (ret) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, "Error to add choices "); ret = -1; goto out; } ret = gf_asprintf(&status, "data-split-brain:%s " "metadata-split-brain:%s Choices:%s", "no", "yes", full_choice); if (-1 == ret) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, "Error to prepare status "); goto out; } ret = dict_set_dynstr(dst, key, status); if (ret) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set full choice"); } } } out: if (old_choice) GF_FREE(old_choice); if (new_choice) GF_FREE(new_choice); if (full_choice) GF_FREE(full_choice); return ret; } static int dht_aggregate(dict_t *this, char *key, data_t *value, void *data) { dict_t *dst = NULL; int32_t ret = -1; data_t *dict_data = NULL; dst = data; /* compare split brain xattr only */ if (strcmp(key, GF_AFR_SBRAIN_STATUS) == 0) { ret = dht_aggregate_split_brain_xattr(dst, key, value); if (!ret) goto out; } else if (strcmp(key, QUOTA_SIZE_KEY) == 0) { ret = dht_aggregate_quota_xattr(dst, key, value); if (ret) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_AGGREGATE_QUOTA_XATTR_FAILED, "Failed to aggregate quota xattr"); } goto out; } else if (fnmatch(GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0) { ret = gf_get_min_stime(THIS, dst, key, value); goto out; } else { /* compare user xattrs only */ if (!strncmp(key, "user.", SLEN("user."))) { ret = dict_lookup(dst, key, &dict_data); if (!ret && dict_data && value) { ret = is_data_equal(dict_data, value); if (!ret) gf_msg_debug("dht", 0, "xattr mismatch for %s", key); } } } ret = dict_set(dst, key, value); if (ret) { gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value: key = %s", key); } out: return ret; } static void dht_aggregate_xattr(dict_t *dst, dict_t *src) { if ((dst == NULL) || (src == NULL)) { goto out; } dict_foreach(src, dht_aggregate, dst); out: return; } /* Code to save hashed subvol on inode ctx as a mds subvol */ int dht_inode_ctx_mdsvol_set(inode_t *inode, xlator_t *this, xlator_t *mds_subvol) { dht_inode_ctx_t *ctx = NULL; int ret = -1; uint64_t ctx_int = 0; gf_boolean_t ctx_free = _gf_false; LOCK(&inode->lock); { ret = __inode_ctx_get(inode, this, &ctx_int); if (ctx_int) { ctx = (dht_inode_ctx_t *)(uintptr_t)ctx_int; ctx->mds_subvol = mds_subvol; } else { ctx = GF_CALLOC(1, sizeof(*ctx), gf_dht_mt_inode_ctx_t); if (!ctx) goto unlock; ctx->mds_subvol = mds_subvol; ctx_free = _gf_true; ctx_int = (long)ctx; ret = __inode_ctx_set(inode, this, &ctx_int); } } unlock: UNLOCK(&inode->lock); if (ret && ctx_free) GF_FREE(ctx); return ret; } /*Code to get mds subvol from inode ctx */ int dht_inode_ctx_mdsvol_get(inode_t *inode, xlator_t *this, xlator_t **mdsvol) { dht_inode_ctx_t *ctx = NULL; int ret = -1; if (!mdsvol) return ret; if (__is_root_gfid(inode->gfid)) { (*mdsvol) = FIRST_CHILD(this); return 0; } ret = dht_inode_ctx_get(inode, this, &ctx); if (!ret && ctx) { if (ctx->mds_subvol) { *mdsvol = ctx->mds_subvol; ret = 0; } else { ret = -1; } } return ret; } /* TODO: - use volumename in xattr instead of "dht" - use NS locks - handle all cases in self heal layout reconstruction - complete linkfile selfheal */ static int dht_lookup_selfheal_cbk(call_frame_t *frame, void *cookie, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; dht_layout_t *layout = NULL; dht_conf_t *conf = NULL; xlator_t *this = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); local = frame->local; this = frame->this; conf = this->private; ret = op_ret; FRAME_SU_UNDO(frame, dht_local_t); if (ret == 0) { layout = local->selfheal.layout; ret = dht_layout_set(this, local->inode, layout); } dht_inode_ctx_time_update(local->inode, this, NULL, &local->stbuf); if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, NULL, &local->postparent); } DHT_STRIP_PHASE1_FLAGS(&local->stbuf); dht_set_fixed_dir_stat(&local->postparent); /* Delete mds xattr at the time of STACK UNWIND */ GF_REMOVE_INTERNAL_XATTR(conf->mds_xattr_key, local->xattr); DHT_STACK_UNWIND(lookup, frame, ret, local->op_errno, local->inode, &local->stbuf, local->xattr, &local->postparent); out: return ret; } static int dht_discover_complete(xlator_t *this, call_frame_t *discover_frame) { dht_local_t *local = NULL; dht_local_t *heal_local = NULL; call_frame_t *main_frame = NULL; call_frame_t *heal_frame = NULL; int op_errno = 0; int ret = -1; dht_layout_t *layout = NULL; dht_conf_t *conf = NULL; uint32_t vol_commit_hash = 0; xlator_t *source = NULL; int heal_path = 0; int error_while_marking_mds = 0; int i = 0; loc_t loc = {0}; int8_t is_read_only = 0, layout_anomalies = 0; char gfid_local[GF_UUID_BUF_SIZE] = {0}; local = discover_frame->local; layout = local->layout; conf = this->private; gf_uuid_unparse(local->gfid, gfid_local); LOCK(&discover_frame->lock); { main_frame = local->main_frame; local->main_frame = NULL; } UNLOCK(&discover_frame->lock); if (!main_frame) return 0; /* Code to update all extended attributed from subvol to local->xattr on that internal xattr has found */ if (conf->subvolume_cnt == 1) local->need_xattr_heal = 0; if (local->need_xattr_heal && (local->mds_xattr)) { dht_dir_set_heal_xattr(this, local, local->xattr, local->mds_xattr, NULL, NULL); dict_unref(local->mds_xattr); local->mds_xattr = NULL; } ret = dict_get_int8(local->xattr_req, QUOTA_READ_ONLY_KEY, &is_read_only); if (ret < 0) gf_msg_debug(this->name, 0, "key = %s not present in dict", QUOTA_READ_ONLY_KEY); if (local->file_count && local->dir_count) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_FILE_TYPE_MISMATCH, "path %s exists as a file on one subvolume " "and directory on another. " "Please fix it manually", local->loc.path); op_errno = EIO; goto out; } if (local->cached_subvol) { ret = dht_layout_preset(this, local->cached_subvol, local->inode); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_SET_FAILED, "failed to set layout for subvolume %s", local->cached_subvol ? local->cached_subvol->name : ""); op_errno = EINVAL; goto out; } } else { ret = dht_layout_normalize(this, &local->loc, layout); if ((ret < 0) || ((ret > 0) && (local->op_ret != 0))) { /* either the layout is incorrect or the directory is * not found even in one subvolume. */ gf_msg_debug(this->name, 0, "normalizing failed on %s " "(overlaps/holes present: %s, " "ENOENT errors: %d)", local->loc.path, (ret < 0) ? "yes" : "no", (ret > 0) ? ret : 0); layout_anomalies = 1; } else if (local->inode) { dht_layout_set(this, local->inode, layout); } } if (!conf->vch_forced) { ret = dict_get_uint32(local->xattr, conf->commithash_xattr_name, &vol_commit_hash); if (ret == 0) { conf->vol_commit_hash = vol_commit_hash; } } if (IA_ISDIR(local->stbuf.ia_type) && !is_read_only) { for (i = 0; i < layout->cnt; i++) { if (!source && !layout->list[i].err) source = layout->list[i].xlator; if (layout->list[i].err == ENOENT || layout->list[i].err == ESTALE) { heal_path = 1; } if (source && heal_path) break; } } if (IA_ISDIR(local->stbuf.ia_type)) { /* Call function to save hashed subvol on inode ctx if internal mds xattr is not present and all subvols are up */ if (!local->op_ret && !__is_root_gfid(local->stbuf.ia_gfid)) (void)dht_common_mark_mdsxattr(discover_frame, &error_while_marking_mds, 1); if (local->need_xattr_heal && !heal_path) { local->need_xattr_heal = 0; ret = dht_dir_xattr_heal(this, local, &op_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_DIR_XATTR_HEAL_FAILED, "xattr heal failed for " "directory gfid is %s ", gfid_local); } } } if (source && (heal_path || layout_anomalies || error_while_marking_mds)) { gf_uuid_copy(loc.gfid, local->gfid); if (gf_uuid_is_null(loc.gfid)) { goto done; } if (local->inode) loc.inode = inode_ref(local->inode); else goto done; heal_frame = create_frame(this, this->ctx->pool); if (heal_frame) { heal_local = dht_local_init(heal_frame, &loc, NULL, 0); if (!heal_local) goto cleanup; gf_uuid_copy(heal_local->gfid, local->gfid); heal_frame->cookie = source; heal_local->xattr = dict_ref(local->xattr); heal_local->stbuf = local->stbuf; heal_local->postparent = local->postparent; heal_local->inode = inode_ref(loc.inode); heal_local->main_frame = main_frame; FRAME_SU_DO(heal_frame, dht_local_t); ret = synctask_new(this->ctx->env, dht_heal_full_path, dht_heal_full_path_done, heal_frame, heal_frame); if (!ret) { loc_wipe(&loc); return 0; } /* * Failed to spawn the synctask. Returning * with out doing heal. */ cleanup: loc_wipe(&loc); DHT_STACK_DESTROY(heal_frame); } } done: dht_set_fixed_dir_stat(&local->postparent); /* Delete mds xattr at the time of STACK UNWIND */ if (local->xattr) GF_REMOVE_INTERNAL_XATTR(conf->mds_xattr_key, local->xattr); DHT_STACK_UNWIND(lookup, main_frame, local->op_ret, local->op_errno, local->inode, &local->stbuf, local->xattr, &local->postparent); return 0; out: DHT_STACK_UNWIND(lookup, main_frame, -1, op_errno, NULL, NULL, NULL, NULL); return ret; } static int dht_common_mark_mdsxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = cookie; int ret = -1; dht_conf_t *conf = 0; dht_layout_t *layout = NULL; int32_t mds_heal_fresh_lookup = 0; GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); local = frame->local; conf = this->private; layout = local->selfheal.layout; mds_heal_fresh_lookup = local->mds_heal_fresh_lookup; if (op_ret) { gf_msg_debug(this->name, op_ret, "Failed to set %s on the MDS %s for path %s. ", conf->mds_xattr_key, prev->name, local->loc.path); } else { /* Save mds subvol on inode ctx */ ret = dht_inode_ctx_mdsvol_set(local->inode, this, prev); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, "Failed to set mds subvol on inode ctx" " %s for %s ", prev->name, local->loc.path); } } if (!local->mds_heal_fresh_lookup && layout) { dht_selfheal_dir_setattr(frame, &local->loc, &local->stbuf, 0xffffffff, layout); return 0; } out: if (mds_heal_fresh_lookup) DHT_STACK_DESTROY(frame); return 0; } static xlator_t * dht_inode_get_hashed_subvol(inode_t *inode, xlator_t *this, loc_t *loc) { char *path = NULL; loc_t populate_loc = { 0, }; char *name = NULL; xlator_t *hash_subvol = NULL; if (!inode) return hash_subvol; if (loc && loc->parent && loc->path) { if (!loc->name) { name = strrchr(loc->path, '/'); if (name) { loc->name = name + 1; } else { goto out; } } hash_subvol = dht_subvol_get_hashed(this, loc); goto out; } if (!gf_uuid_is_null(inode->gfid)) { populate_loc.inode = inode_ref(inode); populate_loc.parent = inode_parent(populate_loc.inode, NULL, NULL); inode_path(populate_loc.inode, NULL, &path); if (!path) goto out; populate_loc.path = path; if (!populate_loc.name && populate_loc.path) { name = strrchr(populate_loc.path, '/'); if (name) { populate_loc.name = name + 1; } else { goto out; } } hash_subvol = dht_subvol_get_hashed(this, &populate_loc); } out: if (populate_loc.inode) loc_wipe(&populate_loc); return hash_subvol; } /* Common function call by revalidate/selfheal code path to populate internal xattr if it is not present, mark_during_fresh_lookup value determines either function is call by revalidate_cbk(discover_complete) or call by selfheal code path while fresh lookup. Here we do wind a call serially in case of fresh lookup and for other lookup code path we do wind a call parallel.The reason to wind a call serially is at the time of fresh lookup directory is not discovered and at the time of revalidate_lookup directory is already discovered. So, revalidate codepath can race with setxattr codepath and can get into spurious heals because of an ongoing setxattr. This can slow down revalidates, if healing happens in foreground. However, if healing happens in background, there is no direct performance penalty. */ int dht_common_mark_mdsxattr(call_frame_t *frame, int *errst, int mark_during_fresh_lookup) { dht_local_t *local = NULL; xlator_t *this = NULL; xlator_t *hashed_subvol = NULL; int ret = 0; int i = 0; dict_t *xattrs = NULL; char gfid_local[GF_UUID_BUF_SIZE] = { 0, }; int32_t zero[1] = {0}; dht_conf_t *conf = 0; dht_layout_t *layout = NULL; dht_local_t *copy_local = NULL; call_frame_t *xattr_frame = NULL; gf_boolean_t vol_down = _gf_false; GF_VALIDATE_OR_GOTO("dht", frame, out); this = frame->this; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); local = frame->local; conf = this->private; layout = local->selfheal.layout; local->mds_heal_fresh_lookup = mark_during_fresh_lookup; gf_uuid_unparse(local->gfid, gfid_local); /* Code to update hashed subvol consider as a mds subvol and wind a setxattr call on hashed subvol to update internal xattr */ if (!local->xattr || !dict_get(local->xattr, conf->mds_xattr_key)) { /* It means no internal MDS xattr has been set yet */ /* Check the status of all subvol are up while call this function call by lookup code path */ if (mark_during_fresh_lookup) { for (i = 0; i < conf->subvolume_cnt; i++) { if (!conf->subvolume_status[i]) { vol_down = _gf_true; break; } } if (vol_down) { gf_msg_debug(this->name, 0, "subvol %s is down. Unable to " " save mds subvol on inode for " " path %s gfid is %s ", conf->subvolumes[i]->name, local->loc.path, gfid_local); goto out; } } /* Calculate hashed subvol based on inode and parent node */ hashed_subvol = dht_inode_get_hashed_subvol(local->inode, this, &local->loc); if (!hashed_subvol) { gf_msg(this->name, GF_LOG_DEBUG, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "Failed to get hashed subvol for path %s" "gfid is %s ", local->loc.path, gfid_local); if (errst) (*errst) = 1; ret = -1; goto out; } xattrs = dict_new(); if (!xattrs) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "dict_new failed"); ret = -1; goto out; } /* Add internal MDS xattr on disk for hashed subvol */ ret = dht_dict_set_array(xattrs, conf->mds_xattr_key, zero, 1); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary" " value:key = %s for " "path %s", conf->mds_xattr_key, local->loc.path); ret = -1; goto out; } /* Create a new frame to wind a call only while this function call by revalidate_cbk code path To wind a call parallel need to create a new frame */ if (mark_during_fresh_lookup) { xattr_frame = create_frame(this, this->ctx->pool); if (!xattr_frame) { ret = -1; goto out; } copy_local = dht_local_init(xattr_frame, &(local->loc), NULL, 0); if (!copy_local) { ret = -1; DHT_STACK_DESTROY(xattr_frame); goto out; } copy_local->stbuf = local->stbuf; copy_local->mds_heal_fresh_lookup = mark_during_fresh_lookup; if (!copy_local->inode) copy_local->inode = inode_ref(local->inode); gf_uuid_copy(copy_local->loc.gfid, local->gfid); FRAME_SU_DO(xattr_frame, dht_local_t); STACK_WIND_COOKIE(xattr_frame, dht_common_mark_mdsxattr_cbk, hashed_subvol, hashed_subvol, hashed_subvol->fops->setxattr, &local->loc, xattrs, 0, NULL); } else { STACK_WIND_COOKIE(frame, dht_common_mark_mdsxattr_cbk, (void *)hashed_subvol, hashed_subvol, hashed_subvol->fops->setxattr, &local->loc, xattrs, 0, NULL); } } else { gf_msg_debug(this->name, 0, "internal xattr %s is present on subvol" "on path %s gfid is %s ", conf->mds_xattr_key, local->loc.path, gfid_local); if (!mark_during_fresh_lookup) dht_selfheal_dir_setattr(frame, &local->loc, &local->stbuf, 0xffffffff, layout); } out: if (xattrs) dict_unref(xattrs); return ret; } /* Get the value of key from dict in the bytewise and save in array after convert from network byte order to host byte order */ static int32_t dht_dict_get_array(dict_t *dict, char *key, int32_t value[], int32_t size, int *errst) { void *ptr = NULL; int32_t len = -1; int32_t vindex = -1; int32_t err = -1; int ret = 0; if (dict == NULL) { (*errst) = -1; return -EINVAL; } err = dict_get_ptr_and_len(dict, key, &ptr, &len); if (err != 0) { (*errst) = -1; return err; } if (len != (size * sizeof(int32_t))) { (*errst) = -1; return -EINVAL; } for (vindex = 0; vindex < size; vindex++) { value[vindex] = be32toh(*((int32_t *)ptr + vindex)); if (value[vindex] < 0) ret = -1; } return ret; } static int dht_discover_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; dht_layout_t *layout = NULL; int ret = -1; int is_dir = 0; int32_t check_mds = 0; int is_linkfile = 0; int attempt_unwind = 0; dht_conf_t *conf = 0; char gfid_local[GF_UUID_BUF_SIZE] = {0}; char gfid_node[GF_UUID_BUF_SIZE] = {0}; int32_t mds_xattr_val[1] = {0}; int errst = 0; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", this->private, out); GF_VALIDATE_OR_GOTO("dht", cookie, out); local = frame->local; prev = cookie; conf = this->private; layout = local->layout; /* Check if the gfid is different for file from other node */ if (!op_ret && gf_uuid_compare(local->gfid, stbuf->ia_gfid)) { gf_uuid_unparse(stbuf->ia_gfid, gfid_node); gf_uuid_unparse(local->gfid, gfid_local); gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_MISMATCH, "%s: gfid different on %s, gfid local = %s" "gfid other = %s", local->loc.path, prev->name, gfid_local, gfid_node); } LOCK(&frame->lock); { /* TODO: assert equal mode on stbuf->st_mode and local->stbuf->st_mode else mkdir/chmod/chown and fix */ ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, xattr); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_MERGE_FAILED, "%s: failed to merge layouts for subvol %s", local->loc.path, prev->name); if (op_ret == -1) { local->op_errno = op_errno; gf_msg_debug(this->name, op_errno, "lookup of %s on %s returned error", local->loc.path, prev->name); goto unlock; } is_linkfile = check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name); is_dir = check_is_dir(inode, stbuf, xattr); if (is_dir) { local->dir_count++; } else { local->file_count++; if (!is_linkfile && !local->cached_subvol) { /* real file */ /* Ok, we somehow managed to find a file on * more than one subvol. ignore this or we * will end up overwriting information while a * a thread is potentially unwinding from * dht_discover_complete */ local->cached_subvol = prev; attempt_unwind = 1; } else { goto unlock; } } local->op_ret = 0; if (local->xattr == NULL) { local->xattr = dict_ref(xattr); } else { /* Don't aggregate for files. See BZ#1484709 */ if (is_dir) dht_aggregate_xattr(local->xattr, xattr); } if (local->inode == NULL) local->inode = inode_ref(inode); dht_iatt_merge(this, &local->stbuf, stbuf); dht_iatt_merge(this, &local->postparent, postparent); if (!dict_get(xattr, conf->mds_xattr_key)) { goto unlock; } else { gf_msg_debug(this->name, 0, "internal xattr %s is present on subvol" "on path %s gfid is %s ", conf->mds_xattr_key, local->loc.path, gfid_local); } check_mds = dht_dict_get_array(xattr, conf->mds_xattr_key, mds_xattr_val, 1, &errst); /* save mds subvol on inode ctx */ ret = dht_inode_ctx_mdsvol_set(local->inode, this, prev); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, "Failed to set hashed subvol for %s vol is %s", local->loc.path, prev->name); } if ((check_mds < 0) && !errst) { local->mds_xattr = dict_ref(xattr); gf_msg_debug(this->name, 0, "Value of %s is not zero on mds subvol" "so xattr needs to be healed on non mds" " path is %s and vol name is %s " " gfid is %s", conf->mds_xattr_key, local->loc.path, prev->name, gfid_local); local->need_xattr_heal = 1; local->mds_subvol = prev; } } unlock: UNLOCK(&frame->lock); out: /* Make sure, the thread executing dht_discover_complete is the one * which calls STACK_DESTROY (frame). In the case of "attempt_unwind", * this makes sure that the thread don't call dht_frame_return, till * call to dht_discover_complete is done. */ if (attempt_unwind) { dht_discover_complete(this, frame); } this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt) && !attempt_unwind) { dht_discover_complete(this, frame); } if (is_last_call(this_call_cnt)) DHT_STACK_DESTROY(frame); return 0; } static int dht_set_file_xattr_req(xlator_t *this, loc_t *loc, dict_t *xattr_req) { int ret = -EINVAL; dht_conf_t *conf = NULL; conf = this->private; if (!conf) { goto err; } if (!xattr_req) { goto err; } /* Used to check whether this is a linkto file. */ ret = dict_set_uint32(xattr_req, conf->link_xattr_name, 256); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value:key = %s for " "path %s", conf->link_xattr_name, loc->path); goto err; } /* This is used to make sure we don't unlink linkto files * which are the target of an ongoing file migration. */ ret = dict_set_uint32(xattr_req, GLUSTERFS_OPEN_FD_COUNT, 4); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value:key = %s for " "path %s", GLUSTERFS_OPEN_FD_COUNT, loc->path); goto err; } ret = 0; err: return ret; } /* This is a gfid based nameless lookup. Without a name, the hashed subvol * cannot be calculated so a lookup is sent to all subvols. */ static int dht_do_discover(call_frame_t *frame, xlator_t *this, loc_t *loc) { int ret; dht_local_t *local = NULL; dht_conf_t *conf = NULL; int call_cnt = 0; int op_errno = EINVAL; int i = 0; call_frame_t *discover_frame = NULL; conf = this->private; local = frame->local; /* As we do not know if this is a file or directory, request * both file and directory xattrs */ ret = dht_set_file_xattr_req(this, loc, local->xattr_req); if (ret) { goto err; } ret = dht_set_dir_xattr_req(this, loc, local->xattr_req); if (ret) { goto err; } if (loc_is_root(loc)) { /* Request the DHT commit hash xattr (trusted.glusterfs.dht.commithash) * set on the brick root. */ ret = dict_set_uint32(local->xattr_req, conf->commithash_xattr_name, sizeof(uint32_t)); } call_cnt = conf->subvolume_cnt; local->call_cnt = call_cnt; local->layout = dht_layout_new(this, conf->subvolume_cnt); if (!local->layout) { op_errno = ENOMEM; goto err; } gf_uuid_copy(local->gfid, loc->gfid); discover_frame = copy_frame(frame); if (!discover_frame) { op_errno = ENOMEM; goto err; } discover_frame->local = local; frame->local = NULL; local->main_frame = frame; for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(discover_frame, dht_discover_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, &local->loc, local->xattr_req); } return 0; err: DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } /* Code to call syntask to heal custom xattr from hashed subvol to non hashed subvol */ int dht_dir_xattr_heal(xlator_t *this, dht_local_t *local, int *op_errno) { dht_local_t *copy_local = NULL; call_frame_t *copy = NULL; int ret = -1; char gfid_local[GF_UUID_BUF_SIZE] = {0}; if (gf_uuid_is_null(local->gfid)) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DIR_XATTR_HEAL_FAILED, "No gfid exists for path %s " "so healing xattr is not possible", local->loc.path); *op_errno = EIO; goto out; } gf_uuid_unparse(local->gfid, gfid_local); copy = create_frame(this, this->ctx->pool); if (copy) { copy_local = dht_local_init(copy, &(local->loc), NULL, 0); if (!copy_local) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DIR_XATTR_HEAL_FAILED, "Memory allocation failed " "for path %s gfid %s ", local->loc.path, gfid_local); *op_errno = ENOMEM; DHT_STACK_DESTROY(copy); } else { copy_local->stbuf = local->stbuf; gf_uuid_copy(copy_local->loc.gfid, local->gfid); copy_local->mds_subvol = local->mds_subvol; FRAME_SU_DO(copy, dht_local_t); ret = synctask_new(this->ctx->env, dht_dir_heal_xattrs, dht_dir_heal_xattrs_done, copy, copy); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DIR_XATTR_HEAL_FAILED, "Synctask creation failed to heal xattr " "for path %s gfid %s ", local->loc.path, gfid_local); *op_errno = ENOMEM; DHT_STACK_DESTROY(copy); } } } out: return ret; } static int dht_needs_selfheal(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; dht_layout_t *layout = NULL; int needs_selfheal = 0; int ret = 0; local = frame->local; layout = local->layout; if (local->need_attrheal || local->need_xattr_heal || local->need_selfheal) { needs_selfheal = 1; } ret = dht_layout_normalize(this, &local->loc, layout); if (ret != 0) { gf_msg_debug(this->name, 0, "fixing assignment on %s", local->loc.path); needs_selfheal = 1; } return needs_selfheal; } static int is_permission_different(ia_prot_t *prot1, ia_prot_t *prot2) { if ((prot1->owner.read != prot2->owner.read) || (prot1->owner.write != prot2->owner.write) || (prot1->owner.exec != prot2->owner.exec) || (prot1->group.read != prot2->group.read) || (prot1->group.write != prot2->group.write) || (prot1->group.exec != prot2->group.exec) || (prot1->other.read != prot2->other.read) || (prot1->other.write != prot2->other.write) || (prot1->other.exec != prot2->other.exec) || (prot1->suid != prot2->suid) || (prot1->sgid != prot2->sgid) || (prot1->sticky != prot2->sticky)) { return 1; } else { return 0; } } int dht_lookup_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; dht_layout_t *layout = NULL; int ret = -1; int is_dir = 0; int32_t check_mds = 0; int errst = 0; char gfid_local[GF_UUID_BUF_SIZE] = {0}; char gfid_node[GF_UUID_BUF_SIZE] = {0}; int32_t mds_xattr_val[1] = {0}; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", this->private, out); GF_VALIDATE_OR_GOTO("dht", cookie, out); local = frame->local; prev = cookie; conf = this->private; layout = local->layout; gf_msg_debug(this->name, op_errno, "%s: lookup on %s returned with op_ret = %d, op_errno = %d", local->loc.path, prev->name, op_ret, op_errno); /* The first successful lookup*/ if (!op_ret && gf_uuid_is_null(local->gfid)) { memcpy(local->gfid, stbuf->ia_gfid, 16); } if (!gf_uuid_is_null(local->gfid)) { gf_uuid_unparse(local->gfid, gfid_local); } /* Check if the gfid is different for file from other node */ if (!op_ret && gf_uuid_compare(local->gfid, stbuf->ia_gfid)) { gf_uuid_unparse(stbuf->ia_gfid, gfid_node); gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_MISMATCH, "%s: gfid different on %s." " gfid local = %s, gfid subvol = %s", local->loc.path, prev->name, gfid_local, gfid_node); } LOCK(&frame->lock); { /* TODO: assert equal mode on stbuf->st_mode and local->stbuf->st_mode else mkdir/chmod/chown and fix */ ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, xattr); if (op_ret == -1) { local->op_errno = op_errno; /* The GFID is missing on this subvol. Force a heal. */ if (op_errno == ENODATA) { local->need_lookup_everywhere = 1; } goto unlock; } is_dir = check_is_dir(inode, stbuf, xattr); if (!is_dir) { gf_msg_debug(this->name, 0, "%s: lookup on %s returned non dir 0%o" "calling lookup_everywhere", local->loc.path, prev->name, stbuf->ia_type); local->need_lookup_everywhere = 1; goto unlock; } local->op_ret = 0; if (local->xattr == NULL) { local->xattr = dict_ref(xattr); } else { dht_aggregate_xattr(local->xattr, xattr); } if (__is_root_gfid(stbuf->ia_gfid)) { ret = dht_dir_has_layout(xattr, conf->xattr_name); if (ret >= 0) { if (is_greater_time(local->prebuf.ia_ctime, local->prebuf.ia_ctime_nsec, stbuf->ia_ctime, stbuf->ia_ctime_nsec)) { /* Choose source */ local->prebuf.ia_gid = stbuf->ia_gid; local->prebuf.ia_uid = stbuf->ia_uid; local->prebuf.ia_ctime = stbuf->ia_ctime; local->prebuf.ia_ctime_nsec = stbuf->ia_ctime_nsec; local->prebuf.ia_prot = stbuf->ia_prot; } } } if (local->stbuf.ia_type != IA_INVAL) { /* This is not the first subvol to respond * Compare values to see if attrs need to be healed */ if ((local->stbuf.ia_gid != stbuf->ia_gid) || (local->stbuf.ia_uid != stbuf->ia_uid) || (is_permission_different(&local->stbuf.ia_prot, &stbuf->ia_prot))) { local->need_attrheal = 1; } } if (local->inode == NULL) local->inode = inode_ref(inode); dht_iatt_merge(this, &local->stbuf, stbuf); dht_iatt_merge(this, &local->postparent, postparent); if (!dict_get(xattr, conf->mds_xattr_key)) { gf_msg_debug(this->name, 0, "%s: mds xattr %s is not present " "on %s(gfid = %s)", local->loc.path, conf->mds_xattr_key, prev->name, gfid_local); goto unlock; } /* Save the mds subvol info and stbuf. This is the value that will * be used for healing */ local->mds_subvol = prev; local->mds_stbuf = *stbuf; /* Save mds subvol on inode ctx */ ret = dht_inode_ctx_mdsvol_set(local->inode, this, prev); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, "%s: Failed to set mds (%s)", local->loc.path, prev->name); } check_mds = dht_dict_get_array(xattr, conf->mds_xattr_key, mds_xattr_val, 1, &errst); if ((check_mds < 0) && !errst) { /* Check if xattrs need to be healed on the directories */ local->mds_xattr = dict_ref(xattr); gf_msg_debug(this->name, 0, "%s: %s is not zero on %s. Xattrs need to be healed." "(gfid = %s)", local->loc.path, conf->mds_xattr_key, prev->name, gfid_local); local->need_xattr_heal = 1; } } unlock: UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { /* If the mds subvol is not set correctly*/ if (!__is_root_gfid(local->gfid) && (!dict_get(local->xattr, conf->mds_xattr_key))) { local->need_selfheal = 1; } /* No need to call xattr heal code if volume count is 1 */ if (conf->subvolume_cnt == 1) { local->need_xattr_heal = 0; } if (local->need_selfheal || local->need_lookup_everywhere) { /* Set the gfid-req so posix will set the GFID*/ if (!gf_uuid_is_null(local->gfid)) { /* Ok, this should _never_ happen */ ret = dict_set_static_bin(local->xattr_req, "gfid-req", local->gfid, 16); } else { if (!gf_uuid_is_null(local->gfid_req)) ret = dict_set_static_bin(local->xattr_req, "gfid-req", local->gfid_req, 16); } } if (local->need_lookup_everywhere) { local->need_lookup_everywhere = 0; dht_lookup_everywhere(frame, this, &local->loc); return 0; } if (local->op_ret == 0) { if (dht_needs_selfheal(frame, this)) { goto selfheal; } dht_layout_set(this, local->inode, layout); if (local->inode) { dht_inode_ctx_time_update(local->inode, this, NULL, &local->stbuf); } if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, NULL, &local->postparent); } } DHT_STRIP_PHASE1_FLAGS(&local->stbuf); dht_set_fixed_dir_stat(&local->postparent); /* Delete mds xattr at the time of STACK UNWIND */ if (local->xattr) GF_REMOVE_INTERNAL_XATTR(conf->mds_xattr_key, local->xattr); DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, local->inode, &local->stbuf, local->xattr, &local->postparent); } return 0; selfheal: ret = dht_selfheal_directory(frame, dht_lookup_selfheal_cbk, &local->loc, layout); out: return ret; } static int dht_lookup_directory(call_frame_t *frame, xlator_t *this, loc_t *loc) { int call_cnt = 0; int i = 0; dht_conf_t *conf = NULL; dht_local_t *local = NULL; int ret = 0; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", this, unwind); GF_VALIDATE_OR_GOTO("dht", frame->local, unwind); GF_VALIDATE_OR_GOTO("dht", this->private, unwind); GF_VALIDATE_OR_GOTO("dht", loc, unwind); conf = this->private; local = frame->local; call_cnt = conf->subvolume_cnt; local->call_cnt = call_cnt; local->layout = dht_layout_new(this, conf->subvolume_cnt); if (!local->layout) { goto unwind; } if (local->xattr != NULL) { dict_unref(local->xattr); local->xattr = NULL; } if (!gf_uuid_is_null(local->gfid)) { /* use this gfid in order to heal any missing ones */ ret = dict_set_gfuuid(local->xattr_req, "gfid-req", local->gfid, true); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "%s: Failed to set dictionary value:" " key = gfid-req", local->loc.path); } for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE( frame, dht_lookup_dir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, &local->loc, local->xattr_req); } return 0; unwind: DHT_STACK_UNWIND(lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL); out: return 0; } int dht_revalidate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; dht_layout_t *layout = NULL; dht_conf_t *conf = NULL; int ret = -1; int is_dir = 0; int is_linkfile = 0; int follow_link = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; uint32_t vol_commit_hash = 0; xlator_t *subvol = NULL; int32_t check_mds = 0; int errst = 0, i = 0; int32_t mds_xattr_val[1] = {0}; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO("dht", this, err); GF_VALIDATE_OR_GOTO("dht", frame->local, err); GF_VALIDATE_OR_GOTO("dht", cookie, err); GF_VALIDATE_OR_GOTO("dht", this->private, err); local = frame->local; prev = cookie; conf = this->private; if (!conf->vch_forced) { /* Update the commithash value if available */ ret = dict_get_uint32(xattr, conf->commithash_xattr_name, &vol_commit_hash); if (ret == 0) { conf->vol_commit_hash = vol_commit_hash; } } gf_uuid_unparse(local->loc.gfid, gfid); gf_msg_debug(this->name, op_errno, "%s: revalidate lookup on %s returned op_ret %d", local->loc.path, prev->name, op_ret); LOCK(&frame->lock); { if (gf_uuid_is_null(local->gfid)) { memcpy(local->gfid, local->loc.gfid, 16); } if (op_ret == -1) { local->op_errno = op_errno; if ((op_errno != ENOTCONN) && (op_errno != ENOENT) && (op_errno != ESTALE)) { gf_msg(this->name, GF_LOG_INFO, op_errno, DHT_MSG_REVALIDATE_CBK_INFO, "Revalidate: subvolume %s for %s " "(gfid = %s) returned -1", prev->name, local->loc.path, gfid); } if (op_errno == ESTALE) { /* propagate the ESTALE to parent. * setting local->return_estale would send * ESTALE to parent. */ local->return_estale = 1; } /* if it is ENOENT, we may have to do a * 'lookup_everywhere()' to make sure * the file is not migrated */ if (op_errno == ENOENT) { if (IA_ISREG(local->loc.inode->ia_type)) { gf_msg_debug(this->name, 0, "found ENOENT for %s. " "Setting " "need_lookup_everywhere" " flag to 1", local->loc.path); local->need_lookup_everywhere = 1; } else if (IA_ISDIR(local->loc.inode->ia_type)) { layout = local->layout; for (i = 0; i < layout->cnt; i++) { if (layout->list[i].xlator == prev) { layout->list[i].err = op_errno; break; } } local->need_selfheal = 1; } } /* The GFID is missing on this subvol. Lookup everywhere to force a * gfid heal */ if ((op_errno == ENODATA) && (IA_ISDIR(local->loc.inode->ia_type))) { local->need_lookup_everywhere = 1; } goto unlock; } if ((!IA_ISINVAL(local->inode->ia_type)) && stbuf->ia_type != local->inode->ia_type) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_FILE_TYPE_MISMATCH, "mismatching filetypes 0%o v/s 0%o for %s," " gfid = %s", (stbuf->ia_type), (local->inode->ia_type), local->loc.path, gfid); local->op_ret = -1; local->op_errno = EINVAL; goto unlock; } layout = local->layout; is_dir = check_is_dir(inode, stbuf, xattr); is_linkfile = check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name); if (is_linkfile) { follow_link = 1; goto unlock; } if (is_dir) { ret = dht_dir_has_layout(xattr, conf->xattr_name); if (ret >= 0) { if (is_greater_time(local->prebuf.ia_ctime, local->prebuf.ia_ctime_nsec, stbuf->ia_ctime, stbuf->ia_ctime_nsec)) { /* Choose source */ local->prebuf.ia_gid = stbuf->ia_gid; local->prebuf.ia_uid = stbuf->ia_uid; local->prebuf.ia_ctime = stbuf->ia_ctime; local->prebuf.ia_ctime_nsec = stbuf->ia_ctime_nsec; if (__is_root_gfid(stbuf->ia_gfid)) local->prebuf.ia_prot = stbuf->ia_prot; } } if (local->stbuf.ia_type != IA_INVAL) { if ((local->stbuf.ia_gid != stbuf->ia_gid) || (local->stbuf.ia_uid != stbuf->ia_uid) || is_permission_different(&local->stbuf.ia_prot, &stbuf->ia_prot)) { local->need_attrheal = 1; } } if (!dict_get(xattr, conf->mds_xattr_key)) { gf_msg_debug(this->name, 0, "%s: internal xattr %s is not present" " on subvol %s(gfid is %s)", local->loc.path, conf->mds_xattr_key, prev->name, gfid); } else { check_mds = dht_dict_get_array(xattr, conf->mds_xattr_key, mds_xattr_val, 1, &errst); local->mds_subvol = prev; local->mds_stbuf.ia_gid = stbuf->ia_gid; local->mds_stbuf.ia_uid = stbuf->ia_uid; local->mds_stbuf.ia_prot = stbuf->ia_prot; /* save mds subvol on inode ctx */ ret = dht_inode_ctx_mdsvol_set(local->inode, this, prev); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, "Failed to set MDS subvol for %s vol is %s", local->loc.path, prev->name); } if ((check_mds < 0) && !errst) { /* Check if xattrs need to be healed on the directory */ local->mds_xattr = dict_ref(xattr); gf_msg_debug(this->name, 0, "Value of %s is not zero on " "hashed subvol so xattr needs to" " be healed on non hashed" " path is %s and vol name is %s " " gfid is %s", conf->mds_xattr_key, local->loc.path, prev->name, gfid); local->need_xattr_heal = 1; } } ret = dht_layout_dir_mismatch(this, layout, prev, &local->loc, xattr); if (ret != 0) { /* In memory layout does not match on-disk layout. */ gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_MISMATCH, "Mismatching layouts for %s, gfid = %s", local->loc.path, gfid); local->layout_mismatch = 1; goto unlock; } } gf_uuid_copy(local->stbuf.ia_gfid, stbuf->ia_gfid); dht_iatt_merge(this, &local->stbuf, stbuf); dht_iatt_merge(this, &local->postparent, postparent); local->op_ret = 0; if (!local->xattr) { local->xattr = dict_ref(xattr); } else if (is_dir) { dht_aggregate_xattr(local->xattr, xattr); } } unlock: UNLOCK(&frame->lock); if (follow_link) { /* Found a linkto file. Follow it to see if the target file exists */ gf_uuid_copy(local->gfid, stbuf->ia_gfid); subvol = dht_linkfile_subvol(this, inode, stbuf, xattr); if (!subvol) { op_errno = ESTALE; local->op_ret = -1; } else { STACK_WIND_COOKIE(frame, dht_lookup_linkfile_cbk, subvol, subvol, subvol->fops->lookup, &local->loc, local->xattr_req); return 0; } } this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if (!IA_ISDIR(local->stbuf.ia_type) && (local->hashed_subvol != local->cached_subvol) && (local->stbuf.ia_nlink == 1) && (conf && conf->unhashed_sticky_bit)) { local->stbuf.ia_prot.sticky = 1; } /* No need to call heal code if volume count is 1 */ if (conf->subvolume_cnt == 1) local->need_xattr_heal = 0; if (IA_ISDIR(local->stbuf.ia_type)) { /* No mds xattr found. Trigger a heal to set it */ if (!__is_root_gfid(local->loc.inode->gfid) && (!dict_get(local->xattr, conf->mds_xattr_key))) local->need_selfheal = 1; if (dht_needs_selfheal(frame, this)) { if (!__is_root_gfid(local->loc.inode->gfid)) { if (local->mds_subvol) { local->stbuf.ia_gid = local->mds_stbuf.ia_gid; local->stbuf.ia_uid = local->mds_stbuf.ia_uid; local->stbuf.ia_prot = local->mds_stbuf.ia_prot; } } else { local->stbuf.ia_gid = local->prebuf.ia_gid; local->stbuf.ia_uid = local->prebuf.ia_uid; local->stbuf.ia_prot = local->prebuf.ia_prot; } layout = local->layout; dht_selfheal_directory(frame, dht_lookup_selfheal_cbk, &local->loc, layout); return 0; } } if (local->layout_mismatch) { /* Found layout mismatch in the directory, need to fix this in the inode context */ dht_layout_unref(local->layout); local->layout = NULL; dht_lookup_directory(frame, this, &local->loc); return 0; } if (local->need_lookup_everywhere) { /* As the current layout gave ENOENT error, we would need a new layout */ dht_layout_unref(local->layout); local->layout = NULL; /* We know that current cached subvol is no longer valid, get the new one */ local->cached_subvol = NULL; if (local->xattr_req) { if (!gf_uuid_is_null(local->gfid)) { ret = dict_set_static_bin(local->xattr_req, "gfid-req", local->gfid, 16); } } dht_lookup_everywhere(frame, this, &local->loc); return 0; } if (local->return_estale) { local->op_ret = -1; local->op_errno = ESTALE; } if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, NULL, &local->postparent); } DHT_STRIP_PHASE1_FLAGS(&local->stbuf); dht_set_fixed_dir_stat(&local->postparent); /* local->stbuf is updated only from subvols which have a layout * The reason is to avoid choosing attr heal source from newly * added bricks. In case e.g we have only one subvol and for * some reason layout is not present on it, then local->stbuf * will be EINVAL. This is an indication that the subvols * active in the cluster do not have layouts on disk. * Unwind with ESTALE to trigger a fresh lookup */ if (is_dir && local->stbuf.ia_type == IA_INVAL) { local->op_ret = -1; local->op_errno = ESTALE; } /* Delete mds xattr at the time of STACK UNWIND */ if (local->xattr) GF_REMOVE_INTERNAL_XATTR(conf->mds_xattr_key, local->xattr); DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, local->inode, &local->stbuf, local->xattr, &local->postparent); } err: return ret; } static int dht_lookup_linkfile_create_cbk(call_frame_t *frame, void *cooie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *cached_subvol = NULL; dht_conf_t *conf = NULL; int ret = -1; char gfid[GF_UUID_BUF_SIZE] = {0}; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", this->private, out); local = frame->local; cached_subvol = local->cached_subvol; conf = this->private; gf_uuid_unparse(local->loc.gfid, gfid); if (local->locked) dht_unlock_namespace(frame, &local->lock[0]); ret = dht_layout_preset(this, local->cached_subvol, local->loc.inode); if (ret < 0) { gf_msg_debug(this->name, EINVAL, "Failed to set layout for subvolume %s, " "(gfid = %s)", cached_subvol ? cached_subvol->name : "", gfid); local->op_ret = -1; local->op_errno = EINVAL; goto unwind; } local->op_ret = 0; if ((local->stbuf.ia_nlink == 1) && (conf && conf->unhashed_sticky_bit)) { local->stbuf.ia_prot.sticky = 1; } if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, NULL, postparent); } unwind: gf_msg_debug(this->name, 0, "creation of linkto on hashed subvol:%s, " "returned with op_ret %d and op_errno %d: %s", local->hashed_subvol->name, op_ret, op_errno, uuid_utoa(local->loc.gfid)); if (local->linked == _gf_true) dht_linkfile_attr_heal(frame, this); dht_set_fixed_dir_stat(&local->postparent); DHT_STRIP_PHASE1_FLAGS(&local->stbuf); DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, local->inode, &local->stbuf, local->xattr, &local->postparent); out: return ret; } static int dht_lookup_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int this_call_cnt = 0; dht_local_t *local = NULL; const char *path = NULL; local = (dht_local_t *)frame->local; path = local->loc.path; FRAME_SU_UNDO(frame, dht_local_t); gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_UNLINK_LOOKUP_INFO, "lookup_unlink returned with " "op_ret -> %d and op-errno -> %d for %s", op_ret, op_errno, ((path == NULL) ? "null" : path)); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { dht_lookup_everywhere_done(frame, this); } return 0; } static int dht_lookup_unlink_of_false_linkto_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int this_call_cnt = 0; dht_local_t *local = NULL; const char *path = NULL; local = (dht_local_t *)frame->local; path = local->loc.path; FRAME_SU_UNDO(frame, dht_local_t); gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_UNLINK_LOOKUP_INFO, "lookup_unlink returned with " "op_ret -> %d and op-errno -> %d for %s", op_ret, op_errno, ((path == NULL) ? "null" : path)); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if ((op_ret == 0) || ((op_errno != EBUSY) && (op_errno != ENOTCONN))) { dht_lookup_everywhere_done(frame, this); } else { /*When dht_lookup_everywhere is performed, one cached *and one hashed file was found and hashed file does *not point to the above mentioned cached node. So it *was considered as stale and an unlink was performed. *But unlink fails. So may be rebalance is in progress. *now ideally we have two data-files. One obtained during *lookup_everywhere and one where unlink-failed. So *at this point in time we cannot decide which one to *choose because there are chances of first cached *file is truncated after rebalance and if it is chosen *as cached node, application will fail. So return EIO.*/ if (op_errno == EBUSY) { gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_UNLINK_FAILED, "Could not unlink the linkto file as " "either fd is open and/or linkto xattr " "is set for %s", ((path == NULL) ? "null" : path)); } DHT_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, NULL, NULL); } } return 0; } static int dht_lookup_unlink_stale_linkto_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; const char *path = NULL; /* NOTE: * If stale file unlink fails either there is an open-fd or is not an * dht-linkto-file then posix_unlink returns EBUSY, which is overwritten * to ENOENT */ local = frame->local; if (local) { FRAME_SU_UNDO(frame, dht_local_t); if (local->loc.path) path = local->loc.path; } gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_UNLINK_LOOKUP_INFO, "Returned with op_ret %d and " "op_errno %d for %s", op_ret, op_errno, ((path == NULL) ? "null" : path)); DHT_STACK_UNWIND(lookup, frame, -1, ENOENT, NULL, NULL, NULL, NULL); return 0; } static int dht_fill_dict_to_avoid_unlink_of_migrating_file(dict_t *dict) { int ret = 0; ret = dict_set_int32_sizen(dict, DHT_SKIP_NON_LINKTO_UNLINK, 1); if (ret) return -1; ret = dict_set_int32_sizen(dict, DHT_SKIP_OPEN_FD_UNLINK, 1); if (ret) return -1; return 0; } static int32_t dht_linkfile_create_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { dht_local_t *local = NULL; int call_cnt = 0, ret = 0; xlator_t *subvol = NULL; uuid_t gfid = { 0, }; char gfid_str[GF_UUID_BUF_SIZE] = {0}; subvol = cookie; local = frame->local; if (subvol == local->hashed_subvol) { if ((op_ret == 0) || (op_errno != ENOENT)) local->dont_create_linkto = _gf_true; } else { if (gf_uuid_is_null(local->gfid)) gf_uuid_copy(gfid, local->loc.gfid); else gf_uuid_copy(gfid, local->gfid); if ((op_ret == 0) && gf_uuid_compare(gfid, buf->ia_gfid)) { gf_uuid_unparse(gfid, gfid_str); gf_msg_debug(this->name, 0, "gfid (%s) different on cached subvol " "(%s) and looked up inode (%s), not " "creating linkto", uuid_utoa(buf->ia_gfid), subvol->name, gfid_str); local->dont_create_linkto = _gf_true; } else if (op_ret == -1) { local->dont_create_linkto = _gf_true; } } call_cnt = dht_frame_return(frame); if (is_last_call(call_cnt)) { if (local->dont_create_linkto) goto no_linkto; else { gf_msg_debug(this->name, 0, "Creating linkto file on %s(hash) to " "%s on %s (gfid = %s)", local->hashed_subvol->name, local->loc.path, local->cached_subvol->name, gfid_str); ret = dht_linkfile_create(frame, dht_lookup_linkfile_create_cbk, this, local->cached_subvol, local->hashed_subvol, &local->loc); if (ret < 0) goto no_linkto; } } return 0; no_linkto: gf_msg_debug(this->name, 0, "skipped linkto creation (path:%s) (gfid:%s) " "(hashed-subvol:%s) (cached-subvol:%s)", local->loc.path, gfid_str, local->hashed_subvol->name, local->cached_subvol->name); dht_lookup_linkfile_create_cbk(frame, NULL, this, 0, 0, local->loc.inode, &local->stbuf, &local->preparent, &local->postparent, local->xattr); return 0; } static int32_t dht_call_lookup_linkfile_create(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; int i = 0; xlator_t *subvol = NULL; local = frame->local; if (gf_uuid_is_null(local->gfid)) gf_uuid_unparse(local->loc.gfid, gfid); else gf_uuid_unparse(local->gfid, gfid); if (op_ret < 0) { gf_log(this->name, GF_LOG_WARNING, "protecting namespace failed, skipping linkto " "creation (path:%s)(gfid:%s)(hashed-subvol:%s)" "(cached-subvol:%s)", local->loc.path, gfid, local->hashed_subvol->name, local->cached_subvol->name); goto err; } local->locked = _gf_true; local->call_cnt = 2; for (i = 0; i < 2; i++) { subvol = (subvol == NULL) ? local->hashed_subvol : local->cached_subvol; STACK_WIND_COOKIE(frame, dht_linkfile_create_lookup_cbk, subvol, subvol, subvol->fops->lookup, &local->loc, NULL); } return 0; err: dht_lookup_linkfile_create_cbk(frame, NULL, this, 0, 0, local->loc.inode, &local->stbuf, &local->preparent, &local->postparent, local->xattr); return 0; } /* Rebalance is performed from cached_node to hashed_node. Initial cached_node * contains a non-linkto file. After migration it is converted to linkto and * then unlinked. And at hashed_subvolume, first a linkto file is present, * then after migration it is converted to a non-linkto file. * * Lets assume a file is present on cached subvolume and a new brick is added * and new brick is the new_hashed subvolume. So fresh lookup on newly added * hashed subvolume will fail and dht_lookup_everywhere gets called. If just * before sending the dht_lookup_everywhere request rebalance is in progress, * * from cached subvolume it may see: Nonlinkto or linkto or No file * from hashed subvolume it may see: No file or linkto file or non-linkto file * * So this boils down to 9 cases: * at cached_subvol at hashed_subvol * ---------------- ----------------- * *a) No file No file * [request reached after [Request reached before * migration] Migration] * *b) No file Linkto File * *c) No file Non-Linkto File * *d) Linkto No-File * *e) Linkto Linkto * *f) Linkto Non-Linkto * *g) NonLinkto No-File * *h) NonLinkto Linkto * *i) NonLinkto NonLinkto * * dht_lookup_everywhere_done takes decision based on any of the above case */ static int dht_lookup_everywhere_done(call_frame_t *frame, xlator_t *this) { int ret = 0; dht_local_t *local = NULL; xlator_t *hashed_subvol = NULL; xlator_t *cached_subvol = NULL; dht_layout_t *layout = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; gf_boolean_t found_non_linkto_on_hashed = _gf_false; local = frame->local; hashed_subvol = local->hashed_subvol; cached_subvol = local->cached_subvol; gf_uuid_unparse(local->loc.gfid, gfid); if (local->file_count && local->dir_count) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_FILE_TYPE_MISMATCH, "path %s (gfid = %s)exists as a file on one " "subvolume and directory on another. " "Please fix it manually", local->loc.path, gfid); DHT_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, NULL, NULL); return 0; } if (local->op_ret && local->gfid_missing) { if (gf_uuid_is_null(local->gfid_req)) { DHT_STACK_UNWIND(lookup, frame, -1, ENODATA, NULL, NULL, NULL, NULL); return 0; } /* A hack */ local->gfid_missing = _gf_false; dht_lookup_directory(frame, this, &local->loc); return 0; } if (local->dir_count) { dht_lookup_directory(frame, this, &local->loc); return 0; } gf_msg_debug(this->name, 0, "STATUS: hashed_subvol %s " "cached_subvol %s", (hashed_subvol == NULL) ? "null" : hashed_subvol->name, (cached_subvol == NULL) ? "null" : cached_subvol->name); if (!cached_subvol) { if (local->skip_unlink.handle_valid_link && hashed_subvol) { /*Purpose of "DHT_SKIP_NON_LINKTO_UNLINK": * If this lookup is performed by rebalance and this * rebalance process detected hashed file and by * the time it sends the lookup request to cached node, * file got migrated and now at initial hashed_node, * final migrated file is present. With current logic, * because this process fails to find the cached_node, * it will unlink the file at initial hashed_node. * * So we avoid this by setting key, and checking at the * posix_unlink that unlink the file only if file is a * linkto file and not a migrated_file. */ ret = dht_fill_dict_to_avoid_unlink_of_migrating_file( local->xattr_req); if (ret) { /* If for some reason, setting key in the dict * fails, return with ENOENT, as with respect to * this process, it detected only a stale link * file. * * Next lookup will delete it. * * Performing deletion of stale link file when * setting key in dict fails, may cause the data * loss because of the above mentioned race. */ DHT_STACK_UNWIND(lookup, frame, -1, ENOENT, NULL, NULL, NULL, NULL); } else { local->skip_unlink.handle_valid_link = _gf_false; gf_msg_debug(this->name, 0, "No Cached was found and " "unlink on hashed was skipped" " so performing now: %s", local->loc.path); FRAME_SU_DO(frame, dht_local_t); STACK_WIND(frame, dht_lookup_unlink_stale_linkto_cbk, hashed_subvol, hashed_subvol->fops->unlink, &local->loc, 0, local->xattr_req); } } else { gf_msg_debug(this->name, 0, "There was no cached file and " "unlink on hashed is not skipped %s", local->loc.path); DHT_STACK_UNWIND(lookup, frame, -1, ENOENT, NULL, NULL, NULL, NULL); } return 0; } /* At the time of dht_lookup, no file was found on hashed and that is * why dht_lookup_everywhere is called, but by the time * dht_lookup_everywhere * reached to server, file might have already migrated. In that case we * will find a migrated file at the hashed_node. In this case store the * layout in context and return successfully. */ if (hashed_subvol || local->need_lookup_everywhere) { if (local->need_lookup_everywhere) { found_non_linkto_on_hashed = _gf_true; } else if ((local->file_count == 1) && (hashed_subvol == cached_subvol)) { gf_msg_debug(this->name, 0, "found cached file on hashed subvolume " "so store in context and return for %s", local->loc.path); found_non_linkto_on_hashed = _gf_true; } if (found_non_linkto_on_hashed) goto preset_layout; } if (hashed_subvol) { if (local->skip_unlink.handle_valid_link == _gf_true) { if (cached_subvol == local->skip_unlink.hash_links_to) { if (gf_uuid_compare(local->skip_unlink.cached_gfid, local->skip_unlink.hashed_gfid)) { /*GFID different, return error*/ DHT_STACK_UNWIND(lookup, frame, -1, ESTALE, NULL, NULL, NULL, NULL); return 0; } ret = dht_layout_preset(this, cached_subvol, local->loc.inode); if (ret) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_PRESET_FAILED, "Could not set pre-set layout " "for subvolume %s", cached_subvol->name); } local->op_ret = (ret == 0) ? ret : -1; local->op_errno = (ret == 0) ? ret : EINVAL; /* Presence of local->cached_subvol validates * that lookup from cached node is successful */ if (!local->op_ret && local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, NULL, &local->postparent); } gf_msg_debug(this->name, 0, "Skipped unlinking linkto file " "on the hashed subvolume. " "Returning success as it is a " "valid linkto file. Path:%s", local->loc.path); goto unwind_hashed_and_cached; } else { local->skip_unlink.handle_valid_link = _gf_false; gf_msg_debug(this->name, 0, "Linkto file found on hashed " "subvol " "and data file found on cached " "subvolume. But linkto points to " "different cached subvolume (%s) " "path %s", (local->skip_unlink.hash_links_to ? local->skip_unlink.hash_links_to->name : " "), local->loc.path); if (local->skip_unlink.opend_fd_count == 0) { ret = dht_fill_dict_to_avoid_unlink_of_migrating_file( local->xattr_req); if (ret) { DHT_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, NULL, NULL); } else { local->call_cnt = 1; FRAME_SU_DO(frame, dht_local_t); STACK_WIND(frame, dht_lookup_unlink_of_false_linkto_cbk, hashed_subvol, hashed_subvol->fops->unlink, &local->loc, 0, local->xattr_req); } return 0; } } } } preset_layout: if (found_non_linkto_on_hashed) { if (local->need_lookup_everywhere) { if (gf_uuid_compare(local->gfid, local->inode->gfid)) { /* GFID different, return error */ DHT_STACK_UNWIND(lookup, frame, -1, ENOENT, NULL, NULL, NULL, NULL); return 0; } } local->op_ret = 0; local->op_errno = 0; layout = dht_layout_for_subvol(this, cached_subvol); if (!layout) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, "%s: no pre-set layout for subvolume %s," " gfid = %s", local->loc.path, (cached_subvol ? cached_subvol->name : ""), gfid); } ret = dht_layout_set(this, local->inode, layout); if (ret < 0) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, "%s: failed to set layout for subvol %s, " "gfid = %s", local->loc.path, (cached_subvol ? cached_subvol->name : ""), gfid); } if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, NULL, &local->postparent); } DHT_STRIP_PHASE1_FLAGS(&local->stbuf); dht_set_fixed_dir_stat(&local->postparent); DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, local->inode, &local->stbuf, local->xattr, &local->postparent); return 0; } if (!hashed_subvol) { gf_msg_debug(this->name, 0, "Cannot create linkfile for %s on %s: " "hashed subvolume cannot be found, gfid = %s.", local->loc.path, cached_subvol->name, gfid); local->op_ret = 0; local->op_errno = 0; ret = dht_layout_preset(frame->this, cached_subvol, local->inode); if (ret < 0) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_PRESET_FAILED, "Failed to set layout for subvol %s" ", gfid = %s", cached_subvol ? cached_subvol->name : "", gfid); local->op_ret = -1; local->op_errno = EINVAL; } if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, NULL, &local->postparent); } DHT_STRIP_PHASE1_FLAGS(&local->stbuf); dht_set_fixed_dir_stat(&local->postparent); DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, local->inode, &local->stbuf, local->xattr, &local->postparent); return 0; } if (frame->root->op != GF_FOP_RENAME) { local->current = &local->lock[0]; ret = dht_protect_namespace(frame, &local->loc, hashed_subvol, &local->current->ns, dht_call_lookup_linkfile_create); } else { gf_msg_debug(this->name, 0, "Creating linkto file on %s(hash) to %s on %s " "(gfid = %s)", hashed_subvol->name, local->loc.path, cached_subvol->name, gfid); ret = dht_linkfile_create(frame, dht_lookup_linkfile_create_cbk, this, cached_subvol, hashed_subvol, &local->loc); } return ret; unwind_hashed_and_cached: DHT_STRIP_PHASE1_FLAGS(&local->stbuf); dht_set_fixed_dir_stat(&local->postparent); DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, local->inode, &local->stbuf, local->xattr, &local->postparent); return 0; } static int dht_lookup_everywhere_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xattr, struct iatt *postparent) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; int is_linkfile = 0; int is_dir = 0; loc_t *loc = NULL; xlator_t *link_subvol = NULL; int ret = -1; int32_t fd_count = 0; dht_conf_t *conf = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; dict_t *dict_req = {0}; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", cookie, out); GF_VALIDATE_OR_GOTO("dht", this->private, out); local = frame->local; loc = &local->loc; conf = this->private; prev = cookie; gf_msg_debug(this->name, 0, "returned with op_ret %d and op_errno %d (%s) " "from subvol %s", op_ret, op_errno, loc->path, prev->name); LOCK(&frame->lock); { if (op_ret == -1) { if (op_errno != ENOENT) local->op_errno = op_errno; if (op_errno == ENODATA) local->gfid_missing = _gf_true; goto unlock; } if (gf_uuid_is_null(local->gfid)) gf_uuid_copy(local->gfid, buf->ia_gfid); gf_uuid_unparse(local->gfid, gfid); if (gf_uuid_compare(local->gfid, buf->ia_gfid)) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_MISMATCH, "%s: gfid differs on subvolume %s," " gfid local = %s, gfid node = %s", loc->path, prev->name, gfid, uuid_utoa(buf->ia_gfid)); } is_linkfile = check_is_linkfile(inode, buf, xattr, conf->link_xattr_name); if (is_linkfile) { link_subvol = dht_linkfile_subvol(this, inode, buf, xattr); gf_msg_debug(this->name, 0, "found on %s linkfile %s (-> %s)", prev->name, loc->path, link_subvol ? link_subvol->name : "''"); goto unlock; } is_dir = check_is_dir(inode, buf, xattr); /* non linkfile GFID takes precedence but don't overwrite gfid if we have already found a cached file*/ if (!local->cached_subvol) gf_uuid_copy(local->gfid, buf->ia_gfid); if (is_dir) { local->dir_count++; gf_msg_debug(this->name, 0, "found on %s directory %s", prev->name, loc->path); } else { local->file_count++; gf_msg_debug(this->name, 0, "found cached file on %s for %s", prev->name, loc->path); if (!local->cached_subvol) { /* found one file */ dht_iatt_merge(this, &local->stbuf, buf); local->xattr = dict_ref(xattr); local->cached_subvol = prev; gf_msg_debug(this->name, 0, "storing cached on %s file" " %s", prev->name, loc->path); dht_iatt_merge(this, &local->postparent, postparent); gf_uuid_copy(local->skip_unlink.cached_gfid, buf->ia_gfid); } else { /* This is where we need 'rename' both entries logic */ gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_FILE_ON_MULT_SUBVOL, "multiple subvolumes (%s and %s) have " "file %s (preferably rename the file " "in the backend,and do a fresh lookup)", local->cached_subvol->name, prev->name, local->loc.path); } } } unlock: UNLOCK(&frame->lock); if (is_linkfile) { ret = dict_get_int32(xattr, GLUSTERFS_OPEN_FD_COUNT, &fd_count); /* Any linkto file found on the non-hashed subvolume should * be unlinked (performed in the "else if" block below) * * But if a linkto file is found on hashed subvolume, it may be * pointing to valid cached node. So unlinking of linkto * file on hashed subvolume is skipped and inside * dht_lookup_everywhere_done, checks are performed. If this * linkto file is found as stale linkto file, it is deleted * otherwise unlink is skipped. */ if (local->hashed_subvol && local->hashed_subvol == prev) { local->skip_unlink.handle_valid_link = _gf_true; local->skip_unlink.opend_fd_count = fd_count; local->skip_unlink.hash_links_to = link_subvol; gf_uuid_copy(local->skip_unlink.hashed_gfid, buf->ia_gfid); gf_msg_debug(this->name, 0, "Found" " one linkto file on hashed subvol %s " "for %s: Skipping unlinking till " "everywhere_done", prev->name, loc->path); } else if (!ret && (fd_count == 0)) { dict_req = dict_new(); ret = dht_fill_dict_to_avoid_unlink_of_migrating_file(dict_req); if (ret) { /* Skip unlinking for dict_failure *File is found as a linkto file on non-hashed, *subvolume. In the current implementation, *finding a linkto-file on non-hashed does not *always implies that it is stale. So deletion *of file should be done only when both fd is *closed and linkto-xattr is set. In case of *dict_set failure, avoid skipping of file. *NOTE: dht_frame_return should get called for * this block. */ dict_unref(dict_req); } else { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, "attempting deletion of stale linkfile " "%s on %s (hashed subvol is %s)", loc->path, prev->name, (local->hashed_subvol ? local->hashed_subvol->name : "")); /* * * These stale files may be created using root * user. Hence deletion will work only with * root. */ FRAME_SU_DO(frame, dht_local_t); STACK_WIND(frame, dht_lookup_unlink_cbk, prev, prev->fops->unlink, loc, 0, dict_req); dict_unref(dict_req); return 0; } } } this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { dht_lookup_everywhere_done(frame, this); } out: return ret; } int dht_lookup_everywhere(call_frame_t *frame, xlator_t *this, loc_t *loc) { dht_conf_t *conf = NULL; dht_local_t *local = NULL; int i = 0; int call_cnt = 0; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", this->private, out); GF_VALIDATE_OR_GOTO("dht", loc, out); conf = this->private; local = frame->local; call_cnt = conf->subvolume_cnt; local->call_cnt = call_cnt; if (!local->inode) local->inode = inode_ref(loc->inode); gf_msg_debug(this->name, 0, "winding lookup call to %d subvols", call_cnt); for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, dht_lookup_everywhere_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, loc, local->xattr_req); } return 0; out: DHT_STACK_UNWIND(lookup, frame, -1, EINVAL, NULL, NULL, NULL, NULL); err: return -1; } int dht_lookup_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { xlator_t *prev = NULL; dht_local_t *local = NULL; xlator_t *subvol = NULL; loc_t *loc = NULL; dht_conf_t *conf = NULL; int ret = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", this, unwind); GF_VALIDATE_OR_GOTO("dht", frame->local, unwind); GF_VALIDATE_OR_GOTO("dht", this->private, unwind); GF_VALIDATE_OR_GOTO("dht", cookie, unwind); prev = cookie; subvol = prev; conf = this->private; local = frame->local; loc = &local->loc; gf_uuid_unparse(loc->gfid, gfid); if (op_ret == -1) { gf_msg(this->name, GF_LOG_INFO, op_errno, DHT_MSG_LINK_FILE_LOOKUP_INFO, "Lookup of %s on %s (following linkfile) failed " ",gfid = %s", local->loc.path, subvol->name, gfid); /* If cached subvol returned ENOTCONN, do not do lookup_everywhere. We need to make sure linkfile does not get removed, which can take away the namespace, and subvol is anyways down. */ local->cached_subvol = NULL; if (op_errno != ENOTCONN) goto err; else goto unwind; } if (check_is_dir(inode, stbuf, xattr)) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LINK_FILE_LOOKUP_INFO, "Lookup of %s on %s (following linkfile) reached dir," " gfid = %s", local->loc.path, subvol->name, gfid); goto err; } if (check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name)) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LINK_FILE_LOOKUP_INFO, "lookup of %s on %s (following linkfile) reached link," "gfid = %s", local->loc.path, subvol->name, gfid); goto err; } if (gf_uuid_compare(local->gfid, stbuf->ia_gfid)) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_MISMATCH, "%s: gfid different on data file on %s," " gfid local = %s, gfid node = %s ", local->loc.path, subvol->name, gfid, uuid_utoa(stbuf->ia_gfid)); goto err; } if ((stbuf->ia_nlink == 1) && (conf && conf->unhashed_sticky_bit)) { stbuf->ia_prot.sticky = 1; } ret = dht_layout_preset(this, prev, inode); if (ret < 0) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_PRESET_FAILED, "Failed to set layout for subvolume %s," "gfid = %s", prev->name, gfid); op_ret = -1; op_errno = EINVAL; } if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, NULL, postparent); } unwind: DHT_STRIP_PHASE1_FLAGS(stbuf); dht_set_fixed_dir_stat(postparent); DHT_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, stbuf, xattr, postparent); return 0; err: dht_lookup_everywhere(frame, this, loc); out: return 0; } /* Code to get hashed subvol based on inode and loc First it check if loc->parent and loc->path exist then it get hashed subvol based on loc. */ static gf_boolean_t dht_should_lookup_everywhere(xlator_t *this, dht_conf_t *conf, loc_t *loc) { dht_layout_t *parent_layout = NULL; int ret = 0; gf_boolean_t lookup_everywhere = _gf_true; /* lookup-optimize supersedes lookup-unhashed settings. * If it is set, do not process search_unhashed * If lookup-optimize if enabled, lookup everywhere if: * - this is the rebalance daemon. * - loc->parent is unavailable. * - parent_layout is unavailable * - parent_layout->commit_hash != conf->vol_commit_hash */ if (conf->lookup_optimize) { if (!conf->defrag && loc->parent) { ret = dht_inode_ctx_layout_get(loc->parent, this, &parent_layout); if (!ret && parent_layout && (parent_layout->commit_hash == conf->vol_commit_hash)) { lookup_everywhere = _gf_false; } if (!ret) dht_layout_unref(parent_layout); } goto out; } else { if (conf->search_unhashed == GF_DHT_LOOKUP_UNHASHED_AUTO) { if (loc->parent) { ret = dht_inode_ctx_layout_get(loc->parent, this, &parent_layout); if (ret || !parent_layout || (!parent_layout->search_unhashed)) { lookup_everywhere = _gf_false; } if (!ret) dht_layout_unref(parent_layout); } else { lookup_everywhere = _gf_false; } goto out; } } out: return lookup_everywhere; } int dht_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { char is_linkfile = 0; char is_dir = 0; xlator_t *subvol = NULL; dht_conf_t *conf = NULL; dht_local_t *local = NULL; loc_t *loc = NULL; xlator_t *prev = NULL; int ret = 0; uint32_t vol_commit_hash = 0; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", cookie, out); GF_VALIDATE_OR_GOTO("dht", this->private, out); conf = this->private; prev = cookie; local = frame->local; loc = &local->loc; gf_msg_debug(this->name, op_errno, "%s: fresh_lookup on %s returned with op_ret %d", loc->path, prev->name, op_ret); if (op_ret == -1) { if (ENTRY_MISSING(op_ret, op_errno)) { if (1 == conf->subvolume_cnt) { /* No need to lookup again */ goto out; } gf_msg_debug(this->name, 0, "Entry %s missing on subvol %s", loc->path, prev->name); if (dht_should_lookup_everywhere(this, conf, loc)) { local->op_errno = ENOENT; dht_lookup_everywhere(frame, this, loc); return 0; } } else { /* posix returns ENODATA if the gfid is not set but the client and * server protocol layers do not send the stbuf. We need to * heal this so check if this is a directory on the other subvols. */ if ((op_errno == ENOTCONN) || (op_errno == ENODATA)) { dht_lookup_directory(frame, this, &local->loc); return 0; } } gf_msg_debug(this->name, op_errno, "%s: Lookup on subvolume %s failed", loc->path, prev->name); goto out; } /* Lookup succeeded - op_ret = 0 */ /* This is required for handling stale linkfile deletion, * or any more call which happens from this 'loc'. */ if (gf_uuid_is_null(local->gfid)) { /*This is set from the first successful response*/ memcpy(local->gfid, stbuf->ia_gfid, 16); } if (!conf->vch_forced) { /* Update the commit hash in conf if it is found */ ret = dict_get_uint32(xattr, conf->commithash_xattr_name, &vol_commit_hash); if (ret == 0) { conf->vol_commit_hash = vol_commit_hash; } } is_dir = check_is_dir(inode, stbuf, xattr); if (is_dir) { /* A directory is present on all subvols, send the lookup to * all subvols now */ local->inode = inode_ref(inode); local->xattr = dict_ref(xattr); dht_lookup_directory(frame, this, &local->loc); return 0; } is_linkfile = check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name); if (!is_linkfile) { /* non-directory and not a linkto file. This is a data file * Update the layout to point to the cached subvol */ ret = dht_layout_preset(this, prev, inode); if (ret < 0) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_PRESET_FAILED, "%s: could not set pre-set layout for subvolume %s", loc->path, prev->name); op_ret = -1; op_errno = EINVAL; goto out; } goto out; } /* This is a linkto file. Get the value of the target subvol from the * linkto xattr and lookup there to see if the file exists */ subvol = dht_linkfile_subvol(this, inode, stbuf, xattr); if (!subvol) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, "%s: No link subvol for linkto", loc->path); dht_lookup_everywhere(frame, this, loc); return 0; } gf_msg_debug(this->name, 0, "%s: Calling lookup on linkto target %s", loc->path, subvol->name); STACK_WIND_COOKIE(frame, dht_lookup_linkfile_cbk, subvol, subvol, subvol->fops->lookup, &local->loc, local->xattr_req); return 0; out: /* * FIXME: postparent->ia_size and postparent->st_blocks do not have * correct values. since, postparent corresponds to a directory these * two members should have values equal to sum of corresponding values * from each of the subvolume. See dht_iatt_merge for reference. */ if (!op_ret && local && local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, NULL, postparent); } DHT_STRIP_PHASE1_FLAGS(stbuf); dht_set_fixed_dir_stat(postparent); DHT_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, stbuf, xattr, postparent); err: return 0; } /* For directories, check if acl xattrs have been requested (by the acl * xlator), if not, request for them. These xattrs are needed for dht dir * self-heal to perform proper self-healing of dirs */ static void dht_check_and_set_acl_xattr_req(xlator_t *this, dict_t *xattr_req) { int ret = 0; GF_ASSERT(xattr_req); if (!dict_get(xattr_req, POSIX_ACL_ACCESS_XATTR)) { ret = dict_set_int8(xattr_req, POSIX_ACL_ACCESS_XATTR, 0); if (ret) gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value:key = %s", POSIX_ACL_ACCESS_XATTR); } if (!dict_get(xattr_req, POSIX_ACL_DEFAULT_XATTR)) { ret = dict_set_int8(xattr_req, POSIX_ACL_DEFAULT_XATTR, 0); if (ret) gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value:key = %s", POSIX_ACL_DEFAULT_XATTR); } return; } /* for directories, we need the following info: * the layout : trusted.glusterfs.dht * the mds information : trusted.glusterfs.dht.mds * the acl info: See above */ static int dht_set_dir_xattr_req(xlator_t *this, loc_t *loc, dict_t *xattr_req) { int ret = -EINVAL; dht_conf_t *conf = NULL; conf = this->private; if (!conf) { goto err; } if (!xattr_req) { goto err; } /* Xattr to get the layout for a directory */ ret = dict_set_uint32(xattr_req, conf->xattr_name, 4 * 4); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value:key = %s for " "path %s", conf->xattr_name, loc->path); goto err; } /*Non-fatal failure */ ret = dict_set_uint32(xattr_req, conf->mds_xattr_key, 4); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value:key = %s for " "path %s", conf->mds_xattr_key, loc->path); } dht_check_and_set_acl_xattr_req(this, xattr_req); ret = 0; err: return ret; } /* If the hashed subvol is present, send the lookup to only that subvol first. * If no hashed subvol, send a lookup to all subvols and proceed based on the * responses. */ static int dht_do_fresh_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc) { int ret = -1; dht_conf_t *conf = NULL; xlator_t *hashed_subvol = NULL; dht_local_t *local = NULL; int op_errno = -1; int call_cnt = 0; int i = 0; conf = this->private; if (!conf) { op_errno = EINVAL; goto err; } local = frame->local; if (!local) { op_errno = EINVAL; goto err; } /* Since we don't know whether this is a file or a directory, * request all xattrs*/ ret = dht_set_file_xattr_req(this, loc, local->xattr_req); if (ret) { op_errno = -ret; goto err; } ret = dht_set_dir_xattr_req(this, loc, local->xattr_req); if (ret) { op_errno = -ret; goto err; } /* Fuse sets a random value in gfid-req. If the gfid is missing * on one or more subvols, posix will set the gfid to this value, * causing GFID mismatches for directories. Remove the value fuse * has sent before sending the lookup. */ ret = dict_get_gfuuid(local->xattr_req, "gfid-req", &local->gfid_req); if (ret) { gf_msg_debug(this->name, 0, "%s: No gfid-req available", loc->path); } else { dict_del(local->xattr_req, "gfid-req"); } /* This should have been set in dht_lookup */ hashed_subvol = local->hashed_subvol; if (!hashed_subvol) { gf_msg_debug(this->name, 0, "%s: no subvolume in layout for path, " "checking on all the subvols to see if " "it is a directory", loc->path); call_cnt = conf->subvolume_cnt; local->call_cnt = call_cnt; /* Allocate a layout. This will be populated and saved in * the dht inode_ctx on successful lookup */ local->layout = dht_layout_new(this, conf->subvolume_cnt); if (!local->layout) { op_errno = ENOMEM; goto err; } gf_msg_debug(this->name, 0, "%s: Found null hashed subvol. Calling lookup" " on all nodes.", loc->path); for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, dht_lookup_dir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, &local->loc, local->xattr_req); } return 0; } /* if the hashed_subvol is non-null, send the lookup there first so * as to see whether we have a file or a directory */ gf_msg_debug(this->name, 0, "%s: Calling fresh lookup on %s", loc->path, hashed_subvol->name); STACK_WIND_COOKIE(frame, dht_lookup_cbk, hashed_subvol, hashed_subvol, hashed_subvol->fops->lookup, loc, local->xattr_req); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } static int dht_do_revalidate(call_frame_t *frame, xlator_t *this, loc_t *loc) { xlator_t *subvol = NULL; xlator_t *mds_subvol = NULL; dht_local_t *local = NULL; dht_conf_t *conf = NULL; int ret = -1; int op_errno = -1; dht_layout_t *layout = NULL; int i = 0; int call_cnt = 0; int gen = 0; conf = this->private; if (!conf) { op_errno = EINVAL; goto err; } local = frame->local; if (!local) { op_errno = EINVAL; goto err; } layout = local->layout; if (!layout) { gf_msg_debug(this->name, 0, "path = %s. No layout found in the inode ctx.", loc->path); op_errno = EINVAL; goto err; } /* Generation number has changed. This layout may be stale. */ if (layout->gen && (layout->gen < conf->gen)) { gen = layout->gen; dht_layout_unref(local->layout); local->layout = NULL; local->cached_subvol = NULL; gf_msg_debug(this->name, 0, "path = %s. In memory layout may be stale." "(layout->gen (%d) is less than " "conf->gen (%d)). Calling fresh lookup.", loc->path, gen, conf->gen); dht_do_fresh_lookup(frame, this, loc); return 0; } local->inode = inode_ref(loc->inode); /* Since we don't know whether this has changed, * request all xattrs*/ ret = dht_set_file_xattr_req(this, loc, local->xattr_req); if (ret) { op_errno = -ret; goto err; } ret = dht_set_dir_xattr_req(this, loc, local->xattr_req); if (ret) { op_errno = -ret; goto err; } if (IA_ISDIR(local->inode->ia_type)) { ret = dht_inode_ctx_mdsvol_get(local->inode, this, &mds_subvol); if (ret || !mds_subvol) { gf_msg_debug(this->name, 0, "path = %s. No mds subvol in inode ctx", local->loc.path); } local->mds_subvol = mds_subvol; local->call_cnt = conf->subvolume_cnt; /* local->call_cnt will change as responses are processed. Always use a * local copy to loop through the STACK_WIND calls */ call_cnt = local->call_cnt; for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, dht_revalidate_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, loc, local->xattr_req); } return 0; } /* If not a dir, this should be 1 */ local->call_cnt = layout->cnt; call_cnt = local->call_cnt; for (i = 0; i < call_cnt; i++) { subvol = layout->list[i].xlator; gf_msg_debug(this->name, 0, "path = %s. Calling " "revalidate lookup on %s", loc->path, subvol->name); STACK_WIND_COOKIE(frame, dht_revalidate_cbk, subvol, subvol, subvol->fops->lookup, &local->loc, local->xattr_req); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } /* Depending on the input, decide if this is a: * fresh-lookup: loc->name is provided but no dht inode ctx * revalidation: loc->name is provided, dht inode ctx is present * discover: gfid based nameless lookup. */ int dht_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { xlator_t *hashed_subvol = NULL; dht_local_t *local = NULL; dht_conf_t *conf = NULL; int ret = -1; int op_errno = -1; loc_t new_loc = { 0, }; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); conf = this->private; if (!conf) goto err; local = dht_local_init(frame, loc, NULL, GF_FOP_LOOKUP); if (!local) { op_errno = ENOMEM; goto err; } ret = dht_filter_loc_subvol_key(this, loc, &new_loc, &hashed_subvol); if (ret) { loc_wipe(&local->loc); ret = loc_dup(&new_loc, &local->loc); /* we no longer need 'new_loc' entries */ loc_wipe(&new_loc); /* check if loc_dup() is successful */ if (ret == -1) { op_errno = errno; gf_msg_debug(this->name, errno, "copying location failed for path=%s", loc->path); goto err; } } if (xattr_req) { local->xattr_req = dict_ref(xattr_req); } else { local->xattr_req = dict_new(); } /* Nameless lookup */ /* This is usually sent by NFS. Lookups are done based on the gfid and * no name information is available. Without the name, dht cannot calculate * the hash and has to send a lookup to all subvols. */ if (gf_uuid_is_null(loc->pargfid) && !gf_uuid_is_null(loc->gfid) && !__is_root_gfid(loc->inode->gfid)) { local->cached_subvol = NULL; dht_do_discover(frame, this, loc); return 0; } if (loc_is_root(loc)) { /* Request the DHT commit hash xattr (trusted.glusterfs.dht.commithash) * set on the brick root. */ ret = dict_set_uint32(local->xattr_req, conf->commithash_xattr_name, sizeof(uint32_t)); } if (!hashed_subvol) hashed_subvol = dht_subvol_get_hashed(this, loc); local->hashed_subvol = hashed_subvol; if (is_revalidate(loc)) { /* The entry has been looked up before and has a dht inode_ctx */ dht_do_revalidate(frame, this, loc); return 0; } else { /* Entry has not been looked up before */ dht_do_fresh_lookup(frame, this, loc); return 0; } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } static int dht_unlink_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; local = frame->local; prev = cookie; LOCK(&frame->lock); { if ((op_ret == -1) && !((op_errno == ENOENT) || (op_errno == ENOTCONN))) { local->op_errno = op_errno; UNLOCK(&frame->lock); gf_msg_debug(this->name, op_errno, "Unlink link: subvolume %s returned -1", prev->name); goto post_unlock; } local->op_ret = 0; } UNLOCK(&frame->lock); post_unlock: dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); DHT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, &local->preparent, &local->postparent, xdata); return 0; } static int dht_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; xlator_t *hashed_subvol = NULL; local = frame->local; prev = cookie; LOCK(&frame->lock); { if (op_ret == -1) { if (op_errno != ENOENT) { local->op_ret = -1; local->op_errno = op_errno; } else { local->op_ret = 0; } UNLOCK(&frame->lock); gf_msg_debug(this->name, op_errno, "Unlink: subvolume %s returned -1", prev->name); goto post_unlock; } local->op_ret = 0; local->postparent = *postparent; local->preparent = *preparent; if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, &local->preparent, &local->postparent); } } UNLOCK(&frame->lock); post_unlock: if (!local->op_ret) { hashed_subvol = dht_subvol_get_hashed(this, &local->loc); if (hashed_subvol && hashed_subvol != local->cached_subvol) { /* * If hashed and cached are different, then we need * to unlink linkfile from hashed subvol if data * file is deleted successfully */ STACK_WIND_COOKIE(frame, dht_unlink_linkfile_cbk, hashed_subvol, hashed_subvol, hashed_subvol->fops->unlink, &local->loc, local->flags, xdata); return 0; } } dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); DHT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, &local->preparent, &local->postparent, xdata); return 0; } static int dht_common_setxattr_cbk(call_frame_t *frame, void *cookie, int32_t op_ret, int32_t op_errno, dict_t *xdata) { DHT_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); return 0; } static int dht_fix_layout_setxattr_cbk(call_frame_t *frame, void *cookie, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; dht_layout_t *layout = NULL; if (op_ret == 0) { /* update the layout in the inode ctx */ local = frame->local; layout = local->selfheal.layout; dht_layout_set(frame->this, local->loc.inode, layout); } DHT_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); return 0; } static int dht_err_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; local = frame->local; prev = cookie; LOCK(&frame->lock); { if (op_ret == -1) { local->op_errno = op_errno; UNLOCK(&frame->lock); gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto post_unlock; } local->op_ret = 0; } UNLOCK(&frame->lock); post_unlock: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if ((local->fop == GF_FOP_SETXATTR) || (local->fop == GF_FOP_FSETXATTR)) { DHT_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, NULL); /* 'local' itself may not be valid after this */ goto out; } if ((local->fop == GF_FOP_REMOVEXATTR) || (local->fop == GF_FOP_FREMOVEXATTR)) { DHT_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, NULL); } } out: return 0; } /* Set the value[] of key into dict after convert from host byte order to network byte order */ int32_t dht_dict_set_array(dict_t *dict, char *key, int32_t value[], int32_t size) { int ret = -1; int32_t *ptr = NULL; int32_t vindex; if (value == NULL) { return -EINVAL; } ptr = GF_MALLOC(sizeof(int32_t) * size, gf_common_mt_char); if (ptr == NULL) { return -ENOMEM; } for (vindex = 0; vindex < size; vindex++) { ptr[vindex] = htobe32(value[vindex]); } ret = dict_set_bin(dict, key, ptr, sizeof(int32_t) * size); if (ret) GF_FREE(ptr); return ret; } static int dht_common_mds_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { dht_local_t *local = NULL; call_frame_t *prev = cookie; local = frame->local; if (op_ret) gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->this->name); if (local->fop == GF_FOP_SETXATTR) { DHT_STACK_UNWIND(setxattr, frame, 0, op_errno, local->xdata); /* 'local' itself may not be valid after this */ goto out; } if (local->fop == GF_FOP_FSETXATTR) { DHT_STACK_UNWIND(fsetxattr, frame, 0, op_errno, local->xdata); /* 'local' itself may not be valid after this */ goto out; } if (local->fop == GF_FOP_REMOVEXATTR) { DHT_STACK_UNWIND(removexattr, frame, 0, op_errno, NULL); /* 'local' itself may not be valid after this */ goto out; } if (local->fop == GF_FOP_FREMOVEXATTR) { DHT_STACK_UNWIND(fremovexattr, frame, 0, op_errno, NULL); } out: return 0; } /* Code to wind a xattrop call to add 1 on current mds internal xattr value */ static int dht_setxattr_non_mds_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; int ret = 0; dict_t *xattrop = NULL; int32_t addone[1] = {1}; call_frame_t *prev = NULL; dht_conf_t *conf = NULL; local = frame->local; prev = cookie; conf = this->private; LOCK(&frame->lock); { if (op_ret && !local->op_ret) { local->op_ret = op_ret; local->op_errno = op_errno; UNLOCK(&frame->lock); gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->this->name); goto post_unlock; } } UNLOCK(&frame->lock); post_unlock: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if (!local->op_ret) { xattrop = dict_new(); if (!xattrop) { gf_msg(this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, 0, "dictionary creation failed"); ret = -1; goto out; } ret = dht_dict_set_array(xattrop, conf->mds_xattr_key, addone, 1); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "dictionary set array failed "); ret = -1; goto out; } if ((local->fop == GF_FOP_SETXATTR) || (local->fop == GF_FOP_REMOVEXATTR)) { STACK_WIND(frame, dht_common_mds_xattrop_cbk, local->mds_subvol, local->mds_subvol->fops->xattrop, &local->loc, GF_XATTROP_ADD_ARRAY, xattrop, NULL); } else { STACK_WIND(frame, dht_common_mds_xattrop_cbk, local->mds_subvol, local->mds_subvol->fops->fxattrop, local->fd, GF_XATTROP_ADD_ARRAY, xattrop, NULL); } } else { if (local->fop == GF_FOP_SETXATTR) { DHT_STACK_UNWIND(setxattr, frame, 0, 0, local->xdata); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_FSETXATTR) { DHT_STACK_UNWIND(fsetxattr, frame, 0, 0, local->xdata); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_REMOVEXATTR) { DHT_STACK_UNWIND(removexattr, frame, 0, 0, NULL); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_FREMOVEXATTR) { DHT_STACK_UNWIND(fremovexattr, frame, 0, 0, NULL); /* 'local' itself may not be valid after this */ goto just_return; } } } out: if (ret) { if (local->fop == GF_FOP_SETXATTR) { DHT_STACK_UNWIND(setxattr, frame, 0, 0, local->xdata); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_FSETXATTR) { DHT_STACK_UNWIND(fsetxattr, frame, 0, 0, local->xdata); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_REMOVEXATTR) { DHT_STACK_UNWIND(removexattr, frame, 0, 0, NULL); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_FREMOVEXATTR) { DHT_STACK_UNWIND(fremovexattr, frame, 0, 0, NULL); } } just_return: if (xattrop) dict_unref(xattrop); return 0; } static int dht_setxattr_mds_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; call_frame_t *prev = NULL; xlator_t *mds_subvol = NULL; int i = 0; local = frame->local; prev = cookie; conf = this->private; mds_subvol = local->mds_subvol; if (op_ret == -1) { local->op_ret = op_ret; local->op_errno = op_errno; gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->this->name); goto out; } local->op_ret = 0; local->call_cnt = conf->subvolume_cnt - 1; local->xdata = dict_ref(xdata); for (i = 0; i < conf->subvolume_cnt; i++) { if (mds_subvol && (mds_subvol == conf->subvolumes[i])) continue; switch (local->fop) { case GF_FOP_SETXATTR: STACK_WIND(frame, dht_setxattr_non_mds_cbk, conf->subvolumes[i], conf->subvolumes[i]->fops->setxattr, &local->loc, local->xattr, local->flags, local->xattr_req); break; case GF_FOP_FSETXATTR: STACK_WIND(frame, dht_setxattr_non_mds_cbk, conf->subvolumes[i], conf->subvolumes[i]->fops->fsetxattr, local->fd, local->xattr, local->flags, local->xattr_req); break; case GF_FOP_REMOVEXATTR: STACK_WIND(frame, dht_setxattr_non_mds_cbk, conf->subvolumes[i], conf->subvolumes[i]->fops->removexattr, &local->loc, local->key, local->xattr_req); break; case GF_FOP_FREMOVEXATTR: STACK_WIND(frame, dht_setxattr_non_mds_cbk, conf->subvolumes[i], conf->subvolumes[i]->fops->fremovexattr, local->fd, local->key, local->xattr_req); break; default: break; } } return 0; out: if (local->fop == GF_FOP_SETXATTR) { DHT_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, xdata); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_FSETXATTR) { DHT_STACK_UNWIND(fsetxattr, frame, local->op_ret, local->op_errno, xdata); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_REMOVEXATTR) { DHT_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, NULL); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_FREMOVEXATTR) { DHT_STACK_UNWIND(fremovexattr, frame, local->op_ret, local->op_errno, NULL); } just_return: return 0; } static int dht_xattrop_mds_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *dict, dict_t *xdata) { dht_local_t *local = NULL; call_frame_t *prev = NULL; local = frame->local; prev = cookie; if (op_ret == -1) { local->op_errno = op_errno; local->op_ret = op_ret; gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->this->name); goto out; } if (local->fop == GF_FOP_SETXATTR) { STACK_WIND(frame, dht_setxattr_mds_cbk, local->mds_subvol, local->mds_subvol->fops->setxattr, &local->loc, local->xattr, local->flags, local->xattr_req); } if (local->fop == GF_FOP_FSETXATTR) { STACK_WIND(frame, dht_setxattr_mds_cbk, local->mds_subvol, local->mds_subvol->fops->fsetxattr, local->fd, local->xattr, local->flags, local->xattr_req); } if (local->fop == GF_FOP_REMOVEXATTR) { STACK_WIND(frame, dht_setxattr_mds_cbk, local->mds_subvol, local->mds_subvol->fops->removexattr, &local->loc, local->key, local->xattr_req); } if (local->fop == GF_FOP_FREMOVEXATTR) { STACK_WIND(frame, dht_setxattr_mds_cbk, local->mds_subvol, local->mds_subvol->fops->fremovexattr, local->fd, local->key, local->xattr_req); } return 0; out: if (local->fop == GF_FOP_SETXATTR) { DHT_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, xdata); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_FSETXATTR) { DHT_STACK_UNWIND(fsetxattr, frame, local->op_ret, local->op_errno, xdata); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_REMOVEXATTR) { DHT_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, NULL); /* 'local' itself may not be valid after this */ goto just_return; } if (local->fop == GF_FOP_FREMOVEXATTR) { DHT_STACK_UNWIND(fremovexattr, frame, local->op_ret, local->op_errno, NULL); } just_return: return 0; } static void fill_layout_info(dht_layout_t *layout, char *buf) { int i = 0; char tmp_buf[128] = { 0, }; for (i = 0; i < layout->cnt; i++) { snprintf(tmp_buf, sizeof(tmp_buf), "(%s %u %u)", layout->list[i].xlator->name, layout->list[i].start, layout->list[i].stop); if (i) strcat(buf, " "); strcat(buf, tmp_buf); } } static void dht_fill_pathinfo_xattr(xlator_t *this, dht_local_t *local, char *xattr_buf, int32_t alloc_len, int flag, char *layout_buf) { if (flag) { if (local->xattr_val) { snprintf(xattr_buf, alloc_len, "((<" DHT_PATHINFO_HEADER "%s> %s) (%s-layout %s))", this->name, local->xattr_val, this->name, layout_buf); } else { snprintf(xattr_buf, alloc_len, "(%s-layout %s)", this->name, layout_buf); } } else if (local->xattr_val) { snprintf(xattr_buf, alloc_len, "(<" DHT_PATHINFO_HEADER "%s> %s)", this->name, local->xattr_val); } else { xattr_buf[0] = '\0'; } } static int dht_vgetxattr_alloc_and_fill(dht_local_t *local, dict_t *xattr, xlator_t *this, int op_errno) { int ret = -1; char *value = NULL; ret = dict_get_str(xattr, local->xsel, &value); if (ret) { gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_GET_XATTR_FAILED, "Subvolume %s returned -1", this->name); local->op_ret = -1; local->op_errno = op_errno; goto out; } local->alloc_len += strlen(value); if (!local->xattr_val) { local->alloc_len += (SLEN(DHT_PATHINFO_HEADER) + 10); local->xattr_val = GF_MALLOC(local->alloc_len, gf_common_mt_char); if (!local->xattr_val) { ret = -1; goto out; } local->xattr_val[0] = '\0'; } int plen = strlen(local->xattr_val); if (plen) { /* extra byte(s) for \0 to be safe */ local->alloc_len += (plen + 2); local->xattr_val = GF_REALLOC(local->xattr_val, local->alloc_len); if (!local->xattr_val) { ret = -1; goto out; } } (void)strcat(local->xattr_val, value); (void)strcat(local->xattr_val, " "); local->op_ret = 0; ret = 0; out: return ret; } static int dht_vgetxattr_fill_and_set(dht_local_t *local, dict_t **dict, xlator_t *this, gf_boolean_t flag) { int ret = -1; char *xattr_buf = NULL; char layout_buf[8192] = { 0, }; if (flag) fill_layout_info(local->layout, layout_buf); *dict = dict_new(); if (!*dict) goto out; local->xattr_val[strlen(local->xattr_val) - 1] = '\0'; /* we would need max this many bytes to create xattr string * extra 40 bytes is just an estimated amount of additional * space required as we include translator name and some * spaces, brackets etc. when forming the pathinfo string. * * For node-uuid we just don't have all the pretty formatting, * but since this is a generic routine for pathinfo & node-uuid * we don't have conditional space allocation and try to be * generic */ local->alloc_len += (2 * strlen(this->name)) + strlen(layout_buf) + 40; xattr_buf = GF_MALLOC(local->alloc_len, gf_common_mt_char); if (!xattr_buf) goto out; if (XATTR_IS_PATHINFO(local->xsel)) { (void)dht_fill_pathinfo_xattr(this, local, xattr_buf, local->alloc_len, flag, layout_buf); } else if ((XATTR_IS_NODE_UUID(local->xsel)) || (XATTR_IS_NODE_UUID_LIST(local->xsel))) { (void)snprintf(xattr_buf, local->alloc_len, "%s", local->xattr_val); } else { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GET_XATTR_FAILED, "Unknown local->xsel (%s)", local->xsel); GF_FREE(xattr_buf); goto out; } ret = dict_set_dynstr(*dict, local->xsel, xattr_buf); if (ret) GF_FREE(xattr_buf); GF_FREE(local->xattr_val); out: return ret; } static int dht_find_local_subvol_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; xlator_t *prev = NULL; int this_call_cnt = 0; int ret = 0; char *uuid_str = NULL; char *uuid_list = NULL; char *next_uuid_str = NULL; char *saveptr = NULL; uuid_t node_uuid = { 0, }; char *uuid_list_copy = NULL; int count = 0; int i = 0; int index = 0; int found = 0; nodeuuid_info_t *tmp_ptr = NULL; VALIDATE_OR_GOTO(frame, out); VALIDATE_OR_GOTO(frame->local, out); local = frame->local; prev = cookie; conf = this->private; VALIDATE_OR_GOTO(conf->defrag, out); gf_msg_debug(this->name, 0, "subvol %s returned", prev->name); LOCK(&frame->lock); { this_call_cnt = --local->call_cnt; if (op_ret < 0) { local->op_ret = -1; local->op_errno = op_errno; UNLOCK(&frame->lock); if (op_errno == ENODATA) gf_msg_debug(this->name, 0, "failed to get node-uuid"); else gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_GET_XATTR_FAILED, "failed to get node-uuid"); goto post_unlock; } ret = dict_get_str(xattr, local->xsel, &uuid_list); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_GET_FAILED, "Failed to get %s", local->xsel); local->op_ret = -1; local->op_errno = EINVAL; goto unlock; } /* As DHT will not know details of its child xlators * we need to parse this twice to get the count first * and allocate memory later. */ count = 0; index = conf->local_subvols_cnt; uuid_list_copy = gf_strdup(uuid_list); if (!uuid_list_copy) goto unlock; for (uuid_str = strtok_r(uuid_list, " ", &saveptr); uuid_str; uuid_str = next_uuid_str) { next_uuid_str = strtok_r(NULL, " ", &saveptr); if (gf_uuid_parse(uuid_str, node_uuid)) { local->op_ret = -1; local->op_errno = EINVAL; UNLOCK(&frame->lock); gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_UUID_PARSE_ERROR, "Failed to parse uuid for %s", prev->name); goto post_unlock; } count++; if (gf_uuid_compare(node_uuid, conf->defrag->node_uuid)) { gf_msg_debug(this->name, 0, "subvol %s does not" "belong to this node", prev->name); } else { /* handle multiple bricks of the same replica * on the same node */ if (found) continue; conf->local_subvols[(conf->local_subvols_cnt)++] = prev; found = 1; gf_msg_debug(this->name, 0, "subvol %s belongs to" " this node", prev->name); } } if (!found) { local->op_ret = 0; goto unlock; } conf->local_nodeuuids[index].count = count; conf->local_nodeuuids[index].elements = GF_CALLOC( count, sizeof(nodeuuid_info_t), 1); /* The node-uuids are guaranteed to be returned in the same * order as the bricks * A null node-uuid is returned for a brick that is down. */ saveptr = NULL; i = 0; for (uuid_str = strtok_r(uuid_list_copy, " ", &saveptr); uuid_str; uuid_str = next_uuid_str) { next_uuid_str = strtok_r(NULL, " ", &saveptr); tmp_ptr = &(conf->local_nodeuuids[index].elements[i]); gf_uuid_parse(uuid_str, tmp_ptr->uuid); if (!gf_uuid_compare(tmp_ptr->uuid, conf->defrag->node_uuid)) { tmp_ptr->info = REBAL_NODEUUID_MINE; } i++; tmp_ptr = NULL; } } local->op_ret = 0; unlock: UNLOCK(&frame->lock); post_unlock: if (!is_last_call(this_call_cnt)) goto out; if (local->op_ret == -1) { goto unwind; } DHT_STACK_UNWIND(getxattr, frame, 0, 0, xattr, xdata); goto out; unwind: GF_FREE(conf->local_nodeuuids[index].elements); conf->local_nodeuuids[index].elements = NULL; DHT_STACK_UNWIND(getxattr, frame, -1, local->op_errno, NULL, xdata); out: GF_FREE(uuid_list_copy); return 0; } static int dht_vgetxattr_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { int ret = 0; dht_local_t *local = NULL; int this_call_cnt = 0; dict_t *dict = NULL; VALIDATE_OR_GOTO(frame, out); VALIDATE_OR_GOTO(frame->local, out); local = frame->local; LOCK(&frame->lock); { this_call_cnt = --local->call_cnt; if (op_ret < 0) { if (op_errno != ENOTCONN) { local->op_ret = -1; local->op_errno = op_errno; UNLOCK(&frame->lock); gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_GET_XATTR_FAILED, "getxattr err for dir"); goto post_unlock; } goto unlock; } ret = dht_vgetxattr_alloc_and_fill(local, xattr, this, op_errno); if (ret) { UNLOCK(&frame->lock); gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_DICT_SET_FAILED, "alloc or fill failure"); goto post_unlock; } } unlock: UNLOCK(&frame->lock); post_unlock: if (!is_last_call(this_call_cnt)) goto out; /* -- last call: do patch ups -- */ if (local->op_ret == -1) { goto unwind; } ret = dht_vgetxattr_fill_and_set(local, &dict, this, _gf_true); if (ret) goto unwind; DHT_STACK_UNWIND(getxattr, frame, 0, 0, dict, xdata); goto cleanup; unwind: DHT_STACK_UNWIND(getxattr, frame, -1, local->op_errno, NULL, NULL); cleanup: if (dict) dict_unref(dict); out: return 0; } static int dht_vgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { dht_local_t *local = NULL; int ret = 0; dict_t *dict = NULL; xlator_t *prev = NULL; gf_boolean_t flag = _gf_true; local = frame->local; prev = cookie; if (op_ret < 0) { local->op_ret = -1; local->op_errno = op_errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_GET_XATTR_FAILED, "vgetxattr: Subvolume %s returned -1", prev->name); goto unwind; } ret = dht_vgetxattr_alloc_and_fill(local, xattr, this, op_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_NO_MEMORY, "Allocation or fill failure"); goto unwind; } flag = (local->layout->cnt > 1) ? _gf_true : _gf_false; ret = dht_vgetxattr_fill_and_set(local, &dict, this, flag); if (ret) goto unwind; DHT_STACK_UNWIND(getxattr, frame, 0, 0, dict, xdata); goto cleanup; unwind: DHT_STACK_UNWIND(getxattr, frame, -1, local->op_errno, NULL, NULL); cleanup: if (dict) dict_unref(dict); return 0; } static int dht_linkinfo_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { int ret = 0; char *value = NULL; if (op_ret != -1) { ret = dict_get_str(xattr, GF_XATTR_PATHINFO_KEY, &value); if (!ret) { ret = dict_set_str(xattr, GF_XATTR_LINKINFO_KEY, value); if (!ret) gf_msg_trace(this->name, 0, "failed to set linkinfo"); } } DHT_STACK_UNWIND(getxattr, frame, op_ret, op_errno, xattr, xdata); return 0; } static int dht_mds_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(frame->local, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = frame->local; if (!xattr || (op_ret == -1)) { local->op_ret = op_ret; goto out; } dict_del(xattr, conf->xattr_name); local->op_ret = 0; if (!local->xattr) { local->xattr = dict_copy_with_ref(xattr, NULL); } out: DHT_STACK_UNWIND(getxattr, frame, local->op_ret, op_errno, local->xattr, xdata); return 0; err: DHT_STACK_UNWIND(getxattr, frame, -1, EINVAL, NULL, NULL); return 0; } int dht_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { int this_call_cnt = 0; dht_local_t *local = NULL; dht_conf_t *conf = NULL; int ret = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(frame->local, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = frame->local; if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto err; return 0; } LOCK(&frame->lock); { if (!xattr || (op_ret == -1)) { local->op_ret = op_ret; goto unlock; } dict_del(xattr, conf->xattr_name); dict_del(xattr, conf->mds_xattr_key); dict_del(xattr, conf->commithash_xattr_name); if (frame->root->pid >= 0) { GF_REMOVE_INTERNAL_XATTR("trusted.glusterfs.quota*", xattr); GF_REMOVE_INTERNAL_XATTR("trusted.pgfid*", xattr); } local->op_ret = 0; if (!local->xattr) { local->xattr = dict_copy_with_ref(xattr, NULL); } else { dht_aggregate_xattr(local->xattr, xattr); } if (!local->xdata) { local->xdata = dict_ref(xdata); } else if ((local->inode && IA_ISDIR(local->inode->ia_type)) || (local->fd && IA_ISDIR(local->fd->inode->ia_type))) { dht_aggregate_xattr(local->xdata, xdata); } } unlock: UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { /* If we have a valid xattr received from any one of the * subvolume, let's return it */ if (local->xattr) { local->op_ret = 0; } DHT_STACK_UNWIND(getxattr, frame, local->op_ret, op_errno, local->xattr, local->xdata); } return 0; err: DHT_STACK_UNWIND(getxattr, frame, -1, EINVAL, NULL, NULL); return 0; } static int32_t dht_getxattr_unwind(call_frame_t *frame, int op_ret, int op_errno, dict_t *dict, dict_t *xdata) { DHT_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } static int dht_getxattr_get_real_filename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { int this_call_cnt = 0; dht_local_t *local = NULL; local = frame->local; LOCK(&frame->lock); { if (local->op_errno == EOPNOTSUPP) { /* Nothing to do here, we have already found * a subvol which does not have the get_real_filename * optimization. If condition is for simple logic. */ goto unlock; } if (op_ret == -1) { if (op_errno == EOPNOTSUPP) { /* This subvol does not have the optimization. * Better let the user know we don't support it. * Remove previous results if any. */ if (local->xattr) { dict_unref(local->xattr); local->xattr = NULL; } if (local->xattr_req) { dict_unref(local->xattr_req); local->xattr_req = NULL; } local->op_ret = op_ret; local->op_errno = op_errno; UNLOCK(&frame->lock); gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_UPGRADE_BRICKS, "At least " "one of the bricks does not support " "this operation. Please upgrade all " "bricks."); goto post_unlock; } if (op_errno == ENOATTR) { /* Do nothing, our defaults are set to this. */ goto unlock; } /* This is a place holder for every other error * case. I am not sure of how to interpret * ENOTCONN etc. As of now, choosing to ignore * down subvol and return a good result(if any) * from other subvol. */ UNLOCK(&frame->lock); gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_GET_XATTR_FAILED, "Failed to get real filename."); goto post_unlock; } /* This subvol has the required file. * There could be other subvols which have returned * success already, choosing to return the latest good * result. */ if (local->xattr) dict_unref(local->xattr); local->xattr = dict_ref(xattr); if (local->xattr_req) { dict_unref(local->xattr_req); local->xattr_req = NULL; } if (xdata) local->xattr_req = dict_ref(xdata); local->op_ret = op_ret; local->op_errno = 0; UNLOCK(&frame->lock); gf_msg_debug(this->name, 0, "Found a matching file."); goto post_unlock; } unlock: UNLOCK(&frame->lock); post_unlock: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { DHT_STACK_UNWIND(getxattr, frame, local->op_ret, local->op_errno, local->xattr, local->xattr_req); } return 0; } static int dht_getxattr_get_real_filename(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, dict_t *xdata) { dht_local_t *local = NULL; int i = 0; dht_layout_t *layout = NULL; int cnt = 0; xlator_t *subvol = NULL; local = frame->local; layout = local->layout; cnt = local->call_cnt = layout->cnt; local->op_ret = -1; local->op_errno = ENOATTR; for (i = 0; i < cnt; i++) { subvol = layout->list[i].xlator; STACK_WIND(frame, dht_getxattr_get_real_filename_cbk, subvol, subvol->fops->getxattr, loc, key, xdata); } return 0; } static int dht_marker_populate_args(call_frame_t *frame, int type, int *gauge, xlator_t **subvols) { dht_local_t *local = NULL; int i = 0; dht_layout_t *layout = NULL; local = frame->local; layout = local->layout; for (i = 0; i < layout->cnt; i++) subvols[i] = layout->list[i].xlator; return layout->cnt; } static int dht_is_debug_xattr_key(const char **array, char *key) { int i = 0; for (i = 0; array[i]; i++) { if (fnmatch(array[i], key, FNM_NOESCAPE) == 0) return i; } return -1; } /* Note we already have frame->local initialised here*/ static int dht_handle_debug_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key) { dht_local_t *local = NULL; int ret = -1; int op_errno = ENODATA; char *value = NULL; loc_t file_loc = {0}; const char *name = NULL; local = frame->local; if (dht_is_debug_xattr_key(dht_dbg_vxattrs, (char *)key) == -1) { goto out; } local->xattr = dict_new(); if (!local->xattr) { op_errno = ENOMEM; goto out; } if (strncmp(key, DHT_DBG_HASHED_SUBVOL_KEY, SLEN(DHT_DBG_HASHED_SUBVOL_KEY)) == 0) { name = key + strlen(DHT_DBG_HASHED_SUBVOL_KEY); if (strlen(name) == 0) { op_errno = EINVAL; goto out; } ret = dht_build_child_loc(this, &file_loc, loc, (char *)name); if (ret) { op_errno = ENOMEM; goto out; } local->hashed_subvol = dht_subvol_get_hashed(this, &file_loc); if (local->hashed_subvol == NULL) { op_errno = ENODATA; goto out; } value = gf_strdup(local->hashed_subvol->name); if (!value) { op_errno = ENOMEM; goto out; } ret = dict_set_dynstr(local->xattr, (char *)key, value); if (ret < 0) { op_errno = -ret; ret = -1; goto out; } ret = 0; goto out; } out: loc_wipe(&file_loc); DHT_STACK_UNWIND(getxattr, frame, ret, op_errno, local->xattr, NULL); return 0; } /* Virtual Xattr which returns 1 if all subvols are up, else returns 0. Geo-rep then uses this virtual xattr after a fresh mount and starts the I/O. */ enum dht_vxattr_subvol { DHT_VXATTR_SUBVOLS_UP = 1, DHT_VXATTR_SUBVOLS_DOWN = 0, }; int dht_vgetxattr_subvol_status(call_frame_t *frame, xlator_t *this, const char *key) { dht_local_t *local = NULL; int ret = -1; int op_errno = ENODATA; int value = DHT_VXATTR_SUBVOLS_UP; int i = 0; dht_conf_t *conf = NULL; conf = this->private; local = frame->local; if (!key) { op_errno = EINVAL; goto out; } local->xattr = dict_new(); if (!local->xattr) { op_errno = ENOMEM; goto out; } for (i = 0; i < conf->subvolume_cnt; i++) { if (!conf->subvolume_status[i]) { value = DHT_VXATTR_SUBVOLS_DOWN; gf_msg_debug(this->name, 0, "subvol %s is down ", conf->subvolumes[i]->name); break; } } ret = dict_set_int8(local->xattr, (char *)key, value); if (ret < 0) { op_errno = -ret; ret = -1; goto out; } ret = 0; out: DHT_STACK_UNWIND(getxattr, frame, ret, op_errno, local->xattr, NULL); return 0; } int dht_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, dict_t *xdata) #define DHT_IS_DIR(layout) (layout->cnt > 1) { xlator_t *subvol = NULL; xlator_t *hashed_subvol = NULL; xlator_t *mds_subvol = NULL; xlator_t *cached_subvol = NULL; dht_conf_t *conf = NULL; dht_local_t *local = NULL; dht_layout_t *layout = NULL; int op_errno = -1; int i = 0; int cnt = 0; char *node_uuid_key = NULL; int ret = -1; GF_CHECK_XATTR_KEY_AND_GOTO(key, IO_THREADS_QUEUE_SIZE_KEY, op_errno, err); VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = dht_local_init(frame, loc, NULL, GF_FOP_GETXATTR); if (!local) { op_errno = ENOMEM; goto err; } layout = local->layout; if (!layout) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LAYOUT_NULL, "Layout is NULL"); op_errno = ENOENT; goto err; } /* skip over code which is irrelevant without a valid key */ if (!key) goto no_key; local->key = gf_strdup(key); if (!local->key) { op_errno = ENOMEM; goto err; } if (strncmp(key, conf->mds_xattr_key, strlen(key)) == 0) { op_errno = ENOTSUP; goto err; } if (strncmp(key, DHT_SUBVOL_STATUS_KEY, SLEN(DHT_SUBVOL_STATUS_KEY)) == 0) { dht_vgetxattr_subvol_status(frame, this, key); return 0; } /* skip over code which is irrelevant if !DHT_IS_DIR(layout) */ if (!DHT_IS_DIR(layout)) goto no_dht_is_dir; if ((strncmp(key, GF_XATTR_GET_REAL_FILENAME_KEY, SLEN(GF_XATTR_GET_REAL_FILENAME_KEY)) == 0) && DHT_IS_DIR(layout)) { dht_getxattr_get_real_filename(frame, this, loc, key, xdata); return 0; } if (!strcmp(key, GF_REBAL_FIND_LOCAL_SUBVOL)) { ret = gf_asprintf(&node_uuid_key, "%s", GF_XATTR_LIST_NODE_UUIDS_KEY); if (ret == -1 || !node_uuid_key) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_NO_MEMORY, "Failed to copy node uuid key"); op_errno = ENOMEM; goto err; } (void)snprintf(local->xsel, sizeof(local->xsel), "%s", node_uuid_key); cnt = local->call_cnt = conf->subvolume_cnt; for (i = 0; i < cnt; i++) { STACK_WIND_COOKIE(frame, dht_find_local_subvol_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->getxattr, loc, node_uuid_key, xdata); } if (node_uuid_key) GF_FREE(node_uuid_key); return 0; } if (!strcmp(key, GF_REBAL_OLD_FIND_LOCAL_SUBVOL)) { ret = gf_asprintf(&node_uuid_key, "%s", GF_XATTR_NODE_UUID_KEY); if (ret == -1 || !node_uuid_key) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_NO_MEMORY, "Failed to copy node uuid key"); op_errno = ENOMEM; goto err; } (void)snprintf(local->xsel, sizeof(local->xsel), "%s", node_uuid_key); cnt = local->call_cnt = conf->subvolume_cnt; for (i = 0; i < cnt; i++) { STACK_WIND_COOKIE(frame, dht_find_local_subvol_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->getxattr, loc, node_uuid_key, xdata); } if (node_uuid_key) GF_FREE(node_uuid_key); return 0; } /* for file use cached subvolume (obviously!): see if {} * below * for directory: * wind to all subvolumes and exclude subvolumes which * return ENOTCONN (in callback) * * NOTE: Don't trust inode here, as that may not be valid * (until inode_link() happens) */ if (XATTR_IS_PATHINFO(key) || (strcmp(key, GF_XATTR_NODE_UUID_KEY) == 0) || (strcmp(key, GF_XATTR_LIST_NODE_UUIDS_KEY) == 0)) { (void)snprintf(local->xsel, sizeof(local->xsel), "%s", key); cnt = local->call_cnt = layout->cnt; for (i = 0; i < cnt; i++) { subvol = layout->list[i].xlator; STACK_WIND(frame, dht_vgetxattr_dir_cbk, subvol, subvol->fops->getxattr, loc, key, xdata); } return 0; } no_dht_is_dir: /* node-uuid or pathinfo for files */ if (XATTR_IS_PATHINFO(key) || (strcmp(key, GF_XATTR_NODE_UUID_KEY) == 0)) { cached_subvol = local->cached_subvol; (void)snprintf(local->xsel, sizeof(local->xsel), "%s", key); local->call_cnt = 1; STACK_WIND_COOKIE(frame, dht_vgetxattr_cbk, cached_subvol, cached_subvol, cached_subvol->fops->getxattr, loc, key, xdata); return 0; } if (strcmp(key, GF_XATTR_LINKINFO_KEY) == 0) { hashed_subvol = dht_subvol_get_hashed(this, loc); if (!hashed_subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "Failed to get hashed subvol for %s", loc->path); op_errno = EINVAL; goto err; } cached_subvol = dht_subvol_get_cached(this, loc->inode); if (!cached_subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_CACHED_SUBVOL_GET_FAILED, "Failed to get cached subvol for %s", loc->path); op_errno = EINVAL; goto err; } if (hashed_subvol == cached_subvol) { op_errno = ENODATA; goto err; } STACK_WIND(frame, dht_linkinfo_getxattr_cbk, hashed_subvol, hashed_subvol->fops->getxattr, loc, GF_XATTR_PATHINFO_KEY, xdata); return 0; } if (dht_is_debug_xattr_key(dht_dbg_vxattrs, (char *)key) >= 0) { dht_handle_debug_getxattr(frame, this, loc, key); return 0; } no_key: if (cluster_handle_marker_getxattr(frame, loc, key, conf->vol_uuid, dht_getxattr_unwind, dht_marker_populate_args) == 0) return 0; if (DHT_IS_DIR(layout)) { local->call_cnt = conf->subvolume_cnt; cnt = conf->subvolume_cnt; ret = dht_inode_ctx_mdsvol_get(loc->inode, this, &mds_subvol); if (!mds_subvol) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "Cannot determine MDS, fetching xattr %s randomly" " from a subvol for path %s ", key, loc->path); } else { /* TODO need to handle it, As of now we are choosing availability instead of chossing consistencty, in case of mds_subvol is down winding a getxattr call on other subvol and return xattr */ local->mds_subvol = mds_subvol; for (i = 0; i < cnt; i++) { if (conf->subvolumes[i] == mds_subvol) { if (!conf->subvolume_status[i]) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_HASHED_SUBVOL_DOWN, "MDS %s is down for path" " path %s so fetching xattr " "%s randomly from a subvol ", local->mds_subvol->name, loc->path, key); ret = 1; } } } } if (!ret && key && local->mds_subvol && dht_match_xattr(key)) { STACK_WIND(frame, dht_mds_getxattr_cbk, local->mds_subvol, local->mds_subvol->fops->getxattr, loc, key, xdata); return 0; } } else { cnt = local->call_cnt = 1; } for (i = 0; i < cnt; i++) { subvol = layout->list[i].xlator; STACK_WIND(frame, dht_getxattr_cbk, subvol, subvol->fops->getxattr, loc, key, xdata); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(getxattr, frame, -1, op_errno, NULL, NULL); return 0; } #undef DHT_IS_DIR int dht_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key, dict_t *xdata) { xlator_t *subvol = NULL; dht_local_t *local = NULL; dht_layout_t *layout = NULL; int op_errno = -1; int i = 0; int cnt = 0; xlator_t *mds_subvol = NULL; int ret = -1; dht_conf_t *conf = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); VALIDATE_OR_GOTO(fd->inode, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = dht_local_init(frame, NULL, fd, GF_FOP_FGETXATTR); if (!local) { op_errno = ENOMEM; goto err; } layout = local->layout; if (!layout) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LAYOUT_NULL, "Layout is NULL"); op_errno = ENOENT; goto err; } if (key) { local->key = gf_strdup(key); if (!local->key) { op_errno = ENOMEM; goto err; } } gf_uuid_unparse(fd->inode->gfid, gfid); if ((fd->inode->ia_type == IA_IFDIR) && key && (strncmp(key, GF_XATTR_LOCKINFO_KEY, SLEN(GF_XATTR_LOCKINFO_KEY)) != 0)) { local->call_cnt = conf->subvolume_cnt; cnt = conf->subvolume_cnt; ret = dht_inode_ctx_mdsvol_get(fd->inode, this, &mds_subvol); if (!mds_subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "cannot determine MDS, fetching xattr %s " " randomly from a subvol for gfid %s ", key, gfid); } else { /* TODO need to handle it, As of now we are choosing availability instead of chossing consistencty, in case of hashed_subvol is down winding a getxattr call on other subvol and return xattr */ local->mds_subvol = mds_subvol; for (i = 0; i < cnt; i++) { if (conf->subvolumes[i] == mds_subvol) { if (!conf->subvolume_status[i]) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_HASHED_SUBVOL_DOWN, "MDS subvolume %s is down" " for gfid %s so fetching xattr " " %s randomly from a subvol ", local->mds_subvol->name, gfid, key); ret = 1; } } } } if (!ret && key && local->mds_subvol && dht_match_xattr(key)) { STACK_WIND(frame, dht_mds_getxattr_cbk, local->mds_subvol, local->mds_subvol->fops->fgetxattr, fd, key, xdata); return 0; } } else { cnt = local->call_cnt = 1; } for (i = 0; i < cnt; i++) { subvol = layout->list[i].xlator; STACK_WIND(frame, dht_getxattr_cbk, subvol, subvol->fops->fgetxattr, fd, key, xdata); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL); return 0; } static int dht_setxattr2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int op_errno = EINVAL; if (!frame || !frame->local) goto err; local = frame->local; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, local->rebalance.xdata); return 0; } if (subvol == NULL) goto err; local->call_cnt = 2; /* This is the second attempt */ if (local->fop == GF_FOP_SETXATTR) { STACK_WIND_COOKIE(frame, dht_file_setxattr_cbk, subvol, subvol, subvol->fops->setxattr, &local->loc, local->rebalance.xattr, local->rebalance.flags, local->xattr_req); } else { STACK_WIND_COOKIE(frame, dht_file_setxattr_cbk, subvol, subvol, subvol->fops->fsetxattr, local->fd, local->rebalance.xattr, local->rebalance.flags, local->xattr_req); } return 0; err: DHT_STACK_UNWIND(setxattr, frame, (local ? local->op_ret : -1), op_errno, NULL); return 0; } int dht_file_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { int ret = -1; dht_local_t *local = NULL; xlator_t *prev = NULL; struct iatt *stbuf = NULL; inode_t *inode = NULL; xlator_t *subvol1 = NULL, *subvol2 = NULL; local = frame->local; prev = cookie; local->op_errno = op_errno; if ((local->fop == GF_FOP_FSETXATTR) && dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if ((op_ret == -1) && !dht_inode_missing(op_errno)) { gf_msg_debug(this->name, op_errno, "subvolume %s returned -1.", prev->name); goto out; } if (local->call_cnt != 1) goto out; ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf); if ((!op_ret) && !stbuf) { goto out; } local->op_ret = op_ret; local->rebalance.target_op_fn = dht_setxattr2; if (xdata) local->rebalance.xdata = dict_ref(xdata); /* Phase 2 of migration */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(stbuf)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* Phase 1 of migration */ if (IS_DHT_MIGRATION_PHASE1(stbuf)) { inode = (local->fd) ? local->fd->inode : local->loc.inode; ret = dht_inode_ctx_get_mig_info(this, inode, &subvol1, &subvol2); if (!dht_mig_info_is_invalid(local->cached_subvol, subvol1, subvol2)) { dht_setxattr2(subvol2, frame, 0); return 0; } ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } out: if (local->fop == GF_FOP_SETXATTR) { DHT_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); } else { DHT_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, xdata); } return 0; } /* Function is call by dict_foreach_fnmatch if key is match with user.* and set boolean flag to true */ static int dht_is_user_xattr(dict_t *this, char *key, data_t *value, void *data) { gf_boolean_t *user_xattr_found = data; *user_xattr_found = _gf_true; return 0; } /* Common code to wind a (f)(set|remove)xattr call to set xattr on directory */ static int dht_dir_common_set_remove_xattr(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xattr, int flags, dict_t *xdata, int *op_errno) { dict_t *xattrop = NULL; int32_t subone[1] = {-1}; gf_boolean_t uxattr_key_found = _gf_false; xlator_t *mds_subvol = NULL; xlator_t *travvol = NULL; dht_conf_t *conf = NULL; int ret = -1; int i = 0; int call_cnt = 0; dht_local_t *local = NULL; char gfid_local[GF_UUID_BUF_SIZE] = {0}; char **xattrs_to_heal; conf = this->private; local = frame->local; call_cnt = conf->subvolume_cnt; local->flags = flags; xattrs_to_heal = get_xattrs_to_heal(); if (!gf_uuid_is_null(local->gfid)) { gf_uuid_unparse(local->gfid, gfid_local); } if ((local->fop == GF_FOP_SETXATTR) || (local->fop == GF_FOP_FSETXATTR)) { /* Check if any user xattr present in xattr */ dict_foreach_fnmatch(xattr, "user*", dht_is_user_xattr, &uxattr_key_found); /* Check if any custom key xattr present in dict xattr and start index from 1 because user xattr already checked in previous line */ for (i = 1; xattrs_to_heal[i]; i++) if (dict_get(xattr, xattrs_to_heal[i])) uxattr_key_found = _gf_true; } if ((local->fop == GF_FOP_REMOVEXATTR) || (local->fop == GF_FOP_FREMOVEXATTR)) { /* Check if any custom key xattr present in local->key */ for (i = 0; xattrs_to_heal[i]; i++) if (strstr(local->key, xattrs_to_heal[i])) uxattr_key_found = _gf_true; } /* If there is no custom key xattr present or gfid is root or call_cnt is 1 then wind a (f)setxattr call on all subvols */ if (!uxattr_key_found || __is_root_gfid(local->gfid) || call_cnt == 1) { for (i = 0; i < conf->subvolume_cnt; i++) { travvol = conf->subvolumes[i]; if ((local->fop == GF_FOP_SETXATTR) || (local->fop == GF_FOP_FSETXATTR)) { if (fd) { STACK_WIND_COOKIE(frame, dht_err_cbk, travvol, travvol, travvol->fops->fsetxattr, fd, xattr, flags, xdata); } else { STACK_WIND_COOKIE(frame, dht_err_cbk, travvol, travvol, travvol->fops->setxattr, loc, xattr, flags, xdata); } } if ((local->fop == GF_FOP_REMOVEXATTR) || (local->fop == GF_FOP_FREMOVEXATTR)) { if (fd) { STACK_WIND_COOKIE(frame, dht_err_cbk, travvol, travvol, travvol->fops->fremovexattr, fd, local->key, local->xattr_req); } else { STACK_WIND_COOKIE(frame, dht_err_cbk, travvol, travvol, travvol->fops->removexattr, loc, local->key, local->xattr_req); } } } return 0; } /* Calculate hash subvol based on inode and parent inode */ if (fd) { ret = dht_inode_ctx_mdsvol_get(fd->inode, this, &mds_subvol); } else { ret = dht_inode_ctx_mdsvol_get(loc->inode, this, &mds_subvol); } if (ret || !mds_subvol) { if (fd) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "Failed to get mds subvol for fd %p" "gfid is %s ", fd, gfid_local); } else { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "%s: Failed to get mds subvol. (gfid is %s)", loc->path, gfid_local); } (*op_errno) = ENOENT; goto err; } local->mds_subvol = mds_subvol; for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == mds_subvol) { if (!conf->subvolume_status[i]) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_HASHED_SUBVOL_DOWN, "MDS subvol is down for path " " %s gfid is %s Unable to set xattr ", local->loc.path, gfid_local); (*op_errno) = ENOTCONN; goto err; } } } if (uxattr_key_found) { xattrop = dict_new(); if (!xattrop) { gf_msg(this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, 0, "dictionary creation failed for path %s " "for gfid is %s ", local->loc.path, gfid_local); (*op_errno) = ENOMEM; goto err; } local->xattr = dict_ref(xattr); /* Subtract current MDS xattr value to -1 , value of MDS xattr represents no. of times xattr modification failed on non MDS subvols. */ ret = dht_dict_set_array(xattrop, conf->mds_xattr_key, subone, 1); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "dictionary set array failed for path %s " "for gfid is %s ", local->loc.path, gfid_local); if (xattrop) dict_unref(xattrop); (*op_errno) = ret; goto err; } /* Wind a xattrop call to use ref counting approach update mds xattr to -1 before update xattr on hashed subvol and update mds xattr to +1 after update xattr on all non hashed subvol */ if (fd) { STACK_WIND(frame, dht_xattrop_mds_cbk, local->mds_subvol, local->mds_subvol->fops->fxattrop, fd, GF_XATTROP_ADD_ARRAY, xattrop, NULL); } else { STACK_WIND(frame, dht_xattrop_mds_cbk, local->mds_subvol, local->mds_subvol->fops->xattrop, loc, GF_XATTROP_ADD_ARRAY, xattrop, NULL); } if (xattrop) dict_unref(xattrop); } return 0; err: return -1; } int dht_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xattr, int flags, dict_t *xdata) { xlator_t *subvol = NULL; dht_local_t *local = NULL; int op_errno = EINVAL; dht_conf_t *conf = NULL; dht_layout_t *layout = NULL; int ret = -1; int call_cnt = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); VALIDATE_OR_GOTO(fd->inode, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; if (!conf->defrag) GF_IF_INTERNAL_XATTR_GOTO(conf->wild_xattr_name, xattr, op_errno, err); local = dht_local_init(frame, NULL, fd, GF_FOP_FSETXATTR); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } layout = local->layout; if (!layout) { gf_msg_debug(this->name, 0, "no layout for fd=%p", fd); op_errno = EINVAL; goto err; } local->xattr_req = xdata ? dict_ref(xdata) : dict_new(); local->call_cnt = call_cnt = layout->cnt; if (IA_ISDIR(fd->inode->ia_type)) { local->hashed_subvol = NULL; ret = dht_dir_common_set_remove_xattr(frame, this, NULL, fd, xattr, flags, xdata, &op_errno); if (ret) goto err; } else { local->call_cnt = 1; local->rebalance.xattr = dict_ref(xattr); local->rebalance.flags = flags; ret = dict_set_int8(local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); if (ret) { gf_msg_debug(this->name, 0, "Failed to set dictionary key %s for fd=%p", DHT_IATT_IN_XDATA_KEY, fd); } STACK_WIND_COOKIE(frame, dht_file_setxattr_cbk, subvol, subvol, subvol->fops->fsetxattr, fd, xattr, flags, local->xattr_req); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); return 0; } static int dht_checking_pathinfo_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { int i = -1; int ret = -1; char *value = NULL; dht_local_t *local = NULL; dht_conf_t *conf = NULL; xlator_t *prev = NULL; int this_call_cnt = 0; local = frame->local; prev = cookie; conf = this->private; if (op_ret == -1) goto out; ret = dict_get_str(xattr, GF_XATTR_PATHINFO_KEY, &value); if (ret) goto out; if (!strcmp(value, local->key)) { for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == prev) conf->decommissioned_bricks[i] = prev; } } out: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { DHT_STACK_UNWIND(setxattr, frame, local->op_ret, ENOTSUP, NULL); } return 0; } static int dht_nuke_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, NULL); return 0; } static int dht_nuke_dir(call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *tmp) { if (!IA_ISDIR(loc->inode->ia_type)) { DHT_STACK_UNWIND(setxattr, frame, -1, ENOTSUP, NULL); return 0; } /* Setxattr didn't need the parent, but rmdir does. */ loc->parent = inode_parent(loc->inode, NULL, NULL); if (!loc->parent) { DHT_STACK_UNWIND(setxattr, frame, -1, ENOENT, NULL); return 0; } gf_uuid_copy(loc->pargfid, loc->parent->gfid); if (!loc->name && loc->path) { loc->name = strrchr(loc->path, '/'); if (loc->name) { ++(loc->name); } } /* * We do this instead of calling dht_rmdir_do directly for two reasons. * The first is that we want to reuse all of the initialization that * dht_rmdir does, so if it ever changes we'll just follow along. The * second (i.e. why we don't use STACK_WIND_TAIL) is so that we don't * obscure the fact that we came in via this path instead of a genuine * rmdir. That makes debugging just a tiny bit easier. */ STACK_WIND(frame, dht_nuke_dir_cbk, this, this->fops->rmdir, loc, 1, NULL); return 0; } int dht_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr, int flags, dict_t *xdata) { xlator_t *subvol = NULL; dht_local_t *local = NULL; dht_conf_t *conf = NULL; dht_methods_t *methods = NULL; dht_layout_t *layout = NULL; int i = 0; int op_errno = EINVAL; int ret = -1; data_t *tmp = NULL; uint32_t dir_spread = 0; char value[4096] = { 0, }; gf_dht_migrate_data_type_t forced_rebalance = GF_DHT_MIGRATE_DATA; int call_cnt = 0; uint32_t new_hash = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, err); methods = &(conf->methods); /* Rebalance daemon is allowed to set internal keys */ if (!conf->defrag) GF_IF_INTERNAL_XATTR_GOTO(conf->wild_xattr_name, xattr, op_errno, err); local = dht_local_init(frame, loc, NULL, GF_FOP_SETXATTR); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", loc->path); op_errno = EINVAL; goto err; } layout = local->layout; if (!layout) { gf_msg_debug(this->name, 0, "no layout for path=%s", loc->path); op_errno = EINVAL; goto err; } local->call_cnt = call_cnt = layout->cnt; tmp = dict_get(xattr, conf->mds_xattr_key); if (tmp) { op_errno = ENOTSUP; goto err; } tmp = dict_get(xattr, GF_XATTR_FILE_MIGRATE_KEY); if (tmp) { if (IA_ISDIR(loc->inode->ia_type)) { op_errno = ENOTSUP; goto err; } /* TODO: need to interpret the 'value' for more meaning (ie, 'target' subvolume given there, etc) */ memcpy(value, tmp->data, tmp->len); if (strcmp(value, "force") == 0) forced_rebalance = GF_DHT_MIGRATE_DATA_EVEN_IF_LINK_EXISTS; if (conf->decommission_in_progress) forced_rebalance = GF_DHT_MIGRATE_HARDLINK; if (!loc->path) { op_errno = EINVAL; goto err; } if (!local->loc.name) local->loc.name = strrchr(local->loc.path, '/') + 1; if (!local->loc.parent) local->loc.parent = inode_parent(local->loc.inode, NULL, NULL); if ((!local->loc.name) || (!local->loc.parent)) { op_errno = EINVAL; goto err; } if (gf_uuid_is_null(local->loc.pargfid)) gf_uuid_copy(local->loc.pargfid, local->loc.parent->gfid); methods->migration_get_dst_subvol(this, local); if (!local->rebalance.target_node) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "Failed to get hashed subvol for %s", loc->path); op_errno = EINVAL; goto err; } local->rebalance.from_subvol = local->cached_subvol; if (local->rebalance.target_node == local->rebalance.from_subvol) { op_errno = EEXIST; goto err; } if (local->rebalance.target_node) { local->flags = forced_rebalance; ret = dht_start_rebalance_task(this, frame); if (!ret) return 0; gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_REBALANCE_START_FAILED, "%s: failed to create a new rebalance synctask", loc->path); } op_errno = EINVAL; goto err; } tmp = dict_get(xattr, "decommission-brick"); if (tmp) { /* This operation should happen only on '/' */ if (!__is_root_gfid(loc->inode->gfid)) { op_errno = ENOTSUP; goto err; } memcpy(value, tmp->data, min(tmp->len, 4095)); local->key = gf_strdup(value); local->call_cnt = conf->subvolume_cnt; for (i = 0; i < conf->subvolume_cnt; i++) { /* Get the pathinfo, and then compare */ STACK_WIND_COOKIE(frame, dht_checking_pathinfo_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->getxattr, loc, GF_XATTR_PATHINFO_KEY, NULL); } return 0; } tmp = dict_get(xattr, GF_XATTR_FIX_LAYOUT_KEY); if (tmp) { if (!IA_ISDIR(loc->inode->ia_type)) { op_errno = ENOTSUP; goto err; } ret = dict_get_uint32(xattr, "new-commit-hash", &new_hash); if (ret == 0) { gf_msg_debug(this->name, 0, "updating commit hash for %s from %u to %u", uuid_utoa(loc->gfid), layout->commit_hash, new_hash); layout->commit_hash = new_hash; ret = dht_update_commit_hash_for_layout(frame); if (ret) { op_errno = ENOTCONN; goto err; } return ret; } gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_FIX_LAYOUT_INFO, "fixing the layout of %s", loc->path); ret = dht_fix_directory_layout(frame, dht_fix_layout_setxattr_cbk, layout); if (ret) { op_errno = ENOTCONN; goto err; } return ret; } tmp = dict_get(xattr, "distribute.directory-spread-count"); if (tmp) { /* Setxattr value is packed as 'binary', not string */ memcpy(value, tmp->data, min(tmp->len, 4095)); ret = gf_string2uint32(value, &dir_spread); if (!ret && ((dir_spread <= conf->subvolume_cnt) && (dir_spread > 0))) { layout->spread_cnt = dir_spread; ret = dht_fix_directory_layout(frame, dht_common_setxattr_cbk, layout); if (ret) { op_errno = ENOTCONN; goto err; } return ret; } gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_OPERATION_NOT_SUP, "wrong 'directory-spread-count' value (%s)", value); op_errno = ENOTSUP; goto err; } tmp = dict_get(xattr, "glusterfs.dht.nuke"); if (tmp) { return dht_nuke_dir(frame, this, loc, tmp); } local->xattr_req = xdata ? dict_ref(xdata) : dict_new(); if (IA_ISDIR(loc->inode->ia_type)) { local->hashed_subvol = NULL; ret = dht_dir_common_set_remove_xattr(frame, this, loc, NULL, xattr, flags, xdata, &op_errno); if (ret) goto err; } else { local->rebalance.xattr = dict_ref(xattr); local->rebalance.flags = flags; local->call_cnt = 1; ret = dict_set_int8(local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); STACK_WIND_COOKIE(frame, dht_file_setxattr_cbk, subvol, subvol, subvol->fops->setxattr, loc, xattr, flags, local->xattr_req); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); return 0; } static int dht_removexattr2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int op_errno = EINVAL; if (!frame || !frame->local) goto err; local = frame->local; op_errno = local->op_errno; local->call_cnt = 2; /* This is the second attempt */ if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, local->rebalance.xdata); return 0; } if (subvol == NULL) goto err; if (local->fop == GF_FOP_REMOVEXATTR) { STACK_WIND_COOKIE(frame, dht_file_removexattr_cbk, subvol, subvol, subvol->fops->removexattr, &local->loc, local->key, local->xattr_req); } else { STACK_WIND_COOKIE(frame, dht_file_removexattr_cbk, subvol, subvol, subvol->fops->fremovexattr, local->fd, local->key, local->xattr_req); } return 0; err: DHT_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); return 0; } int dht_file_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { int ret = -1; dht_local_t *local = NULL; xlator_t *prev = NULL; struct iatt *stbuf = NULL; inode_t *inode = NULL; xlator_t *subvol1 = NULL, *subvol2 = NULL; local = frame->local; prev = cookie; local->op_errno = op_errno; if ((local->fop == GF_FOP_FREMOVEXATTR) && dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if ((op_ret == -1) && !dht_inode_missing(op_errno)) { gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if (local->call_cnt != 1) goto out; ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf); if ((!op_ret) && !stbuf) { goto out; } local->op_ret = 0; local->rebalance.target_op_fn = dht_removexattr2; if (xdata) local->rebalance.xdata = dict_ref(xdata); /* Phase 2 of migration */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(stbuf)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* Phase 1 of migration */ if (IS_DHT_MIGRATION_PHASE1(stbuf)) { inode = (local->fd) ? local->fd->inode : local->loc.inode; ret = dht_inode_ctx_get_mig_info(this, inode, &subvol1, &subvol2); if (!dht_mig_info_is_invalid(local->cached_subvol, subvol1, subvol2)) { dht_removexattr2(subvol2, frame, 0); return 0; } ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } out: if (local->fop == GF_FOP_REMOVEXATTR) { DHT_STACK_UNWIND(removexattr, frame, op_ret, op_errno, xdata); } else { DHT_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, xdata); } return 0; } int dht_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; dht_layout_t *layout = NULL; int call_cnt = 0; dht_conf_t *conf = NULL; int ret = 0; VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; GF_IF_NATIVE_XATTR_GOTO(conf->wild_xattr_name, key, op_errno, err); VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); local = dht_local_init(frame, loc, NULL, GF_FOP_REMOVEXATTR); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", loc->path); op_errno = EINVAL; goto err; } layout = local->layout; if (!local->layout) { gf_msg_debug(this->name, 0, "no layout for path=%s", loc->path); op_errno = EINVAL; goto err; } local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); local->call_cnt = call_cnt = layout->cnt; local->key = gf_strdup(key); if (key && (strncmp(key, conf->mds_xattr_key, strlen(key)) == 0)) { op_errno = ENOTSUP; goto err; } if (IA_ISDIR(loc->inode->ia_type)) { local->hashed_subvol = NULL; ret = dht_dir_common_set_remove_xattr(frame, this, loc, NULL, NULL, 0, local->xattr_req, &op_errno); if (ret) goto err; } else { local->call_cnt = 1; ret = dict_set_int8(local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to " "set dictionary key %s for %s", DHT_IATT_IN_XDATA_KEY, loc->path); } STACK_WIND_COOKIE(frame, dht_file_removexattr_cbk, subvol, subvol, subvol->fops->removexattr, loc, key, local->xattr_req); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); return 0; } int dht_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; dht_layout_t *layout = NULL; int call_cnt = 0; dht_conf_t *conf = 0; int ret = 0; VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; GF_IF_NATIVE_XATTR_GOTO(conf->wild_xattr_name, key, op_errno, err); VALIDATE_OR_GOTO(frame, err); local = dht_local_init(frame, NULL, fd, GF_FOP_FREMOVEXATTR); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for inode=%s", uuid_utoa(fd->inode->gfid)); op_errno = EINVAL; goto err; } layout = local->layout; if (!local->layout) { gf_msg_debug(this->name, 0, "no layout for inode=%s", uuid_utoa(fd->inode->gfid)); op_errno = EINVAL; goto err; } local->xattr_req = xdata ? dict_ref(xdata) : dict_new(); local->call_cnt = call_cnt = layout->cnt; local->key = gf_strdup(key); if (IA_ISDIR(fd->inode->ia_type)) { local->hashed_subvol = NULL; ret = dht_dir_common_set_remove_xattr(frame, this, NULL, fd, NULL, 0, local->xattr_req, &op_errno); if (ret) goto err; } else { local->call_cnt = 1; ret = dict_set_int8(local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to " "set dictionary key %s for fd=%p", DHT_IATT_IN_XDATA_KEY, fd); } STACK_WIND_COOKIE(frame, dht_file_removexattr_cbk, subvol, subvol, subvol->fops->fremovexattr, fd, key, local->xattr_req); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fremovexattr, frame, -1, op_errno, NULL); return 0; } int dht_fd_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; local = frame->local; prev = cookie; LOCK(&frame->lock); { if (op_ret == -1) { local->op_errno = op_errno; UNLOCK(&frame->lock); gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto post_unlock; } local->op_ret = 0; } UNLOCK(&frame->lock); post_unlock: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) DHT_STACK_UNWIND(open, frame, local->op_ret, local->op_errno, local->fd, NULL); return 0; } /* * dht_normalize_stats - */ static void dht_normalize_stats(struct statvfs *buf, unsigned long bsize, unsigned long frsize) { double factor = 0; if (buf->f_bsize != bsize) { buf->f_bsize = bsize; } if (buf->f_frsize != frsize) { factor = ((double)buf->f_frsize) / frsize; buf->f_frsize = frsize; buf->f_blocks = (fsblkcnt_t)(factor * buf->f_blocks); buf->f_bfree = (fsblkcnt_t)(factor * buf->f_bfree); buf->f_bavail = (fsblkcnt_t)(factor * buf->f_bavail); } } static int dht_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct statvfs *statvfs, dict_t *xdata) { gf_boolean_t event = _gf_false; qdstatfs_action_t action = qdstatfs_action_OFF; dht_local_t *local = NULL; dht_conf_t *conf = this->private; int this_call_cnt = 0; int bsize = 0; int frsize = 0; GF_UNUSED int ret = 0; unsigned long new_usage = 0; unsigned long cur_usage = 0; int32_t simple_quota = 0; local = frame->local; GF_ASSERT(local); if (xdata) { ret = dict_get_int8(xdata, "quota-deem-statfs", (int8_t *)&event); if (IS_ERROR(ret)) { gf_msg_trace(this->name, ENOENT, "Failed to get key = quota-deem-statfs"); } ret = dict_get_int32(xdata, "simple-quota", &simple_quota); if (IS_ERROR(ret)) { gf_msg_trace(this->name, ENOENT, "Failed to get key = simple-quota"); } } LOCK(&frame->lock); { if (simple_quota) { local->simple_quota = true; } if (op_ret == -1) { local->op_errno = op_errno; /* overload file_count variable for number of failures */ local->file_count++; goto unlock; } if (!statvfs) { op_errno = EINVAL; local->op_ret = -1; goto unlock; } local->op_ret = 0; if (local->quota_deem_statfs) { if (event == _gf_true) { action = qdstatfs_action_COMPARE; } else { action = qdstatfs_action_NEGLECT; } } else { if (event == _gf_true) { action = qdstatfs_action_REPLACE; local->quota_deem_statfs = _gf_true; } } if (local->quota_deem_statfs) { switch (action) { case qdstatfs_action_NEGLECT: goto unlock; case qdstatfs_action_REPLACE: local->statvfs = *statvfs; goto unlock; case qdstatfs_action_COMPARE: new_usage = statvfs->f_blocks - statvfs->f_bfree; cur_usage = local->statvfs.f_blocks - local->statvfs.f_bfree; /* Take the max of the usage from subvols */ if (new_usage >= cur_usage) local->statvfs = *statvfs; goto unlock; default: break; } } if (local->statvfs.f_bsize != 0) { bsize = max(local->statvfs.f_bsize, statvfs->f_bsize); frsize = max(local->statvfs.f_frsize, statvfs->f_frsize); dht_normalize_stats(&local->statvfs, bsize, frsize); dht_normalize_stats(statvfs, bsize, frsize); } else { local->statvfs.f_bsize = statvfs->f_bsize; local->statvfs.f_frsize = statvfs->f_frsize; local->statvfs.f_fsid = statvfs->f_fsid; local->statvfs.f_flag = statvfs->f_flag; local->statvfs.f_namemax = statvfs->f_namemax; } /* when simple-quota is present, DHT acts as aggregator */ if (local->simple_quota) { if (!local->statvfs.f_blocks) { local->statvfs = *statvfs; } else { /* Used space reduces */ int64_t usage = statvfs->f_blocks - statvfs->f_bfree; int64_t fusage = statvfs->f_files - statvfs->f_ffree; if (local->statvfs.f_bfree >= usage) { local->statvfs.f_bfree -= usage; local->statvfs.f_bavail -= usage; } else { local->statvfs.f_bfree = 0; local->statvfs.f_bavail = 0; } if (local->statvfs.f_ffree >= fusage) { local->statvfs.f_ffree -= fusage; local->statvfs.f_favail -= fusage; } else { local->statvfs.f_ffree = 0; local->statvfs.f_favail = 0; } } } else { local->statvfs.f_blocks += statvfs->f_blocks; local->statvfs.f_files += statvfs->f_files; local->statvfs.f_bfree += statvfs->f_bfree; local->statvfs.f_bavail += statvfs->f_bavail; local->statvfs.f_ffree += statvfs->f_ffree; local->statvfs.f_favail += statvfs->f_favail; } } unlock: UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if (local->simple_quota) { /* Even if 1 subvolume passes df, make sure to send the Avg usage in * this case */ if ((local->file_count > 0) && (local->file_count < conf->subvolume_cnt)) { /* handle averaging the block usage */ int64_t avg_usage = (local->statvfs.f_blocks - local->statvfs.f_bfree) / (conf->subvolume_cnt - local->file_count); int64_t update = avg_usage * local->file_count; if (update > local->statvfs.f_bfree) { local->statvfs.f_bfree = 0; local->statvfs.f_bavail = 0; } else { local->statvfs.f_bfree -= update; local->statvfs.f_bavail -= update; } } } DHT_STACK_UNWIND(statfs, frame, local->op_ret, local->op_errno, &local->statvfs, xdata); } return 0; } int dht_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int op_errno = -1; int i = -1; inode_t *inode = NULL; inode_table_t *itable = NULL; static uuid_t root_gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; loc_t newloc = { 0, }; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = dht_local_init(frame, NULL, NULL, GF_FOP_STATFS); if (!local) { op_errno = ENOMEM; goto err; } if (loc->inode && !IA_ISDIR(loc->inode->ia_type)) { itable = loc->inode->table; if (!itable) { op_errno = EINVAL; goto err; } loc = &local->loc2; inode = inode_find(itable, root_gfid); if (!inode) { op_errno = EINVAL; goto err; } dht_build_root_loc(inode, &newloc); loc = &newloc; } local->call_cnt = conf->subvolume_cnt; for (i = 0; i < conf->subvolume_cnt; i++) { STACK_WIND(frame, dht_statfs_cbk, conf->subvolumes[i], conf->subvolumes[i]->fops->statfs, loc, xdata); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); return 0; } int dht_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int op_errno = -1; int i = -1; int ret = 0; gf_boolean_t new_xdata = _gf_false; xlator_t **subvolumes = NULL; int call_count = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = dht_local_init(frame, loc, fd, GF_FOP_OPENDIR); if (!local) { op_errno = ENOMEM; goto err; } local->first_up_subvol = dht_first_up_subvol(this); if (!xdata) { xdata = dict_new(); if (!xdata) { op_errno = ENOMEM; goto err; } new_xdata = _gf_true; } ret = dict_set_uint32(xdata, conf->link_xattr_name, 256); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value : key = %s", conf->link_xattr_name); /* dht_readdirp will wind to all subvols so open has to be sent to * all subvols whether or not conf->local_subvols is set */ call_count = local->call_cnt = conf->subvolume_cnt; subvolumes = conf->subvolumes; /* In case of parallel-readdir, the readdir-ahead will be loaded * below dht, in this case, if we want to enable or disable SKIP_DIRs * it has to be done in opendir, so that prefetching logic in * readdir-ahead, honors it */ for (i = 0; i < call_count; i++) { if (conf->readdir_optimize == _gf_true) { if (subvolumes[i] != local->first_up_subvol) { ret = dict_set_int32(xdata, GF_READDIR_SKIP_DIRS, 1); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary" " value :key = %s, ret:%d", GF_READDIR_SKIP_DIRS, ret); } } STACK_WIND_COOKIE(frame, dht_fd_cbk, subvolumes[i], subvolumes[i], subvolumes[i]->fops->opendir, loc, fd, xdata); dict_del(xdata, GF_READDIR_SKIP_DIRS); } if (new_xdata) dict_unref(xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(opendir, frame, -1, op_errno, NULL, NULL); return 0; } /* dht_readdirp_cbk creates a new dentry and dentry->inode is not assigned. This functions assigns an inode if all of the following conditions are true: * DHT has only one child. In this case the entire layout is present on this single child and hence we can set complete layout in inode. * backend has complete layout and there are no anomalies in it and from this information layout can be constructed and set in inode. */ static void dht_populate_inode_for_dentry(xlator_t *this, xlator_t *subvol, gf_dirent_t *entry, gf_dirent_t *orig_entry) { dht_layout_t *layout = NULL; int ret = 0; loc_t loc = { 0, }; if (gf_uuid_is_null(orig_entry->d_stat.ia_gfid)) { /* this skips the '..' entry for the root of the volume */ return; } gf_uuid_copy(loc.gfid, orig_entry->d_stat.ia_gfid); loc.inode = inode_ref(orig_entry->inode); if (is_revalidate(&loc)) { goto out; } layout = dht_layout_new(this, 1); if (!layout) goto out; ret = dht_layout_merge(this, layout, subvol, 0, 0, orig_entry->dict); if (!ret) { ret = dht_layout_normalize(this, &loc, layout); if (ret == 0) { dht_layout_set(this, orig_entry->inode, layout); entry->inode = inode_ref(orig_entry->inode); layout = NULL; } } if (layout) dht_layout_unref(layout); out: loc_wipe(&loc); return; } /* Execute a READDIR request if no other request is in progress. Otherwise * queue it to be executed when the current one finishes. * * When parallel-readdir is enabled and directory contents are cached, the * callback of a readdirp will be called before returning from STACK_WIND. * If the returned contents are not useful for DHT, and the buffer is not * yet full, a nested readdirp request will be sent. This means that there * will be many recursive calls. In the worst case there might be a stack * overflow. * * To avoid this, we only wind a request if no other request is being wound. * If there's another request, we simple store the values for the next call. * When the thread processing the current wind completes it, it will take * the new arguments and send the request from the top level stack. */ static void dht_queue_readdir(call_frame_t *frame, xlator_t *xl, off_t offset, fop_readdir_cbk_t cbk) { dht_local_t *local; int32_t queue; local = frame->local; local->queue_xl = xl; local->queue_offset = offset; if (uatomic_add_return(&local->queue, 1) == 1) { /* If we are here it means that we are the first one to send a * readdir request. Any attempt to send more readdir requests will * find local->queue > 1, so it won't do anything. The needed data * to send the request has been stored into local->queue_*. * * Note: this works because we will only have 1 additional request * at most (the one called by the cbk function) while we are * processing another readdir. */ do { STACK_WIND_COOKIE(frame, cbk, local->queue_xl, local->queue_xl, local->queue_xl->fops->readdir, local->fd, local->size, local->queue_offset, local->xattr); /* If a new readdirp request has been added before returning * from winding, we process it. */ } while ((queue = uatomic_sub_return(&local->queue, 1)) > 0); if (queue < 0) { /* A negative value means that an unwind has been called before * returning from the previous wind. This means that 'local' is * not needed anymore and must be destroyed. */ dht_local_wipe(local); } } } /* Execute a READDIRP request if no other request is in progress. Otherwise * queue it to be executed when the current one finishes. */ static void dht_queue_readdirp(call_frame_t *frame, xlator_t *xl, off_t offset, fop_readdirp_cbk_t cbk) { dht_local_t *local; int32_t queue; local = frame->local; local->queue_xl = xl; local->queue_offset = offset; /* Check dht_queue_readdir() comments for an explanation of this. */ if (uatomic_add_return(&local->queue, 1) == 1) { do { STACK_WIND_COOKIE(frame, cbk, local->queue_xl, local->queue_xl, local->queue_xl->fops->readdirp, local->fd, local->size, local->queue_offset, local->xattr); } while ((queue = uatomic_sub_return(&local->queue, 1)) > 0); if (queue < 0) { /* A negative value means that an unwind has been called before * returning from the previous wind. This means that 'local' is * not needed anymore and must be destroyed. */ dht_local_wipe(local); } } } /* Posix returns op_errno = ENOENT to indicate that there are no more * entries */ static int dht_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *orig_entries, dict_t *xdata) { dht_local_t *local = NULL; gf_dirent_t entries; gf_dirent_t *orig_entry = NULL; gf_dirent_t *entry = NULL; xlator_t *prev = NULL; xlator_t *next_subvol = NULL; off_t next_offset = 0; int count = 0; dht_layout_t *layout = NULL; dht_conf_t *conf = NULL; dht_methods_t *methods = NULL; xlator_t *subvol = 0; xlator_t *hashed_subvol = 0; int ret = 0; int readdir_optimize = 0; inode_table_t *itable = NULL; inode_t *inode = NULL; gf_boolean_t skip_hashed_check = _gf_false; INIT_LIST_HEAD(&entries.list); prev = cookie; local = frame->local; GF_VALIDATE_OR_GOTO(this->name, local->fd, unwind); itable = local->fd->inode->table; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, unwind); methods = &(conf->methods); if (op_ret <= 0) { goto done; } /* Why aren't we skipping DHT entirely in case of a single subvol? * Because if this was a larger volume earlier and all but one subvol * was removed, there might be stale linkto files on the subvol. */ if (conf->subvolume_cnt == 1) { /* return all directory and file entries except * linkto files for a single child DHT */ skip_hashed_check = _gf_true; } if (!local->layout) local->layout = dht_layout_get(this, local->fd->inode); layout = local->layout; /* This will skip the entries on the subvol without a layout, * hence preventing the crash but rmdir might fail with * "directory not empty" errors*/ if (layout == NULL) goto done; if (conf->readdir_optimize == _gf_true) readdir_optimize = 1; gf_msg_debug(this->name, 0, "Processing entries from %s", prev->name); list_for_each_entry(orig_entry, (&orig_entries->list), list) { next_offset = orig_entry->d_off; gf_msg_debug(this->name, 0, "%s: entry = %s, type = %d", prev->name, orig_entry->d_name, orig_entry->d_type); if (IA_ISINVAL(orig_entry->d_stat.ia_type)) { /*stat failed somewhere- display this entry but the data may * be inaccurate. */ gf_msg_debug(this->name, EINVAL, "Invalid stat for %s (gfid %s)", orig_entry->d_name, uuid_utoa(orig_entry->d_stat.ia_gfid)); } if (check_is_linkfile(NULL, (&orig_entry->d_stat), orig_entry->dict, conf->link_xattr_name)) { gf_msg_debug(this->name, 0, "%s: %s is a linkto file", prev->name, orig_entry->d_name); continue; } if (skip_hashed_check) { goto list; } if (check_is_dir(NULL, (&orig_entry->d_stat), NULL)) { /*Directory entries filtering : * a) If rebalance is running, pick from first_up_subvol * b) (rebalance not running)hashed subvolume is NULL or * down then filter in first_up_subvolume. Other wise the * corresponding hashed subvolume will take care of the * directory entry. */ if (readdir_optimize) { if (prev == local->first_up_subvol) goto list; else continue; } hashed_subvol = methods->layout_search(this, layout, orig_entry->d_name); if (prev == hashed_subvol) goto list; if ((hashed_subvol && dht_subvol_status(conf, hashed_subvol)) || (prev != local->first_up_subvol)) continue; goto list; } list: entry = gf_dirent_for_name2(orig_entry->d_name, orig_entry->d_len, orig_entry->d_ino, orig_entry->d_off, orig_entry->d_type, &orig_entry->d_stat); if (!entry) { goto unwind; } /* Do this if conf->search_unhashed is set to "auto" */ if (conf->search_unhashed == GF_DHT_LOOKUP_UNHASHED_AUTO) { subvol = methods->layout_search(this, layout, orig_entry->d_name); if (!subvol || (subvol != prev)) { /* TODO: Count the number of entries which need linkfile to prove its existence in fs */ layout->search_unhashed++; } } if (orig_entry->dict) entry->dict = dict_ref(orig_entry->dict); /* making sure we set the inode ctx right with layout, currently possible only for non-directories, so for directories don't set entry inodes */ if (IA_ISDIR(entry->d_stat.ia_type)) { entry->d_stat.ia_blocks = DHT_DIR_STAT_BLOCKS; entry->d_stat.ia_size = DHT_DIR_STAT_SIZE; if (orig_entry->inode) { dht_inode_ctx_time_update(orig_entry->inode, this, NULL, &entry->d_stat); if (conf->subvolume_cnt == 1) { dht_populate_inode_for_dentry(this, prev, entry, orig_entry); } } } else { if (orig_entry->dict && dict_get(orig_entry->dict, conf->link_xattr_name)) { /* Strip out the S and T flags set by rebalance*/ DHT_STRIP_PHASE1_FLAGS(&entry->d_stat); } if (orig_entry->inode) { ret = dht_layout_preset(this, prev, orig_entry->inode); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_SET_FAILED, "failed to link the layout " "in inode for %s", orig_entry->d_name); entry->inode = inode_ref(orig_entry->inode); } else if (itable) { /* * orig_entry->inode might be null if any upper * layer xlators below client set to null, to * force a lookup on the inode even if the inode * is present in the inode table. In that case * we just update the ctx to make sure we didn't * missed anything. */ inode = inode_find(itable, orig_entry->d_stat.ia_gfid); if (inode) { ret = dht_layout_preset(this, prev, inode); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_SET_FAILED, "failed to link the layout" " in inode for %s", orig_entry->d_name); inode_unref(inode); inode = NULL; } } } gf_msg_debug(this->name, 0, "%s: Adding entry = %s", prev->name, entry->d_name); list_add_tail(&entry->list, &entries.list); count++; } done: /* We need to ensure that only the last subvolume's end-of-directory * notification is respected so that directory reading does not stop * before all subvolumes have been read. That could happen because the * posix for each subvolume sends a ENOENT on end-of-directory but in * distribute we're not concerned only with a posix's view of the * directory but the aggregated namespace' view of the directory. * Possible values: * op_ret == 0 and op_errno != 0 * if op_errno != ENOENT : Error.Unwind. * if op_errno == ENOENT : There are no more entries on this subvol. * Move to the next one. * op_ret > 0 and count == 0 : * The subvol returned entries to dht but all were stripped out. * For example, if they were linkto files or dirs where * hashed_subvol != prev. Try to get some entries by winding * to the next subvol. This can be dangerous if parallel readdir * is enabled as it grows the stack. * * op_ret > 0 and count > 0: * We found some entries. Unwind even if the buffer is not full. * */ op_ret = count; if (count == 0) { /* non-zero next_offset means that * EOF is not yet hit on the current subvol */ if ((next_offset == 0) || (op_errno == ENOENT)) { next_offset = 0; next_subvol = dht_subvol_next(this, prev); } else { next_subvol = prev; } if (!next_subvol) { goto unwind; } if (conf->readdir_optimize == _gf_true) { if (next_subvol != local->first_up_subvol) { ret = dict_set_int32(local->xattr, GF_READDIR_SKIP_DIRS, 1); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value" ":key = %s", GF_READDIR_SKIP_DIRS); } else { dict_del(local->xattr, GF_READDIR_SKIP_DIRS); } } dht_queue_readdirp(frame, next_subvol, next_offset, dht_readdirp_cbk); return 0; } unwind: /* We need to ensure that only the last subvolume's end-of-directory * notification is respected so that directory reading does not stop * before all subvolumes have been read. That could happen because the * posix for each subvolume sends a ENOENT on end-of-directory but in * distribute we're not concerned only with a posix's view of the * directory but the aggregated namespace' view of the directory. */ if (op_ret < 0) op_ret = 0; if (prev != dht_last_up_subvol(this)) op_errno = 0; /* If we are inside a recursive call (or not inside a recursive call but * the cbk is completed before the wind returns), local->queue will be 1. * In this case we cannot destroy 'local' because it will be needed by * the caller of STACK_WIND. In this case, we decrease the value to let * the caller know that the operation has terminated and it must destroy * 'local'. If local->queue 0, we can destroy it here because there are * no other users. */ if (uatomic_sub_return(&local->queue, 1) >= 0) { frame->local = NULL; } DHT_STACK_UNWIND(readdirp, frame, op_ret, op_errno, &entries, NULL); gf_dirent_free(&entries); return 0; } static int dht_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *orig_entries, dict_t *xdata) { dht_local_t *local = NULL; gf_dirent_t entries; gf_dirent_t *orig_entry = NULL; gf_dirent_t *entry = NULL; xlator_t *prev = NULL; xlator_t *next_subvol = NULL; off_t next_offset = 0; int count = 0; dht_layout_t *layout = 0; xlator_t *subvol = 0; dht_conf_t *conf = NULL; dht_methods_t *methods = NULL; gf_boolean_t skip_hashed_check = _gf_false; gf_boolean_t readdir_optimize = _gf_false; gf_boolean_t add = _gf_false; INIT_LIST_HEAD(&entries.list); prev = cookie; local = frame->local; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, done); readdir_optimize = conf->readdir_optimize; methods = &(conf->methods); if (op_ret <= 0) goto done; if (!local->layout) local->layout = dht_layout_get(this, local->fd->inode); layout = local->layout; gf_msg_debug(this->name, 0, "Processing entries from %s", prev->name); if (conf->subvolume_cnt == 1) { /*return everything*/ skip_hashed_check = _gf_true; count = op_ret; goto done; } list_for_each_entry(orig_entry, (&orig_entries->list), list) { next_offset = orig_entry->d_off; subvol = methods->layout_search(this, layout, orig_entry->d_name); gf_msg_debug(this->name, 0, "%s: entry = %s, type = %d %p, %p", prev->name, orig_entry->d_name, orig_entry->d_type, subvol, prev); /* a) If rebalance is running, pick from first_up_subvol */ if (DT_ISDIR(orig_entry->d_type) && readdir_optimize) { if (prev == local->first_up_subvol) { add = _gf_true; } else { continue; } } else if (!subvol || (subvol == prev)) { add = _gf_true; } if (add) { add = _gf_false; entry = gf_dirent_for_name2(orig_entry->d_name, orig_entry->d_len, orig_entry->d_ino, orig_entry->d_off, orig_entry->d_type, NULL); if (!entry) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "Memory allocation failed "); goto unwind; } gf_msg_debug(this->name, 0, "%s: Adding = entry %s", prev->name, entry->d_name); list_add_tail(&entry->list, &entries.list); count++; } } done: op_ret = count; /* We need to ensure that only the last subvolume's end-of-directory * notification is respected so that directory reading does not stop * before all subvolumes have been read. That could happen because the * posix for each subvolume sends a ENOENT on end-of-directory but in * distribute we're not concerned only with a posix's view of the * directory but the aggregated namespace' view of the directory. */ if (count == 0) { if ((next_offset == 0) || (op_errno == ENOENT)) { next_offset = 0; next_subvol = dht_subvol_next(this, prev); } else { next_subvol = prev; } if (!next_subvol) { goto unwind; } dht_queue_readdir(frame, next_subvol, next_offset, dht_readdir_cbk); return 0; } unwind: /* We need to ensure that only the last subvolume's end-of-directory * notification is respected so that directory reading does not stop * before all subvolumes have been read. That could happen because the * posix for each subvolume sends a ENOENT on end-of-directory but in * distribute we're not concerned only with a posix's view of the * directory but the aggregated namespace' view of the directory. */ if (prev != dht_last_up_subvol(this)) op_errno = 0; /* If we are inside a recursive call (or not inside a recursive call but * the cbk is completed before the wind returns), local->queue will be 1. * In this case we cannot destroy 'local' because it will be needed by * the caller of STACK_WIND. In this case, we decrease the value to let * the caller know that the operation has terminated and it must destroy * 'local'. If local->queue 0, we can destroy it here because there are * no other users. */ if (uatomic_sub_return(&local->queue, 1) >= 0) { frame->local = NULL; } if (!skip_hashed_check) { DHT_STACK_UNWIND(readdir, frame, op_ret, op_errno, &entries, NULL); gf_dirent_free(&entries); } else { DHT_STACK_UNWIND(readdir, frame, op_ret, op_errno, orig_entries, NULL); } return 0; } static int dht_do_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t yoff, int whichop, dict_t *dict) { dht_local_t *local = NULL; int op_errno = -1; xlator_t *xvol = NULL; int ret = 0; dht_conf_t *conf = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = dht_local_init(frame, NULL, NULL, whichop); if (!local) { op_errno = ENOMEM; goto err; } local->fd = fd_ref(fd); local->size = size; local->xattr_req = (dict) ? dict_ref(dict) : NULL; local->first_up_subvol = dht_first_up_subvol(this); local->op_ret = -1; dht_deitransform(this, yoff, &xvol); /* TODO: do proper readdir */ if (whichop == GF_FOP_READDIRP) { if (dict) local->xattr = dict_ref(dict); else local->xattr = dict_new(); if (local->xattr) { ret = dict_set_uint32(local->xattr, conf->link_xattr_name, 256); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value" " : key = %s", conf->link_xattr_name); if (conf->readdir_optimize == _gf_true) { if (xvol != local->first_up_subvol) { ret = dict_set_int32(local->xattr, GF_READDIR_SKIP_DIRS, 1); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set " "dictionary value: " "key = %s", GF_READDIR_SKIP_DIRS); } else { dict_del(local->xattr, GF_READDIR_SKIP_DIRS); } } if (conf->subvolume_cnt == 1) { ret = dict_set_uint32(local->xattr, conf->xattr_name, 4 * 4); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary " "value:key = %s ", conf->xattr_name); } } } dht_queue_readdirp(frame, xvol, yoff, dht_readdirp_cbk); } else { dht_queue_readdir(frame, xvol, yoff, dht_readdir_cbk); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(readdir, frame, -1, op_errno, NULL, NULL); return 0; } int dht_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t yoff, dict_t *xdata) { int op = GF_FOP_READDIR; dht_conf_t *conf = NULL; int i = 0; conf = this->private; if (!conf) goto out; for (i = 0; i < conf->subvolume_cnt; i++) { if (!conf->subvolume_status[i]) { op = GF_FOP_READDIRP; break; } } if (conf->use_readdirp) op = GF_FOP_READDIRP; out: dht_do_readdir(frame, this, fd, size, yoff, op, 0); return 0; } int dht_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t yoff, dict_t *dict) { dht_do_readdir(frame, this, fd, size, yoff, GF_FOP_READDIRP, dict); return 0; } static int dht_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; local = frame->local; LOCK(&frame->lock); { if (op_ret == -1) local->op_errno = op_errno; else if (op_ret == 0) local->op_ret = 0; } UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) DHT_STACK_UNWIND(fsyncdir, frame, local->op_ret, local->op_errno, xdata); return 0; } int dht_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int op_errno = -1; int i = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = dht_local_init(frame, NULL, NULL, GF_FOP_FSYNCDIR); if (!local) { op_errno = ENOMEM; goto err; } local->fd = fd_ref(fd); local->call_cnt = conf->subvolume_cnt; for (i = 0; i < conf->subvolume_cnt; i++) { STACK_WIND(frame, dht_fsyncdir_cbk, conf->subvolumes[i], conf->subvolumes[i]->fops->fsyncdir, fd, datasync, xdata); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fsyncdir, frame, -1, op_errno, NULL); return 0; } int dht_newfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { xlator_t *prev = NULL; int ret = -1; dht_local_t *local = NULL; if (op_ret == -1) goto out; local = frame->local; if (!local) { op_ret = -1; op_errno = EINVAL; goto out; } prev = cookie; if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, preparent, postparent); } ret = dht_layout_preset(this, prev, inode); if (ret < 0) { gf_msg_debug(this->name, EINVAL, "could not set pre-set layout for subvolume %s", prev ? prev->name : NULL); op_ret = -1; op_errno = EINVAL; goto out; } if (local->linked == _gf_true) dht_linkfile_attr_heal(frame, this); out: /* * FIXME: ia_size and st_blocks of preparent and postparent do not have * correct values. since, preparent and postparent buffers correspond * to a directory these two members should have values equal to sum of * corresponding values from each of the subvolume. * See dht_iatt_merge for reference. */ DHT_STRIP_PHASE1_FLAGS(stbuf); dht_set_fixed_dir_stat(postparent); dht_set_fixed_dir_stat(preparent); if (local && local->lock[0].layout.parent_layout.locks) { /* store op_errno for failure case*/ local->op_errno = op_errno; local->refresh_layout_unlock(frame, op_ret, 1); if (op_ret == 0) { DHT_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); } } else { DHT_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); } return 0; } static int dht_mknod_linkfile_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *cached_subvol = NULL; dht_conf_t *conf = NULL; local = frame->local; if (!local || !local->cached_subvol) { op_errno = EINVAL; goto err; } if (op_ret == -1) { local->op_errno = op_errno; goto err; } conf = this->private; if (!conf) { local->op_errno = EINVAL; op_errno = EINVAL; goto err; } cached_subvol = local->cached_subvol; if (local->params) { dict_del(local->params, conf->link_xattr_name); dict_del(local->params, GLUSTERFS_INTERNAL_FOP_KEY); } STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)cached_subvol, cached_subvol, cached_subvol->fops->mknod, &local->loc, local->mode, local->rdev, local->umask, local->params); return 0; err: if (local && local->lock[0].layout.parent_layout.locks) { local->refresh_layout_unlock(frame, -1, 1); } else { DHT_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); } return 0; } static int dht_mknod_wind_to_avail_subvol(call_frame_t *frame, xlator_t *this, xlator_t *subvol, loc_t *loc, dev_t rdev, mode_t mode, mode_t umask, dict_t *params) { dht_local_t *local = NULL; xlator_t *avail_subvol = NULL; local = frame->local; if (!dht_is_subvol_filled(this, subvol)) { gf_msg_debug(this->name, 0, "creating %s on %s", loc->path, subvol->name); STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)subvol, subvol, subvol->fops->mknod, loc, mode, rdev, umask, params); } else { avail_subvol = dht_free_disk_available_subvol(this, subvol, local); if (avail_subvol != subvol) { local->params = dict_ref(params); local->rdev = rdev; local->mode = mode; local->umask = umask; local->cached_subvol = avail_subvol; local->hashed_subvol = subvol; gf_msg_debug(this->name, 0, "creating %s on %s (link at %s)", loc->path, avail_subvol->name, subvol->name); dht_linkfile_create(frame, dht_mknod_linkfile_create_cbk, this, avail_subvol, subvol, loc); goto out; } gf_msg_debug(this->name, 0, "creating %s on %s", loc->path, subvol->name); STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)subvol, subvol, subvol->fops->mknod, loc, mode, rdev, umask, params); } out: return 0; } static int32_t dht_mknod_do(call_frame_t *frame) { dht_local_t *local = NULL; dht_layout_t *refreshed = NULL; xlator_t *subvol = NULL; xlator_t *this = NULL; dht_conf_t *conf = NULL; dht_methods_t *methods = NULL; local = frame->local; this = THIS; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, err); methods = &(conf->methods); /* We don't need parent_loc anymore */ loc_wipe(&local->loc); loc_copy(&local->loc, &local->loc2); loc_wipe(&local->loc2); refreshed = local->selfheal.refreshed_layout; subvol = methods->layout_search(this, refreshed, local->loc.name); if (!subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "no subvolume in " "layout for path=%s", local->loc.path); local->op_errno = ENOENT; goto err; } dht_mknod_wind_to_avail_subvol(frame, this, subvol, &local->loc, local->rdev, local->mode, local->umask, local->params); return 0; err: local->refresh_layout_unlock(frame, -1, 1); return 0; } static int32_t dht_mknod_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { DHT_STACK_DESTROY(frame); return 0; } static int32_t dht_mknod_finish(call_frame_t *frame, int op_ret, int invoke_cbk) { dht_local_t *local = NULL, *lock_local = NULL; call_frame_t *lock_frame = NULL; int lock_count = 0; dht_lock_wrap_t *parent_layout, *lock_local_parent_layout; local = frame->local; parent_layout = &local->lock[0].layout.parent_layout; lock_count = dht_lock_count(parent_layout); if (lock_count == 0) goto done; lock_frame = copy_frame(frame); if (lock_frame == NULL) { goto done; } lock_local = dht_local_init(lock_frame, &local->loc, NULL, lock_frame->root->op); if (lock_local == NULL) { goto done; } lock_local_parent_layout = &lock_local->lock[0].layout.parent_layout; dht_lock_array_copy(parent_layout, lock_local_parent_layout); dht_lock_array_reset(parent_layout); dht_unlock_inodelk(lock_frame, lock_local_parent_layout, dht_mknod_unlock_cbk); lock_frame = NULL; done: if (lock_frame != NULL) { DHT_STACK_DESTROY(lock_frame); } if (op_ret == 0) return 0; DHT_STACK_UNWIND(mknod, frame, op_ret, local->op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t dht_mknod_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (!local) { goto err; } if (op_ret < 0) { gf_msg("DHT", GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, "mknod lock failed for file: %s", local->loc2.name); local->op_errno = op_errno; goto err; } local->refresh_layout_unlock = dht_mknod_finish; local->refresh_layout_done = dht_mknod_do; dht_refresh_layout(frame); return 0; err: if (local) dht_mknod_finish(frame, -1, 0); else DHT_STACK_UNWIND(mknod, frame, -1, EINVAL, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t dht_mknod_lock(call_frame_t *frame, xlator_t *subvol) { dht_local_t *local = NULL; int count = 1, ret = -1; dht_lock_t **lk_array = NULL; dht_lock_wrap_t *parent_layout; local = frame->local; lk_array = GF_CALLOC(count, sizeof(*lk_array), gf_common_mt_pointer); if (lk_array == NULL) goto err; lk_array[0] = dht_lock_new(frame->this, subvol, &local->loc, F_RDLCK, DHT_LAYOUT_HEAL_DOMAIN, NULL, IGNORE_ENOENT_ESTALE); if (lk_array[0] == NULL) goto err; parent_layout = &local->lock[0].layout.parent_layout; parent_layout->locks = lk_array; parent_layout->lk_count = count; ret = dht_blocking_inodelk(frame, lk_array, count, dht_mknod_lock_cbk); if (ret < 0) { dht_lock_array_reset(parent_layout); goto err; } return 0; err: if (lk_array != NULL) { dht_lock_array_free(lk_array, count); GF_FREE(lk_array); } return -1; } static int dht_refresh_parent_layout_resume(call_frame_t *frame, int ret, int invoke_cbk) { dht_local_t *local = NULL, *parent_local = NULL; call_stub_t *stub = NULL; call_frame_t *parent_frame = NULL; local = frame->local; stub = local->stub; local->stub = NULL; parent_frame = stub->frame; parent_local = parent_frame->local; if (ret < 0) { parent_local->op_ret = -1; parent_local->op_errno = local->op_errno ? local->op_errno : EIO; } else { parent_local->op_ret = 0; } call_resume(stub); DHT_STACK_DESTROY(frame); return 0; } static int dht_refresh_parent_layout_done(call_frame_t *frame) { dht_local_t *local = NULL; int ret = 0; local = frame->local; if (local->op_ret < 0) { ret = -1; goto resume; } dht_layout_set(frame->this, local->loc.inode, local->selfheal.refreshed_layout); resume: dht_refresh_parent_layout_resume(frame, ret, 1); return 0; } static int dht_handle_parent_layout_change(xlator_t *this, call_stub_t *stub) { call_frame_t *refresh_frame = NULL, *frame = NULL; dht_local_t *refresh_local = NULL, *local = NULL; frame = stub->frame; local = frame->local; refresh_frame = copy_frame(frame); if (!refresh_frame) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "mem allocation failed for refresh_frame"); return -1; } refresh_local = dht_local_init(refresh_frame, NULL, NULL, stub->fop); if (!refresh_local) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "mem allocation failed for refresh_local"); return -1; } refresh_local->loc.inode = inode_ref(local->loc.parent); gf_uuid_copy(refresh_local->loc.gfid, local->loc.parent->gfid); refresh_local->stub = stub; refresh_local->refresh_layout_unlock = dht_refresh_parent_layout_resume; refresh_local->refresh_layout_done = dht_refresh_parent_layout_done; dht_refresh_layout(refresh_frame); return 0; } static int32_t dht_call_mkdir_stub(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; call_stub_t *stub = NULL; local = frame->local; stub = local->stub; local->stub = NULL; if (op_ret < 0) { local->op_ret = -1; local->op_errno = op_errno; } else { local->op_ret = 0; } call_resume(stub); return 0; } static int32_t dht_guard_parent_layout_and_namespace(xlator_t *subvol, call_stub_t *stub) { dht_local_t *local = NULL; int ret = -1; loc_t *loc = NULL; xlator_t *hashed_subvol = NULL, *this = NULL; ; call_frame_t *frame = NULL; char pgfid[GF_UUID_BUF_SIZE] = {0}; int32_t *parent_disk_layout = NULL; dht_layout_t *parent_layout = NULL; dht_conf_t *conf = NULL; GF_VALIDATE_OR_GOTO("dht", stub, err); frame = stub->frame; this = frame->this; conf = this->private; local = frame->local; local->stub = stub; /* TODO: recheck whether we should lock on src or dst if we do similar * stale layout checks for rename. */ loc = &stub->args.loc; gf_uuid_unparse(loc->parent->gfid, pgfid); if (local->params == NULL) { local->params = dict_new(); if (local->params == NULL) { local->op_errno = ENOMEM; gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "%s (%s/%s) (path: %s): " "dict allocation failed", gf_fop_list[stub->fop], pgfid, loc->name, loc->path); goto err; } } hashed_subvol = dht_subvol_get_hashed(this, loc); if (hashed_subvol == NULL) { local->op_errno = EINVAL; gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "%s (%s/%s) (path: %s): " "hashed subvolume not found", gf_fop_list[stub->fop], pgfid, loc->name, loc->path); goto err; } parent_layout = dht_layout_get(this, loc->parent); ret = dht_disk_layout_extract_for_subvol(this, parent_layout, hashed_subvol, &parent_disk_layout); if (ret == -1) { local->op_errno = EINVAL; gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "%s (%s/%s) (path: %s): " "extracting in-memory layout of parent failed. ", gf_fop_list[stub->fop], pgfid, loc->name, loc->path); goto err; } memcpy((void *)local->parent_disk_layout, (void *)parent_disk_layout, sizeof(local->parent_disk_layout)); dht_layout_unref(parent_layout); parent_layout = NULL; ret = dict_set_str(local->params, GF_PREOP_PARENT_KEY, conf->xattr_name); if (ret < 0) { local->op_errno = -ret; gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "%s (%s/%s) (path: %s): " "setting %s key in params dictionary failed. ", gf_fop_list[stub->fop], pgfid, loc->name, loc->path, GF_PREOP_PARENT_KEY); goto err; } ret = dict_set_bin(local->params, conf->xattr_name, parent_disk_layout, 4 * 4); if (ret < 0) { local->op_errno = -ret; gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "%s (%s/%s) (path: %s): " "setting parent-layout in params dictionary failed. ", gf_fop_list[stub->fop], pgfid, loc->name, loc->path); goto err; } parent_disk_layout = NULL; local->hashed_subvol = hashed_subvol; local->current = &local->lock[0]; ret = dht_protect_namespace(frame, loc, hashed_subvol, &local->current->ns, dht_call_mkdir_stub); if (ret < 0) goto err; return 0; err: if (parent_disk_layout != NULL) GF_FREE(parent_disk_layout); if (parent_layout != NULL) dht_layout_unref(parent_layout); return -1; } int dht_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *params) { xlator_t *subvol = NULL; int op_errno = -1; int i = 0; int ret = 0; dht_local_t *local = NULL; dht_conf_t *conf = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); conf = this->private; dht_get_du_info(frame, this, loc); local = dht_local_init(frame, loc, NULL, GF_FOP_MKNOD); if (!local) { op_errno = ENOMEM; goto err; } subvol = dht_subvol_get_hashed(this, loc); if (!subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", loc->path); op_errno = EIO; goto err; } /* Post remove-brick, the client layout may not be in sync with * disk layout because of lack of lookup. Hence,a mknod call * may fall on the decommissioned brick. Hence, if the * hashed_subvol is part of decommissioned bricks list, do a * lookup on parent dir. If a fix-layout is already done by the * remove-brick process, the parent directory layout will be in * sync with that of the disk. If fix-layout is still ending * on the parent directory, we can let the file get created on * the decommissioned brick which will be eventually migrated to * non-decommissioned brick based on the new layout. */ if (conf->decommission_subvols_cnt) { for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->decommissioned_bricks[i] && conf->decommissioned_bricks[i] == subvol) { gf_msg_debug(this->name, 0, "hashed subvol:%s is " "part of decommission brick list for " "file: %s", subvol->name, loc->path); /* dht_refresh_layout needs directory info in * local->loc. Hence, storing the parent_loc in * local->loc and storing the create context in * local->loc2. We will restore this information * in dht_creation do */ ret = loc_copy(&local->loc2, &local->loc); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "loc_copy failed %s", loc->path); goto err; } local->params = dict_ref(params); local->rdev = rdev; local->mode = mode; local->umask = umask; loc_wipe(&local->loc); ret = dht_build_parent_loc(this, &local->loc, loc, &op_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_LOC_FAILED, "parent loc build failed"); goto err; } ret = dht_mknod_lock(frame, subvol); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, "locking parent failed"); goto err; } goto done; } } } dht_mknod_wind_to_avail_subvol(frame, this, subvol, loc, rdev, mode, umask, params); done: return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int dht_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *params) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); local = dht_local_init(frame, loc, NULL, GF_FOP_SYMLINK); if (!local) { op_errno = ENOMEM; goto err; } subvol = dht_subvol_get_hashed(this, loc); if (!subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", loc->path); op_errno = EIO; goto err; } gf_msg_trace(this->name, 0, "creating %s on %s", loc->path, subvol->name); STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)subvol, subvol, subvol->fops->symlink, linkname, loc, umask, params); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int dht_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { xlator_t *cached_subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); local = dht_local_init(frame, loc, NULL, GF_FOP_UNLINK); if (!local) { op_errno = ENOMEM; goto err; } cached_subvol = local->cached_subvol; if (!cached_subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", loc->path); op_errno = EINVAL; goto err; } local->flags = xflag; STACK_WIND_COOKIE(frame, dht_unlink_cbk, cached_subvol, cached_subvol, cached_subvol->fops->unlink, loc, xflag, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int dht_remove_stale_linkto_cbk(int ret, call_frame_t *sync_frame, void *data) { DHT_STACK_DESTROY(sync_frame); return 0; } static int dht_remove_stale_linkto(void *data) { call_frame_t *frame = NULL; dht_local_t *local = NULL; xlator_t *this = NULL; dict_t *xdata_in = NULL; int ret = 0; GF_VALIDATE_OR_GOTO("dht", data, out); frame = data; local = frame->local; this = frame->this; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", local, out); GF_VALIDATE_OR_GOTO("dht", local->link_subvol, out); xdata_in = dict_new(); if (!xdata_in) goto out; ret = dht_fill_dict_to_avoid_unlink_of_migrating_file(xdata_in); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, 0, "Failed to set keys for stale linkto" "deletion on path %s", local->loc.path); goto out; } ret = syncop_unlink(local->link_subvol, &local->loc, xdata_in, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, 0, "Removal of linkto failed" " on path %s at subvol %s", local->loc.path, local->link_subvol->name); } out: if (xdata_in) dict_unref(xdata_in); return ret; } static int dht_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; int ret = -1; gf_boolean_t stbuf_merged = _gf_false; xlator_t *subvol = NULL; call_frame_t *cleanup_frame = NULL; dht_local_t *cleanup_local = NULL; local = frame->local; if (op_ret == -1) { /* Remove the linkto if exists */ if (local->linked) { cleanup_frame = create_frame(this, this->ctx->pool); if (cleanup_frame) { cleanup_local = dht_local_init(cleanup_frame, &local->loc2, NULL, 0); if (!cleanup_local || !local->link_subvol) { DHT_STACK_DESTROY(cleanup_frame); goto out; } cleanup_local->link_subvol = local->link_subvol; FRAME_SU_DO(cleanup_frame, dht_local_t); ret = synctask_new(this->ctx->env, dht_remove_stale_linkto, dht_remove_stale_linkto_cbk, cleanup_frame, cleanup_frame); } } /* No continuation on DHT inode missing errors, as we should * then have a good stbuf that states P2 happened. We would * get inode missing if, the file completed migrated between * the lookup and the link call */ goto out; } /* Update parent on success, even if P1/2 checks are positive. * The second call on success will further update the parent */ if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, preparent, postparent); } /* Update linkto attrs, if this is the first call and non-P2, * if we detect P2 then we need to trust the attrs from the * second call, not the first */ if (local->linked == _gf_true && ((local->call_cnt == 1 && !IS_DHT_MIGRATION_PHASE2(stbuf)) || (local->call_cnt != 1 && IS_DHT_MIGRATION_PHASE2(&local->stbuf)))) { dht_iatt_merge(this, &local->stbuf, stbuf); stbuf_merged = _gf_true; dht_linkfile_attr_heal(frame, this); } /* No further P1/2 checks if we are in the second iteration of * the call */ if (local->call_cnt != 1) { goto out; } else { /* Preserve the return values, in case the migration decides * to recreate the link on the same subvol that the current * hased for the link was created on. */ dht_iatt_merge(this, &local->preparent, preparent); dht_iatt_merge(this, &local->postparent, postparent); if (!stbuf_merged) { dht_iatt_merge(this, &local->stbuf, stbuf); stbuf_merged = _gf_true; } local->inode = inode_ref(inode); } local->op_ret = op_ret; local->op_errno = op_errno; local->rebalance.target_op_fn = dht_link2; dht_set_local_rebalance(this, local, stbuf, preparent, postparent, xdata); /* Check if the rebalance phase2 is true */ if (IS_DHT_MIGRATION_PHASE2(stbuf)) { ret = dht_inode_ctx_get_mig_info(this, local->loc.inode, NULL, &subvol); if (!subvol) { /* Phase 2 of migration */ ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } else { dht_link2(subvol, frame, 0); return 0; } } /* Check if the rebalance phase1 is true */ if (IS_DHT_MIGRATION_PHASE1(stbuf)) { ret = dht_inode_ctx_get_mig_info(this, local->loc.inode, NULL, &subvol); if (subvol) { dht_link2(subvol, frame, 0); return 0; } ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } out: DHT_STRIP_PHASE1_FLAGS(stbuf); dht_set_fixed_dir_stat(preparent); dht_set_fixed_dir_stat(postparent); DHT_STACK_UNWIND(link, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, NULL); return 0; } static int dht_link2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int op_errno = EINVAL; local = frame->local; if (!local) goto err; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); DHT_STACK_UNWIND(link, frame, local->op_ret, op_errno, local->inode, &local->stbuf, &local->preparent, &local->postparent, NULL); return 0; } if (subvol == NULL) { op_errno = EINVAL; goto err; } /* Second call to create link file could result in EEXIST as the * first call created the linkto in the currently * migrating subvol, which could be the new hashed subvol */ if (local->link_subvol == subvol) { DHT_STRIP_PHASE1_FLAGS(&local->stbuf); dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); DHT_STACK_UNWIND(link, frame, 0, 0, local->inode, &local->stbuf, &local->preparent, &local->postparent, NULL); return 0; } local->call_cnt = 2; STACK_WIND(frame, dht_link_cbk, subvol, subvol->fops->link, &local->loc, &local->loc2, local->xattr_req); return 0; err: DHT_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int dht_link_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *srcvol = NULL; if (op_ret == -1) goto err; local = frame->local; srcvol = local->linkfile.srcvol; STACK_WIND(frame, dht_link_cbk, srcvol, srcvol->fops->link, &local->loc, &local->loc2, local->xattr_req); return 0; err: DHT_STRIP_PHASE1_FLAGS(stbuf); dht_set_fixed_dir_stat(preparent); dht_set_fixed_dir_stat(postparent); DHT_STACK_UNWIND(link, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); return 0; } int dht_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { xlator_t *cached_subvol = NULL; xlator_t *hashed_subvol = NULL; int op_errno = -1; int ret = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(oldloc, err); VALIDATE_OR_GOTO(newloc, err); local = dht_local_init(frame, oldloc, NULL, GF_FOP_LINK); if (!local) { op_errno = ENOMEM; goto err; } local->call_cnt = 1; cached_subvol = local->cached_subvol; if (!cached_subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", oldloc->path); op_errno = ENOENT; goto err; } hashed_subvol = dht_subvol_get_hashed(this, newloc); if (!hashed_subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", newloc->path); op_errno = EIO; goto err; } ret = loc_copy(&local->loc2, newloc); if (ret == -1) { op_errno = ENOMEM; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); if (hashed_subvol != cached_subvol) { gf_uuid_copy(local->gfid, oldloc->inode->gfid); dht_linkfile_create(frame, dht_link_linkfile_cbk, this, cached_subvol, hashed_subvol, newloc); } else { STACK_WIND(frame, dht_link_cbk, cached_subvol, cached_subvol->fops->link, oldloc, newloc, xdata); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int dht_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { xlator_t *prev = NULL; int ret = -1; dht_local_t *local = NULL; gf_boolean_t parent_layout_changed = _gf_false; char pgfid[GF_UUID_BUF_SIZE] = {0}; xlator_t *subvol = NULL; local = frame->local; local = frame->local; if (!local) { op_ret = -1; op_errno = EINVAL; goto out; } if (op_ret == -1) { local->op_errno = op_errno; parent_layout_changed = (xdata && dict_get(xdata, GF_PREOP_CHECK_FAILED)) ? _gf_true : _gf_false; if (parent_layout_changed) { if (local && local->lock[0].layout.parent_layout.locks) { /* Returning failure as the layout could not be fixed even under * the lock */ goto out; } gf_uuid_unparse(local->loc.parent->gfid, pgfid); gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_PARENT_LAYOUT_CHANGED, "create (%s/%s) (path: %s): parent layout " "changed. Attempting a layout refresh and then a " "retry", pgfid, local->loc.name, local->loc.path); /* dht_refresh_layout needs directory info in local->loc.Hence, storing the parent_loc in local->loc and storing the create context in local->loc2. We will restore this information in dht_creation_do. */ loc_wipe(&local->loc2); ret = loc_copy(&local->loc2, &local->loc); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "loc_copy failed %s", local->loc.path); goto out; } loc_wipe(&local->loc); ret = dht_build_parent_loc(this, &local->loc, &local->loc2, &op_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_LOC_FAILED, "parent loc build failed"); goto out; } subvol = dht_subvol_get_hashed(this, &local->loc2); ret = dht_create_lock(frame, subvol); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, "locking parent failed"); goto out; } return 0; } goto out; } prev = cookie; if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, preparent, postparent); } ret = dht_fd_ctx_set(this, fd, prev); if (ret != 0) { gf_msg_debug(this->name, 0, "Possible fd leak. " "Could not set fd ctx for subvol %s", prev->name); } ret = dht_layout_preset(this, prev, inode); if (ret != 0) { gf_msg_debug(this->name, 0, "could not set preset layout for subvol %s", prev->name); op_ret = -1; op_errno = EINVAL; goto out; } local->op_errno = op_errno; if (local->linked == _gf_true) { local->stbuf = *stbuf; dht_linkfile_attr_heal(frame, this); } out: DHT_STRIP_PHASE1_FLAGS(stbuf); dht_set_fixed_dir_stat(preparent); dht_set_fixed_dir_stat(postparent); if (local && local->lock[0].layout.parent_layout.locks) { /* store op_errno for failure case*/ local->op_errno = op_errno; local->refresh_layout_unlock(frame, op_ret, 1); if (op_ret == 0) { DHT_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, stbuf, preparent, postparent, xdata); } } else { DHT_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, stbuf, preparent, postparent, xdata); } return 0; } static int dht_create_linkfile_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *cached_subvol = NULL; dht_conf_t *conf = NULL; local = frame->local; if (!local) { op_errno = EINVAL; goto err; } if (op_ret == -1) { local->op_errno = op_errno; goto err; } conf = this->private; if (!conf) { local->op_errno = EINVAL; op_errno = EINVAL; goto err; } cached_subvol = local->cached_subvol; if (local->params) { dict_del(local->params, conf->link_xattr_name); dict_del(local->params, GLUSTERFS_INTERNAL_FOP_KEY); } STACK_WIND_COOKIE(frame, dht_create_cbk, cached_subvol, cached_subvol, cached_subvol->fops->create, &local->loc, local->flags, local->mode, local->umask, local->fd, local->params); return 0; err: if (local && local->lock[0].layout.parent_layout.locks) { local->refresh_layout_unlock(frame, -1, 1); } else { DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); } return 0; } static int dht_create_wind_to_avail_subvol(call_frame_t *frame, xlator_t *this, xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *params) { dht_local_t *local = NULL; xlator_t *avail_subvol = NULL; int lk_count = 0; local = frame->local; if (!dht_is_subvol_filled(this, subvol)) { lk_count = local->lock[0].layout.parent_layout.lk_count; gf_msg_debug(this->name, 0, "creating %s on %s with lock_count %d", loc->path, subvol->name, lk_count); /*The function dht_set_parent_layout_in_dict sets the layout in dictionary and posix_create validates a layout before creating a file.In case if parent layout does not match with disk layout posix xlator throw an error but in case if volume is shrunk layout has been changed by rebalance daemon so we need to call this function only while a function is calling without taking any lock otherwise we would not able to populate a layout on disk in case if layout has changed. */ if (!lk_count) { dht_set_parent_layout_in_dict(loc, this, local); } else { /* Delete a key to avoid layout validate if it was set by previous STACK_WIND attempt when a lock was not taken by dht_create */ (void)dict_del_sizen(local->params, GF_PREOP_PARENT_KEY); } STACK_WIND_COOKIE(frame, dht_create_cbk, subvol, subvol, subvol->fops->create, loc, flags, mode, umask, fd, params); } else { avail_subvol = dht_free_disk_available_subvol(this, subvol, local); if (avail_subvol != subvol) { local->cached_subvol = avail_subvol; local->hashed_subvol = subvol; gf_msg_debug(this->name, 0, "creating %s on %s (link at %s)", loc->path, avail_subvol->name, subvol->name); dht_linkfile_create(frame, dht_create_linkfile_create_cbk, this, avail_subvol, subvol, loc); goto out; } lk_count = local->lock[0].layout.parent_layout.lk_count; gf_msg_debug(this->name, 0, "creating %s on %s with lk_count %d", loc->path, subvol->name, lk_count); if (!lk_count) { dht_set_parent_layout_in_dict(loc, this, local); } else { (void)dict_del_sizen(local->params, GF_PREOP_PARENT_KEY); } STACK_WIND_COOKIE(frame, dht_create_cbk, subvol, subvol, subvol->fops->create, loc, flags, mode, umask, fd, params); } out: return 0; } int dht_build_parent_loc(xlator_t *this, loc_t *parent, loc_t *child, int32_t *op_errno) { inode_table_t *table = NULL; int ret = -1; if (!parent || !child) { if (op_errno) *op_errno = EINVAL; goto out; } if (child->parent) { parent->inode = inode_ref(child->parent); if (!parent->inode) { if (op_errno) *op_errno = EINVAL; goto out; } gf_uuid_copy(parent->gfid, child->pargfid); ret = 0; goto out; } else { if (gf_uuid_is_null(child->pargfid)) { if (op_errno) *op_errno = EINVAL; goto out; } table = this->itable; if (!table) { if (op_errno) { *op_errno = EINVAL; goto out; } } parent->inode = inode_find(table, child->pargfid); if (!parent->inode) { if (op_errno) { *op_errno = EINVAL; goto out; } } gf_uuid_copy(parent->gfid, child->pargfid); ret = 0; } out: return ret; } static int32_t dht_create_do(call_frame_t *frame) { dht_local_t *local = NULL; dht_layout_t *refreshed = NULL; xlator_t *subvol = NULL; xlator_t *this = NULL; dht_conf_t *conf = NULL; dht_methods_t *methods = NULL; local = frame->local; this = THIS; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, err); methods = &(conf->methods); /* We don't need parent_loc anymore */ loc_wipe(&local->loc); loc_copy(&local->loc, &local->loc2); loc_wipe(&local->loc2); refreshed = local->selfheal.refreshed_layout; subvol = methods->layout_search(this, refreshed, local->loc.name); if (!subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "no subvolume in " "layout for path=%s", local->loc.path); local->op_errno = ENOENT; goto err; } dht_create_wind_to_avail_subvol(frame, this, subvol, &local->loc, local->flags, local->mode, local->umask, local->fd, local->params); return 0; err: local->refresh_layout_unlock(frame, -1, 1); return 0; } static int32_t dht_create_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { DHT_STACK_DESTROY(frame); return 0; } static int32_t dht_create_finish(call_frame_t *frame, int op_ret, int invoke_cbk) { dht_local_t *local = NULL, *lock_local = NULL; call_frame_t *lock_frame = NULL; int lock_count = 0; dht_lock_wrap_t *parent_layout, *lock_local_parent_layout; local = frame->local; parent_layout = &local->lock[0].layout.parent_layout; lock_count = dht_lock_count(parent_layout); if (lock_count == 0) goto done; lock_frame = copy_frame(frame); if (lock_frame == NULL) { goto done; } lock_local = dht_local_init(lock_frame, &local->loc, NULL, lock_frame->root->op); if (lock_local == NULL) { goto done; } lock_local_parent_layout = &lock_local->lock[0].layout.parent_layout; dht_lock_array_copy(parent_layout, lock_local_parent_layout); dht_lock_array_reset(parent_layout); dht_unlock_inodelk(lock_frame, lock_local_parent_layout, dht_create_unlock_cbk); lock_frame = NULL; done: if (lock_frame != NULL) { DHT_STACK_DESTROY(lock_frame); } if (op_ret == 0) return 0; DHT_STACK_UNWIND(create, frame, op_ret, local->op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t dht_create_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (!local) { goto err; } if (op_ret < 0) { gf_msg("DHT", GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, "Create lock failed for file: %s", local->loc2.name); local->op_errno = op_errno; goto err; } local->refresh_layout_unlock = dht_create_finish; local->refresh_layout_done = dht_create_do; dht_refresh_layout(frame); return 0; err: if (local) dht_create_finish(frame, -1, 0); else DHT_STACK_UNWIND(create, frame, -1, EINVAL, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t dht_create_lock(call_frame_t *frame, xlator_t *subvol) { dht_local_t *local = NULL; int count = 1, ret = -1; dht_lock_t **lk_array = NULL; dht_lock_wrap_t *parent_layout; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO(frame->this->name, frame->local, err); local = frame->local; lk_array = GF_CALLOC(count, sizeof(*lk_array), gf_common_mt_pointer); if (lk_array == NULL) goto err; lk_array[0] = dht_lock_new(frame->this, subvol, &local->loc, F_RDLCK, DHT_LAYOUT_HEAL_DOMAIN, NULL, IGNORE_ENOENT_ESTALE); if (lk_array[0] == NULL) goto err; parent_layout = &local->lock[0].layout.parent_layout; parent_layout->locks = lk_array; parent_layout->lk_count = count; ret = dht_blocking_inodelk(frame, lk_array, count, dht_create_lock_cbk); if (ret < 0) { dht_lock_array_reset(parent_layout); goto err; } return 0; err: if (lk_array != NULL) { dht_lock_array_free(lk_array, count); GF_FREE(lk_array); } return -1; } int dht_set_parent_layout_in_dict(loc_t *loc, xlator_t *this, dht_local_t *local) { dht_conf_t *conf = this->private; dht_layout_t *parent_layout = NULL; int *parent_disk_layout = NULL; xlator_t *hashed_subvol = NULL; char pgfid[GF_UUID_BUF_SIZE] = {0}; int ret = 0; gf_uuid_unparse(loc->parent->gfid, pgfid); parent_layout = dht_layout_get(this, loc->parent); hashed_subvol = dht_subvol_get_hashed(this, loc); ret = dht_disk_layout_extract_for_subvol(this, parent_layout, hashed_subvol, &parent_disk_layout); if (ret == -1) { gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "%s (%s/%s) (path: %s): " "extracting in-memory layout of parent failed. ", gf_fop_list[local->fop], pgfid, loc->name, loc->path); goto err; } ret = dict_set_str_sizen(local->params, GF_PREOP_PARENT_KEY, conf->xattr_name); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "%s (%s/%s) (path: %s): " "setting %s key in params dictionary failed. ", gf_fop_list[local->fop], pgfid, loc->name, loc->path, GF_PREOP_PARENT_KEY); goto err; } ret = dict_set_bin(local->params, conf->xattr_name, parent_disk_layout, 4 * 4); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "%s (%s/%s) (path: %s): " "setting parent-layout in params dictionary failed. ", gf_fop_list[local->fop], pgfid, loc->name, loc->path); goto err; } err: dht_layout_unref(parent_layout); return ret; } int dht_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *params) { int op_errno = -1; xlator_t *subvol = NULL; xlator_t *hashed_subvol = NULL; dht_local_t *local = NULL; int i = 0; dht_conf_t *conf = NULL; int ret = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); conf = this->private; dht_get_du_info(frame, this, loc); local = dht_local_init(frame, loc, fd, GF_FOP_CREATE); if (!local) { op_errno = ENOMEM; goto err; } local->params = dict_ref(params); local->flags = flags; local->mode = mode; local->umask = umask; if (dht_filter_loc_subvol_key(this, loc, &local->loc, &subvol)) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, "creating %s on %s (got create on %s)", local->loc.path, subvol->name, loc->path); /* Since lookup-optimize is enabled by default, we need * to create the linkto file if required. * Note this does not check for decommisioned bricks * and min-free-disk limits as this is a debugging tool * and not expected to be used in production. */ hashed_subvol = dht_subvol_get_hashed(this, &local->loc); if (hashed_subvol && (hashed_subvol != subvol)) { /* Create the linkto file and then the data file */ local->cached_subvol = subvol; local->hashed_subvol = hashed_subvol; dht_linkfile_create(frame, dht_create_linkfile_create_cbk, this, subvol, hashed_subvol, &local->loc); goto done; } /* We either don't have a hashed subvol or the hashed subvol is * the same as the one specified. No need to create the linkto * file as we expect a lookup everywhere if there are problems * with the parent layout */ dht_set_parent_layout_in_dict(loc, this, local); STACK_WIND_COOKIE(frame, dht_create_cbk, subvol, subvol, subvol->fops->create, &local->loc, flags, mode, umask, fd, params); goto done; } subvol = dht_subvol_get_hashed(this, loc); if (!subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "no subvolume in layout for path=%s", loc->path); op_errno = EIO; goto err; } /* Post remove-brick, the client layout may not be in sync with * disk layout because of lack of lookup. Hence,a create call * may fall on the decommissioned brick. Hence, if the * hashed_subvol is part of decommissioned bricks list, do a * lookup on parent dir. If a fix-layout is already done by the * remove-brick process, the parent directory layout will be in * sync with that of the disk. If fix-layout is still ending * on the parent directory, we can let the file get created on * the decommissioned brick which will be eventually migrated to * non-decommissioned brick based on the new layout. */ if (conf->decommission_subvols_cnt) { for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->decommissioned_bricks[i] && conf->decommissioned_bricks[i] == subvol) { gf_msg_debug(this->name, 0, "hashed subvol:%s is " "part of decommission brick list for " "file: %s", subvol->name, loc->path); /* dht_refresh_layout needs directory info in * local->loc. Hence, storing the parent_loc in * local->loc and storing the create context in * local->loc2. We will restore this information * in dht_creation do */ ret = loc_copy(&local->loc2, &local->loc); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "loc_copy failed %s", loc->path); goto err; } loc_wipe(&local->loc); ret = dht_build_parent_loc(this, &local->loc, loc, &op_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_LOC_FAILED, "parent loc build failed"); goto err; } ret = dht_create_lock(frame, subvol); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, "locking parent failed"); goto err; } goto done; } } } dht_create_wind_to_avail_subvol(frame, this, subvol, loc, flags, mode, umask, fd, params); done: return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } static int dht_mkdir_selfheal_cbk(call_frame_t *frame, void *cookie, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; dht_layout_t *layout = NULL; xlator_t *this = NULL; local = frame->local; this = frame->this; layout = local->selfheal.layout; FRAME_SU_UNDO(frame, dht_local_t); dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); if (op_ret == 0) { dht_layout_set(this, local->inode, layout); dht_inode_ctx_time_update(local->inode, this, NULL, &local->stbuf); if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, &local->preparent, &local->postparent); } } DHT_STACK_UNWIND(mkdir, frame, op_ret, op_errno, local->inode, &local->stbuf, &local->preparent, &local->postparent, NULL); return 0; } static int dht_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; int ret = -1; gf_boolean_t subvol_filled = _gf_false; gf_boolean_t dir_exists = _gf_false; xlator_t *prev = NULL; dht_layout_t *layout = NULL; local = frame->local; prev = cookie; layout = local->layout; subvol_filled = dht_is_subvol_filled(this, prev); LOCK(&frame->lock); { if (subvol_filled && (op_ret != -1)) { ret = dht_layout_merge(this, layout, prev, -1, ENOSPC, NULL); } else { if (op_ret == -1 && op_errno == EEXIST) { /* Very likely just a race between mkdir and self-heal (from lookup of a concurrent mkdir attempt). Ignore error for now. layout setting will anyways fail if this was a different (old) pre-existing different directory. */ op_ret = 0; dir_exists = _gf_true; } ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, NULL); } if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_MERGE_FAILED, "%s: failed to merge layouts for subvol %s", local->loc.path, prev->name); if (op_ret == -1) { local->op_errno = op_errno; goto unlock; } if (dir_exists) goto unlock; dht_iatt_merge(this, &local->stbuf, stbuf); dht_iatt_merge(this, &local->preparent, preparent); dht_iatt_merge(this, &local->postparent, postparent); } unlock: UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { /*Unlock entrylk and inodelk once mkdir is done on all subvols*/ dht_unlock_namespace(frame, &local->lock[0]); FRAME_SU_DO(frame, dht_local_t); dht_selfheal_new_directory(frame, dht_mkdir_selfheal_cbk, layout); } return 0; } static int dht_mkdir_hashed_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata); static int dht_mkdir_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *params) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int op_errno = -1, ret = -1; xlator_t *hashed_subvol = NULL; int32_t *parent_disk_layout = NULL; dht_layout_t *parent_layout = NULL; char pgfid[GF_UUID_BUF_SIZE] = {0}; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(loc->path, err); VALIDATE_OR_GOTO(this->private, err); gf_uuid_unparse(loc->parent->gfid, pgfid); conf = this->private; local = frame->local; if (local->op_ret == -1) { gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "mkdir (%s/%s) (path: %s): refreshing parent layout " "failed.", pgfid, loc->name, loc->path); op_errno = local->op_errno; goto err; } local->op_ret = -1; hashed_subvol = dht_subvol_get_hashed(this, loc); if (hashed_subvol == NULL) { gf_msg_debug(this->name, 0, "mkdir (%s/%s) (path: %s): hashed subvol not " "found", pgfid, loc->name, loc->path); op_errno = ENOENT; goto err; } local->hashed_subvol = hashed_subvol; parent_layout = dht_layout_get(this, loc->parent); ret = dht_disk_layout_extract_for_subvol(this, parent_layout, hashed_subvol, &parent_disk_layout); if (ret == -1) { gf_msg(this->name, GF_LOG_WARNING, EIO, DHT_MSG_PARENT_LAYOUT_CHANGED, "mkdir (%s/%s) (path: %s): " "extracting in-memory layout of parent failed. ", pgfid, loc->name, loc->path); goto err; } if (memcmp(local->parent_disk_layout, parent_disk_layout, sizeof(local->parent_disk_layout)) == 0) { gf_msg(this->name, GF_LOG_WARNING, EIO, DHT_MSG_PARENT_LAYOUT_CHANGED, "mkdir (%s/%s) (path: %s): loop detected. " "parent layout didn't change even though " "previous attempt of mkdir failed because of " "in-memory layout not matching with that on disk.", pgfid, loc->name, loc->path); op_errno = EIO; goto err; } memcpy((void *)local->parent_disk_layout, (void *)parent_disk_layout, sizeof(local->parent_disk_layout)); dht_layout_unref(parent_layout); parent_layout = NULL; ret = dict_set_str(params, GF_PREOP_PARENT_KEY, conf->xattr_name); if (ret < 0) { local->op_errno = -ret; gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "mkdir (%s/%s) (path: %s): " "setting %s key in params dictionary failed. ", pgfid, loc->name, loc->path, GF_PREOP_PARENT_KEY); goto err; } ret = dict_set_bin(params, conf->xattr_name, parent_disk_layout, 4 * 4); if (ret < 0) { local->op_errno = -ret; gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "setting parent-layout in params dictionary failed. " "mkdir (%s/%s) (path: %s)", pgfid, loc->name, loc->path); goto err; } parent_disk_layout = NULL; STACK_WIND_COOKIE(frame, dht_mkdir_hashed_cbk, hashed_subvol, hashed_subvol, hashed_subvol->fops->mkdir, loc, mode, umask, params); return 0; err: dht_unlock_namespace(frame, &local->lock[0]); op_errno = local ? local->op_errno : op_errno; DHT_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); if (parent_disk_layout != NULL) GF_FREE(parent_disk_layout); if (parent_layout != NULL) dht_layout_unref(parent_layout); return 0; } static int dht_mkdir_hashed_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; int ret = -1; xlator_t *prev = NULL; dht_layout_t *layout = NULL; dht_conf_t *conf = NULL; int i = 0; xlator_t *hashed_subvol = NULL; char pgfid[GF_UUID_BUF_SIZE] = {0}; gf_boolean_t parent_layout_changed = _gf_false; call_stub_t *stub = NULL; local = frame->local; prev = cookie; layout = local->layout; conf = this->private; hashed_subvol = local->hashed_subvol; gf_uuid_unparse(local->loc.parent->gfid, pgfid); if (gf_uuid_is_null(local->loc.gfid) && !op_ret) gf_uuid_copy(local->loc.gfid, stbuf->ia_gfid); if (op_ret == -1) { local->op_errno = op_errno; parent_layout_changed = (xdata && dict_get(xdata, GF_PREOP_CHECK_FAILED)) ? 1 : 0; if (parent_layout_changed) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_PARENT_LAYOUT_CHANGED, "mkdir (%s/%s) (path: %s): parent layout " "changed. Attempting a refresh and then a " "retry", pgfid, local->loc.name, local->loc.path); stub = fop_mkdir_stub(frame, dht_mkdir_helper, &local->loc, local->mode, local->umask, local->params); if (stub == NULL) { goto err; } ret = dht_handle_parent_layout_change(this, stub); if (ret) { goto err; } stub = NULL; return 0; } goto err; } dict_del(local->params, GF_PREOP_PARENT_KEY); dict_del(local->params, conf->xattr_name); if (dht_is_subvol_filled(this, hashed_subvol)) ret = dht_layout_merge(this, layout, prev, -1, ENOSPC, NULL); else ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, NULL); /* TODO: we may have to return from the function if layout merge fails. For now, lets just log an error */ if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_MERGE_FAILED, "%s: failed to merge layouts for subvol %s", local->loc.path, prev->name); local->op_ret = 0; dht_iatt_merge(this, &local->stbuf, stbuf); dht_iatt_merge(this, &local->preparent, preparent); dht_iatt_merge(this, &local->postparent, postparent); local->call_cnt = conf->subvolume_cnt - 1; /* Delete internal mds xattr from params dict to avoid store internal mds xattr on other subvols */ dict_del(local->params, conf->mds_xattr_key); if (gf_uuid_is_null(local->loc.gfid)) gf_uuid_copy(local->loc.gfid, stbuf->ia_gfid); /* Set hashed subvol as a mds subvol on inode ctx */ /*if (!local->inode) local->inode = inode_ref (inode); */ ret = dht_inode_ctx_mdsvol_set(local->inode, this, hashed_subvol); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, "Failed to set hashed subvol for %s on inode vol is %s", local->loc.path, hashed_subvol->name); } if (local->call_cnt == 0) { /*Unlock namespace lock once mkdir is done on all subvols*/ dht_unlock_namespace(frame, &local->lock[0]); dht_selfheal_directory(frame, dht_mkdir_selfheal_cbk, &local->loc, layout); return 0; } for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == hashed_subvol) continue; STACK_WIND_COOKIE(frame, dht_mkdir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->mkdir, &local->loc, local->mode, local->umask, local->params); } return 0; err: if (local->op_ret != 0) { dht_unlock_namespace(frame, &local->lock[0]); } DHT_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int dht_mkdir_guard_parent_layout_cbk(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *params) { dht_local_t *local = NULL; dht_conf_t *conf = 0; char pgfid[GF_UUID_BUF_SIZE] = {0}; int ret = -1; int32_t zero[1] = {0}; local = frame->local; conf = this->private; gf_uuid_unparse(loc->parent->gfid, pgfid); if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_PARENT_LAYOUT_CHANGED, "mkdir (%s/%s) (path: %s): " "Acquiring lock on parent to guard against " "layout-change failed.", pgfid, loc->name, loc->path); goto err; } local->op_ret = -1; /* Add internal MDS xattr on disk for hashed subvol */ ret = dht_dict_set_array(params, conf->mds_xattr_key, zero, 1); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value:key = %s for " "path %s", conf->mds_xattr_key, loc->path); } STACK_WIND_COOKIE(frame, dht_mkdir_hashed_cbk, local->hashed_subvol, local->hashed_subvol, local->hashed_subvol->fops->mkdir, loc, mode, umask, params); return 0; err: DHT_STACK_UNWIND(mkdir, frame, -1, local->op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int dht_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *params) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int op_errno = EINVAL, ret = -1; xlator_t *hashed_subvol = NULL; char pgfid[GF_UUID_BUF_SIZE] = {0}; call_stub_t *stub = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(loc->path, err); VALIDATE_OR_GOTO(this->private, err); gf_uuid_unparse(loc->parent->gfid, pgfid); conf = this->private; if (!params || !dict_get(params, "gfid-req")) { op_errno = EPERM; gf_msg_callingfn(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_GFID_NULL, "mkdir: %s is received " "without gfid-req %p", loc->path, params); goto err; } dht_get_du_info(frame, this, loc); local = dht_local_init(frame, loc, NULL, GF_FOP_MKDIR); if (!local) { op_errno = ENOMEM; goto err; } hashed_subvol = dht_subvol_get_hashed(this, loc); if (hashed_subvol == NULL) { gf_msg_debug(this->name, 0, "hashed subvol not found for %s", loc->path); local->op_errno = EIO; goto err; } local->hashed_subvol = hashed_subvol; local->mode = mode; local->umask = umask; if (params) local->params = dict_ref(params); local->inode = inode_ref(loc->inode); local->layout = dht_layout_new(this, conf->subvolume_cnt); if (!local->layout) { op_errno = ENOMEM; goto err; } /* set the newly created directory hash to the commit hash * if the configuration option is set. If configuration option * is not set, the older clients may still be connecting to the * volume and hence we need to preserve the 1 in disk[0] part of the * layout xattr */ if (conf->lookup_optimize) local->layout->commit_hash = conf->vol_commit_hash; else local->layout->commit_hash = DHT_LAYOUT_HASH_INVALID; stub = fop_mkdir_stub(frame, dht_mkdir_guard_parent_layout_cbk, loc, mode, umask, params); if (stub == NULL) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_PARENT_LAYOUT_CHANGED, "mkdir (%s/%s) (path: %s): " "creating stub failed.", pgfid, loc->name, loc->path); local->op_errno = ENOMEM; goto err; } ret = dht_guard_parent_layout_and_namespace(this, stub); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_PARENT_LAYOUT_CHANGED, "mkdir (%s/%s) (path: %s) cannot wind lock request to " "guard parent layout", pgfid, loc->name, loc->path); goto err; } return 0; err: op_errno = local ? local->op_errno : op_errno; DHT_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int dht_rmdir_selfheal_cbk(call_frame_t *heal_frame, void *cookie, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; dht_local_t *heal_local = NULL; call_frame_t *main_frame = NULL; heal_local = heal_frame->local; main_frame = heal_local->main_frame; local = main_frame->local; DHT_STACK_DESTROY(heal_frame); dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); DHT_STACK_UNWIND(rmdir, main_frame, local->op_ret, local->op_errno, &local->preparent, &local->postparent, NULL); return 0; } static int dht_rmdir_hashed_subvol_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; dht_local_t *heal_local = NULL; call_frame_t *heal_frame = NULL; dht_conf_t *conf = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; prev = cookie; conf = this->private; gf_uuid_unparse(local->loc.gfid, gfid); LOCK(&frame->lock); { if (op_ret == -1) { local->op_errno = op_errno; local->op_ret = -1; if (conf->subvolume_cnt != 1) { if (op_errno != ENOENT && op_errno != EACCES && op_errno != ESTALE) { local->need_selfheal = 1; } } gf_msg_debug(this->name, op_errno, "rmdir on %s for %s failed " "(gfid = %s)", prev->name, local->loc.path, gfid); goto unlock; } dht_iatt_merge(this, &local->preparent, preparent); dht_iatt_merge(this, &local->postparent, postparent); } unlock: UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if (local->need_selfheal) { dht_rmdir_unlock(frame, this); local->layout = dht_layout_get(this, local->loc.inode); /* TODO: neater interface needed below */ local->stbuf.ia_type = local->loc.inode->ia_type; gf_uuid_copy(local->gfid, local->loc.inode->gfid); /* Use a different frame or else the rmdir op_ret is * overwritten by that of the selfheal */ heal_frame = copy_frame(frame); if (heal_frame == NULL) { goto err; } heal_local = dht_local_init(heal_frame, &local->loc, NULL, 0); if (!heal_local) { DHT_STACK_DESTROY(heal_frame); goto err; } heal_local->inode = inode_ref(local->loc.inode); heal_local->main_frame = frame; gf_uuid_copy(heal_local->gfid, local->loc.inode->gfid); dht_selfheal_restore(heal_frame, dht_rmdir_selfheal_cbk, &heal_local->loc, heal_local->layout); return 0; } else { if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, &local->preparent, &local->postparent); } dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); dht_rmdir_unlock(frame, this); DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, &local->preparent, &local->postparent, NULL); } } return 0; err: DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, NULL, NULL, NULL); return 0; } static int dht_rmdir_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { DHT_STACK_DESTROY(frame); return 0; } static int dht_rmdir_unlock(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL, *lock_local = NULL; call_frame_t *lock_frame = NULL; int lock_count = 0; dht_lock_wrap_t *parent_layout, *lock_local_parent_layout; local = frame->local; parent_layout = &local->lock[0].ns.parent_layout; /* Unlock entrylk */ dht_unlock_entrylk_wrapper(frame, &local->lock[0].ns.directory_ns); /* Unlock inodelk */ lock_count = dht_lock_count(parent_layout); if (lock_count == 0) goto done; lock_frame = copy_frame(frame); if (lock_frame == NULL) goto done; lock_local = dht_local_init(lock_frame, &local->loc, NULL, lock_frame->root->op); if (lock_local == NULL) goto done; lock_local_parent_layout = &lock_local->lock[0].ns.parent_layout; dht_lock_array_copy(parent_layout, lock_local_parent_layout); dht_lock_array_reset(parent_layout); dht_unlock_inodelk(lock_frame, lock_local_parent_layout, dht_rmdir_unlock_cbk); lock_frame = NULL; done: if (lock_frame != NULL) { DHT_STACK_DESTROY(lock_frame); } return 0; } static int dht_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; int done = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; dht_local_t *heal_local = NULL; call_frame_t *heal_frame = NULL; int ret = -1; local = frame->local; prev = cookie; LOCK(&frame->lock); { if (op_ret == -1) { if ((op_errno != ENOENT) && (op_errno != ESTALE)) { local->op_errno = op_errno; local->op_ret = -1; if (op_errno != EACCES) local->need_selfheal = 1; } gf_uuid_unparse(local->loc.gfid, gfid); gf_msg_debug(this->name, op_errno, "rmdir on %s for %s failed." "(gfid = %s)", prev->name, local->loc.path, gfid); goto unlock; } /* Track if rmdir succeeded on at least one subvol*/ local->fop_succeeded = 1; dht_iatt_merge(this, &local->preparent, preparent); dht_iatt_merge(this, &local->postparent, postparent); } unlock: UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); /* if local->hashed_subvol, we are yet to wind to hashed_subvol. */ if (local->hashed_subvol && (this_call_cnt == 1)) { done = 1; } else if (!local->hashed_subvol && !this_call_cnt) { done = 1; } if (done) { if (local->need_selfheal && local->fop_succeeded) { dht_rmdir_unlock(frame, this); local->layout = dht_layout_get(this, local->loc.inode); /* TODO: neater interface needed below */ local->stbuf.ia_type = local->loc.inode->ia_type; gf_uuid_copy(local->gfid, local->loc.inode->gfid); heal_frame = copy_frame(frame); if (heal_frame == NULL) { goto err; } heal_local = dht_local_init(heal_frame, &local->loc, NULL, 0); if (!heal_local) { DHT_STACK_DESTROY(heal_frame); goto err; } heal_local->inode = inode_ref(local->loc.inode); heal_local->main_frame = frame; gf_uuid_copy(heal_local->gfid, local->loc.inode->gfid); ret = dht_selfheal_restore(heal_frame, dht_rmdir_selfheal_cbk, &heal_local->loc, heal_local->layout); if (ret) { DHT_STACK_DESTROY(heal_frame); goto err; } } else if (this_call_cnt) { /* If non-hashed subvol's have responded, proceed */ if (local->op_ret == 0) { /* Delete the dir from the hashed subvol if: * The fop succeeded on at least one subvol * and did not fail on any * or * The fop failed with ENOENT/ESTALE on * all subvols */ STACK_WIND_COOKIE(frame, dht_rmdir_hashed_subvol_cbk, local->hashed_subvol, local->hashed_subvol, local->hashed_subvol->fops->rmdir, &local->loc, local->flags, NULL); } else { /* hashed-subvol was non-NULL and rmdir failed on * all non hashed-subvols. Unwind rmdir with * local->op_ret and local->op_errno. */ dht_rmdir_unlock(frame, this); DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, &local->preparent, &local->postparent, NULL); return 0; } } else if (!this_call_cnt) { /* All subvol's have responded, proceed */ if (local->loc.parent) { dht_inode_ctx_time_update(local->loc.parent, this, &local->preparent, &local->postparent); } dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); dht_rmdir_unlock(frame, this); DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, &local->preparent, &local->postparent, NULL); } } return 0; err: DHT_STACK_UNWIND(rmdir, frame, -1, local->op_errno, NULL, NULL, NULL); return 0; } static int dht_rmdir_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int i = 0; xlator_t *hashed_subvol; conf = this->private; local = frame->local; if (op_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_INODE_LK_ERROR, "acquiring entrylk after inodelk failed rmdir for %s)", local->loc.path); local->op_ret = -1; local->op_errno = op_errno; goto err; } hashed_subvol = local->hashed_subvol; for (i = 0; i < conf->subvolume_cnt; i++) { if (hashed_subvol && (hashed_subvol == conf->subvolumes[i])) continue; STACK_WIND_COOKIE(frame, dht_rmdir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->rmdir, &local->loc, local->flags, NULL); } return 0; err: DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, &local->preparent, &local->postparent, NULL); return 0; } static int dht_rmdir_do(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int ret = -1; xlator_t *hashed_subvol = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; VALIDATE_OR_GOTO(frame->local, err); local = frame->local; VALIDATE_OR_GOTO(this->private, out); conf = this->private; if (local->op_ret == -1) goto out; local->call_cnt = conf->subvolume_cnt; /* first remove from non-hashed_subvol */ hashed_subvol = dht_subvol_get_hashed(this, &local->loc); if (!hashed_subvol) { gf_uuid_unparse(local->loc.gfid, gfid); gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "Failed to get hashed subvol for %s (gfid = %s)", local->loc.path, gfid); } else { local->hashed_subvol = hashed_subvol; } /* When DHT has only 1 child */ if (conf->subvolume_cnt == 1) { STACK_WIND_COOKIE(frame, dht_rmdir_hashed_subvol_cbk, conf->subvolumes[0], conf->subvolumes[0], conf->subvolumes[0]->fops->rmdir, &local->loc, local->flags, NULL); return 0; } local->current = &local->lock[0]; ret = dht_protect_namespace(frame, &local->loc, local->hashed_subvol, &local->current->ns, dht_rmdir_lock_cbk); if (ret < 0) { local->op_ret = -1; local->op_errno = errno ? errno : EINVAL; goto out; } return 0; out: dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, &local->preparent, &local->postparent, NULL); return 0; err: DHT_STACK_UNWIND(rmdir, frame, -1, EINVAL, NULL, NULL, NULL); return 0; } static void dht_rmdir_readdirp_done(call_frame_t *readdirp_frame, xlator_t *this) { call_frame_t *main_frame = NULL; dht_local_t *main_local = NULL; dht_local_t *local = NULL; int this_call_cnt = 0; local = readdirp_frame->local; main_frame = local->main_frame; main_local = main_frame->local; /* At least one readdirp failed. * This is a bit hit or miss - if readdirp failed on more than * one subvol, we don't know which error is returned. */ if (local->op_ret == -1) { main_local->op_ret = local->op_ret; main_local->op_errno = local->op_errno; } this_call_cnt = dht_frame_return(main_frame); if (is_last_call(this_call_cnt)) dht_rmdir_do(main_frame, this); DHT_STACK_DESTROY(readdirp_frame); } /* Keep sending readdirp on the subvol until it returns no more entries * It is possible that not all entries will fit in a single readdirp in * which case the rmdir will keep failing with ENOTEMPTY */ static int dht_rmdir_readdirp_do(call_frame_t *readdirp_frame, xlator_t *this) { dht_local_t *local = NULL; local = readdirp_frame->local; if (local->op_ret == -1) { /* there is no point doing another readdirp on this * subvol . */ dht_rmdir_readdirp_done(readdirp_frame, this); return 0; } STACK_WIND_COOKIE(readdirp_frame, dht_rmdir_readdirp_cbk, local->hashed_subvol, local->hashed_subvol, local->hashed_subvol->fops->readdirp, local->fd, 4096, 0, local->xattr); return 0; } static int dht_rmdir_linkfile_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; xlator_t *src = NULL; call_frame_t *readdirp_frame = NULL; dht_local_t *readdirp_local = NULL; int this_call_cnt = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; prev = cookie; src = prev; readdirp_frame = local->main_frame; readdirp_local = readdirp_frame->local; gf_uuid_unparse(local->loc.gfid, gfid); if (op_ret == 0) { gf_msg_trace(this->name, 0, "Unlinked linkfile %s on %s, gfid = %s", local->loc.path, src->name, gfid); } else { if (op_errno != ENOENT) { readdirp_local->op_ret = -1; readdirp_local->op_errno = op_errno; } gf_msg_debug(this->name, op_errno, "Unlink of %s on %s failed. (gfid = %s)", local->loc.path, src->name, gfid); } this_call_cnt = dht_frame_return(readdirp_frame); if (is_last_call(this_call_cnt)) dht_rmdir_readdirp_do(readdirp_frame, this); DHT_STACK_DESTROY(frame); return 0; } static int dht_rmdir_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *parent) { dht_local_t *local = NULL; xlator_t *prev = NULL; xlator_t *src = NULL; call_frame_t *readdirp_frame = NULL; dht_local_t *readdirp_local = NULL; int this_call_cnt = 0; dht_conf_t *conf = this->private; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; prev = cookie; src = prev; gf_msg_debug(this->name, 0, "dht_rmdir_lookup_cbk %s", local->loc.path); readdirp_frame = local->main_frame; readdirp_local = readdirp_frame->local; if (op_ret != 0) { gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_FILE_LOOKUP_FAILED, "lookup failed for %s on %s", local->loc.path, src->name); goto err; } if (!check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name)) { readdirp_local->op_ret = -1; readdirp_local->op_errno = ENOTEMPTY; gf_uuid_unparse(local->loc.gfid, gfid); gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_NOT_LINK_FILE_ERROR, "%s on %s is not a linkfile (type=0%o, gfid = %s)", local->loc.path, src->name, stbuf->ia_type, gfid); goto err; } STACK_WIND_COOKIE(frame, dht_rmdir_linkfile_unlink_cbk, src, src, src->fops->unlink, &local->loc, 0, NULL); return 0; err: this_call_cnt = dht_frame_return(readdirp_frame); if (is_last_call(this_call_cnt)) { dht_rmdir_readdirp_do(readdirp_frame, this); } DHT_STACK_DESTROY(frame); return 0; } static int dht_rmdir_cached_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *parent) { dht_local_t *local = NULL; xlator_t *src = NULL; call_frame_t *readdirp_frame = NULL; dht_local_t *readdirp_local = NULL; int this_call_cnt = 0; dht_conf_t *conf = this->private; dict_t *xattrs = NULL; int ret = 0; local = frame->local; src = local->hashed_subvol; /* main_frame here is the readdirp_frame */ readdirp_frame = local->main_frame; readdirp_local = readdirp_frame->local; gf_msg_debug(this->name, 0, "returning for %s ", local->loc.path); if (op_ret == 0) { readdirp_local->op_ret = -1; readdirp_local->op_errno = ENOTEMPTY; gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_SUBVOL_ERROR, "%s found on cached subvol %s", local->loc.path, src->name); goto err; } else if (op_errno != ENOENT) { readdirp_local->op_ret = -1; readdirp_local->op_errno = op_errno; gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_SUBVOL_ERROR, "%s not found on cached subvol %s", local->loc.path, src->name); goto err; } xattrs = dict_new(); if (!xattrs) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "dict_new failed"); goto err; } ret = dict_set_uint32(xattrs, conf->link_xattr_name, 256); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value: key = %s", conf->link_xattr_name); if (xattrs) dict_unref(xattrs); goto err; } STACK_WIND_COOKIE(frame, dht_rmdir_lookup_cbk, src, src, src->fops->lookup, &local->loc, xattrs); if (xattrs) dict_unref(xattrs); return 0; err: this_call_cnt = dht_frame_return(readdirp_frame); /* Once all the lookups/unlinks etc have returned, proceed to wind * readdirp on the subvol again until no entries are returned. * This is required if there are more entries than can be returned * in a single readdirp call. */ if (is_last_call(this_call_cnt)) dht_rmdir_readdirp_do(readdirp_frame, this); DHT_STACK_DESTROY(frame); return 0; } static int dht_rmdir_is_subvol_empty(call_frame_t *frame, xlator_t *this, gf_dirent_t *entries, xlator_t *src) { int ret = 0; int build_ret = 0; gf_dirent_t *trav = NULL; call_frame_t *lookup_frame = NULL; dht_local_t *lookup_local = NULL; dht_local_t *local = NULL; dict_t *xattrs = NULL; dht_conf_t *conf = this->private; xlator_t *subvol = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; int count = 0; gf_boolean_t unwind = _gf_false; local = frame->local; list_for_each_entry(trav, &entries->list, list) { /* skip . and .. */ if (inode_dir_or_parentdir(trav)) continue; if (check_is_linkfile(NULL, (&trav->d_stat), trav->dict, conf->link_xattr_name)) { count++; continue; } /* this entry is either a directory which is neither "." nor "..", or a non directory which is not a linkfile. the directory is to be treated as non-empty */ return 0; } xattrs = dict_new(); if (!xattrs) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "dict_new failed"); return -1; } ret = dict_set_uint32(xattrs, conf->link_xattr_name, 256); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value: key = %s", conf->link_xattr_name); if (xattrs) dict_unref(xattrs); return -1; } local->call_cnt = count; ret = 0; list_for_each_entry(trav, &entries->list, list) { /* skip . and .. */ if (inode_dir_or_parentdir(trav)) continue; lookup_frame = copy_frame(frame); if (!lookup_frame) { /* out of memory, let the rmdir fail (as non-empty, unfortunately) */ goto err; } lookup_local = dht_local_init(lookup_frame, NULL, NULL, GF_FOP_LOOKUP); if (!lookup_local) { goto err; } lookup_frame->local = lookup_local; lookup_local->main_frame = frame; lookup_local->hashed_subvol = src; build_ret = dht_build_child_loc(this, &lookup_local->loc, &local->loc, trav->d_name); if (build_ret != 0) goto err; gf_uuid_copy(lookup_local->loc.gfid, trav->d_stat.ia_gfid); gf_uuid_unparse(lookup_local->loc.gfid, gfid); gf_msg_trace(this->name, 0, "looking up %s on subvolume %s, gfid = %s", lookup_local->loc.path, src->name, gfid); subvol = dht_linkfile_subvol(this, NULL, &trav->d_stat, trav->dict); if (!subvol || (subvol == src)) { /* we need to delete the linkto file if it does not have a * valid subvol or it points to itself. */ gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_INVALID_LINKFILE, "Linkfile does not have link subvolume. " "path = %s, gfid = %s", lookup_local->loc.path, gfid); gf_msg_debug(this->name, 0, "looking up %s on subvol %s, gfid = %s", lookup_local->loc.path, src->name, gfid); STACK_WIND_COOKIE(lookup_frame, dht_rmdir_lookup_cbk, src, src, src->fops->lookup, &lookup_local->loc, xattrs); } else { gf_msg_debug(this->name, 0, "Looking up linkfile target %s on " " subvol %s, gfid = %s", lookup_local->loc.path, subvol->name, gfid); STACK_WIND(lookup_frame, dht_rmdir_cached_lookup_cbk, subvol, subvol->fops->lookup, &lookup_local->loc, xattrs); } ret++; lookup_frame = NULL; lookup_local = NULL; } if (xattrs) dict_unref(xattrs); return ret; err: if (xattrs) dict_unref(xattrs); if (lookup_frame) DHT_STACK_DESTROY(lookup_frame); /* Handle the case where the wound calls have unwound before the * loop processing is done */ LOCK(&frame->lock); { local->op_ret = -1; local->op_errno = ENOTEMPTY; local->call_cnt -= (count - ret); if (!local->call_cnt) unwind = _gf_true; } UNLOCK(&frame->lock); if (!unwind) { return ret; } return 0; } /* * No more entries on this subvol. Proceed to the actual rmdir operation. */ static int dht_rmdir_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; xlator_t *src = NULL; int ret = 0; char *path = NULL; local = frame->local; prev = cookie; src = prev; if (op_ret > 2) { /* dht_rmdir_is_subvol_empty() may free the frame, * copy path for logging. */ path = gf_strdup(local->loc.path); ret = dht_rmdir_is_subvol_empty(frame, this, entries, src); switch (ret) { case 0: /* non linkfiles exist */ gf_msg_trace(this->name, 0, "readdir on %s for %s returned %d " "entries", prev->name, local->loc.path, op_ret); local->op_ret = -1; local->op_errno = ENOTEMPTY; break; default: /* @ret number of linkfiles are getting unlinked */ gf_msg_trace(this->name, 0, "readdir on %s for %s found %d " "linkfiles", prev->name, path, ret); break; } } /* readdirp failed or no linkto files were found on this subvol */ if (!ret) dht_rmdir_readdirp_done(frame, this); GF_FREE(path); return 0; } static int dht_rmdir_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = -1; xlator_t *prev = NULL; int ret = 0; dht_conf_t *conf = this->private; dict_t *dict = NULL; int i = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; dht_local_t *readdirp_local = NULL; call_frame_t *readdirp_frame = NULL; int cnt = 0; local = frame->local; prev = cookie; this_call_cnt = dht_frame_return(frame); if (op_ret == -1) { gf_uuid_unparse(local->loc.gfid, gfid); gf_msg_debug(this->name, op_errno, "opendir on %s for %s failed, " "gfid = %s,", prev->name, local->loc.path, gfid); if ((op_errno != ENOENT) && (op_errno != ESTALE)) { local->op_ret = -1; local->op_errno = op_errno; } goto err; } if (!is_last_call(this_call_cnt)) return 0; if (local->op_ret == -1) goto err; fd_bind(fd); dict = dict_new(); if (!dict) { local->op_ret = -1; local->op_errno = ENOMEM; goto err; } ret = dict_set_uint32(dict, conf->link_xattr_name, 256); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "%s: Failed to set dictionary value:key = %s", local->loc.path, conf->link_xattr_name); cnt = local->call_cnt = conf->subvolume_cnt; /* Create a separate frame per subvol as we might need * to resend readdirp multiple times to get all the * entries. */ for (i = 0; i < conf->subvolume_cnt; i++) { readdirp_frame = copy_frame(frame); if (!readdirp_frame) { cnt--; /* Reduce the local->call_cnt as well */ (void)dht_frame_return(frame); continue; } readdirp_local = dht_local_init(readdirp_frame, &local->loc, local->fd, 0); if (!readdirp_local) { DHT_STACK_DESTROY(readdirp_frame); cnt--; /* Reduce the local->call_cnt as well */ dht_frame_return(frame); continue; } readdirp_local->main_frame = frame; readdirp_local->op_ret = 0; readdirp_local->xattr = dict_ref(dict); /* overload this field to save the subvol info */ readdirp_local->hashed_subvol = conf->subvolumes[i]; STACK_WIND_COOKIE(readdirp_frame, dht_rmdir_readdirp_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->readdirp, readdirp_local->fd, 4096, 0, readdirp_local->xattr); } if (dict) dict_unref(dict); /* Could not wind readdirp to any subvol */ if (!cnt) goto err; return 0; err: if (is_last_call(this_call_cnt)) { dht_rmdir_do(frame, this); } return 0; } int dht_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int op_errno = -1; int i = -1; int ret = -1; dict_t *xattr_req = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(loc->path, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = dht_local_init(frame, loc, NULL, GF_FOP_RMDIR); if (!local) { op_errno = ENOMEM; goto err; } local->call_cnt = conf->subvolume_cnt; local->op_ret = 0; local->fop_succeeded = 0; local->flags = flags; local->fd = fd_create(local->loc.inode, frame->root->pid); if (!local->fd) { op_errno = ENOMEM; goto err; } /* By default rmdir_optimize is enabled, In this case we don't need to wind a readdirp call to unlink about linkto files, After fixing the stale linkto files issue by the patch https://github.com/gluster/glusterfs/issues/3683 it is unlikely the stale linkto files exist on the backend */ if (flags || conf->rmdir_optimize) { return dht_rmdir_do(frame, this); } if (xdata) { xattr_req = dict_ref(xdata); } else { xattr_req = dict_new(); } if (xattr_req) { ret = dict_set_uint32(xattr_req, conf->link_xattr_name, 256); /* If parallel-readdir is enabled, this is required * to handle stale linkto files in the directory * being deleted. If this fails, log an error but * do not prevent the operation. */ if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "%s: failed to set key %s", loc->path, conf->link_xattr_name); } } else { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "%s: failed to set key %s", loc->path, conf->link_xattr_name); } for (i = 0; i < conf->subvolume_cnt; i++) { STACK_WIND_COOKIE(frame, dht_rmdir_opendir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->opendir, loc, local->fd, xattr_req); } if (xattr_req) { dict_unref(xattr_req); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(rmdir, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int dht_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { DHT_STACK_UNWIND(entrylk, frame, op_ret, op_errno, xdata); return 0; } /* TODO * Sending entrylk to cached subvol can result in stale lock * as described in the bug 1311002. */ int dht_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); local = dht_local_init(frame, loc, NULL, GF_FOP_ENTRYLK); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_uuid_unparse(loc->gfid, gfid); gf_msg_debug(this->name, 0, "no cached subvolume for path=%s, " "gfid = %s", loc->path, gfid); op_errno = EINVAL; goto err; } local->call_cnt = 1; STACK_WIND(frame, dht_entrylk_cbk, subvol, subvol->fops->entrylk, volume, loc, basename, cmd, type, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(entrylk, frame, -1, op_errno, NULL); return 0; } static int dht_fentrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { DHT_STACK_UNWIND(fentrylk, frame, op_ret, op_errno, NULL); return 0; } int dht_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; char gfid[GF_UUID_BUF_SIZE] = {0}; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); VALIDATE_OR_GOTO(fd->inode, err); gf_uuid_unparse(fd->inode->gfid, gfid); subvol = dht_subvol_get_cached(this, fd->inode); if (!subvol) { gf_msg_debug(this->name, 0, "No cached subvolume for fd=%p," " gfid = %s", fd, gfid); op_errno = EINVAL; goto err; } STACK_WIND(frame, dht_fentrylk_cbk, subvol, subvol->fops->fentrylk, volume, fd, basename, cmd, type, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fentrylk, frame, -1, op_errno, NULL); return 0; } static int32_t dht_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); local = frame->local; LOCK(&frame->lock); { if (op_ret < 0 && op_errno != ENOTCONN) { local->op_errno = op_errno; goto unlock; } local->op_ret = 0; } unlock: UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { DHT_STACK_UNWIND(ipc, frame, local->op_ret, local->op_errno, NULL); } out: return 0; } int32_t dht_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) { dht_local_t *local = NULL; int op_errno = EINVAL; dht_conf_t *conf = NULL; int call_cnt = 0; int i = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); if (op != GF_IPC_TARGET_UPCALL) goto wind_default; VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = dht_local_init(frame, NULL, NULL, GF_FOP_IPC); if (!local) { op_errno = ENOMEM; goto err; } call_cnt = conf->subvolume_cnt; local->call_cnt = call_cnt; if (xdata) { if (dict_set_int8(xdata, conf->xattr_name, 0) < 0) goto err; } for (i = 0; i < call_cnt; i++) { STACK_WIND(frame, dht_ipc_cbk, conf->subvolumes[i], conf->subvolumes[i]->fops->ipc, op, xdata); } return 0; err: DHT_STACK_UNWIND(ipc, frame, -1, op_errno, NULL); return 0; wind_default: STACK_WIND(frame, default_ipc_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc, op, xdata); return 0; } int dht_forget(xlator_t *this, inode_t *inode) { uint64_t ctx_int = 0; dht_inode_ctx_t *ctx = NULL; dht_layout_t *layout = NULL; inode_ctx_del(inode, this, &ctx_int); if (!ctx_int) return 0; ctx = (dht_inode_ctx_t *)(long)ctx_int; layout = ctx->layout; ctx->layout = NULL; dht_layout_unref(layout); GF_FREE(ctx); return 0; } int dht_notify(xlator_t *this, int event, void *data, ...) { xlator_t *subvol = NULL; int cnt = -1; int i = -1; dht_conf_t *conf = NULL; int ret = -1; int propagate = 0; int had_heard_from_all = 0; int have_heard_from_all = 0; gf_defrag_info_t *defrag = NULL; dict_t *dict = NULL; gf_defrag_type_t cmd = 0; dict_t *output = NULL; va_list ap; struct gf_upcall *up_data = NULL; struct gf_upcall_cache_invalidation *up_ci = NULL; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); /* had all subvolumes reported status once till now? */ had_heard_from_all = 1; for (i = 0; i < conf->subvolume_cnt; i++) { if (!conf->last_event[i]) { had_heard_from_all = 0; } } switch (event) { case GF_EVENT_CHILD_UP: subvol = data; conf->gen++; for (i = 0; i < conf->subvolume_cnt; i++) { if (subvol == conf->subvolumes[i]) { cnt = i; break; } } if (cnt == -1) { gf_msg_debug(this->name, 0, "got GF_EVENT_CHILD_UP bad " "subvolume %s", subvol->name); break; } LOCK(&conf->subvolume_lock); { conf->subvolume_status[cnt] = 1; conf->last_event[cnt] = event; conf->subvol_up_time[cnt] = gf_time(); } UNLOCK(&conf->subvolume_lock); /* one of the node came back up, do a stat update */ dht_get_du_info_for_subvol(this, cnt); break; case GF_EVENT_SOME_DESCENDENT_UP: subvol = data; conf->gen++; propagate = 1; break; case GF_EVENT_SOME_DESCENDENT_DOWN: subvol = data; propagate = 1; break; case GF_EVENT_CHILD_DOWN: subvol = data; if (conf->assert_no_child_down) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_CHILD_DOWN, "Received CHILD_DOWN. Exiting"); if (conf->defrag) { gf_defrag_stop(conf, GF_DEFRAG_STATUS_FAILED, NULL); } else { kill(getpid(), SIGTERM); } } for (i = 0; i < conf->subvolume_cnt; i++) { if (subvol == conf->subvolumes[i]) { cnt = i; break; } } if (cnt == -1) { gf_msg_debug(this->name, 0, "got GF_EVENT_CHILD_DOWN bad " "subvolume %s", subvol->name); break; } LOCK(&conf->subvolume_lock); { conf->subvolume_status[cnt] = 0; conf->last_event[cnt] = event; conf->subvol_up_time[cnt] = 0; } UNLOCK(&conf->subvolume_lock); for (i = 0; i < conf->subvolume_cnt; i++) if (conf->last_event[i] != event) event = GF_EVENT_SOME_DESCENDENT_DOWN; break; case GF_EVENT_CHILD_CONNECTING: subvol = data; for (i = 0; i < conf->subvolume_cnt; i++) { if (subvol == conf->subvolumes[i]) { cnt = i; break; } } if (cnt == -1) { gf_msg_debug(this->name, 0, "got GF_EVENT_CHILD_CONNECTING" " bad subvolume %s", subvol->name); break; } LOCK(&conf->subvolume_lock); { conf->last_event[cnt] = event; } UNLOCK(&conf->subvolume_lock); break; case GF_EVENT_VOLUME_DEFRAG: { if (!conf->defrag) { return ret; } defrag = conf->defrag; dict = data; va_start(ap, data); output = va_arg(ap, dict_t *); ret = dict_get_int32(dict, "rebalance-command", (int32_t *)&cmd); if (ret) { va_end(ap); return ret; } LOCK(&defrag->lock); { if (defrag->is_exiting) goto unlock; if ((cmd == GF_DEFRAG_CMD_STATUS) || (cmd == GF_DEFRAG_CMD_DETACH_STATUS)) gf_defrag_status_get(this, conf, output, _gf_false); else if (cmd == GF_DEFRAG_CMD_DETACH_START) defrag->cmd = GF_DEFRAG_CMD_DETACH_START; else if (cmd == GF_DEFRAG_CMD_STOP || cmd == GF_DEFRAG_CMD_DETACH_STOP) gf_defrag_stop(conf, GF_DEFRAG_STATUS_STOPPED, output); } unlock: UNLOCK(&defrag->lock); va_end(ap); return ret; break; } case GF_EVENT_UPCALL: up_data = (struct gf_upcall *)data; if (up_data->event_type != GF_UPCALL_CACHE_INVALIDATION) break; up_ci = (struct gf_upcall_cache_invalidation *)up_data->data; /* Since md-cache will be aggressively filtering lookups, * the stale layout issue will be more pronounced. Hence * when a layout xattr is changed by the rebalance process * notify all the md-cache clients to invalidate the existing * stat cache and send the lookup next time*/ if (up_ci->dict && dict_get(up_ci->dict, conf->xattr_name)) up_ci->flags |= UP_EXPLICIT_LOOKUP; /* TODO: Instead of invalidating iatt, update the new * hashed/cached subvolume in dht inode_ctx */ if (IS_DHT_LINKFILE_MODE(&up_ci->stat)) up_ci->flags |= UP_EXPLICIT_LOOKUP; propagate = 1; break; default: propagate = 1; break; } /* have all subvolumes reported status once by now? */ have_heard_from_all = 1; for (i = 0; i < conf->subvolume_cnt; i++) { if (!conf->last_event[i]) have_heard_from_all = 0; } /* if all subvols have reported status, no need to hide anything or wait for anything else. Just propagate blindly */ if (have_heard_from_all) { propagate = 1; } if (!had_heard_from_all && have_heard_from_all) { static int run_defrag = 0; /* This is the first event which completes aggregation of events from all subvolumes. If at least one subvol had come up, propagate CHILD_UP, but only this time */ event = GF_EVENT_CHILD_DOWN; for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->last_event[i] == GF_EVENT_CHILD_UP) { event = GF_EVENT_CHILD_UP; break; } if (conf->last_event[i] == GF_EVENT_CHILD_CONNECTING) { event = GF_EVENT_CHILD_CONNECTING; /* continue to check other events for CHILD_UP */ } } /* Rebalance is started with assert_no_child_down. So we do * not need to handle CHILD_DOWN event here. * * If there is a graph switch, we should not restart the * rebalance daemon. Use 'run_defrag' to indicate if the * thread has already started. */ if (conf->defrag && !run_defrag) { run_defrag = 1; ret = gf_thread_create(&conf->defrag->th, NULL, gf_defrag_start, this, "dhtdg"); if (ret) { GF_FREE(conf->defrag); conf->defrag = NULL; kill(getpid(), SIGTERM); } } } ret = 0; if (propagate) ret = default_notify(this, event, data); out: return ret; } int dht_inode_ctx_layout_get(inode_t *inode, xlator_t *this, dht_layout_t **layout) { dht_inode_ctx_t *ctx = NULL; int ret = -1; uint64_t ctx_int = 0; LOCK(&inode->lock); { ret = __inode_ctx_get(inode, this, &ctx_int); if (!ret) { ctx = (dht_inode_ctx_t *)(uintptr_t)ctx_int; if (ctx && ctx->layout) { if (layout) { *layout = ctx->layout; dht_layout_ref(ctx->layout); } } else { ret = -1; } } } UNLOCK(&inode->lock); return ret; } void dht_log_new_layout_for_dir_selfheal(xlator_t *this, loc_t *loc, dht_layout_t *layout) { char string[2048] = {0}; char *output_string = NULL; int len = 0; int off = 0; int i = 0; gf_loglevel_t log_level = gf_log_get_loglevel(); int ret = 0; if (log_level < GF_LOG_INFO) return; if (!layout) return; if (!layout->cnt) return; if (!loc) return; if (!loc->path) return; ret = snprintf(string, sizeof(string), "Setting layout of %s with ", loc->path); if (ret < 0) return; len += ret; /* Calculation of total length of the string required to calloc * output_string. Log includes subvolume-name, start-range, end-range * and err value. * * This log will help to debug cases where: * a) Different processes set different layout of a directory. * b) Error captured in lookup, which will be filled in layout->err * (like ENOENT, ESTALE etc) */ for (i = 0; i < layout->cnt; i++) { ret = snprintf(string, sizeof(string), "[Subvol_name: %s, Err: %d , Start: " "0x%x, Stop: 0x%x, Hash: 0x%x], ", layout->list[i].xlator->name, layout->list[i].err, layout->list[i].start, layout->list[i].stop, layout->list[i].commit_hash); if (ret < 0) return; len += ret; } len++; output_string = GF_MALLOC(len + 1, gf_common_mt_char); if (!output_string) return; ret = snprintf(output_string, len + 1, "Setting layout of %s with ", loc->path); if (ret < 0) goto err; off += ret; for (i = 0; i < layout->cnt; i++) { ret = snprintf(output_string + off, len - off, "[Subvol_name: %s, Err: %d , Start: " "0x%x, Stop: 0x%x, Hash: 0x%x], ", layout->list[i].xlator->name, layout->list[i].err, layout->list[i].start, layout->list[i].stop, layout->list[i].commit_hash); if (ret < 0) goto err; off += ret; } gf_msg(this->name, GF_LOG_DEBUG, 0, DHT_MSG_LOG_FIXED_LAYOUT, "%s", output_string); err: GF_FREE(output_string); } int32_t dht_migration_get_dst_subvol(xlator_t *this, dht_local_t *local) { int ret = -1; if (!local) goto out; local->rebalance.target_node = dht_subvol_get_hashed(this, &local->loc); if (local->rebalance.target_node) ret = 0; out: return ret; } /* This function should not be called more then once during a FOP handling path. It is valid only for for ops on files */ int32_t dht_set_local_rebalance(xlator_t *this, dht_local_t *local, struct iatt *stbuf, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { if (!local) return -1; if (local->rebalance.set) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_REBAL_STRUCT_SET, "local->rebalance already set"); } if (stbuf) memcpy(&local->rebalance.stbuf, stbuf, sizeof(struct iatt)); if (prebuf) memcpy(&local->rebalance.prebuf, prebuf, sizeof(struct iatt)); if (postbuf) memcpy(&local->rebalance.postbuf, postbuf, sizeof(struct iatt)); if (xdata) local->rebalance.xdata = dict_ref(xdata); local->rebalance.set = 1; return 0; } int32_t dht_release(xlator_t *this, fd_t *fd) { return dht_fd_ctx_destroy(this, fd); } static int dht_pt_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (!op_ret) { dht_layout_set(this, inode, local->layout); } DHT_STACK_UNWIND(mkdir, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, NULL); return 0; } int32_t dht_pt_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { dht_layout_t *layout = NULL; dht_conf_t *conf = NULL; dht_local_t *local = NULL; bool free_xdata = false; int ret = 0; int op_errno = 0; int32_t *disk_layout_p = NULL; conf = this->private; local = dht_local_init(frame, loc, NULL, GF_FOP_MKDIR); if (!local) { op_errno = ENOMEM; goto err; } layout = dht_layout_new(this, conf->subvolume_cnt); if (!layout) goto wind; local->layout = layout; if (!xdata) { xdata = dict_new(); if (!xdata) goto wind; free_xdata = true; } /*Set the xlator or the following will crash*/ layout->list[0].xlator = conf->subvolumes[0]; dht_selfheal_layout_new_directory(frame, loc, layout); dht_disk_layout_extract(this, layout, 0, &disk_layout_p); ret = dict_set_bin(xdata, conf->xattr_name, disk_layout_p, 4 * 4); if (ret) { gf_msg("dht", GF_LOG_DEBUG, EINVAL, DHT_MSG_DICT_SET_FAILED, "dht layout dict set failed"); } wind: STACK_WIND(frame, dht_pt_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); if (free_xdata) dict_unref(xdata); return 0; err: op_errno = local ? local->op_errno : op_errno; DHT_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int dht_pt_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { dht_conf_t *conf = NULL; conf = this->private; dict_del(xattr, conf->xattr_name); dict_del(xattr, conf->mds_xattr_key); dict_del(xattr, conf->commithash_xattr_name); if (frame->root->pid >= 0) { GF_REMOVE_INTERNAL_XATTR("trusted.glusterfs.quota*", xattr); GF_REMOVE_INTERNAL_XATTR("trusted.pgfid*", xattr); } DHT_STACK_UNWIND(getxattr, frame, op_ret, op_errno, xattr, xdata); return 0; } int dht_pt_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, dict_t *xdata) { int op_errno = EINVAL; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(this->private, err); local = dht_local_init(frame, loc, NULL, GF_FOP_GETXATTR); if (!local) { op_errno = ENOMEM; goto err; } if (key && strncmp(key, DHT_SUBVOL_STATUS_KEY, SLEN(DHT_SUBVOL_STATUS_KEY)) == 0) { dht_vgetxattr_subvol_status(frame, this, key); return 0; } STACK_WIND(frame, dht_pt_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, key, xdata); return 0; err: DHT_STACK_UNWIND(getxattr, frame, -1, op_errno, NULL, NULL); return 0; } static int dht_pt_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { dht_conf_t *conf = NULL; conf = this->private; dict_del(xattr, conf->xattr_name); if (frame->root->pid >= 0) { GF_REMOVE_INTERNAL_XATTR("trusted.glusterfs.quota*", xattr); GF_REMOVE_INTERNAL_XATTR("trusted.pgfid*", xattr); } DHT_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, xattr, xdata); return 0; } int dht_pt_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key, dict_t *xdata) { STACK_WIND(frame, dht_pt_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, key, xdata); return 0; } /* The job of this function is to check if all the xlators have updated * error in the layout. */ int dht_dir_layout_error_check(xlator_t *this, inode_t *inode) { dht_layout_t *layout = NULL; int i = 0; layout = dht_layout_get(this, inode); for (i = 0; i < layout->cnt; i++) { if (layout->list[i].err == 0) { return 0; } } /* Returning the first xlator error as all xlators have errors */ return layout->list[0].err; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-lock.h0000644000000000000000000000013214522202451022761 xustar000000000000000030 mtime=1699284265.626027308 30 atime=1699284265.626027308 30 ctime=1699284301.217134508 glusterfs-11.1/xlators/cluster/dht/src/dht-lock.h0000664000175100017510000000350314522202451023241 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _DHT_LOCK_H #define _DHT_LOCK_H #include "dht-common.h" void dht_lock_array_free(dht_lock_t **lk_array, int count); int32_t dht_lock_count(dht_lock_wrap_t *lock_wrap); dht_lock_t * dht_lock_new(xlator_t *this, xlator_t *xl, loc_t *loc, short type, const char *domain, const char *basename, dht_reaction_type_t do_on_failure); int32_t dht_unlock_entrylk_wrapper(call_frame_t *, dht_lock_wrap_t *); int32_t dht_unlock_inodelk(call_frame_t *frame, dht_lock_wrap_t *lock_wrap, fop_inodelk_cbk_t inodelk_cbk); int32_t dht_unlock_inodelk_wrapper(call_frame_t *, dht_lock_wrap_t *); /* Acquire blocking inodelk on a list of xlators. * * @lk_array: array of lock requests lock on. * * @lk_count: number of locks in @lk_array * * @inodelk_cbk: will be called after inodelk replies are received * * @retval: -1 if stack_winding inodelk fails. 0 otherwise. * inodelk_cbk is called with appropriate error on errors. * On failure to acquire lock on all members of list, successful * locks are unlocked before invoking cbk. */ int dht_blocking_inodelk(call_frame_t *frame, dht_lock_t **lk_array, int lk_count, fop_inodelk_cbk_t inodelk_cbk); void dht_unlock_namespace(call_frame_t *, dht_dir_transaction_t *); int dht_protect_namespace(call_frame_t *frame, loc_t *loc, xlator_t *subvol, struct dht_namespace *ns, fop_entrylk_cbk_t ns_cbk); #endif /* _DHT_LOCK_H */ glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-lock.c0000644000000000000000000000013214522202451022754 xustar000000000000000030 mtime=1699284265.626027308 30 atime=1699284265.626027308 30 ctime=1699284301.236134565 glusterfs-11.1/xlators/cluster/dht/src/dht-lock.c0000664000175100017510000010204014522202451023230 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-lock.h" static void dht_blocking_entrylk_rec(call_frame_t *frame, int i); static void dht_blocking_inodelk_rec(call_frame_t *frame, int i); static char * dht_lock_asprintf(dht_lock_t *lock) { char *lk_buf = NULL; if (lock) gf_asprintf(&lk_buf, "%s:%s", lock->xl->name, uuid_utoa(lock->loc.gfid)); return lk_buf; } static void dht_log_lk_array(char *name, gf_loglevel_t log_level, dht_lock_wrap_t *lock_wrap) { int i = 0; char *lk_buf = NULL; int count; dht_lock_t **lk_array; lk_array = lock_wrap->locks; count = lock_wrap->lk_count; if ((lk_array == NULL) || (count == 0)) goto out; for (i = 0; i < count; i++) { lk_buf = dht_lock_asprintf(lk_array[i]); if (!lk_buf) goto out; gf_smsg(name, log_level, 0, DHT_MSG_LK_ARRAY_INFO, "index=%d", i, "lk_buf=%s", lk_buf, NULL); GF_FREE(lk_buf); } out: return; } static void dht_lock_stack_destroy(call_frame_t *lock_frame, dht_lock_type_t lk) { dht_local_t *local = NULL; dht_lock_wrap_t *dht_lock; local = lock_frame->local; if (lk == DHT_INODELK) { dht_lock = &local->lock[0].layout.my_layout; } else { dht_lock = &local->lock[0].ns.directory_ns; } dht_lock_array_reset(dht_lock); DHT_STACK_DESTROY(lock_frame); return; } static void dht_lock_free(dht_lock_t *lock) { if (lock == NULL) goto out; loc_wipe(&lock->loc); GF_FREE(lock->domain); GF_FREE(lock->basename); mem_put(lock); out: return; } static void dht_set_lkowner(dht_lock_t **lk_array, int count, gf_lkowner_t *lkowner) { int i = 0; if (!lk_array || !lkowner) goto out; for (i = 0; i < count; i++) { lk_owner_copy(&lk_array[i]->lk_owner, lkowner); } out: return; } static int dht_lock_request_cmp(const void *val1, const void *val2) { dht_lock_t *lock1 = NULL; dht_lock_t *lock2 = NULL; int ret = -1; lock1 = *(dht_lock_t **)val1; lock2 = *(dht_lock_t **)val2; GF_VALIDATE_OR_GOTO("dht-locks", lock1, out); GF_VALIDATE_OR_GOTO("dht-locks", lock2, out); ret = strcmp(lock1->xl->name, lock2->xl->name); if (ret == 0) { ret = gf_uuid_compare(lock1->loc.gfid, lock2->loc.gfid); } out: return ret; } static int dht_lock_order_requests(dht_lock_t **locks, int count) { if (!locks || !count) return -1; qsort(locks, count, sizeof(*locks), dht_lock_request_cmp); return 0; } void dht_lock_array_free(dht_lock_t **lk_array, int count) { int i = 0; dht_lock_t *lock = NULL; if (lk_array == NULL) goto out; for (i = 0; i < count; i++) { lock = lk_array[i]; lk_array[i] = NULL; dht_lock_free(lock); } out: return; } int32_t dht_lock_count(dht_lock_wrap_t *lock_wrap) { int i = 0, locked = 0; dht_lock_t **lk_array; int lk_count; if (!lock_wrap) goto out; lk_array = lock_wrap->locks; lk_count = lock_wrap->lk_count; if ((lk_array == NULL) || (lk_count == 0)) goto out; for (i = 0; i < lk_count; i++) { if (lk_array[i]->locked) locked++; } out: return locked; } static call_frame_t * dht_lock_frame(call_frame_t *parent_frame) { call_frame_t *lock_frame = NULL; lock_frame = copy_frame(parent_frame); if (lock_frame) set_lk_owner_from_ptr(&lock_frame->root->lk_owner, parent_frame->root); return lock_frame; } dht_lock_t * dht_lock_new(xlator_t *this, xlator_t *xl, loc_t *loc, short type, const char *domain, const char *basename, dht_reaction_type_t do_on_failure) { dht_conf_t *conf = NULL; dht_lock_t *lock = NULL; conf = this->private; lock = mem_get0(conf->lock_pool); if (lock == NULL) goto out; lock->xl = xl; lock->type = type; lock->do_on_failure = do_on_failure; lock->domain = gf_strdup(domain); if (lock->domain == NULL) { dht_lock_free(lock); lock = NULL; goto out; } if (basename) { lock->basename = gf_strdup(basename); if (lock->basename == NULL) { dht_lock_free(lock); lock = NULL; goto out; } } /* Fill only inode and gfid. posix and protocol/server give preference to pargfid/basename over gfid/inode for resolution if all the three parameters of loc_t are present. I want to avoid the following hypothetical situation: 1. rebalance did a lookup on a dentry and got a gfid. 2. rebalance acquires lock on loc_t which was filled with gfid and path (pargfid/bname) from step 1. 3. somebody deleted and recreated the same file 4. rename on the same path acquires lock on loc_t which now points to a different inode (and hence gets the lock). 5. rebalance continues to migrate file (note that not all fops done by rebalance during migration are inode/gfid based Eg., unlink) 6. rename continues. */ lock->loc.inode = inode_ref(loc->inode); loc_gfid(loc, lock->loc.gfid); out: return lock; } static int dht_local_entrylk_init(call_frame_t *frame, dht_lock_t **lk_array, int lk_count, fop_entrylk_cbk_t entrylk_cbk) { int ret = -1; dht_local_t *local = NULL; dht_lock_wrap_t *directory_ns; local = frame->local; if (local == NULL) { local = dht_local_init(frame, NULL, NULL, 0); if (local == NULL) goto out; } directory_ns = &local->lock[0].ns.directory_ns; directory_ns->entrylk_cbk = entrylk_cbk; directory_ns->locks = lk_array; directory_ns->lk_count = lk_count; ret = dht_lock_order_requests(directory_ns->locks, directory_ns->lk_count); out: return ret; } static void dht_entrylk_done(call_frame_t *lock_frame) { fop_entrylk_cbk_t entrylk_cbk = NULL; call_frame_t *main_frame = NULL; dht_local_t *local = NULL; dht_lock_wrap_t *directory_ns; local = lock_frame->local; main_frame = local->main_frame; directory_ns = &local->lock[0].ns.directory_ns; dht_lock_array_reset(directory_ns); entrylk_cbk = directory_ns->entrylk_cbk; directory_ns->entrylk_cbk = NULL; entrylk_cbk(main_frame, NULL, main_frame->this, directory_ns->op_ret, directory_ns->op_errno, NULL); dht_lock_stack_destroy(lock_frame, DHT_ENTRYLK); return; } static int32_t dht_unlock_entrylk_done(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; if (op_ret < 0) { local = frame->local; gf_smsg( this->name, GF_LOG_WARNING, op_errno, DHT_MSG_UNLOCK_GFID_FAILED, "gfid=%s", uuid_utoa(local->lock[0].ns.directory_ns.locks[0]->loc.inode->gfid), "DHT_LAYOUT_HEAL_DOMAIN", NULL); } DHT_STACK_DESTROY(frame); return 0; } static int32_t dht_unlock_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; int lk_index = 0, call_cnt = 0; dht_lock_t *dht_lock; lk_index = (long)cookie; local = frame->local; dht_lock = local->lock[0].ns.directory_ns.locks[lk_index]; if (op_ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_UNLOCKING_FAILED, "name=%s", dht_lock->xl->name, "gfid=%s", uuid_utoa(dht_lock->loc.gfid), NULL); } else { dht_lock->locked = 0; } call_cnt = dht_frame_return(frame); if (is_last_call(call_cnt)) { dht_entrylk_done(frame); } return 0; } static int32_t dht_unlock_entrylk(call_frame_t *frame, dht_lock_wrap_t *directory_ns, int call_cnt, fop_entrylk_cbk_t entrylk_cbk) { dht_local_t *local = NULL; int ret = -1, i = 0; call_frame_t *lock_frame = NULL; dht_lock_t *dht_lock; lock_frame = dht_lock_frame(frame); if (lock_frame == NULL) { gf_smsg(frame->this->name, GF_LOG_WARNING, 0, DHT_MSG_ALLOC_FRAME_FAILED_NOT_UNLOCKING_FOLLOWING_ENTRYLKS, NULL); dht_log_lk_array(frame->this->name, GF_LOG_WARNING, directory_ns); goto done; } ret = dht_local_entrylk_init(lock_frame, directory_ns->locks, directory_ns->lk_count, entrylk_cbk); if (ret < 0) { gf_smsg(frame->this->name, GF_LOG_WARNING, 0, DHT_MSG_LOCAL_LOCKS_STORE_FAILED_UNLOCKING_FOLLOWING_ENTRYLK, NULL); dht_log_lk_array(frame->this->name, GF_LOG_WARNING, directory_ns); goto done; } local = lock_frame->local; local->main_frame = frame; local->call_cnt = call_cnt; for (i = 0; i < directory_ns->lk_count; i++) { dht_lock = directory_ns->locks[i]; if (!dht_lock->locked) continue; lk_owner_copy(&lock_frame->root->lk_owner, &dht_lock->lk_owner); STACK_WIND_COOKIE(lock_frame, dht_unlock_entrylk_cbk, (void *)(long)i, dht_lock->xl, dht_lock->xl->fops->entrylk, dht_lock->domain, &dht_lock->loc, dht_lock->basename, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL); if (!--call_cnt) break; } return 0; done: if (lock_frame) dht_lock_stack_destroy(lock_frame, DHT_ENTRYLK); /* no locks acquired, invoke entrylk_cbk */ if (ret == 0) entrylk_cbk(frame, NULL, frame->this, 0, 0, NULL); return ret; } int32_t dht_unlock_entrylk_wrapper(call_frame_t *frame, dht_lock_wrap_t *entrylk) { dht_local_t *local = NULL, *lock_local = NULL; call_frame_t *lock_frame = NULL; int ret = 0, call_cnt; dht_lock_wrap_t *directory_ns; local = frame->local; if (!entrylk || !entrylk->locks) goto out; lock_frame = copy_frame(frame); if (lock_frame == NULL) { gf_smsg(frame->this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_COPY_FRAME_FAILED, "pgfid=%s", uuid_utoa(local->loc.parent->gfid), "name=%s", local->loc.name, "path=%s", local->loc.path, NULL); goto done; } lock_local = dht_local_init(lock_frame, NULL, NULL, 0); if (lock_local == NULL) { gf_smsg(frame->this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_CREATE_FAILED, "local", "pgfid=%s", uuid_utoa(local->loc.parent->gfid), "name=%s", local->loc.name, "path=%s", local->loc.path, NULL); goto done; } lock_frame->local = lock_local; directory_ns = &lock_local->lock[0].ns.directory_ns; directory_ns->locks = entrylk->locks; directory_ns->lk_count = entrylk->lk_count; dht_lock_array_reset(entrylk); call_cnt = dht_lock_count(directory_ns); if (call_cnt) { ret = dht_unlock_entrylk(lock_frame, directory_ns, call_cnt, dht_unlock_entrylk_done); if (ret) goto done; } lock_frame = NULL; done: if (lock_frame != NULL) { DHT_STACK_DESTROY(lock_frame); } out: return 0; } static int dht_entrylk_cleanup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_entrylk_done(frame); return 0; } static void dht_entrylk_cleanup(call_frame_t *lock_frame) { int lk_acquired = 0; dht_local_t *local = NULL; dht_lock_wrap_t *directory_ns; local = lock_frame->local; directory_ns = &local->lock[0].ns.directory_ns; lk_acquired = dht_lock_count(directory_ns); if (lk_acquired != 0) { dht_unlock_entrylk(lock_frame, directory_ns, lk_acquired, dht_entrylk_cleanup_cbk); } else { dht_entrylk_done(lock_frame); } return; } static int32_t dht_blocking_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { int lk_index = 0; int i = 0; dht_local_t *local = NULL; dht_lock_wrap_t *directory_ns; lk_index = (long)cookie; local = frame->local; directory_ns = &local->lock[0].ns.directory_ns; if (op_ret == 0) { directory_ns->locks[lk_index]->locked = _gf_true; } else { switch (op_errno) { case ESTALE: case ENOENT: if (directory_ns->locks[lk_index]->do_on_failure != IGNORE_ENOENT_ESTALE) { directory_ns->op_ret = -1; directory_ns->op_errno = op_errno; goto cleanup; } break; default: directory_ns->op_ret = -1; directory_ns->op_errno = op_errno; goto cleanup; } } if (lk_index == (directory_ns->lk_count - 1)) { for (i = 0; (i < directory_ns->lk_count) && (!directory_ns->locks[i]->locked); i++) ; if (i == directory_ns->lk_count) { directory_ns->op_ret = -1; directory_ns->op_errno = op_errno; } dht_entrylk_done(frame); } else { dht_blocking_entrylk_rec(frame, ++lk_index); } return 0; cleanup: dht_entrylk_cleanup(frame); return 0; } static void dht_blocking_entrylk_rec(call_frame_t *frame, int i) { dht_local_t *local = NULL; dht_lock_t *dht_lock; local = frame->local; dht_lock = local->lock[0].ns.directory_ns.locks[i]; STACK_WIND_COOKIE(frame, dht_blocking_entrylk_cbk, (void *)(long)i, dht_lock->xl, dht_lock->xl->fops->entrylk, dht_lock->domain, &dht_lock->loc, dht_lock->basename, ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL); return; } static int dht_blocking_entrylk(call_frame_t *frame, dht_lock_t **lk_array, int lk_count, fop_entrylk_cbk_t entrylk_cbk) { int ret = -1; call_frame_t *lock_frame = NULL; dht_local_t *local = NULL; GF_VALIDATE_OR_GOTO(frame->this->name, lk_array, out); lock_frame = dht_lock_frame(frame); if (lock_frame == NULL) goto out; ret = dht_local_entrylk_init(lock_frame, lk_array, lk_count, entrylk_cbk); if (ret < 0) { goto out; } dht_set_lkowner(lk_array, lk_count, &lock_frame->root->lk_owner); local = lock_frame->local; local->main_frame = frame; dht_blocking_entrylk_rec(lock_frame, 0); return 0; out: if (lock_frame) dht_lock_stack_destroy(lock_frame, DHT_ENTRYLK); return -1; } static int dht_local_inodelk_init(call_frame_t *frame, dht_lock_t **lk_array, int lk_count, fop_inodelk_cbk_t inodelk_cbk) { int ret = -1; dht_local_t *local = NULL; dht_lock_wrap_t *my_layout; local = frame->local; if (local == NULL) { local = dht_local_init(frame, NULL, NULL, 0); if (local == NULL) goto out; } my_layout = &local->lock[0].layout.my_layout; my_layout->inodelk_cbk = inodelk_cbk; my_layout->locks = lk_array; my_layout->lk_count = lk_count; ret = dht_lock_order_requests(my_layout->locks, my_layout->lk_count); out: return ret; } static void dht_inodelk_done(call_frame_t *lock_frame) { fop_inodelk_cbk_t inodelk_cbk = NULL; call_frame_t *main_frame = NULL; dht_local_t *local = NULL; dht_lock_wrap_t *my_layout; local = lock_frame->local; main_frame = local->main_frame; my_layout = &local->lock[0].layout.my_layout; dht_lock_array_reset(my_layout); inodelk_cbk = my_layout->inodelk_cbk; my_layout->inodelk_cbk = NULL; inodelk_cbk(main_frame, NULL, main_frame->this, my_layout->op_ret, my_layout->op_errno, NULL); dht_lock_stack_destroy(lock_frame, DHT_INODELK); return; } static int32_t dht_unlock_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; int lk_index = 0, call_cnt = 0; dht_lock_t *dht_lock; lk_index = (long)cookie; local = frame->local; dht_lock = local->lock[0].layout.my_layout.locks[lk_index]; if (op_ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_UNLOCKING_FAILED, "name=%s", dht_lock->xl->name, "gfid=%s", uuid_utoa(dht_lock->loc.gfid), NULL); } else { dht_lock->locked = 0; } call_cnt = dht_frame_return(frame); if (is_last_call(call_cnt)) { dht_inodelk_done(frame); } return 0; } static int32_t dht_unlock_inodelk_done(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; if (op_ret < 0) { local = frame->local; gf_smsg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_UNLOCK_GFID_FAILED, "DHT_LAYOUT_HEAL_DOMAIN gfid=%s", uuid_utoa( local->lock[0].layout.my_layout.locks[0]->loc.inode->gfid), NULL); } DHT_STACK_DESTROY(frame); return 0; } int32_t dht_unlock_inodelk(call_frame_t *frame, dht_lock_wrap_t *lock_wrap, fop_inodelk_cbk_t inodelk_cbk) { dht_local_t *local = NULL; struct gf_flock flock = { 0, }; int ret = -1, i = 0; call_frame_t *lock_frame = NULL; int call_cnt = 0, lk_count; dht_lock_t **lk_array; dht_lock_t *dht_lock; GF_VALIDATE_OR_GOTO("dht-locks", frame, done); GF_VALIDATE_OR_GOTO(frame->this->name, lock_wrap, done); lk_array = lock_wrap->locks; GF_VALIDATE_OR_GOTO(frame->this->name, lk_array, done); lk_count = lock_wrap->lk_count; GF_VALIDATE_OR_GOTO(frame->this->name, inodelk_cbk, done); call_cnt = dht_lock_count(lock_wrap); if (call_cnt == 0) { ret = 0; goto done; } lock_frame = dht_lock_frame(frame); if (lock_frame == NULL) { gf_smsg(frame->this->name, GF_LOG_WARNING, 0, DHT_MSG_ALLOC_FRAME_FAILED_NOT_UNLOCKING_FOLLOWING_ENTRYLKS, NULL); dht_log_lk_array(frame->this->name, GF_LOG_WARNING, lock_wrap); goto done; } ret = dht_local_inodelk_init(lock_frame, lk_array, lk_count, inodelk_cbk); if (ret < 0) { gf_smsg(frame->this->name, GF_LOG_WARNING, 0, DHT_MSG_LOCAL_LOCKS_STORE_FAILED_UNLOCKING_FOLLOWING_ENTRYLK, NULL); dht_log_lk_array(frame->this->name, GF_LOG_WARNING, lock_wrap); goto done; } local = lock_frame->local; local->main_frame = frame; local->call_cnt = call_cnt; flock.l_type = F_UNLCK; for (i = 0; i < local->lock[0].layout.my_layout.lk_count; i++) { dht_lock = local->lock[0].layout.my_layout.locks[i]; if (!dht_lock->locked) continue; lk_owner_copy(&lock_frame->root->lk_owner, &dht_lock->lk_owner); STACK_WIND_COOKIE(lock_frame, dht_unlock_inodelk_cbk, (void *)(long)i, dht_lock->xl, dht_lock->xl->fops->inodelk, dht_lock->domain, &dht_lock->loc, F_SETLK, &flock, NULL); if (!--call_cnt) break; } return 0; done: if (lock_frame) dht_lock_stack_destroy(lock_frame, DHT_INODELK); /* no locks acquired, invoke inodelk_cbk */ if (ret == 0) inodelk_cbk(frame, NULL, frame->this, 0, 0, NULL); return ret; } int32_t dht_unlock_inodelk_wrapper(call_frame_t *frame, dht_lock_wrap_t *inodelk) { dht_local_t *local = NULL, *lock_local = NULL; call_frame_t *lock_frame = NULL; int ret = 0; dht_lock_wrap_t *my_layout; if (!inodelk || !inodelk->locks) goto out; lock_frame = copy_frame(frame); if (lock_frame == NULL) { local = frame->local; gf_smsg(frame->this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_COPY_FRAME_FAILED, "pgfid=%s", uuid_utoa(local->loc.parent->gfid), "name=%s", local->loc.name, "path=%s", local->loc.path, NULL); goto done; } lock_local = dht_local_init(lock_frame, NULL, NULL, 0); if (lock_local == NULL) { local = frame->local; gf_smsg(frame->this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_CREATE_FAILED, "local", "gfid=%s", uuid_utoa(local->loc.parent->gfid), "name=%s", local->loc.name, "path=%s", local->loc.path, NULL); goto done; } lock_frame->local = lock_local; my_layout = &lock_local->lock[0].layout.my_layout; my_layout->locks = inodelk->locks; my_layout->lk_count = inodelk->lk_count; dht_lock_array_reset(inodelk); ret = dht_unlock_inodelk(lock_frame, my_layout, dht_unlock_inodelk_done); if (ret) goto done; lock_frame = NULL; done: if (lock_frame != NULL) { DHT_STACK_DESTROY(lock_frame); } out: return 0; } static int dht_inodelk_cleanup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_inodelk_done(frame); return 0; } static void dht_inodelk_cleanup(call_frame_t *lock_frame) { int lk_acquired = 0; dht_local_t *local = NULL; dht_lock_wrap_t *my_layout; local = lock_frame->local; my_layout = &local->lock[0].layout.my_layout; lk_acquired = dht_lock_count(my_layout); if (lk_acquired != 0) { dht_unlock_inodelk(lock_frame, my_layout, dht_inodelk_cleanup_cbk); } else { dht_inodelk_done(lock_frame); } return; } static int32_t dht_blocking_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { int lk_index = 0; int i = 0; dht_local_t *local = NULL; dht_reaction_type_t reaction = 0; dht_lock_wrap_t *my_layout; dht_lock_t *dht_lock; lk_index = (long)cookie; local = frame->local; my_layout = &local->lock[0].layout.my_layout; dht_lock = my_layout->locks[lk_index]; if (op_ret == 0) { dht_lock->locked = _gf_true; } else { switch (op_errno) { case ESTALE: case ENOENT: reaction = dht_lock->do_on_failure; if ((reaction != IGNORE_ENOENT_ESTALE) && (reaction != IGNORE_ENOENT_ESTALE_EIO)) { my_layout->op_ret = -1; my_layout->op_errno = op_errno; gf_smsg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_INODELK_FAILED, "subvol=%s", dht_lock->xl->name, "gfid=%s", uuid_utoa(dht_lock->loc.gfid), NULL); goto cleanup; } break; case EIO: reaction = dht_lock->do_on_failure; if (reaction != IGNORE_ENOENT_ESTALE_EIO) { my_layout->op_ret = -1; my_layout->op_errno = op_errno; gf_smsg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_INODELK_FAILED, "subvol=%s", dht_lock->xl->name, "gfid=%s", uuid_utoa(dht_lock->loc.gfid), NULL); goto cleanup; } break; default: my_layout->op_ret = -1; my_layout->op_errno = op_errno; gf_smsg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_INODELK_FAILED, "subvol=%s", dht_lock->xl->name, "gfid=%s", uuid_utoa(dht_lock->loc.gfid), NULL); goto cleanup; } } if (lk_index == (my_layout->lk_count - 1)) { for (i = 0; (i < my_layout->lk_count) && (!dht_lock->locked); i++) ; if (i == my_layout->lk_count) { my_layout->op_ret = -1; my_layout->op_errno = op_errno; } dht_inodelk_done(frame); } else { dht_blocking_inodelk_rec(frame, ++lk_index); } return 0; cleanup: dht_inodelk_cleanup(frame); return 0; } static void dht_blocking_inodelk_rec(call_frame_t *frame, int i) { dht_local_t *local = NULL; struct gf_flock flock = { 0, }; dht_lock_t *dht_lock; local = frame->local; dht_lock = local->lock[0].layout.my_layout.locks[i]; flock.l_type = dht_lock->type; STACK_WIND_COOKIE(frame, dht_blocking_inodelk_cbk, (void *)(long)i, dht_lock->xl, dht_lock->xl->fops->inodelk, dht_lock->domain, &dht_lock->loc, F_SETLKW, &flock, NULL); return; } int dht_blocking_inodelk(call_frame_t *frame, dht_lock_t **lk_array, int lk_count, fop_inodelk_cbk_t inodelk_cbk) { int ret = -1; call_frame_t *lock_frame = NULL; dht_local_t *local = NULL; dht_local_t *tmp_local = NULL; GF_VALIDATE_OR_GOTO("dht-locks", frame, out); GF_VALIDATE_OR_GOTO(frame->this->name, lk_array, out); GF_VALIDATE_OR_GOTO(frame->this->name, inodelk_cbk, out); lock_frame = dht_lock_frame(frame); if (lock_frame == NULL) { tmp_local = frame->local; gf_smsg("dht", GF_LOG_ERROR, ENOMEM, DHT_MSG_LOCK_FRAME_FAILED, "gfid=%s", uuid_utoa(tmp_local->loc.gfid), "path=%s", tmp_local->loc.path, NULL); goto out; } ret = dht_local_inodelk_init(lock_frame, lk_array, lk_count, inodelk_cbk); if (ret < 0) { tmp_local = frame->local; gf_smsg("dht", GF_LOG_ERROR, ENOMEM, DHT_MSG_LOCAL_LOCK_INIT_FAILED, "gfid=%s", uuid_utoa(tmp_local->loc.gfid), "path=%s", tmp_local->loc.path, NULL); goto out; } dht_set_lkowner(lk_array, lk_count, &lock_frame->root->lk_owner); local = lock_frame->local; local->main_frame = frame; dht_blocking_inodelk_rec(lock_frame, 0); return 0; out: if (lock_frame) dht_lock_stack_destroy(lock_frame, DHT_INODELK); return -1; } void dht_unlock_namespace(call_frame_t *frame, dht_dir_transaction_t *lock) { GF_VALIDATE_OR_GOTO("dht-locks", frame, out); GF_VALIDATE_OR_GOTO(frame->this->name, lock, out); dht_unlock_entrylk_wrapper(frame, &lock->ns.directory_ns); dht_unlock_inodelk_wrapper(frame, &lock->ns.parent_layout); out: return; } static int32_t dht_protect_namespace_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (op_ret != 0) dht_unlock_inodelk_wrapper(frame, &local->current->ns.parent_layout); local->current->ns.ns_cbk(frame, cookie, this, op_ret, op_errno, xdata); return 0; } static int32_t dht_blocking_entrylk_after_inodelk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; int ret = -1; loc_t *loc = NULL; dht_lock_t **lk_array = NULL; int count = 0; dht_lock_wrap_t *entrylk = NULL; local = frame->local; entrylk = &local->current->ns.directory_ns; if (op_ret < 0) { local->op_ret = -1; local->op_errno = op_errno; goto err; } local->op_ret = 0; lk_array = entrylk->locks; count = entrylk->lk_count; ret = dht_blocking_entrylk(frame, lk_array, count, dht_protect_namespace_cbk); if (ret < 0) { local->op_ret = -1; local->op_errno = EIO; loc = &entrylk->locks[0]->loc; gf_smsg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_ENTRYLK_FAILED_AFT_INODELK, "fop=%s", gf_fop_list[local->fop], "pgfid=%s", uuid_utoa(loc->gfid), "basename=%s", entrylk->locks[0]->basename, NULL); goto err; } return 0; err: if (lk_array != NULL) { dht_lock_array_free(lk_array, count); GF_FREE(lk_array); dht_lock_array_reset(entrylk); } /* Unlock inodelk. No harm calling unlock twice */ dht_unlock_inodelk_wrapper(frame, &local->current->ns.parent_layout); /* Call ns_cbk. It will take care of unwinding */ local->current->ns.ns_cbk(frame, NULL, this, local->op_ret, local->op_errno, NULL); return 0; } /* Given the loc and the subvol, this routine takes the inodelk on * the parent inode and entrylk on (parent, loc->name). This routine * is specific as it supports only one subvol on which it takes inodelk * and then entrylk serially. */ int dht_protect_namespace(call_frame_t *frame, loc_t *loc, xlator_t *subvol, struct dht_namespace *ns, fop_entrylk_cbk_t ns_cbk) { dht_lock_wrap_t *inodelk = NULL; dht_lock_wrap_t *entrylk = NULL; dht_lock_t **lk_array = NULL; dht_local_t *local = NULL; xlator_t *this = NULL; loc_t parent = { 0, }; int ret = -1; int32_t op_errno = 0; int count = 1; GF_VALIDATE_OR_GOTO("dht-locks", frame, out); this = frame->this; GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->parent, out); GF_VALIDATE_OR_GOTO(this->name, subvol, out); local = frame->local; inodelk = &ns->parent_layout; entrylk = &ns->directory_ns; /* Initialize entrylk_cbk and parent loc */ ns->ns_cbk = ns_cbk; ret = dht_build_parent_loc(this, &parent, loc, &op_errno); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_LOC_FAILED, "gfid=%s", uuid_utoa(loc->gfid), "name=%s", loc->name, "path=%s", loc->path, NULL); goto out; } /* Alloc inodelk */ inodelk->locks = GF_CALLOC(count, sizeof(*lk_array), gf_common_mt_pointer); if (inodelk->locks == NULL) { local->op_errno = ENOMEM; gf_smsg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_CALLOC_FAILED, "fop=%s", gf_fop_list[local->fop], "pgfid=%s", uuid_utoa(parent.gfid), "name=%s", loc->name, "path=%s", loc->path, NULL); goto out; } inodelk->locks[0] = dht_lock_new(this, subvol, &parent, F_RDLCK, DHT_LAYOUT_HEAL_DOMAIN, NULL, FAIL_ON_ANY_ERROR); if (inodelk->locks[0] == NULL) { local->op_errno = ENOMEM; gf_smsg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_LOCK_ALLOC_FAILED, "inodelk-fop=%s", gf_fop_list[local->fop], "pgfid=%s", uuid_utoa(parent.gfid), "name=%s", loc->name, "path=%s", loc->path, NULL); goto err; } inodelk->lk_count = count; /* Allock entrylk */ entrylk->locks = GF_CALLOC(count, sizeof(*lk_array), gf_common_mt_pointer); if (entrylk->locks == NULL) { local->op_errno = ENOMEM; gf_smsg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_CALLOC_FAILED, "entrylk-fop=%s", gf_fop_list[local->fop], "pgfid=%s", uuid_utoa(parent.gfid), "name=%s", loc->name, "path=%s", loc->path, NULL); goto err; } entrylk->locks[0] = dht_lock_new(this, subvol, &parent, F_WRLCK, DHT_ENTRY_SYNC_DOMAIN, loc->name, FAIL_ON_ANY_ERROR); if (entrylk->locks[0] == NULL) { local->op_errno = ENOMEM; gf_smsg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_LOCK_ALLOC_FAILED, "entrylk-fop=%s", gf_fop_list[local->fop], "pgfid=%s", uuid_utoa(parent.gfid), "name=%s", loc->name, "path=%s", loc->path, NULL); goto err; } entrylk->lk_count = count; /* Take read inodelk on parent. If it is successful, take write entrylk * on name in cbk. */ lk_array = inodelk->locks; ret = dht_blocking_inodelk(frame, lk_array, count, dht_blocking_entrylk_after_inodelk); if (ret < 0) { local->op_errno = EIO; gf_smsg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_BLOCK_INODELK_FAILED, "fop=%s", gf_fop_list[local->fop], "pgfid=%s", uuid_utoa(parent.gfid), "name=%s", loc->name, "path=%s", loc->path, NULL); goto err; } loc_wipe(&parent); return 0; err: if (entrylk->locks != NULL) { dht_lock_array_free(entrylk->locks, count); GF_FREE(entrylk->locks); dht_lock_array_reset(entrylk); } if (inodelk->locks != NULL) { dht_lock_array_free(inodelk->locks, count); GF_FREE(inodelk->locks); dht_lock_array_reset(inodelk); } loc_wipe(&parent); out: return -1; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-rebalance.c0000644000000000000000000000013214522202451023740 xustar000000000000000030 mtime=1699284265.628027314 30 atime=1699284265.627027311 30 ctime=1699284301.223134526 glusterfs-11.1/xlators/cluster/dht/src/dht-rebalance.c0000664000175100017510000043345214522202451024232 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-common.h" #include #include #include #include #include "glusterfs/compat-errno.h" // for ENODATA on BSD #define GF_DISK_SECTOR_SIZE 512 #define DHT_REBALANCE_PID 4242 /* Change it if required */ #define DHT_REBALANCE_BLKSIZE 1048576 /* 1 MB */ #define MAX_MIGRATE_QUEUE_COUNT 500 #define MIN_MIGRATE_QUEUE_COUNT 200 #define MAX_REBAL_TYPE_SIZE 16 #define FILE_CNT_INTERVAL 600 /* 10 mins */ #define ESTIMATE_START_INTERVAL 600 /* 10 mins */ #define HARDLINK_MIG_INPROGRESS -2 #define SKIP_MIGRATION_FD_POSITIVE -3 #define GF_CRAWL_INDEX_MOVE(idx, sv_cnt) \ { \ idx++; \ idx %= sv_cnt; \ } static int dht_migrate_file(xlator_t *this, loc_t *loc, xlator_t *cached_subvol, xlator_t *hashed_subvol, int flag, int *fop_errno); static void gf_defrag_free_dir_dfmeta(struct dir_dfmeta *meta, int local_subvols_cnt) { int i = 0; if (meta) { for (i = 0; i < local_subvols_cnt; i++) { if (meta->equeue) gf_dirent_free(&meta->equeue[i]); if (meta->lfd && meta->lfd[i]) fd_unref(meta->lfd[i]); } GF_FREE(meta->equeue); GF_FREE(meta->head); GF_FREE(meta->iterator); GF_FREE(meta->offset_var); GF_FREE(meta->fetch_entries); GF_FREE(meta->lfd); GF_FREE(meta); } } static void gf_defrag_free_container(dht_container_t *container) { if (container) { gf_dirent_entry_free(container->df_entry); if (container->parent_loc) { loc_wipe(container->parent_loc); } GF_FREE(container->parent_loc); GF_FREE(container); } } static void dht_set_global_defrag_error(gf_defrag_info_t *defrag, int ret) { LOCK(&defrag->lock); { defrag->global_error = ret; } UNLOCK(&defrag->lock); return; } static int dht_send_rebalance_event(xlator_t *this, int cmd, gf_defrag_status_t status) { int ret = -1; char *volname = NULL; char *tmpstr = NULL; char *ptr = NULL; char *suffix = "-dht"; int len = 0; eventtypes_t event = EVENT_LAST; switch (status) { case GF_DEFRAG_STATUS_COMPLETE: event = EVENT_VOLUME_REBALANCE_COMPLETE; break; case GF_DEFRAG_STATUS_FAILED: event = EVENT_VOLUME_REBALANCE_FAILED; break; case GF_DEFRAG_STATUS_STOPPED: event = EVENT_VOLUME_REBALANCE_STOP; break; default: break; } /* DHT volume */ len = strlen(this->name) - strlen(suffix); tmpstr = gf_strdup(this->name); if (tmpstr) { ptr = tmpstr + len; if (!strcmp(ptr, suffix)) { tmpstr[len] = '\0'; volname = tmpstr; } } if (!volname) { /* Better than nothing */ volname = this->name; } if (event != EVENT_LAST) { gf_event(event, "volume=%s", volname); } GF_FREE(tmpstr); return ret; } static void dht_strip_out_acls(dict_t *dict) { if (dict) { dict_del(dict, "trusted.SGI_ACL_FILE"); dict_del(dict, POSIX_ACL_ACCESS_XATTR); } } /* return values: -1 : failure -2 : success Hard link migration is carried out in three stages. (Say there are n hardlinks) Stage 1: Setting the new hashed subvol information on the 1st hardlink encountered (linkto setxattr) Stage 2: Creating hardlinks on new hashed subvol for the 2nd to (n-1)th hardlink Stage 3: Physical migration of the data file for nth hardlink Why to deem "-2" as success and not "0": dht_migrate_file expects return value "0" from _is_file_migratable if the file has to be migrated. _is_file_migratable returns zero only when it is called with the flag "GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS". gf_defrag_handle_hardlink calls dht_migrate_file for physical migration of the data file with the flag "GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS" Hence, gf_defrag_handle_hardlink returning "0" for success will force "dht_migrate_file" to migrate each of the hardlink which is not intended. For each of the three stage mentioned above "-2" will be returned and will be converted to "0" in dht_migrate_file. */ int32_t gf_defrag_handle_hardlink(xlator_t *this, loc_t *loc, int *fop_errno) { int32_t ret = -1; xlator_t *cached_subvol = NULL; xlator_t *hashed_subvol = NULL; xlator_t *linkto_subvol = NULL; data_t *data = NULL; struct iatt iatt = { 0, }; int32_t op_errno = 0; dht_conf_t *conf = NULL; gf_loglevel_t loglevel = 0; dict_t *link_xattr = NULL; dict_t *dict = NULL; dict_t *xattr_rsp = NULL; struct iatt stbuf = { 0, }; *fop_errno = EINVAL; GF_VALIDATE_OR_GOTO("defrag", loc, out); GF_VALIDATE_OR_GOTO("defrag", loc->name, out); GF_VALIDATE_OR_GOTO("defrag", this, out); GF_VALIDATE_OR_GOTO("defrag", this->private, out); conf = this->private; if (gf_uuid_is_null(loc->pargfid)) { gf_msg("", GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed :" "loc->pargfid is NULL for %s", loc->path); *fop_errno = EINVAL; ret = -1; goto out; } if (gf_uuid_is_null(loc->gfid)) { gf_msg("", GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed :" "loc->gfid is NULL for %s", loc->path); *fop_errno = EINVAL; ret = -1; goto out; } link_xattr = dict_new(); if (!link_xattr) { ret = -1; *fop_errno = ENOMEM; goto out; } /* Parallel migration can lead to migration of the hard link multiple times which can lead to data loss. Hence, adding a fresh lookup to decide whether migration is required or not. Elaborating the scenario for let say 10 hardlinks [link{1..10}]: Let say the first hard link "link1" does the setxattr of the new hashed subvolume info on the cached file. As there are multiple threads working, we might have already all the links created on the new hashed by the time we reach hardlink let say link5. Now the number of links on hashed is equal to that of cached. Hence, file migration will happen for link6. Cached Hashed --------T link6 rwxrwxrwx link6 Now post above state all the link file on the cached will be zero byte linkto files. Hence, if we still do migration for the following files link{7..10}, we will end up migrating 0 data leading to data loss. Hence, a lookup can make sure whether we need to migrate the file or not. */ dict = dict_new(); if (!dict) { ret = -1; *fop_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "could not allocate memory for dict"); goto out; } ret = dict_set_int32(dict, conf->link_xattr_name, 256); if (ret) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: failed to set 'linkto' key in dict", loc->path); goto out; } ret = syncop_lookup(this, loc, &stbuf, NULL, dict, &xattr_rsp); if (ret) { /*Ignore ENOENT and ESTALE as file might have been migrated already*/ if (-ret == ENOENT || -ret == ESTALE) { ret = -2; goto out; } gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:%s lookup failed with ret = %d", loc->path, ret); *fop_errno = -ret; ret = -1; goto out; } cached_subvol = dht_subvol_get_cached(this, loc->inode); if (!cached_subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed :" "Failed to get cached subvol" " for %s on %s", loc->name, this->name); *fop_errno = EINVAL; ret = -1; goto out; } hashed_subvol = dht_subvol_get_hashed(this, loc); if (!hashed_subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed :" "Failed to get hashed subvol" " for %s on %s", loc->name, this->name); *fop_errno = EINVAL; ret = -1; goto out; } /* Hardlink migration happens only with remove-brick. So this condition will * be true only when the migration has happened. In case hardlinks are * migrated for rebalance case, remove this check. Having this check here * avoid redundant calls below*/ if (hashed_subvol == cached_subvol) { ret = -2; goto out; } gf_log(this->name, GF_LOG_INFO, "Attempting to migrate hardlink %s " "with gfid %s from %s -> %s", loc->name, uuid_utoa(loc->gfid), cached_subvol->name, hashed_subvol->name); data = dict_get(xattr_rsp, conf->link_xattr_name); /* set linkto on cached -> hashed if not present, else link it */ if (!data) { ret = dict_set_str(link_xattr, conf->link_xattr_name, hashed_subvol->name); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed :" "Failed to set dictionary value:" " key = %s for %s", conf->link_xattr_name, loc->name); *fop_errno = ENOMEM; ret = -1; goto out; } ret = syncop_setxattr(cached_subvol, loc, link_xattr, 0, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed :" "Linkto setxattr failed %s -> %s", cached_subvol->name, loc->name); *fop_errno = -ret; ret = -1; goto out; } gf_msg_debug(this->name, 0, "hardlink target subvol created on %s " ",cached %s, file %s", hashed_subvol->name, cached_subvol->name, loc->path); ret = -2; goto out; } else { linkto_subvol = dht_linkfile_subvol(this, NULL, NULL, xattr_rsp); if (!linkto_subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SUBVOL_ERROR, "Failed to get " "linkto subvol for %s", loc->name); } else { hashed_subvol = linkto_subvol; } ret = syncop_link(hashed_subvol, loc, loc, &iatt, NULL, NULL); if (ret) { op_errno = -ret; ret = -1; loglevel = (op_errno == EEXIST) ? GF_LOG_DEBUG : GF_LOG_ERROR; gf_msg(this->name, loglevel, op_errno, DHT_MSG_MIGRATE_HARDLINK_FILE_FAILED, "link of %s -> %s" " failed on subvol %s", loc->name, uuid_utoa(loc->gfid), hashed_subvol->name); if (op_errno != EEXIST) { *fop_errno = op_errno; goto out; } } else { gf_msg_debug(this->name, 0, "syncop_link successful for" " hardlink %s on subvol %s, cached %s", loc->path, hashed_subvol->name, cached_subvol->name); } } ret = syncop_lookup(hashed_subvol, loc, &iatt, NULL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed :Failed lookup %s on %s ", loc->name, hashed_subvol->name); *fop_errno = -ret; ret = -1; goto out; } /* There is a race where on the target subvol for the hardlink * (note: hash subvol for the hardlink might differ from this), some * other client(non-rebalance) would have created a linkto file for that * hardlink as part of lookup. So let say there are 10 hardlinks, on the * 5th hardlink it self the hardlinks might have migrated. Now for * (6..10th) hardlinks the cached and target would be same as the file * has already migrated. Hence this check is needed */ if (cached_subvol == hashed_subvol) { gf_msg_debug(this->name, 0, "source %s and destination %s " "for hardlink %s are same", cached_subvol->name, hashed_subvol->name, loc->path); ret = -2; goto out; } if (iatt.ia_nlink == stbuf.ia_nlink) { ret = dht_migrate_file(this, loc, cached_subvol, hashed_subvol, GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS, fop_errno); if (ret) { goto out; } } ret = -2; out: if (link_xattr) dict_unref(link_xattr); if (xattr_rsp) dict_unref(xattr_rsp); if (dict) dict_unref(dict); return ret; } static int __check_file_has_hardlink(xlator_t *this, loc_t *loc, struct iatt *stbuf, dict_t *xattrs, int flags, dht_conf_t *conf, int *fop_errno) { int ret = 0; if (flags == GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS) { ret = 0; return ret; } if (stbuf->ia_nlink > 1) { /* support for decomission */ if (flags == GF_DHT_MIGRATE_HARDLINK) { synclock_lock(&conf->link_lock); ret = gf_defrag_handle_hardlink(this, loc, fop_errno); synclock_unlock(&conf->link_lock); /* Returning zero will force the file to be remigrated. Checkout gf_defrag_handle_hardlink for more information. */ if (ret && ret != -2) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: failed to migrate file with link", loc->path); } } else { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migration skipped for:" "%s: file has hardlinks", loc->path); *fop_errno = ENOTSUP; ret = 1; } } return ret; } /* return values 0 : File will be migrated -2 : File will not be migrated (This is the return value from gf_defrag_handle_hardlink. Checkout gf_defrag_handle_hardlink for description of "returning -2") -1 : failure */ static int __is_file_migratable(xlator_t *this, loc_t *loc, struct iatt *stbuf, dict_t *xattrs, int flags, dht_conf_t *conf, int *fop_errno) { int ret = -1; int lock_count = 0; if (IA_ISDIR(stbuf->ia_type)) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: migrate-file called on directory", loc->path); *fop_errno = EISDIR; ret = -1; goto out; } if (!conf->lock_migration_enabled) { ret = dict_get_int32(xattrs, GLUSTERFS_POSIXLK_COUNT, &lock_count); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: Unable to get lock count for file", loc->path); *fop_errno = EINVAL; ret = -1; goto out; } if (lock_count) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed: %s: File has locks." " Skipping file migration", loc->path); *fop_errno = ENOTSUP; ret = 1; goto out; } } /* Check if file has hardlink*/ ret = __check_file_has_hardlink(this, loc, stbuf, xattrs, flags, conf, fop_errno); out: return ret; } static int __dht_rebalance_create_dst_file(xlator_t *this, xlator_t *to, xlator_t *from, loc_t *loc, struct iatt *stbuf, fd_t **dst_fd, int *fop_errno, int file_has_holes) { int ret = -1; int ret2 = -1; fd_t *fd = NULL; struct iatt new_stbuf = { 0, }; struct iatt check_stbuf = { 0, }; dht_conf_t *conf = NULL; dict_t *dict = NULL; dict_t *xdata = NULL; conf = this->private; dict = dict_new(); if (!dict) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "dictionary allocation failed for" "path:%s", loc->path); goto out; } ret = dict_set_gfuuid(dict, "gfid-req", stbuf->ia_gfid, true); if (ret) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "%s: failed to set dictionary value: key = gfid-req", loc->path); goto out; } ret = dict_set_str(dict, conf->link_xattr_name, from->name); if (ret) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "%s: failed to set dictionary value: key = %s ", loc->path, conf->link_xattr_name); goto out; } fd = fd_create(loc->inode, DHT_REBALANCE_PID); if (!fd) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_MIGRATE_FILE_FAILED, "%s: fd create failed (destination)", loc->path); goto out; } xdata = dict_new(); if (!xdata) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_MIGRATE_FILE_FAILED, "%s: dict_new failed)", loc->path); goto out; } ret = dict_set_int32_sizen(xdata, GF_CLEAN_WRITE_PROTECTION, 1); if (ret) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "%s: failed to set dictionary value: key = %s ", loc->path, GF_CLEAN_WRITE_PROTECTION); goto out; } ret = syncop_lookup(to, loc, &new_stbuf, NULL, xdata, NULL); if (!ret) { /* File exits in the destination, check if gfid matches */ if (gf_uuid_compare(stbuf->ia_gfid, new_stbuf.ia_gfid) != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_GFID_MISMATCH, "file %s exists in %s with different gfid", loc->path, to->name); *fop_errno = EINVAL; ret = -1; goto out; } } if ((ret < 0) && (-ret != ENOENT)) { /* File exists in destination, but not accessible */ gf_msg(THIS->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to lookup file", loc->path); *fop_errno = -ret; ret = -1; goto out; } /* Create the destination with LINKFILE mode, and linkto xattr, if the linkfile already exists, just open the file */ if (!ret) { /* * File already present, just open the file. */ ret = syncop_open(to, loc, O_RDWR, fd, NULL, NULL); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "failed to open %s on %s", loc->path, to->name); *fop_errno = -ret; ret = -1; goto out; } } else { ret = syncop_create(to, loc, O_RDWR, DHT_LINKFILE_MODE, fd, NULL, dict, NULL); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "failed to create %s on %s", loc->path, to->name); *fop_errno = -ret; ret = -1; goto out; } } fd_bind(fd); /*Reason of doing lookup after create again: *In the create, there is some time-gap between opening fd at the *server (posix_layer) and binding it in server (incrementing fd count), *so if in that time-gap, if other process sends unlink considering it *as a linkto file, because inode->fd count will be 0, so file will be *unlinked at the backend. And because further operations are performed *on fd, so though migration will be done but will end with no file *at the backend. */ ret = syncop_lookup(to, loc, &check_stbuf, NULL, NULL, NULL); if (!ret) { if (gf_uuid_compare(stbuf->ia_gfid, check_stbuf.ia_gfid) != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_GFID_MISMATCH, "file %s exists in %s with different gfid," "found in lookup after create", loc->path, to->name); *fop_errno = EINVAL; ret = -1; goto out; } } if (-ret == ENOENT) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: file does not exist" "on %s", loc->path, to->name); *fop_errno = -ret; ret = -1; goto out; } ret = syncop_fsetattr(to, fd, stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID), NULL, NULL, NULL, NULL); if (ret < 0) { *fop_errno = -ret; gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "chown failed for %s on %s", loc->path, to->name); } /* No need to bother about 0 byte size files */ if (stbuf->ia_size > 0) { if (conf->use_fallocate && !file_has_holes) { ret = syncop_fallocate(to, fd, 0, 0, stbuf->ia_size, NULL, NULL); if (ret < 0) { if (ret == -EOPNOTSUPP || ret == -EINVAL || ret == -ENOSYS) { conf->use_fallocate = _gf_false; } else { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "fallocate failed for %s on %s", loc->path, to->name); *fop_errno = -ret; /* fallocate does not release the space * in some cases */ ret2 = syncop_ftruncate(to, fd, 0, NULL, NULL, NULL, NULL); if (ret2 < 0) { gf_msg(this->name, GF_LOG_WARNING, -ret2, DHT_MSG_MIGRATE_FILE_FAILED, "ftruncate failed for " "%s on %s", loc->path, to->name); } goto out; } } } else { ret = syncop_ftruncate(to, fd, stbuf->ia_size, NULL, NULL, NULL, NULL); if (ret < 0) { *fop_errno = -ret; gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "ftruncate failed for %s on %s", loc->path, to->name); } } } /* success */ ret = 0; if (dst_fd) *dst_fd = fd; out: if (ret) { if (fd) { fd_unref(fd); } } if (dict) dict_unref(dict); if (xdata) dict_unref(xdata); return ret; } static int __dht_check_free_space(xlator_t *this, xlator_t *to, xlator_t *from, loc_t *loc, struct iatt *stbuf, int flag, dht_conf_t *conf, gf_boolean_t *target_changed, xlator_t **new_subvol, int *fop_errno) { struct statvfs src_statfs = { 0, }; struct statvfs dst_statfs = { 0, }; int ret = -1; dict_t *xdata = NULL; dht_layout_t *layout = NULL; uint64_t src_statfs_blocks = 1; uint64_t dst_statfs_blocks = 1; double dst_post_availspacepercent = 0; double src_post_availspacepercent = 0; uint64_t file_blocks = 0; uint64_t src_total_blocks = 0; uint64_t dst_total_blocks = 0; xdata = dict_new(); if (!xdata) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "failed to allocate dictionary"); goto out; } ret = dict_set_int8(xdata, GF_INTERNAL_IGNORE_DEEM_STATFS, 1); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to set " GF_INTERNAL_IGNORE_DEEM_STATFS " in dict"); ret = -1; *fop_errno = ENOMEM; goto out; } ret = syncop_statfs(from, loc, &src_statfs, xdata, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "failed to get statfs of %s on %s", loc->path, from->name); *fop_errno = -ret; ret = -1; goto out; } ret = syncop_statfs(to, loc, &dst_statfs, xdata, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "failed to get statfs of %s on %s", loc->path, to->name); *fop_errno = -ret; ret = -1; goto out; } gf_msg_debug(this->name, 0, "min_free_disk - %f , block available - %" PRId64 ", block size - %lu", conf->min_free_disk, dst_statfs.f_bavail, dst_statfs.f_bsize); dst_statfs_blocks = dst_statfs.f_bavail * (dst_statfs.f_frsize / GF_DISK_SECTOR_SIZE); src_statfs_blocks = src_statfs.f_bavail * (src_statfs.f_frsize / GF_DISK_SECTOR_SIZE); dst_total_blocks = dst_statfs.f_blocks * (dst_statfs.f_frsize / GF_DISK_SECTOR_SIZE); src_total_blocks = src_statfs.f_blocks * (src_statfs.f_frsize / GF_DISK_SECTOR_SIZE); /* if force option is given, do not check for space @ dst. * Check only if space is avail for the file */ if (flag != GF_DHT_MIGRATE_DATA) goto check_avail_space; /* Check: During rebalance `migrate-data` - Destination subvol experiences a `reduction` in 'blocks' of free space, at the same time source subvol gains certain 'blocks' of free space. A valid check is necessary here to avoid erroneous move to destination where the space could be scantily available. With heterogeneous brick support, an actual space comparison could prevent any files being migrated to newly added bricks if they are smaller then the free space available on the existing bricks. */ if (!conf->use_fallocate) { file_blocks = stbuf->ia_size + GF_DISK_SECTOR_SIZE - 1; file_blocks /= GF_DISK_SECTOR_SIZE; if (file_blocks >= dst_statfs_blocks) { dst_statfs_blocks = 0; } else { dst_statfs_blocks -= file_blocks; } } src_post_availspacepercent = ((src_statfs_blocks + file_blocks) * 100) / src_total_blocks; dst_post_availspacepercent = (dst_statfs_blocks * 100) / dst_total_blocks; if (dst_post_availspacepercent < src_post_availspacepercent) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_MIGRATE_FILE_FAILED, "data movement of file " "{blocks:%" PRIu64 " name:(%s)} would result in " "dst node (%s:%" PRIu64 ") having lower disk " "space than the source node (%s:%" PRIu64 ")" ".Skipping file.", stbuf->ia_blocks, loc->path, to->name, dst_statfs_blocks, from->name, src_statfs_blocks); /* this is not a 'failure', but we don't want to consider this as 'success' too :-/ */ *fop_errno = ENOSPC; ret = 1; goto out; } check_avail_space: if (conf->disk_unit_percent && dst_statfs.f_blocks) { dst_post_availspacepercent = (dst_statfs_blocks * 100) / dst_total_blocks; gf_msg_debug(this->name, 0, "file : %s, post_availspacepercent" " : %lf f_bavail : %" PRIu64 " min-free-disk: %lf", loc->path, dst_post_availspacepercent, dst_statfs.f_bavail, conf->min_free_disk); if (dst_post_availspacepercent < conf->min_free_disk) { gf_msg(this->name, GF_LOG_WARNING, 0, 0, "Write will cross min-free-disk for " "file - %s on subvol - %s. Looking " "for new subvol", loc->path, to->name); goto find_new_subvol; } else { ret = 0; goto out; } } if (!conf->disk_unit_percent) { if ((dst_statfs_blocks * GF_DISK_SECTOR_SIZE) < conf->min_free_disk) { gf_msg_debug(this->name, 0, "file : %s, destination frsize: %lu " "f_bavail : %" PRIu64 " min-free-disk: %lf", loc->path, dst_statfs.f_frsize, dst_statfs.f_bavail, conf->min_free_disk); gf_msg(this->name, GF_LOG_WARNING, 0, 0, "write will" " cross min-free-disk for file - %s on subvol -" " %s. looking for new subvol", loc->path, to->name); goto find_new_subvol; } else { ret = 0; goto out; } } find_new_subvol: layout = dht_layout_get(this, loc->parent); if (!layout) { gf_log(this->name, GF_LOG_ERROR, "Layout is NULL"); *fop_errno = EINVAL; ret = -1; goto out; } *new_subvol = dht_subvol_with_free_space_inodes(this, to, from, layout, stbuf->ia_size); if ((!(*new_subvol)) || (*new_subvol == from)) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_SUBVOL_INSUFF_SPACE, "Could not find any subvol" " with space accommodating the file - %s. Consider " "adding bricks", loc->path); *target_changed = _gf_false; *fop_errno = ENOSPC; ret = -1; } else { gf_msg(this->name, GF_LOG_INFO, 0, 0, "new target found - %s" " for file - %s", (*new_subvol)->name, loc->path); *target_changed = _gf_true; ret = 0; } out: if (xdata) dict_unref(xdata); return ret; } static int32_t dht_rebalance_sparse_segment(xlator_t *subvol, fd_t *fd, off_t *offset, size_t *size) { off_t hole; int32_t ret; do { ret = syncop_seek(subvol, fd, *offset, GF_SEEK_DATA, NULL, offset); if (ret >= 0) { /* Starting at the offset of the last data segment, find the * next hole. After a data segment there should always be a * hole, since EOF is considered a hole. */ ret = syncop_seek(subvol, fd, *offset, GF_SEEK_HOLE, NULL, &hole); } if (ret < 0) { if (ret == -ENXIO) { /* This can happen if there are no more data segments (i.e. * the offset is at EOF), or there was a data segment but the * file has been truncated to a smaller size between both * seek requests. In both cases we are done. The file doesn't * contain more data. */ ret = 0; } return ret; } /* It could happen that at the same offset we detected data in the * first seek, there could be a hole in the second seek if user is * modifying the file concurrently. In this case we need to find a * new data segment to migrate. */ } while (hole <= *offset); /* Calculate the total size of the current data block */ *size = hole - *offset; return 1; } static int __dht_rebalance_migrate_data(xlator_t *this, xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst, uint64_t ia_size, int hole_exists, int *fop_errno) { int ret = 0; int count = 0; off_t offset = 0; struct iovec *vector = NULL; struct iobref *iobref = NULL; uint64_t total = 0; size_t read_size = 0; size_t data_block_size = 0; dict_t *xdata = NULL; dht_conf_t *conf = NULL; conf = this->private; /* if file size is '0', no need to enter this loop */ while (total < ia_size) { /* This is a regular file - read it sequentially */ if (!hole_exists) { data_block_size = ia_size - total; } else { /* This is a sparse file - read only the data segments in the file */ /* If the previous data block is fully copied, find the next data * segment starting at the offset of the last read and written * byte. */ if (data_block_size <= 0) { ret = dht_rebalance_sparse_segment(from, src, &offset, &data_block_size); if (ret <= 0) { *fop_errno = -ret; break; } } } /* Calculate how much data needs to be read and written. If the data * segment's length is bigger than DHT_REBALANCE_BLKSIZE, read and * write DHT_REBALANCE_BLKSIZE data length and the rest in the * next iteration(s) */ read_size = ((data_block_size > DHT_REBALANCE_BLKSIZE) ? DHT_REBALANCE_BLKSIZE : data_block_size); /* Calculate the remaining size of the data block - maybe there's no * need to seek for data in the next iteration */ data_block_size -= read_size; ret = syncop_readv(from, src, read_size, offset, 0, &vector, &count, &iobref, NULL, NULL, NULL); if (!ret || (ret < 0)) { if (!ret) { /* File was probably truncated*/ ret = -1; *fop_errno = ENOSPC; } else { *fop_errno = -ret; } break; } if (!conf->force_migration) { if (!xdata) { xdata = dict_new(); if (!xdata) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "insufficient memory"); ret = -1; *fop_errno = ENOMEM; break; } /* Fail this write and abort rebalance if we * detect a write from client since migration of * this file started. This is done to avoid * potential data corruption due to out of order * writes from rebalance and client to the same * region (as compared between src and dst * files). See * https://github.com/gluster/glusterfs/issues/308 * for more details. */ ret = dict_set_int32_sizen(xdata, GF_AVOID_OVERWRITE, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, ENOMEM, "failed to set dict"); ret = -1; *fop_errno = ENOMEM; break; } } } ret = syncop_writev(to, dst, vector, count, offset, iobref, 0, NULL, NULL, xdata, NULL); if (ret < 0) { *fop_errno = -ret; break; } offset += ret; total += ret; GF_FREE(vector); if (iobref) iobref_unref(iobref); iobref = NULL; vector = NULL; } if (iobref) iobref_unref(iobref); GF_FREE(vector); if (ret >= 0) ret = 0; else ret = -1; if (xdata) { dict_unref(xdata); } return ret; } static int __dht_rebalance_open_src_file(xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc, struct iatt *stbuf, fd_t **src_fd, gf_boolean_t *clean_src, int *fop_errno) { int ret = 0; fd_t *fd = NULL; dict_t *dict = NULL; struct iatt iatt = { 0, }; dht_conf_t *conf = NULL; conf = this->private; *clean_src = _gf_false; fd = fd_create(loc->inode, DHT_REBALANCE_PID); if (!fd) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "%s: fd create failed (source)", loc->path); *fop_errno = ENOMEM; ret = -1; goto out; } ret = syncop_open(from, loc, O_RDWR, fd, NULL, NULL); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "failed to open file %s on %s", loc->path, from->name); *fop_errno = -ret; ret = -1; goto out; } fd_bind(fd); if (src_fd) *src_fd = fd; ret = -1; dict = dict_new(); if (!dict) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "%s: Could not allocate memory for dict", loc->path); *fop_errno = ENOMEM; ret = -1; goto out; } ret = dict_set_str(dict, conf->link_xattr_name, to->name); if (ret) { gf_log(this->name, GF_LOG_ERROR, "failed to set xattr in dict for %s (linkto:%s)", loc->path, to->name); *fop_errno = ENOMEM; ret = -1; goto out; } /* Once the migration starts, the source should have 'linkto' key set to show which is the target, so other clients can work around it */ ret = syncop_setxattr(from, loc, dict, 0, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "failed to set xattr on %s in %s", loc->path, from->name); *fop_errno = -ret; ret = -1; goto out; } /* Reset source mode/xattr if migration fails*/ *clean_src = _gf_true; /* mode should be (+S+T) to indicate migration is in progress */ iatt.ia_prot = stbuf->ia_prot; iatt.ia_type = stbuf->ia_type; iatt.ia_prot.sticky = 1; iatt.ia_prot.sgid = 1; ret = syncop_setattr(from, loc, &iatt, GF_SET_ATTR_MODE, NULL, NULL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "failed to set mode on %s in %s", loc->path, from->name); *fop_errno = -ret; ret = -1; goto out; } /* success */ ret = 0; out: if (dict) dict_unref(dict); return ret; } static int migrate_special_files(xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc, struct iatt *buf, int *fop_errno) { int ret = -1; dict_t *rsp_dict = NULL; dict_t *dict = NULL; char *link = NULL; struct iatt stbuf = { 0, }; dht_conf_t *conf = this->private; dict = dict_new(); if (!dict) { *fop_errno = ENOMEM; ret = -1; goto out; } ret = dict_set_int32(dict, conf->link_xattr_name, 256); if (ret) { *fop_errno = ENOMEM; ret = -1; gf_log(this->name, GF_LOG_ERROR, "%s: failed to set 'linkto' key in dict", loc->path); goto out; } /* check in the destination if the file is link file */ ret = syncop_lookup(to, loc, &stbuf, NULL, dict, &rsp_dict); if ((ret < 0) && (-ret != ENOENT)) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: lookup failed", loc->path); *fop_errno = -ret; ret = -1; goto out; } /* we no more require this key */ dict_del(dict, conf->link_xattr_name); /* file exists in target node, only if it is 'linkfile' its valid, otherwise, error out */ if (!ret) { if (!check_is_linkfile(loc->inode, &stbuf, rsp_dict, conf->link_xattr_name)) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_MIGRATE_FILE_FAILED, "%s: file exists in destination", loc->path); *fop_errno = EINVAL; ret = -1; goto out; } /* as file is linkfile, delete it */ ret = syncop_unlink(to, loc, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to delete the linkfile", loc->path); *fop_errno = -ret; ret = -1; goto out; } } /* Set the gfid of the source file in dict */ ret = dict_set_gfuuid(dict, "gfid-req", buf->ia_gfid, true); if (ret) { *fop_errno = ENOMEM; ret = -1; gf_log(this->name, GF_LOG_ERROR, "%s: failed to set gfid in dict for create", loc->path); goto out; } /* Create the file in target */ if (IA_ISLNK(buf->ia_type)) { /* Handle symlinks separately */ ret = syncop_readlink(from, loc, &link, buf->ia_size, NULL, NULL); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: readlink on symlink failed", loc->path); *fop_errno = -ret; ret = -1; goto out; } ret = syncop_symlink(to, loc, link, 0, dict, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: creating symlink failed", loc->path); *fop_errno = -ret; ret = -1; goto out; } goto done; } ret = syncop_mknod(to, loc, st_mode_from_ia(buf->ia_prot, buf->ia_type), makedev(ia_major(buf->ia_rdev), ia_minor(buf->ia_rdev)), 0, dict, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: mknod failed", loc->path); *fop_errno = -ret; ret = -1; goto out; } done: ret = syncop_setattr(to, loc, buf, (GF_SET_ATTR_MTIME | GF_SET_ATTR_UID | GF_SET_ATTR_GID | GF_SET_ATTR_MODE), NULL, NULL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to perform setattr on %s", loc->path, to->name); *fop_errno = -ret; } ret = syncop_unlink(from, loc, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: unlink failed", loc->path); *fop_errno = -ret; ret = -1; } out: GF_FREE(link); if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); return ret; } static int __dht_migration_cleanup_src_file(xlator_t *this, loc_t *loc, fd_t *fd, xlator_t *from, ia_prot_t *src_ia_prot) { int ret = -1; dht_conf_t *conf = NULL; struct iatt new_stbuf = { 0, }; if (!this || !fd || !from || !src_ia_prot) { goto out; } conf = this->private; /*Revert source mode and xattr changes*/ ret = syncop_fstat(from, fd, &new_stbuf, NULL, NULL); if (ret < 0) { /* Failed to get the stat info */ gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file cleanup failed: failed to fstat " "file %s on %s ", loc->path, from->name); ret = -1; goto out; } /* Remove the sticky bit and sgid bit set, reset it to 0*/ if (!src_ia_prot->sticky) new_stbuf.ia_prot.sticky = 0; if (!src_ia_prot->sgid) new_stbuf.ia_prot.sgid = 0; ret = syncop_fsetattr(from, fd, &new_stbuf, (GF_SET_ATTR_GID | GF_SET_ATTR_MODE), NULL, NULL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file cleanup failed:" "%s: failed to perform fsetattr on %s ", loc->path, from->name); ret = -1; goto out; } ret = syncop_fremovexattr(from, fd, conf->link_xattr_name, 0, NULL); if (ret) { gf_log(this->name, GF_LOG_WARNING, "%s: failed to remove linkto xattr on %s (%s)", loc->path, from->name, strerror(-ret)); ret = -1; goto out; } ret = 0; out: return ret; } /* return values: -1 : failure 0 : successfully migrated data 1 : not a failure, but we can't migrate data as of now */ static int dht_migrate_file(xlator_t *this, loc_t *loc, xlator_t *cached_subvol, xlator_t *hashed_subvol, int flag, int *fop_errno) { int ret = -1; struct iatt new_stbuf = { 0, }; struct iatt stbuf = { 0, }; struct iatt empty_iatt = { 0, }; ia_prot_t src_ia_prot = { 0, }; fd_t *src_fd = NULL; fd_t *dst_fd = NULL; dict_t *dict = NULL; dict_t *xattr = NULL; dict_t *xattr_rsp = NULL; int file_has_holes = 0; dht_conf_t *conf = this->private; int rcvd_enoent_from_src = 0; struct gf_flock flock = { 0, }; struct gf_flock plock = { 0, }; loc_t tmp_loc = { 0, }; loc_t parent_loc = { 0, }; gf_boolean_t inodelk_locked = _gf_false; gf_boolean_t entrylk_locked = _gf_false; gf_boolean_t p_locked = _gf_false; int lk_ret = -1; gf_boolean_t clean_src = _gf_false; gf_boolean_t clean_dst = _gf_false; int log_level = GF_LOG_INFO; gf_boolean_t delete_src_linkto = _gf_true; lock_migration_info_t locklist; dict_t *meta_dict = NULL; gf_boolean_t meta_locked = _gf_false; gf_boolean_t target_changed = _gf_false; xlator_t *new_target = NULL; xlator_t *old_target = NULL; fd_t *linkto_fd = NULL; dict_t *xdata = NULL; gf_log(this->name, log_level, "%s: attempting to move from %s to %s", loc->path, cached_subvol->name, hashed_subvol->name); dict = dict_new(); if (!dict) { ret = -1; *fop_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "Could not allocate memory for dict"); goto out; } ret = dict_set_int32(dict, conf->link_xattr_name, 256); if (ret) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: failed to set 'linkto' key in dict", loc->path); goto out; } /* Do not migrate file in case lock migration is not enabled on the * volume*/ if (!conf->lock_migration_enabled) { ret = dict_set_int32(dict, GLUSTERFS_POSIXLK_COUNT, sizeof(int32_t)); if (ret) { *fop_errno = ENOMEM; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed: %s: failed to " "set " GLUSTERFS_POSIXLK_COUNT " key in dict", loc->path); goto out; } } else { gf_msg(this->name, GF_LOG_INFO, 0, 0, "locks will be migrated" " for file: %s", loc->path); } /* The file is locked to prevent a rename during a migration. Renames * and migrations on the file at the same time can lead to data loss. */ ret = dht_build_parent_loc(this, &parent_loc, loc, fop_errno); if (ret < 0) { ret = -1; gf_msg(this->name, GF_LOG_WARNING, *fop_errno, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to build parent loc, which is needed to " "acquire entrylk to synchronize with renames on this " "path. Skipping migration", loc->path); goto out; } flock.l_type = F_WRLCK; tmp_loc.inode = inode_ref(loc->inode); gf_uuid_copy(tmp_loc.gfid, loc->gfid); tmp_loc.path = gf_strdup(loc->path); /* this inodelk happens with flock.owner being zero. But to synchronize * hardlink migration we need to have different lkowner for each migration * Filed a bug here: https://bugzilla.redhat.com/show_bug.cgi?id=1468202 to * track the fix for this. Currently synclock takes care of synchronizing * hardlink migration. Once this bug is fixed we can avoid taking synclock */ ret = syncop_inodelk(cached_subvol, DHT_FILE_MIGRATE_DOMAIN, &tmp_loc, F_SETLKW, &flock, NULL, NULL); if (ret < 0) { *fop_errno = -ret; ret = -1; gf_msg(this->name, GF_LOG_WARNING, *fop_errno, DHT_MSG_MIGRATE_FILE_FAILED, "migrate file failed: " "%s: failed to lock file on %s", loc->path, cached_subvol->name); goto out; } inodelk_locked = _gf_true; /* dht_rename has changed to use entrylk on hashed subvol for * synchronization. So, rebalance too has to acquire an entrylk on * hashed subvol. */ ret = syncop_entrylk(hashed_subvol, DHT_ENTRY_SYNC_DOMAIN, &parent_loc, loc->name, ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL, NULL); if (ret < 0) { *fop_errno = -ret; ret = -1; gf_msg(this->name, GF_LOG_WARNING, *fop_errno, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to acquire entrylk on subvol %s", loc->path, hashed_subvol->name); goto out; } entrylk_locked = _gf_true; /* Phase 1 - Data migration is in progress from now on */ ret = syncop_lookup(cached_subvol, loc, &stbuf, NULL, dict, &xattr_rsp); if (ret) { *fop_errno = -ret; ret = -1; gf_msg(this->name, GF_LOG_ERROR, *fop_errno, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: lookup failed on %s", loc->path, cached_subvol->name); goto out; } /* preserve source mode, so set the same to the destination */ src_ia_prot = stbuf.ia_prot; /* Check if file can be migrated */ ret = __is_file_migratable(this, loc, &stbuf, xattr_rsp, flag, conf, fop_errno); if (ret) { if (ret == HARDLINK_MIG_INPROGRESS) ret = 0; goto out; } /* Take care of the special files */ if (!IA_ISREG(stbuf.ia_type)) { /* Special files */ ret = migrate_special_files(this, cached_subvol, hashed_subvol, loc, &stbuf, fop_errno); goto out; } /* Try to preserve 'holes' while migrating data */ if (stbuf.ia_size > (stbuf.ia_blocks * GF_DISK_SECTOR_SIZE)) file_has_holes = 1; /* create the destination, with required modes/xattr */ ret = __dht_rebalance_create_dst_file(this, hashed_subvol, cached_subvol, loc, &stbuf, &dst_fd, fop_errno, file_has_holes); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "Create dst failed" " on - %s for file - %s", hashed_subvol->name, loc->path); goto out; } clean_dst = _gf_true; ret = __dht_check_free_space(this, hashed_subvol, cached_subvol, loc, &stbuf, flag, conf, &target_changed, &new_target, fop_errno); if (target_changed) { /* Can't handle for hardlinks. Marking this as failure */ if (flag == GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS || stbuf.ia_nlink > 1) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SUBVOL_INSUFF_SPACE, "Exiting migration for" " file - %s. flag - %d, stbuf.ia_nlink - %d", loc->path, flag, stbuf.ia_nlink); ret = -1; goto out; } ret = syncop_ftruncate(hashed_subvol, dst_fd, 0, NULL, NULL, NULL, NULL); if (ret) { gf_log(this->name, GF_LOG_WARNING, "%s: failed to perform truncate on %s (%s)", loc->path, hashed_subvol->name, strerror(-ret)); } syncop_close(dst_fd); dst_fd = NULL; old_target = hashed_subvol; hashed_subvol = new_target; clean_dst = _gf_false; /* if the file migration is successful to this new target, then * update the xattr on the old destination to point the new * destination. We need to do update this only post migration * as in case of failure the linkto needs to point to the source * subvol */ ret = __dht_rebalance_create_dst_file( this, hashed_subvol, cached_subvol, loc, &stbuf, &dst_fd, fop_errno, file_has_holes); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Create dst failed" " on - %s for file - %s", hashed_subvol->name, loc->path); goto out; } else { gf_msg(this->name, GF_LOG_INFO, 0, 0, "destination for file " "- %s is changed to - %s", loc->path, hashed_subvol->name); clean_dst = _gf_true; } } if (ret) { goto out; } /* Open the source, and also update mode/xattr */ ret = __dht_rebalance_open_src_file(this, cached_subvol, hashed_subvol, loc, &stbuf, &src_fd, &clean_src, fop_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed: failed to open %s on %s", loc->path, cached_subvol->name); goto out; } /* TODO: move all xattr related operations to fd based operations */ ret = syncop_listxattr(cached_subvol, loc, &xattr, NULL, NULL); if (ret < 0) { *fop_errno = -ret; gf_msg(this->name, GF_LOG_WARNING, *fop_errno, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: failed to get xattr from %s", loc->path, cached_subvol->name); ret = -1; goto out; } /* Copying posix acls to the linkto file messes up the permissions*/ dht_strip_out_acls(xattr); /* Remove the linkto xattr as we don't want to overwrite the value * set on the dst. */ dict_del(xattr, conf->link_xattr_name); /* We need to error out if this fails as having the wrong shard xattrs * set on the dst could cause data corruption */ ret = syncop_fsetxattr(hashed_subvol, dst_fd, xattr, 0, NULL, NULL); if (ret < 0) { *fop_errno = -ret; gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to set xattr on %s", loc->path, hashed_subvol->name); ret = -1; goto out; } if (xattr_rsp) { /* we no more require this key */ dict_del(dict, conf->link_xattr_name); dict_unref(xattr_rsp); } ret = syncop_fstat(cached_subvol, src_fd, &stbuf, dict, &xattr_rsp); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:failed to lookup %s on %s ", loc->path, cached_subvol->name); *fop_errno = -ret; ret = -1; goto out; } /* Check again if file has hardlink */ ret = __check_file_has_hardlink(this, loc, &stbuf, xattr_rsp, flag, conf, fop_errno); if (ret) { if (ret == HARDLINK_MIG_INPROGRESS) ret = 0; goto out; } ret = __dht_rebalance_migrate_data(this, cached_subvol, hashed_subvol, src_fd, dst_fd, stbuf.ia_size, file_has_holes, fop_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed: %s: failed to migrate data", loc->path); ret = -1; goto out; } /* TODO: Sync the locks */ if (conf->ensure_durability) { xdata = dict_new(); if (!xdata || dict_set_int8(xdata, "last-fsync", 1)) { gf_log(this->name, GF_LOG_ERROR, "%s: failed to set last-fsync flag on " "%s (%s)", loc->path, hashed_subvol->name, strerror(ENOMEM)); } ret = syncop_fsync(hashed_subvol, dst_fd, 0, NULL, NULL, xdata, NULL); if (ret) { gf_log(this->name, GF_LOG_WARNING, "%s: failed to fsync on %s (%s)", loc->path, hashed_subvol->name, strerror(-ret)); *fop_errno = -ret; ret = -1; goto out; } } /* Phase 2 - Data-Migration Complete, Housekeeping updates pending */ ret = syncop_fstat(cached_subvol, src_fd, &new_stbuf, NULL, NULL); if (ret < 0) { /* Failed to get the stat info */ gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed: failed to fstat file %s on %s ", loc->path, cached_subvol->name); *fop_errno = -ret; ret = -1; goto out; } /* Lock the entire source file to prevent clients from taking a lock on it as dht_lk does not handle file migration. This still leaves a small window where conflicting locks can be granted to different clients. If client1 requests a blocking lock on the src file, it will be granted after the migrating process releases its lock. If client2 requests a lock on the dst data file, it will also be granted, but all FOPs will be redirected to the dst data file. */ /* Take meta lock */ if (conf->lock_migration_enabled) { meta_dict = dict_new(); if (!meta_dict) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "dict_new failed"); *fop_errno = ENOMEM; ret = -1; goto out; } ret = dict_set_str(meta_dict, GLUSTERFS_INTERNAL_FOP_KEY, "yes"); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value: key = %s," " path = %s", GLUSTERFS_INTERNAL_FOP_KEY, loc->path); *fop_errno = ENOMEM; ret = -1; goto out; } ret = dict_set_int32(meta_dict, GF_META_LOCK_KEY, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Trace dict_set failed"); *fop_errno = ENOMEM; ret = -1; goto out; } ret = syncop_setxattr(cached_subvol, loc, meta_dict, 0, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Trace syncop_setxattr metalock failed"); *fop_errno = -ret; ret = -1; goto out; } else { meta_locked = _gf_true; } } if (!conf->lock_migration_enabled) { plock.l_type = F_WRLCK; plock.l_start = 0; plock.l_len = 0; plock.l_whence = SEEK_SET; ret = syncop_lk(cached_subvol, src_fd, F_SETLK, &plock, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: Failed to lock on %s", loc->path, cached_subvol->name); *fop_errno = -ret; ret = -1; goto out; } p_locked = _gf_true; } else { INIT_LIST_HEAD(&locklist.list); ret = syncop_getactivelk(cached_subvol, loc, &locklist, NULL, NULL); if (ret == 0) { gf_log(this->name, GF_LOG_INFO, "No active locks on:%s", loc->path); } else if (ret > 0) { ret = syncop_setactivelk(hashed_subvol, loc, &locklist, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_LOCK_MIGRATION_FAILED, "write lock failed on:%s", loc->path); *fop_errno = -ret; ret = -1; goto metaunlock; } } else { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_LOCK_MIGRATION_FAILED, "getactivelk failed for file: %s", loc->path); *fop_errno = -ret; } } /* source would have both sticky bit and sgid bit set, reset it to 0, and set the source permission on destination, if it was not set prior to setting rebalance-modes in source */ if (!src_ia_prot.sticky) new_stbuf.ia_prot.sticky = 0; if (!src_ia_prot.sgid) new_stbuf.ia_prot.sgid = 0; /* TODO: if the source actually had sticky bit, or sgid bit set, we are not handling it */ ret = syncop_fsetattr( hashed_subvol, dst_fd, &new_stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID | GF_SET_ATTR_MODE), NULL, NULL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: failed to perform setattr on %s ", loc->path, hashed_subvol->name); *fop_errno = -ret; ret = -1; goto metaunlock; } /* Because 'futimes' is not portable */ ret = syncop_setattr(hashed_subvol, loc, &new_stbuf, (GF_SET_ATTR_MTIME | GF_SET_ATTR_ATIME), NULL, NULL, NULL, NULL); if (ret) { gf_log(this->name, GF_LOG_WARNING, "%s: failed to perform setattr on %s ", loc->path, hashed_subvol->name); *fop_errno = -ret; } if (target_changed) { dict_del(dict, GLUSTERFS_POSIXLK_COUNT); ret = dict_set_str(dict, conf->link_xattr_name, hashed_subvol->name); if (ret) { gf_log(this->name, GF_LOG_ERROR, "failed to set xattr in dict for %s (linkto:%s)", loc->path, hashed_subvol->name); *fop_errno = ENOMEM; ret = -1; goto out; } ret = syncop_setxattr(old_target, loc, dict, 0, NULL, NULL); if (ret && -ret != ESTALE && -ret != ENOENT) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "failed to set xattr on %s in %s", loc->path, old_target->name); *fop_errno = -ret; ret = -1; goto out; } else if (-ret == ESTALE || -ret == ENOENT) { /* The failure ESTALE indicates that the linkto * file on the hashed subvol might have been deleted. * In this case will create a linkto file with new target * as linkto xattr value*/ linkto_fd = fd_create(loc->inode, DHT_REBALANCE_PID); if (!linkto_fd) { gf_msg(this->name, GF_LOG_ERROR, errno, DHT_MSG_MIGRATE_FILE_FAILED, "%s: fd create failed", loc->path); *fop_errno = ENOMEM; ret = -1; goto out; } ret = syncop_create(old_target, loc, O_RDWR, DHT_LINKFILE_MODE, linkto_fd, NULL, dict, NULL); if (ret != 0 && -ret != EEXIST && -ret != ESTALE) { *fop_errno = -ret; ret = -1; gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "failed to create linkto file on %s in %s", loc->path, old_target->name); goto out; } else if (ret == 0) { ret = syncop_fsetattr(old_target, linkto_fd, &stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID), NULL, NULL, NULL, NULL); if (ret < 0) { *fop_errno = -ret; gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "chown failed for %s on %s", loc->path, old_target->name); } } } } clean_dst = _gf_false; /* Posix acls are not set on DHT linkto files as part of the initial * initial xattrs set on the dst file, so these need * to be set on the dst file after the linkto attrs are removed. * TODO: Optimize this. */ if (xattr) { dict_unref(xattr); xattr = NULL; } /* Set only the Posix ACLs this time */ ret = syncop_getxattr(cached_subvol, loc, &xattr, POSIX_ACL_ACCESS_XATTR, NULL, NULL); if (ret < 0) { if ((-ret != ENODATA) && (-ret != ENOATTR)) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: failed to get xattr from %s", loc->path, cached_subvol->name); *fop_errno = -ret; } } else { ret = syncop_setxattr(hashed_subvol, loc, xattr, 0, NULL, NULL); if (ret < 0) { /* Potential problem here where Posix ACLs will * not be set on the target file */ gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: failed to set xattr on %s", loc->path, hashed_subvol->name); *fop_errno = -ret; } } /* The src file is being unlinked after this so we don't need to clean it up */ clean_src = _gf_false; /* Make the source as a linkfile first before deleting it */ empty_iatt.ia_prot.sticky = 1; ret = syncop_fsetattr(cached_subvol, src_fd, &empty_iatt, GF_SET_ATTR_MODE, NULL, NULL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed:" "%s: failed to perform setattr on %s ", loc->path, cached_subvol->name); *fop_errno = -ret; ret = -1; goto metaunlock; } /* Free up the data blocks on the source node, as the whole file is migrated */ ret = syncop_ftruncate(cached_subvol, src_fd, 0, NULL, NULL, NULL, NULL); if (ret) { gf_log(this->name, GF_LOG_WARNING, "%s: failed to perform truncate on %s (%s)", loc->path, cached_subvol->name, strerror(-ret)); *fop_errno = -ret; } /* remove the 'linkto' xattr from the destination */ ret = syncop_fremovexattr(hashed_subvol, dst_fd, conf->link_xattr_name, 0, NULL); if (ret) { gf_log(this->name, GF_LOG_WARNING, "%s: failed to perform removexattr on %s (%s)", loc->path, hashed_subvol->name, strerror(-ret)); *fop_errno = -ret; } /* Do a stat and check the gfid before unlink */ /* * Cached file changes its state from non-linkto to linkto file after * migrating data. If lookup from any other mount-point is performed, * converted-linkto-cached file will be treated as a stale and will be * unlinked. But by this time, file is already migrated. So further * failure because of ENOENT should not be treated as error */ ret = syncop_stat(cached_subvol, loc, &empty_iatt, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to do a stat on %s", loc->path, cached_subvol->name); if (-ret != ENOENT) { *fop_errno = -ret; ret = -1; goto metaunlock; } rcvd_enoent_from_src = 1; } if ((gf_uuid_compare(empty_iatt.ia_gfid, loc->gfid) == 0) && (!rcvd_enoent_from_src) && delete_src_linkto) { /* take out the source from namespace */ ret = syncop_unlink(cached_subvol, loc, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to perform unlink on %s", loc->path, cached_subvol->name); *fop_errno = -ret; ret = -1; goto metaunlock; } } ret = syncop_lookup(this, loc, NULL, NULL, NULL, NULL); if (ret) { gf_msg_debug(this->name, -ret, "%s: failed to lookup the file on subvolumes", loc->path); *fop_errno = -ret; } gf_msg(this->name, log_level, 0, DHT_MSG_MIGRATE_FILE_COMPLETE, "completed migration of %s from subvolume %s to %s", loc->path, cached_subvol->name, hashed_subvol->name); ret = 0; metaunlock: if (conf->lock_migration_enabled && meta_locked) { dict_del(meta_dict, GF_META_LOCK_KEY); ret = dict_set_int32(meta_dict, GF_META_UNLOCK_KEY, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Trace dict_set failed"); *fop_errno = ENOMEM; ret = -1; goto out; } if (clean_dst == _gf_false) ret = dict_set_int32(meta_dict, "status", 1); else ret = dict_set_int32(meta_dict, "status", 0); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, "Trace dict_set failed"); *fop_errno = ENOMEM; ret = -1; goto out; } ret = syncop_setxattr(cached_subvol, loc, meta_dict, 0, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Trace syncop_setxattr meta unlock failed"); *fop_errno = -ret; ret = -1; goto out; } } out: if (clean_src) { /* Revert source mode and xattr changes*/ lk_ret = __dht_migration_cleanup_src_file(this, loc, src_fd, cached_subvol, &src_ia_prot); if (lk_ret) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to cleanup source file on %s", loc->path, cached_subvol->name); } } /* reset the destination back to 0 */ if (clean_dst) { lk_ret = syncop_ftruncate(hashed_subvol, dst_fd, 0, NULL, NULL, NULL, NULL); if (lk_ret) { gf_msg(this->name, GF_LOG_ERROR, -lk_ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed: " "%s: failed to reset target size back to 0", loc->path); } } if (inodelk_locked) { flock.l_type = F_UNLCK; lk_ret = syncop_inodelk(cached_subvol, DHT_FILE_MIGRATE_DOMAIN, &tmp_loc, F_SETLK, &flock, NULL, NULL); if (lk_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -lk_ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to unlock file on %s", loc->path, cached_subvol->name); } } if (entrylk_locked) { lk_ret = syncop_entrylk(hashed_subvol, DHT_ENTRY_SYNC_DOMAIN, &parent_loc, loc->name, ENTRYLK_UNLOCK, ENTRYLK_UNLOCK, NULL, NULL); if (lk_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -lk_ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to unlock entrylk on %s", loc->path, hashed_subvol->name); } } if (p_locked) { plock.l_type = F_UNLCK; lk_ret = syncop_lk(cached_subvol, src_fd, F_SETLK, &plock, NULL, NULL); if (lk_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -lk_ret, DHT_MSG_MIGRATE_FILE_FAILED, "%s: failed to unlock file on %s", loc->path, cached_subvol->name); } } lk_ret = syncop_removexattr(hashed_subvol, loc, GF_PROTECT_FROM_EXTERNAL_WRITES, NULL, NULL); if (lk_ret && (lk_ret != -ENODATA) && (lk_ret != -ENOATTR)) { gf_msg(this->name, GF_LOG_WARNING, -lk_ret, 0, "%s: removexattr failed key %s", loc->path, GF_PROTECT_FROM_EXTERNAL_WRITES); } if (dict) dict_unref(dict); if (xattr) dict_unref(xattr); if (xattr_rsp) dict_unref(xattr_rsp); if (dst_fd) syncop_close(dst_fd); if (src_fd) syncop_close(src_fd); if (linkto_fd) syncop_close(linkto_fd); if (xdata) dict_unref(xdata); loc_wipe(&tmp_loc); loc_wipe(&parent_loc); return ret; } static int rebalance_task(void *data) { int ret = -1; xlator_t *this = NULL; dht_local_t *local = NULL; call_frame_t *frame = NULL; int fop_errno = 0; xlator_t *hashed_subvol; xlator_t *cached_subvol; frame = data; this = frame->this; local = frame->local; /* This function is 'synchrounous', hence if it returns, we are done with the task */ hashed_subvol = local->rebalance.target_node; cached_subvol = local->rebalance.from_subvol; if (cached_subvol == hashed_subvol) { gf_msg_debug(this->name, 0, "destination and source are same. file %s" " might have migrated already", local->loc.path); ret = 0; goto out; } ret = dht_migrate_file(this, &local->loc, cached_subvol, hashed_subvol, local->flags, &fop_errno); out: return ret; } static int rebalance_task_completion(int op_ret, call_frame_t *syncop_frame, void *data) { int32_t op_errno = EINVAL; call_frame_t *setxattr_frame = data; if (op_ret == -1) { /* Failure of migration process, mostly due to write process. as we can't preserve the exact errno, lets say there was no space to migrate-data */ op_errno = ENOSPC; } else if (op_ret == 1) { /* migration didn't happen, but is not a failure, let the user understand that he doesn't have permission to migrate the file. */ op_ret = -1; op_errno = EPERM; } else if (op_ret != 0) { op_errno = -op_ret; op_ret = -1; } DHT_STACK_UNWIND(setxattr, setxattr_frame, op_ret, op_errno, NULL); GF_ASSERT(syncop_frame->local == NULL); STACK_DESTROY(syncop_frame->root); return 0; } int dht_start_rebalance_task(xlator_t *this, call_frame_t *frame) { int ret = -1; call_frame_t *syncop_frame = NULL; syncop_frame = copy_frame(frame); if (!syncop_frame) { goto out; } syncop_frame->root->pid = GF_CLIENT_PID_DEFRAG; set_lk_owner_from_ptr(&syncop_frame->root->lk_owner, syncop_frame->root); ret = synctask_new(this->ctx->env, rebalance_task, rebalance_task_completion, syncop_frame, frame); out: if ((ret < 0) && syncop_frame) { STACK_DESTROY(syncop_frame->root); } return ret; } static void gf_listener_stop(xlator_t *this) { glusterfs_ctx_t *ctx = NULL; cmd_args_t *cmd_args = NULL; ctx = this->ctx; GF_ASSERT(ctx); cmd_args = &ctx->cmd_args; GF_ASSERT(cmd_args); if (cmd_args->sock_file) gf_unlink(cmd_args->sock_file); } static void dht_build_root_inode(xlator_t *this, inode_t **inode) { inode_table_t *itable = NULL; static uuid_t root_gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; itable = inode_table_new(0, this, 0, 0); if (!itable) return; *inode = inode_find(itable, root_gfid); } void dht_build_root_loc(inode_t *inode, loc_t *loc) { loc->path = "/"; loc->inode = inode; loc->inode->ia_type = IA_IFDIR; memset(loc->gfid, 0, 16); loc->gfid[15] = 1; } /* return values: 1 -> error, bug ignore and continue 0 -> proceed -1 -> error, handle it */ static int32_t gf_defrag_handle_migrate_error(int32_t op_errno, gf_defrag_info_t *defrag) { int ret = 0; /* if errno is not ENOTCONN, we can still continue with rebalance process */ if (op_errno != ENOTCONN) { ret = 1; goto out; } if (op_errno == ENOTCONN) { /* Most probably mount point went missing (mostly due to a brick down), say rebalance failure to user, let him restart it if everything is fine */ defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; ret = -1; goto out; } out: return ret; } static gf_boolean_t gf_defrag_pattern_match(gf_defrag_info_t *defrag, char *name, uint64_t size) { gf_defrag_pattern_list_t *trav = NULL; gf_boolean_t match = _gf_false; gf_boolean_t ret = _gf_false; GF_VALIDATE_OR_GOTO("dht", defrag, out); list_for_each_entry(trav, &defrag->defrag_pattern, list) { if (!fnmatch(trav->path_pattern, name, FNM_NOESCAPE)) { match = _gf_true; break; } } if ((match == _gf_true) && (size >= trav->size)) ret = _gf_true; out: return ret; } static int dht_dfreaddirp_done(dht_dfoffset_ctx_t *offset_var, int cnt) { int i; int result = 1; for (i = 0; i < cnt; i++) { if (offset_var[i].readdir_done == 0) { result = 0; break; } } return result; } static int dht_get_first_non_null_index(subvol_nodeuuids_info_t *entry) { int i = 0; int index = 0; for (i = 0; i < entry->count; i++) { if (!gf_uuid_is_null(entry->elements[i].uuid)) { index = i; goto out; } } if (i == entry->count) { index = -1; } out: return index; } /* Return value * 0 : this node does not migrate the file * 1 : this node migrates the file * * Use the hash value of the gfid to determine which node will migrate files. * Using the gfid instead of the name also ensures that the same node handles * all hardlinks. */ static gf_boolean_t gf_defrag_should_i_migrate(xlator_t *this, int local_subvol_index, uuid_t gfid) { gf_boolean_t ret = _gf_false; int i = local_subvol_index; char *str = NULL; uint32_t hashval = 0; int32_t index = 0; dht_conf_t *conf = NULL; char buf[UUID_CANONICAL_FORM_LEN + 1] = { 0, }; subvol_nodeuuids_info_t *entry = NULL; conf = this->private; /* Pure distribute. A subvol in this case will be handled by only one node */ entry = &(conf->local_nodeuuids[i]); if (entry->count == 1) { return 1; } str = uuid_utoa_r(gfid, buf); if (dht_hash_compute(this, 0, str, &hashval) == 0) { index = (hashval % entry->count); if (entry->elements[index].info == REBAL_NODEUUID_MINE) { /* Index matches this node's nodeuuid.*/ ret = _gf_true; goto out; } /* Brick down - some other node has to migrate these files*/ if (gf_uuid_is_null(entry->elements[index].uuid)) { /* Fall back to the first non-null index */ index = dht_get_first_non_null_index(entry); if (index == -1) { /* None of the bricks in the subvol are up. * CHILD_DOWN will kill the process soon */ return _gf_false; } if (entry->elements[index].info == REBAL_NODEUUID_MINE) { /* Index matches this node's nodeuuid.*/ ret = _gf_true; goto out; } } } out: return ret; } static int gf_defrag_migrate_single_file(xlator_t *this, dht_container_t *rebal_entry) { dht_conf_t *conf = NULL; gf_defrag_info_t *defrag = NULL; int ret = 0; gf_dirent_t *entry = NULL; struct timeval start = { 0, }; loc_t entry_loc = { 0, }; loc_t *loc = NULL; struct iatt iatt = { 0, }; dict_t *migrate_data = NULL; struct timeval end = { 0, }; double elapsed = { 0, }; inode_t *inode = NULL; xlator_t *hashed_subvol = NULL; xlator_t *cached_subvol = NULL; xlator_t *linkfile_subvol = NULL; call_frame_t *statfs_frame = NULL; xlator_t *old_THIS = NULL; data_t *tmp = NULL; int fop_errno = 0; gf_dht_migrate_data_type_t rebal_type = GF_DHT_MIGRATE_DATA; char value[MAX_REBAL_TYPE_SIZE] = { 0, }; struct iatt *iatt_ptr = NULL; gf_boolean_t update_skippedcount = _gf_true; int i = 0; gf_boolean_t should_i_migrate = 0; char is_linkfile = 0; GF_ASSERT(this); if (!rebal_entry) { gf_log(this->name, GF_LOG_ERROR, "rebal_entry is NULL"); ret = -1; goto out; } conf = this->private; defrag = conf->defrag; loc = rebal_entry->parent_loc; migrate_data = rebal_entry->migrate_data; entry = rebal_entry->df_entry; iatt_ptr = &entry->d_stat; if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { goto out; } if (defrag->stats == _gf_true) { gettimeofday(&start, NULL); } if (!list_empty(&defrag->defrag_pattern) && (gf_defrag_pattern_match(defrag, entry->d_name, entry->d_stat.ia_size) == _gf_false)) { gf_log(this->name, GF_LOG_ERROR, "pattern_match failed"); goto out; } memset(&entry_loc, 0, sizeof(entry_loc)); ret = dht_build_child_loc(this, &entry_loc, loc, entry->d_name); if (ret) { LOCK(&defrag->lock); { defrag->total_failures += 1; } UNLOCK(&defrag->lock); ret = 0; gf_log(this->name, GF_LOG_ERROR, "Child loc build failed"); goto out; } should_i_migrate = gf_defrag_should_i_migrate( this, rebal_entry->local_subvol_index, entry->d_stat.ia_gfid); gf_uuid_copy(entry_loc.gfid, entry->d_stat.ia_gfid); gf_uuid_copy(entry_loc.pargfid, loc->gfid); ret = syncop_lookup(this, &entry_loc, &iatt, NULL, NULL, NULL); is_linkfile = check_is_linkfile(NULL, &rebal_entry->df_entry->d_stat, rebal_entry->df_entry->dict, conf->link_xattr_name); if (!should_i_migrate) { /* this node isn't supposed to migrate the file. suppressing any * potential error from lookup as this file is under migration by * another node */ if (ret) { gf_msg_debug(this->name, -ret, "Ignoring lookup failure: node isn't migrating %s", entry_loc.path); ret = 0; } gf_msg_debug(this->name, 0, "Don't migrate %s ", entry_loc.path); goto out; } if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_MIGRATE_FILE_FAILED, "Migrate file failed: %s lookup failed", entry_loc.path); /* Increase failure count only for remove-brick op, so that * user is warned to check the removed-brick for any files left * unmigrated */ if (conf->decommission_subvols_cnt) { LOCK(&defrag->lock); { defrag->total_failures += 1; } UNLOCK(&defrag->lock); } ret = 0; goto out; } iatt_ptr = &iatt; hashed_subvol = dht_subvol_get_hashed(this, &entry_loc); if (!hashed_subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "Failed to get hashed subvol for %s", entry_loc.path); ret = 0; goto out; } cached_subvol = dht_subvol_get_cached(this, entry_loc.inode); if (!cached_subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_CACHED_SUBVOL_GET_FAILED, "Failed to get cached subvol for %s", entry_loc.path); ret = 0; goto out; } if (hashed_subvol == cached_subvol) { i = rebal_entry->local_subvol_index; linkfile_subvol = conf->local_subvols[i]; if (is_linkfile == 1 && hashed_subvol != linkfile_subvol) { ret = syncop_unlink(linkfile_subvol, &entry_loc, NULL, NULL); gf_msg_debug(this->name, 0, "Unlink linkfile" " %s on subvol: %s status is %d", entry_loc.path, linkfile_subvol->name, ret); } ret = 0; goto out; } if (is_linkfile == 1) { linkfile_subvol = conf->local_subvols[i]; /* No need to migrate the linkfile. Following scenario can happen * if (hashed_subvol != linkfile_subvol) { * This should be a stale linkfile and the above lookup * should be deleted it, so we should be fine to skip it, * May be we can do a verification to make sure that the * linkfiles are deleted * } else { * This means that we have a linkfile that is valid, either the * migration is still on going triggered by the actual data file, * hence we don't need to migrate this file.* } */ gf_msg_debug(this->name, 0, "skipping linkfile migration" " %s on subvol: %s", entry_loc.path, linkfile_subvol->name); ret = 0; goto out; } inode = inode_link(entry_loc.inode, entry_loc.parent, entry->d_name, &iatt); inode_unref(entry_loc.inode); /* use the inode returned by inode_link */ entry_loc.inode = inode; old_THIS = THIS; THIS = this; statfs_frame = create_frame(this, this->ctx->pool); if (!statfs_frame) { gf_msg(this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, ENOMEM, "Insufficient memory. Frame creation failed"); ret = -1; goto out; } /* async statfs information for honoring min-free-disk */ dht_get_du_info(statfs_frame, this, loc); THIS = old_THIS; tmp = dict_get(migrate_data, GF_XATTR_FILE_MIGRATE_KEY); if (tmp) { memcpy(value, tmp->data, tmp->len); if (strcmp(value, "force") == 0) rebal_type = GF_DHT_MIGRATE_DATA_EVEN_IF_LINK_EXISTS; if (conf->decommission_in_progress) rebal_type = GF_DHT_MIGRATE_HARDLINK; } ret = dht_migrate_file(this, &entry_loc, cached_subvol, hashed_subvol, rebal_type, &fop_errno); if (ret == 1) { if (fop_errno == ENOSPC) { gf_msg_debug(this->name, 0, "migrate-data skipped for" " %s due to space constraints", entry_loc.path); /* For remove-brick case if the source is not one of the * removed-brick, do not mark the error as failure */ if (conf->decommission_subvols_cnt) { for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->decommissioned_bricks[i] == cached_subvol) { LOCK(&defrag->lock); { defrag->total_failures += 1; update_skippedcount = _gf_false; } UNLOCK(&defrag->lock); break; } } } if (update_skippedcount) { LOCK(&defrag->lock); { defrag->skipped += 1; } UNLOCK(&defrag->lock); gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_MIGRATE_FILE_SKIPPED, "File migration skipped for %s.", entry_loc.path); } } else if (fop_errno == ENOTSUP) { gf_msg_debug(this->name, 0, "migrate-data skipped for" " hardlink %s ", entry_loc.path); LOCK(&defrag->lock); { defrag->skipped += 1; } UNLOCK(&defrag->lock); gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_MIGRATE_FILE_SKIPPED, "File migration skipped for %s.", entry_loc.path); } ret = 0; goto out; } else if (ret < 0) { if (fop_errno != EEXIST) { gf_msg(this->name, GF_LOG_ERROR, fop_errno, DHT_MSG_MIGRATE_FILE_FAILED, "migrate-data failed for %s", entry_loc.path); LOCK(&defrag->lock); { defrag->total_failures += 1; } UNLOCK(&defrag->lock); } ret = gf_defrag_handle_migrate_error(fop_errno, defrag); if (!ret) { gf_msg(this->name, GF_LOG_ERROR, fop_errno, DHT_MSG_MIGRATE_FILE_FAILED, "migrate-data on %s failed:", entry_loc.path); } else if (ret == 1) { ret = 0; } goto out; } LOCK(&defrag->lock); { defrag->total_files += 1; defrag->total_data += iatt.ia_size; } UNLOCK(&defrag->lock); if (defrag->stats == _gf_true) { gettimeofday(&end, NULL); elapsed = gf_tvdiff(&start, &end); gf_log(this->name, GF_LOG_INFO, "Migration of " "file:%s size:%" PRIu64 " bytes took %.2f" "secs and ret: %d", entry_loc.name, iatt.ia_size, elapsed / 1e6, ret); } out: if (statfs_frame) { STACK_DESTROY(statfs_frame->root); } if (iatt_ptr) { LOCK(&defrag->lock); { defrag->size_processed += iatt_ptr->ia_size; } UNLOCK(&defrag->lock); } loc_wipe(&entry_loc); return ret; } void * gf_defrag_task(void *opaque) { xlator_t *this = NULL; struct list_head *q_head = NULL; dht_container_t *iterator = NULL; gf_defrag_info_t *defrag = NULL; int ret = 0; pid_t pid = GF_CLIENT_PID_DEFRAG; gf_lkowner_t lkowner; defrag = (gf_defrag_info_t *)opaque; GF_ASSERT(defrag); this = defrag->this; syncopctx_setfspid(&pid); /* setting lkowner stack memory address as lkowner * which will be unique per thread*/ set_lk_owner_from_ptr(&lkowner, &lkowner); syncopctx_setfslkowner(&lkowner); q_head = &(defrag->queue[0].list); /* The following while loop will dequeue one entry from the defrag->queue under lock. We will update the defrag->global_error only when there is an error which is critical to stop the rebalance process. The stop message will be intimated to other migrator threads by setting the defrag->defrag_status to GF_DEFRAG_STATUS_FAILED. In defrag->queue, a low watermark (MIN_MIGRATE_QUEUE_COUNT) is maintained so that crawler does not starve the file migration workers and a high watermark (MAX_MIGRATE_QUEUE_COUNT) so that crawler does not go far ahead in filling up the queue. */ while (_gf_true) { if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { pthread_cond_broadcast(&defrag->rebalance_crawler_alarm); pthread_cond_broadcast(&defrag->parallel_migration_cond); goto out; } pthread_mutex_lock(&defrag->dfq_mutex); { /*Throttle down: If the reconfigured count is less than current thread count, then the current thread will sleep */ /*TODO: Need to refactor the following block to work *under defrag->lock. For now access * defrag->current_thread_count and rthcount under * dfq_mutex lock */ while (!defrag->crawl_done && (defrag->recon_thread_count < defrag->current_thread_count)) { defrag->current_thread_count--; gf_msg_debug(this->name, 0, "Thread sleeping, current thread count: %d", defrag->current_thread_count); pthread_cond_wait(&defrag->df_wakeup_thread, &defrag->dfq_mutex); defrag->current_thread_count++; gf_msg_debug(this->name, 0, "Thread wakeup, current thread count: %d", defrag->current_thread_count); } if (defrag->q_entry_count) { iterator = list_entry(q_head->next, typeof(*iterator), list); gf_msg_debug(this->name, 0, "picking entry %s", iterator->df_entry->d_name); list_del_init(&(iterator->list)); defrag->q_entry_count--; if ((defrag->q_entry_count < MIN_MIGRATE_QUEUE_COUNT) && defrag->wakeup_crawler) { pthread_cond_broadcast(&defrag->rebalance_crawler_alarm); } pthread_mutex_unlock(&defrag->dfq_mutex); ret = gf_defrag_migrate_single_file(this, iterator); /* Critical errors: ENOTCONN and ENOSPACE. */ if (ret) { dht_set_global_defrag_error(defrag, ret); defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; pthread_cond_broadcast(&defrag->rebalance_crawler_alarm); pthread_cond_broadcast(&defrag->parallel_migration_cond); goto out; } gf_defrag_free_container(iterator); continue; } else { /* defrag->crawl_done flag is set means crawling file system is done and hence a list_empty when the above flag is set indicates there are no more entries to be added to the queue and rebalance is finished */ if (!defrag->crawl_done) { defrag->current_thread_count--; gf_msg_debug(this->name, 0, "Thread sleeping while waiting for " "migration entries, current thread count:%d", defrag->current_thread_count); pthread_cond_wait(&defrag->parallel_migration_cond, &defrag->dfq_mutex); } if (defrag->crawl_done && !defrag->q_entry_count) { defrag->current_thread_count++; gf_msg_debug(this->name, 0, "Exiting thread"); pthread_cond_broadcast(&defrag->parallel_migration_cond); goto unlock; } else { defrag->current_thread_count++; gf_msg_debug(this->name, 0, "Thread woken up due to found migrating " "entries, current thread count:%d", defrag->current_thread_count); pthread_mutex_unlock(&defrag->dfq_mutex); continue; } } } unlock: pthread_mutex_unlock(&defrag->dfq_mutex); break; } out: return NULL; } static int gf_defrag_get_entry(xlator_t *this, int i, dht_container_t **container, loc_t *loc, dht_conf_t *conf, gf_defrag_info_t *defrag, fd_t *fd, dict_t *migrate_data, struct dir_dfmeta *dir_dfmeta, dict_t *xattr_req, int *perrno) { int ret = 0; char is_linkfile = 0; gf_dirent_t *df_entry = NULL; dht_container_t *tmp_container = NULL; loc_t entry_loc = { 0, }; int j = 0; if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { goto out; } if (dir_dfmeta->offset_var[i].readdir_done == 1) { goto out; } if (dir_dfmeta->fetch_entries[i] == 1) { if (!fd) { dir_dfmeta->fetch_entries[i] = 0; dir_dfmeta->offset_var[i].readdir_done = 1; ret = 0; goto out; } ret = syncop_readdirp(conf->local_subvols[i], fd, 131072, dir_dfmeta->offset_var[i].offset, &(dir_dfmeta->equeue[i]), xattr_req, NULL); if (ret == 0) { dir_dfmeta->offset_var[i].readdir_done = 1; goto out; } if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_MIGRATE_DATA_FAILED, "Readdirp failed. Aborting data migration for " "directory: %s", loc->path); *perrno = -ret; ret = -1; goto out; } if (list_empty(&(dir_dfmeta->equeue[i].list))) { dir_dfmeta->offset_var[i].readdir_done = 1; ret = 0; goto out; } dir_dfmeta->fetch_entries[i] = 0; } while (1) { if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { goto out; } df_entry = list_entry(dir_dfmeta->iterator[i]->next, typeof(*df_entry), list); if (&df_entry->list == dir_dfmeta->head[i]) { gf_dirent_free(&(dir_dfmeta->equeue[i])); INIT_LIST_HEAD(&(dir_dfmeta->equeue[i].list)); dir_dfmeta->fetch_entries[i] = 1; dir_dfmeta->iterator[i] = dir_dfmeta->head[i]; ret = 0; goto out; } dir_dfmeta->iterator[i] = dir_dfmeta->iterator[i]->next; dir_dfmeta->offset_var[i].offset = df_entry->d_off; /* skip . and .. */ if (inode_dir_or_parentdir(df_entry)) continue; if (IA_ISDIR(df_entry->d_stat.ia_type)) { defrag->size_processed += df_entry->d_stat.ia_size; continue; } defrag->num_files_lookedup++; if (!list_empty(&defrag->defrag_pattern) && (gf_defrag_pattern_match(defrag, df_entry->d_name, df_entry->d_stat.ia_size) == _gf_false)) { defrag->size_processed += df_entry->d_stat.ia_size; continue; } is_linkfile = check_is_linkfile(NULL, &df_entry->d_stat, df_entry->dict, conf->link_xattr_name); if (is_linkfile) { for (j = 0; j < conf->subvolume_cnt; j++) { if (conf->decommissioned_bricks[j] == conf->local_subvols[i]) { loc_wipe(&entry_loc); ret = dht_build_child_loc(conf->local_subvols[i], &entry_loc, loc, df_entry->d_name); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Child loc" " build failed for entry: %s", df_entry->d_name); } else { ret = syncop_unlink(conf->local_subvols[i], &entry_loc, NULL, NULL); } gf_msg_debug(this->name, 0, "Unlink linkfile" " %s on subvol: %s status is %d", df_entry->d_name, conf->local_subvols[i]->name, ret); break; } } if (j < conf->subvolume_cnt) continue; } /*Build Container Structure */ tmp_container = GF_CALLOC(1, sizeof(struct dht_container), gf_dht_mt_container_t); if (!tmp_container) { gf_log(this->name, GF_LOG_ERROR, "Failed to allocate " "memory for container"); ret = -1; goto out; } tmp_container->df_entry = gf_dirent_for_name2( df_entry->d_name, df_entry->d_len, df_entry->d_ino, 0, df_entry->d_type, &df_entry->d_stat); if (!tmp_container->df_entry) { gf_log(this->name, GF_LOG_ERROR, "Failed to allocate " "memory for df_entry"); ret = -1; goto out; } tmp_container->local_subvol_index = i; tmp_container->parent_loc = GF_CALLOC(1, sizeof(*loc), gf_dht_mt_loc_t); if (!tmp_container->parent_loc) { gf_log(this->name, GF_LOG_ERROR, "Failed to allocate " "memory for loc"); ret = -1; goto out; } ret = loc_copy(tmp_container->parent_loc, loc); if (ret) { gf_log(this->name, GF_LOG_ERROR, "loc_copy failed"); ret = -1; goto out; } tmp_container->migrate_data = migrate_data; if (df_entry->dict) tmp_container->df_entry->dict = dict_ref(df_entry->dict); /*Build Container Structure >> END*/ ret = 0; goto out; } out: if (defrag->defrag_status == GF_DEFRAG_STATUS_STARTED) { if (ret == 0) { *container = tmp_container; } else { gf_defrag_free_container(tmp_container); } } else { gf_defrag_free_container(tmp_container); } return ret; } int gf_defrag_process_dir(xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, dict_t *migrate_data, int *perrno) { int ret = -1; dht_conf_t *conf = NULL; gf_dirent_t entries; dict_t *xattr_req = NULL; struct timeval dir_start = { 0, }; struct timeval end = { 0, }; double elapsed = { 0, }; int local_subvols_cnt = 0; int i = 0; int j = 0; dht_container_t *container = NULL; int ldfq_count = 0; int dfc_index = 0; int throttle_up = 0; struct dir_dfmeta *dir_dfmeta = NULL; xlator_t *old_THIS = NULL; gf_log(this->name, GF_LOG_INFO, "migrate data called on %s", loc->path); gettimeofday(&dir_start, NULL); conf = this->private; local_subvols_cnt = conf->local_subvols_cnt; if (!local_subvols_cnt) { ret = 0; goto out; } old_THIS = THIS; THIS = this; dir_dfmeta = GF_CALLOC(1, sizeof(*dir_dfmeta), gf_common_mt_pointer); if (!dir_dfmeta) { gf_log(this->name, GF_LOG_ERROR, "dir_dfmeta is NULL"); ret = -1; goto out; } dir_dfmeta->lfd = GF_CALLOC(local_subvols_cnt, sizeof(fd_t *), gf_common_mt_pointer); if (!dir_dfmeta->lfd) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_INSUFF_MEMORY, "for dir_dfmeta", NULL); ret = -1; *perrno = ENOMEM; goto out; } for (i = 0; i < local_subvols_cnt; i++) { dir_dfmeta->lfd[i] = fd_create(loc->inode, defrag->pid); if (!dir_dfmeta->lfd[i]) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_FD_CREATE_FAILED, NULL); *perrno = ENOMEM; ret = -1; goto out; } ret = syncop_opendir(conf->local_subvols[i], loc, dir_dfmeta->lfd[i], NULL, NULL); if (ret) { fd_unref(dir_dfmeta->lfd[i]); dir_dfmeta->lfd[i] = NULL; gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_FAILED_TO_OPEN, "dir: %s", loc->path, "subvol: %s", conf->local_subvols[i]->name, NULL); if (conf->decommission_in_progress) { *perrno = -ret; ret = -1; goto out; } } else { fd_bind(dir_dfmeta->lfd[i]); } } dir_dfmeta->head = GF_CALLOC(local_subvols_cnt, sizeof(*(dir_dfmeta->head)), gf_common_mt_pointer); if (!dir_dfmeta->head) { gf_log(this->name, GF_LOG_ERROR, "dir_dfmeta->head is NULL"); ret = -1; goto out; } dir_dfmeta->iterator = GF_CALLOC(local_subvols_cnt, sizeof(*(dir_dfmeta->iterator)), gf_common_mt_pointer); if (!dir_dfmeta->iterator) { gf_log(this->name, GF_LOG_ERROR, "dir_dfmeta->iterator is NULL"); ret = -1; goto out; } dir_dfmeta->equeue = GF_CALLOC(local_subvols_cnt, sizeof(entries), gf_dht_mt_dirent_t); if (!dir_dfmeta->equeue) { gf_log(this->name, GF_LOG_ERROR, "dir_dfmeta->equeue is NULL"); ret = -1; goto out; } dir_dfmeta->offset_var = GF_CALLOC( local_subvols_cnt, sizeof(dht_dfoffset_ctx_t), gf_dht_mt_octx_t); if (!dir_dfmeta->offset_var) { gf_log(this->name, GF_LOG_ERROR, "dir_dfmeta->offset_var is NULL"); ret = -1; goto out; } dir_dfmeta->fetch_entries = GF_CALLOC(local_subvols_cnt, sizeof(int), gf_common_mt_int); if (!dir_dfmeta->fetch_entries) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_INSUFF_MEMORY, "for dir_dfmeta->fetch_entries", NULL); ret = -1; goto out; } for (i = 0; i < local_subvols_cnt; i++) { INIT_LIST_HEAD(&(dir_dfmeta->equeue[i].list)); dir_dfmeta->head[i] = &(dir_dfmeta->equeue[i].list); dir_dfmeta->iterator[i] = dir_dfmeta->head[i]; dir_dfmeta->fetch_entries[i] = 1; } xattr_req = dict_new(); if (!xattr_req) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); ret = -1; goto out; } ret = dict_set_uint32(xattr_req, conf->link_xattr_name, 256); if (ret) { gf_log(this->name, GF_LOG_ERROR, "failed to set dict for " "key: %s", conf->link_xattr_name); ret = -1; goto out; } /* Job: Read entries from each local subvol and store the entries in equeue array of linked list. Now pick one entry from the equeue array in a round robin basis and add them to defrag Queue. */ while (!dht_dfreaddirp_done(dir_dfmeta->offset_var, local_subvols_cnt)) { pthread_mutex_lock(&defrag->dfq_mutex); { /*Throttle up: If reconfigured count is higher than current thread count, wake up the sleeping threads TODO: Need to refactor this. Instead of making the thread sleep and wake, we should terminate and spawn threads on-demand*/ if (defrag->recon_thread_count > defrag->current_thread_count) { throttle_up = (defrag->recon_thread_count - defrag->current_thread_count); for (j = 0; j < throttle_up; j++) { pthread_cond_signal(&defrag->df_wakeup_thread); } } while (defrag->q_entry_count > MAX_MIGRATE_QUEUE_COUNT) { defrag->wakeup_crawler = 1; pthread_cond_wait(&defrag->rebalance_crawler_alarm, &defrag->dfq_mutex); } ldfq_count = defrag->q_entry_count; if (defrag->wakeup_crawler) { defrag->wakeup_crawler = 0; } } pthread_mutex_unlock(&defrag->dfq_mutex); while ( ldfq_count <= MAX_MIGRATE_QUEUE_COUNT && !dht_dfreaddirp_done(dir_dfmeta->offset_var, local_subvols_cnt)) { ret = gf_defrag_get_entry(this, dfc_index, &container, loc, conf, defrag, dir_dfmeta->lfd[dfc_index], migrate_data, dir_dfmeta, xattr_req, perrno); if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { goto out; } if (ret) { gf_log(this->name, GF_LOG_WARNING, "Found " "error from gf_defrag_get_entry"); ret = -1; goto out; } /* Check if we got an entry, else we need to move the index to the next subvol */ if (!container) { GF_CRAWL_INDEX_MOVE(dfc_index, local_subvols_cnt); continue; } /* Q this entry in the dfq */ pthread_mutex_lock(&defrag->dfq_mutex); { list_add_tail(&container->list, &(defrag->queue[0].list)); defrag->q_entry_count++; ldfq_count = defrag->q_entry_count; gf_msg_debug(this->name, 0, "added " "file:%s parent:%s to the queue ", container->df_entry->d_name, container->parent_loc->path); pthread_cond_signal(&defrag->parallel_migration_cond); } pthread_mutex_unlock(&defrag->dfq_mutex); GF_CRAWL_INDEX_MOVE(dfc_index, local_subvols_cnt); } } gettimeofday(&end, NULL); elapsed = gf_tvdiff(&dir_start, &end); gf_log(this->name, GF_LOG_INFO, "Migration operation on dir %s took " "%.2f secs", loc->path, elapsed / 1e6); ret = 0; out: THIS = old_THIS; gf_defrag_free_dir_dfmeta(dir_dfmeta, local_subvols_cnt); if (xattr_req) dict_unref(xattr_req); /* It does not matter if it errored out - this number is * used to calculate rebalance estimated time to complete. * No locking required as dirs are processed by a single thread. */ defrag->num_dirs_processed++; return ret; } static int gf_defrag_settle_hash(xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, dict_t *fix_layout) { int ret; dht_conf_t *conf = NULL; /* * Now we're ready to update the directory commit hash for the volume * root, so that hash miscompares and broadcast lookups can stop. * However, we want to skip that if fix-layout is all we did. In * that case, we want the miscompares etc. to continue until a real * rebalance is complete. */ if (defrag->cmd == GF_DEFRAG_CMD_START_LAYOUT_FIX || defrag->cmd == GF_DEFRAG_CMD_DETACH_START) { return 0; } conf = this->private; if (conf->local_subvols_cnt == 0 || !conf->lookup_optimize) { /* Commit hash updates are only done on local subvolumes and * only when lookup optimization is needed (for older client * support) */ return 0; } ret = dict_set_uint32(fix_layout, "new-commit-hash", defrag->new_commit_hash); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to set new-commit-hash"); return -1; } ret = syncop_setxattr(this, loc, fix_layout, 0, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_LAYOUT_FIX_FAILED, "fix layout on %s failed", loc->path); if (-ret == ENOENT || -ret == ESTALE) { /* Dir most likely is deleted */ return 0; } return -1; } /* TBD: find more efficient solution than adding/deleting every time */ dict_del(fix_layout, "new-commit-hash"); return 0; } static int gf_defrag_fix_layout(xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, dict_t *fix_layout, dict_t *migrate_data) { int ret = -1; loc_t entry_loc = { 0, }; fd_t *fd = NULL; gf_dirent_t entries; gf_dirent_t *tmp = NULL; gf_dirent_t *entry = NULL; gf_boolean_t free_entries = _gf_false; off_t offset = 0; struct iatt iatt = { 0, }; struct iatt entry_iatt = { 0, }; inode_t *linked_inode = NULL, *inode = NULL; dht_conf_t *conf = NULL; int perrno = 0; conf = this->private; ret = syncop_lookup(this, loc, &iatt, NULL, NULL, NULL); if (ret) { if (-ret == ENOENT || -ret == ESTALE) { gf_msg(this->name, GF_LOG_INFO, -ret, DHT_MSG_DIR_LOOKUP_FAILED, "Dir:%s renamed or removed. " "Skipping", loc->path); if (conf->decommission_subvols_cnt) { defrag->total_failures++; } ret = 0; } else { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_DIR_LOOKUP_FAILED, "lookup failed for:%s", loc->path); defrag->total_failures++; if (conf->decommission_in_progress) { defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; ret = -1; } } goto out; } linked_inode = inode_link(loc->inode, loc->parent, loc->name, &iatt); inode = loc->inode; loc->inode = linked_inode; inode_unref(inode); fd = fd_create(loc->inode, defrag->pid); if (!fd) { gf_log(this->name, GF_LOG_ERROR, "Failed to create fd"); defrag->total_failures++; ret = -1; goto out; } ret = syncop_opendir(this, loc, fd, NULL, NULL); if (ret) { if (-ret == ENOENT || -ret == ESTALE) { if (conf->decommission_subvols_cnt) { defrag->total_failures++; } ret = 0; goto out; } gf_log(this->name, GF_LOG_ERROR, "Failed to open dir %s, " "err:%d", loc->path, -ret); defrag->total_failures++; ret = -1; goto out; } fd_bind(fd); INIT_LIST_HEAD(&entries.list); while ((ret = syncop_readdir(this, fd, 131072, offset, &entries, NULL, NULL)) != 0) { if (ret < 0) { if (-ret == ENOENT || -ret == ESTALE) { if (conf->decommission_subvols_cnt) { defrag->total_failures++; } ret = 0; goto out; } gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_READDIR_ERROR, "readdirp failed for " "path %s. Aborting fix-layout", loc->path); defrag->total_failures++; ret = -1; goto out; } if (list_empty(&entries.list)) break; free_entries = _gf_true; list_for_each_entry_safe(entry, tmp, &entries.list, list) { if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { goto out; } offset = entry->d_off; /* skip . and .. */ if (inode_dir_or_parentdir(entry)) continue; if ((DT_DIR != entry->d_type) && (DT_UNKNOWN != entry->d_type)) { continue; } loc_wipe(&entry_loc); ret = dht_build_child_loc(this, &entry_loc, loc, entry->d_name); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Child loc" " build failed for entry: %s", entry->d_name); defrag->total_failures++; if (conf->decommission_in_progress) { defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; goto out; } else { continue; } } if (DT_UNKNOWN == entry->d_type) { ret = syncop_lookup(this, &entry_loc, &entry_iatt, NULL, NULL, NULL); if ((ret == 0) && (entry_iatt.ia_type != IA_IFDIR)) { continue; } /*If it is directory, gf_defrag_fix_layout() call will again do * one more lookup. Not optimizing this part as all modern * filesystems populate entry->d_type. We can optimize it when * such a filesystem is found.*/ } /* A return value of 2 means, either process_dir or * lookup of a dir failed. Hence, don't commit hash * for the current directory*/ ret = gf_defrag_fix_layout(this, defrag, &entry_loc, fix_layout, migrate_data); if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { goto out; } if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LAYOUT_FIX_FAILED, "Fix layout failed for %s", entry_loc.path); if (conf->decommission_in_progress) { defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; goto out; } else { /* Let's not commit-hash if * gf_defrag_fix_layout failed*/ continue; } } } gf_dirent_free(&entries); free_entries = _gf_false; INIT_LIST_HEAD(&entries.list); } /* A directory layout is fixed only after its subdirs are healed to * any newly added bricks. If the layout is fixed before subdirs are * healed, the newly added brick will get a non-null layout. * Any subdirs which hash to that layout will no longer show up * in a directory listing until they are healed. */ ret = syncop_setxattr(this, loc, fix_layout, 0, NULL, NULL); /* In case of a race where the directory is deleted just before * layout setxattr, the errors are updated in the layout structure. * We can use this information to make a decision whether the directory * is deleted entirely. */ if (ret == 0) { ret = dht_dir_layout_error_check(this, loc->inode); ret = -ret; } if (ret) { if (-ret == ENOENT || -ret == ESTALE) { gf_msg(this->name, GF_LOG_INFO, -ret, DHT_MSG_LAYOUT_FIX_FAILED, "Setxattr failed. Dir %s " "renamed or removed", loc->path); if (conf->decommission_subvols_cnt) { defrag->total_failures++; } ret = 0; goto out; } else { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_LAYOUT_FIX_FAILED, "Setxattr failed for %s", loc->path); defrag->total_failures++; if (conf->decommission_in_progress) { defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; ret = -1; goto out; } } } if (defrag->cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX) { ret = gf_defrag_process_dir(this, defrag, loc, migrate_data, &perrno); if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { goto out; } if (ret) { if (perrno == ENOENT || perrno == ESTALE) { ret = 0; goto out; } else { defrag->total_failures++; gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DEFRAG_PROCESS_DIR_FAILED, "gf_defrag_process_dir failed for " "directory: %s", loc->path); if (conf->decommission_in_progress) { goto out; } } } } gf_msg_trace(this->name, 0, "fix layout called on %s", loc->path); if (gf_defrag_settle_hash(this, defrag, loc, fix_layout) != 0) { defrag->total_failures++; gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SETTLE_HASH_FAILED, "Settle hash failed for %s", loc->path); ret = -1; if (conf->decommission_in_progress) { defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; goto out; } } ret = 0; out: if (free_entries) gf_dirent_free(&entries); loc_wipe(&entry_loc); if (fd) fd_unref(fd); return ret; } static int dht_init_local_subvols_and_nodeuuids(xlator_t *this, dht_conf_t *conf, loc_t *loc) { dict_t *dict = NULL; uuid_t *uuid_ptr = NULL; int ret = -1; int i = 0; int j = 0; /* Find local subvolumes */ ret = syncop_getxattr(this, loc, &dict, GF_REBAL_FIND_LOCAL_SUBVOL, NULL, NULL); if (ret && (ret != -ENODATA)) { gf_msg(this->name, GF_LOG_ERROR, -ret, 0, "local " "subvolume determination failed with error: %d", -ret); ret = -1; goto out; } if (!ret) goto out; ret = syncop_getxattr(this, loc, &dict, GF_REBAL_OLD_FIND_LOCAL_SUBVOL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, 0, "local " "subvolume determination failed with error: %d", -ret); ret = -1; goto out; } ret = 0; out: if (ret) { return ret; } for (i = 0; i < conf->local_subvols_cnt; i++) { gf_msg(this->name, GF_LOG_INFO, 0, 0, "local subvol: " "%s", conf->local_subvols[i]->name); for (j = 0; j < conf->local_nodeuuids[i].count; j++) { uuid_ptr = &(conf->local_nodeuuids[i].elements[j].uuid); gf_msg(this->name, GF_LOG_INFO, 0, 0, "node uuid : %s", uuid_utoa(*uuid_ptr)); } } return ret; } /* Functions for the rebalance estimates feature */ static uint64_t gf_defrag_subvol_file_size(xlator_t *this, loc_t *root_loc) { int ret = -1; struct statvfs buf = { 0, }; ret = syncop_statfs(this, root_loc, &buf, NULL, NULL); if (ret) { /* Aargh! */ return 0; } return ((buf.f_blocks - buf.f_bfree) * buf.f_frsize); } static uint64_t gf_defrag_total_file_size(xlator_t *this, loc_t *root_loc) { dht_conf_t *conf = NULL; int i = 0; uint64_t size_files = 0; uint64_t total_size = 0; conf = this->private; if (!conf) { return 0; } for (i = 0; i < conf->local_subvols_cnt; i++) { size_files = gf_defrag_subvol_file_size(conf->local_subvols[i], root_loc); total_size += size_files; gf_msg(this->name, GF_LOG_INFO, 0, 0, "local subvol: %s," "cnt = %" PRIu64, conf->local_subvols[i]->name, size_files); } gf_msg(this->name, GF_LOG_INFO, 0, 0, "Total size files = %" PRIu64, total_size); return total_size; } static void * dht_file_counter_thread(void *args) { gf_defrag_info_t *defrag = NULL; xlator_t *this = NULL; loc_t root_loc = { 0, }; struct timespec time_to_wait = { 0, }; uint64_t tmp_size = 0; if (!args) return NULL; defrag = (gf_defrag_info_t *)args; this = defrag->this; dht_build_root_loc(defrag->root_inode, &root_loc); while (defrag->defrag_status == GF_DEFRAG_STATUS_STARTED) { timespec_now_realtime(&time_to_wait); time_to_wait.tv_sec += 600; pthread_mutex_lock(&defrag->fc_mutex); pthread_cond_timedwait(&defrag->fc_wakeup_cond, &defrag->fc_mutex, &time_to_wait); pthread_mutex_unlock(&defrag->fc_mutex); if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) break; tmp_size = gf_defrag_total_file_size(defrag->this, &root_loc); gf_log(this->name, GF_LOG_INFO, "tmp data size =%" PRIu64, tmp_size); if (!tmp_size) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "Failed to get " "the total data size. Unable to estimate " "time to complete rebalance."); } else { defrag->total_size = tmp_size; gf_msg_debug(this->name, 0, "total data size =%" PRIu64, defrag->total_size); } } return NULL; } static int gf_defrag_estimates_cleanup(xlator_t *this, gf_defrag_info_t *defrag, pthread_t filecnt_thread) { int ret = -1; /* Wake up the filecounter thread. * By now the defrag status will no longer be * GF_DEFRAG_STATUS_STARTED so the thread will exit the loop. */ pthread_mutex_lock(&defrag->fc_mutex); { pthread_cond_broadcast(&defrag->fc_wakeup_cond); } pthread_mutex_unlock(&defrag->fc_mutex); ret = pthread_join(filecnt_thread, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ret, 0, "file_counter_thread: pthread_join failed."); ret = -1; } return ret; } int gf_defrag_estimates_init(xlator_t *this, loc_t *loc, pthread_t *filecnt_thread) { int ret = -1; dht_conf_t *conf = NULL; gf_defrag_info_t *defrag = NULL; conf = this->private; defrag = conf->defrag; defrag->total_size = gf_defrag_total_file_size(this, loc); if (!defrag->total_size) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "Failed to get " "the total data size. Unable to estimate " "time to complete rebalance."); goto out; } ret = gf_thread_create(filecnt_thread, NULL, dht_file_counter_thread, (void *)defrag, "dhtfcnt"); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ret, 0, "Failed to " "create the file counter thread "); ret = -1; goto out; } ret = 0; out: return ret; } /* Init and cleanup functions for parallel file migration*/ static int gf_defrag_parallel_migration_init(xlator_t *this, gf_defrag_info_t *defrag, pthread_t **tid_array, int *thread_index) { int ret = -1; int thread_spawn_count = 0; int index = 0; pthread_t *tid = NULL; /* Initialize global entry queue */ defrag->queue = GF_CALLOC(1, sizeof(struct dht_container), gf_dht_mt_container_t); if (!defrag->queue) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "Failed to initialise migration queue"); ret = -1; goto out; } INIT_LIST_HEAD(&(defrag->queue[0].list)); thread_spawn_count = max(sysconf(_SC_NPROCESSORS_ONLN), 4); gf_msg_debug(this->name, 0, "thread_spawn_count: %d", thread_spawn_count); tid = GF_CALLOC(thread_spawn_count, sizeof(pthread_t), gf_common_mt_pthread_t); if (!tid) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "Failed to create migration threads"); ret = -1; goto out; } defrag->current_thread_count = thread_spawn_count; /* Spawn threads here. */ while (index < thread_spawn_count) { ret = gf_thread_create(&(tid[index]), NULL, gf_defrag_task, (void *)defrag, "dhtmig%d", (index + 1) & 0x3ff); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, ret, 0, "Failed to create migration thread %d of %d", index, thread_spawn_count); ret = -1; goto out; } else { gf_log(this->name, GF_LOG_INFO, "Successfully creating migration" " thread %d of %d", index, thread_spawn_count); } index++; } ret = 0; out: *thread_index = index; *tid_array = tid; return ret; } static void gf_defrag_parallel_migration_cleanup(gf_defrag_info_t *defrag, pthread_t *tid_array, int thread_index) { int i = 0; /* Wake up all migration threads */ pthread_mutex_lock(&defrag->dfq_mutex); { defrag->crawl_done = 1; pthread_cond_broadcast(&defrag->parallel_migration_cond); pthread_cond_broadcast(&defrag->df_wakeup_thread); } pthread_mutex_unlock(&defrag->dfq_mutex); /*Wait for all the threads to complete their task*/ for (i = 0; i < thread_index; i++) { pthread_join(tid_array[i], NULL); } GF_FREE(tid_array); /* Cleanup the migration queue */ if (defrag->queue) { gf_dirent_free(defrag->queue[0].df_entry); INIT_LIST_HEAD(&(defrag->queue[0].list)); } GF_FREE(defrag->queue); } static int gf_defrag_start_crawl(void *data) { xlator_t *this = NULL; dht_conf_t *conf = NULL; gf_defrag_info_t *defrag = NULL; dict_t *fix_layout = NULL; dict_t *migrate_data = NULL; dict_t *status = NULL; glusterfs_ctx_t *ctx = NULL; call_frame_t *statfs_frame = NULL; xlator_t *old_THIS = NULL; int ret = -1; loc_t loc = { 0, }; int thread_index = 0; pthread_t *tid = NULL; pthread_t filecnt_thread; gf_boolean_t fc_thread_started = _gf_false; this = data; if (!this) goto exit; ctx = this->ctx; if (!ctx) goto exit; conf = this->private; if (!conf) goto exit; defrag = conf->defrag; if (!defrag) goto exit; defrag->start_time = gf_time(); dht_build_root_inode(this, &defrag->root_inode); if (!defrag->root_inode) goto out; dht_build_root_loc(defrag->root_inode, &loc); /* fix-layout on '/' first */ ret = syncop_lookup(this, &loc, NULL, NULL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_REBALANCE_START_FAILED, "Failed to start rebalance: look up on / failed"); ret = -1; goto out; } old_THIS = THIS; THIS = this; statfs_frame = create_frame(this, this->ctx->pool); if (!statfs_frame) { gf_msg(this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, ENOMEM, "Insufficient memory. Frame creation failed"); ret = -1; goto out; } /* async statfs update for honoring min-free-disk */ dht_get_du_info(statfs_frame, this, &loc); THIS = old_THIS; fix_layout = dict_new(); if (!fix_layout) { ret = -1; goto out; } /* * Unfortunately, we can't do special xattrs (like fix.layout) and * real ones in the same call currently, and changing it seems * riskier than just doing two calls. */ gf_log(this->name, GF_LOG_INFO, "%s using commit hash %u", __func__, conf->vol_commit_hash); ret = dict_set_uint32(fix_layout, conf->commithash_xattr_name, conf->vol_commit_hash); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to set %s", conf->commithash_xattr_name); defrag->total_failures++; ret = -1; goto out; } ret = syncop_setxattr(this, &loc, fix_layout, 0, NULL, NULL); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to set commit hash on %s. " "Rebalance cannot proceed.", loc.path); defrag->total_failures++; ret = -1; goto out; } /* We now return to our regularly scheduled program. */ ret = dict_set_str(fix_layout, GF_XATTR_FIX_LAYOUT_KEY, "yes"); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_REBALANCE_START_FAILED, "Failed to start rebalance:" "Failed to set dictionary value: key = %s", GF_XATTR_FIX_LAYOUT_KEY); defrag->total_failures++; ret = -1; goto out; } defrag->new_commit_hash = conf->vol_commit_hash; ret = syncop_setxattr(this, &loc, fix_layout, 0, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_REBALANCE_FAILED, "fix layout on %s failed", loc.path); defrag->total_failures++; ret = -1; goto out; } if (defrag->cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX) { /* We need to migrate files */ migrate_data = dict_new(); if (!migrate_data) { defrag->total_failures++; ret = -1; goto out; } ret = dict_set_str( migrate_data, GF_XATTR_FILE_MIGRATE_KEY, (defrag->cmd == GF_DEFRAG_CMD_START_FORCE) ? "force" : "non-force"); if (ret) { defrag->total_failures++; ret = -1; goto out; } ret = dht_init_local_subvols_and_nodeuuids(this, conf, &loc); if (ret) { ret = -1; goto out; } /* Initialise the structures required for parallel migration */ ret = gf_defrag_parallel_migration_init(this, defrag, &tid, &thread_index); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "Aborting rebalance."); goto out; } ret = gf_defrag_estimates_init(this, &loc, &filecnt_thread); if (ret) { /* Not a fatal error. Allow the rebalance to proceed*/ ret = 0; } else { fc_thread_started = _gf_true; } } ret = gf_defrag_fix_layout(this, defrag, &loc, fix_layout, migrate_data); if (ret) { ret = -1; goto out; } if (gf_defrag_settle_hash(this, defrag, &loc, fix_layout) != 0) { defrag->total_failures++; ret = -1; goto out; } gf_log(this->name, GF_LOG_INFO, "crawling file-system completed"); out: /* We are here means crawling the entire file system is done or something failed. Set defrag->crawl_done flag to intimate the migrator threads to exhaust the defrag->queue and terminate*/ if (ret) { defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; } gf_defrag_parallel_migration_cleanup(defrag, tid, thread_index); if ((defrag->defrag_status != GF_DEFRAG_STATUS_STOPPED) && (defrag->defrag_status != GF_DEFRAG_STATUS_FAILED)) { defrag->defrag_status = GF_DEFRAG_STATUS_COMPLETE; } if (fc_thread_started) { gf_defrag_estimates_cleanup(this, defrag, filecnt_thread); } status = dict_new(); LOCK(&defrag->lock); { gf_defrag_status_get(this, conf, status, _gf_true); if (ctx && ctx->notify) ctx->notify(GF_EN_DEFRAG_STATUS, status); if (status) dict_unref(status); defrag->is_exiting = 1; } UNLOCK(&defrag->lock); dht_send_rebalance_event(this, defrag->cmd, defrag->defrag_status); GF_FREE(defrag); conf->defrag = NULL; if (migrate_data) dict_unref(migrate_data); if (fix_layout) dict_unref(fix_layout); if (statfs_frame) { STACK_DESTROY(statfs_frame->root); } exit: return ret; } static int gf_defrag_done(int ret, call_frame_t *sync_frame, void *data) { gf_listener_stop(sync_frame->this); STACK_DESTROY(sync_frame->root); kill(getpid(), SIGTERM); return 0; } void * gf_defrag_start(void *data) { int ret = -1; call_frame_t *frame = NULL; dht_conf_t *conf = NULL; gf_defrag_info_t *defrag = NULL; xlator_t *this = NULL; xlator_t *old_THIS = NULL; this = data; conf = this->private; if (!conf) goto out; defrag = conf->defrag; if (!defrag) goto out; frame = create_frame(this, this->ctx->pool); if (!frame) goto out; frame->root->pid = GF_CLIENT_PID_DEFRAG; defrag->pid = frame->root->pid; defrag->defrag_status = GF_DEFRAG_STATUS_STARTED; old_THIS = THIS; THIS = this; ret = synctask_new(this->ctx->env, gf_defrag_start_crawl, gf_defrag_done, frame, this); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_REBALANCE_START_FAILED, "Could not create task for rebalance"); THIS = old_THIS; out: return NULL; } static uint64_t gf_defrag_get_estimates_based_on_size(dht_conf_t *conf) { gf_defrag_info_t *defrag = NULL; double rate_processed = 0; uint64_t total_processed = 0; uint64_t tmp_count = 0; uint64_t time_to_complete = 0; double elapsed = 0; defrag = conf->defrag; if (!defrag->total_size) goto out; elapsed = gf_time() - defrag->start_time; /* Don't calculate the estimates for the first 10 minutes. * It is unlikely to be accurate and estimates are not required * if the process finishes in less than 10 mins. */ if (elapsed < ESTIMATE_START_INTERVAL) { gf_msg(THIS->name, GF_LOG_INFO, 0, 0, "Rebalance estimates will not be available for the " "first %d seconds.", ESTIMATE_START_INTERVAL); goto out; } total_processed = defrag->size_processed; /* rate at which files processed */ rate_processed = (total_processed) / elapsed; tmp_count = defrag->total_size; if (rate_processed) { time_to_complete = (tmp_count) / rate_processed; } else { gf_msg(THIS->name, GF_LOG_ERROR, 0, 0, "Unable to calculate estimated time for rebalance"); } gf_log(THIS->name, GF_LOG_INFO, "TIME: (size) total_processed=%" PRIu64 " tmp_cnt = %" PRIu64 "," "rate_processed=%f, elapsed = %f", total_processed, tmp_count, rate_processed, elapsed); out: return time_to_complete; } int gf_defrag_status_get(xlator_t *this, dht_conf_t *conf, dict_t *dict, gf_boolean_t log_status) { int ret = 0; uint64_t files = 0; uint64_t size = 0; uint64_t lookup = 0; uint64_t failures = 0; uint64_t skipped = 0; char *status = ""; time_t elapsed = 0; time_t time_to_complete = 0; time_t time_left = 0; gf_defrag_info_t *defrag = conf->defrag; if (!defrag) goto out; ret = 0; if (defrag->defrag_status == GF_DEFRAG_STATUS_NOT_STARTED) goto out; files = defrag->total_files; size = defrag->total_data; lookup = defrag->num_files_lookedup; failures = defrag->total_failures; skipped = defrag->skipped; elapsed = gf_time() - defrag->start_time; /* The rebalance is still in progress */ if (defrag->defrag_status == GF_DEFRAG_STATUS_STARTED) { time_to_complete = gf_defrag_get_estimates_based_on_size(conf); if (time_to_complete && (time_to_complete > elapsed)) time_left = time_to_complete - elapsed; gf_log(this->name, GF_LOG_INFO, "TIME: Estimated total time to complete (size)= %ld" " seconds, seconds left = %ld", time_to_complete, time_left); } if (!dict) goto log; ret = dict_set_uint64(dict, "files", files); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set file count"); ret = dict_set_uint64(dict, "size", size); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set size of xfer"); ret = dict_set_uint64(dict, "lookups", lookup); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set lookedup file count"); ret = dict_set_int32(dict, "status", defrag->defrag_status); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set status"); ret = dict_set_time(dict, "run-time", elapsed); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set run-time"); ret = dict_set_uint64(dict, "failures", failures); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set failure count"); ret = dict_set_uint64(dict, "skipped", skipped); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set skipped file count"); ret = dict_set_time(dict, "time-left", time_left); if (ret) gf_log(this->name, GF_LOG_WARNING, "failed to set time-left"); log: if (log_status) { switch (defrag->defrag_status) { case GF_DEFRAG_STATUS_NOT_STARTED: status = "not started"; break; case GF_DEFRAG_STATUS_STARTED: status = "in progress"; break; case GF_DEFRAG_STATUS_STOPPED: status = "stopped"; break; case GF_DEFRAG_STATUS_COMPLETE: status = "completed"; break; case GF_DEFRAG_STATUS_FAILED: status = "failed"; break; default: break; } gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_REBALANCE_STATUS, "Rebalance is %s. Time taken is %ld secs " "Files migrated: %" PRIu64 ", size: %" PRIu64 ", lookups: %" PRIu64 ", failures: %" PRIu64 ", skipped: " "%" PRIu64, status, elapsed, files, size, lookup, failures, skipped); } out: return 0; } int gf_defrag_stop(dht_conf_t *conf, gf_defrag_status_t status, dict_t *output) { /* TODO: set a variable 'stop_defrag' here, it should be checked in defrag loop */ int ret = -1; gf_defrag_info_t *defrag = conf->defrag; xlator_t *this = NULL; GF_ASSERT(defrag); this = defrag->this; if (defrag->defrag_status == GF_DEFRAG_STATUS_NOT_STARTED) { goto out; } gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_REBALANCE_STOPPED, "Received stop command on rebalance"); defrag->defrag_status = status; if (output) gf_defrag_status_get(this, conf, output, _gf_false); ret = 0; out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-inode-write.c0000644000000000000000000000013214522202451024252 xustar000000000000000030 mtime=1699284265.625027305 30 atime=1699284265.625027305 30 ctime=1699284301.232134553 glusterfs-11.1/xlators/cluster/dht/src/dht-inode-write.c0000664000175100017510000012040614522202451024534 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-common.h" static int dht_writev2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_truncate2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_setattr2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_fallocate2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_discard2(xlator_t *subvol, call_frame_t *frame, int ret); static int dht_zerofill2(xlator_t *subvol, call_frame_t *frame, int ret); int dht_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = -1; xlator_t *subvol1 = NULL; xlator_t *subvol2 = NULL; local = frame->local; prev = cookie; if (!local) { op_ret = -1; op_errno = EINVAL; goto out; } /* writev fails with EBADF if dht has not yet opened the fd * on the cached subvol. This could happen if the file was migrated * and a lookup updated the cached subvol in the inode ctx. * We only check once as this could be a valid bad fd error. */ if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if (op_ret == -1 && !dht_inode_missing(op_errno)) { local->op_errno = op_errno; local->op_ret = -1; gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if (local->call_cnt != 1) { /* preserve the modes of source */ if (local->stbuf.ia_blocks) { dht_iatt_merge(this, postbuf, &local->stbuf); dht_iatt_merge(this, prebuf, &local->prebuf); } goto out; } local->rebalance.target_op_fn = dht_writev2; local->op_ret = op_ret; local->op_errno = op_errno; /* We might need to pass the stbuf information to the higher DHT * layer for appropriate handling. */ dht_set_local_rebalance(this, local, NULL, prebuf, postbuf, xdata); /* Phase 2 of migration */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(postbuf)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* Check if the rebalance phase1 is true */ if (IS_DHT_MIGRATION_PHASE1(postbuf)) { if (!local->xattr_req) { local->xattr_req = dict_new(); if (!local->xattr_req) { gf_msg(this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, ENOMEM, "insufficient memory"); local->op_errno = ENOMEM; local->op_ret = -1; goto out; } } ret = dict_set_uint32(local->xattr_req, GF_PROTECT_FROM_EXTERNAL_WRITES, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, DHT_MSG_DICT_SET_FAILED, 0, "Failed to set key %s in dictionary", GF_PROTECT_FROM_EXTERNAL_WRITES); local->op_errno = ENOMEM; local->op_ret = -1; goto out; } dht_iatt_merge(this, &local->stbuf, postbuf); dht_iatt_merge(this, &local->prebuf, prebuf); ret = dht_inode_ctx_get_mig_info(this, local->fd->inode, &subvol1, &subvol2); if (!dht_mig_info_is_invalid(local->cached_subvol, subvol1, subvol2)) { if (dht_fd_open_on_dst(this, local->fd, subvol2)) { dht_writev2(subvol2, frame, 0); return 0; } } ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } out: DHT_STRIP_PHASE1_FLAGS(postbuf); DHT_STRIP_PHASE1_FLAGS(prebuf); DHT_STACK_UNWIND(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } static int dht_writev2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if ((frame == NULL) || (frame->local == NULL)) goto out; local = frame->local; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(writev, frame, local->op_ret, local->op_errno, &local->rebalance.prebuf, &local->rebalance.postbuf, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ STACK_WIND_COOKIE(frame, dht_writev_cbk, subvol, subvol, subvol->fops->writev, local->fd, local->rebalance.vector, local->rebalance.count, local->rebalance.offset, local->rebalance.flags, local->rebalance.iobref, local->xattr_req); return 0; out: DHT_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_WRITE); if (!local) { op_errno = ENOMEM; goto err; } subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); local->rebalance.vector = iov_dup(vector, count); local->rebalance.offset = off; local->rebalance.count = count; local->rebalance.flags = flags; local->rebalance.iobref = iobref_ref(iobref); local->call_cnt = 1; STACK_WIND_COOKIE(frame, dht_writev_cbk, subvol, subvol, subvol->fops->writev, fd, local->rebalance.vector, local->rebalance.count, local->rebalance.offset, local->rebalance.flags, local->rebalance.iobref, local->xattr_req); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = -1; xlator_t *src_subvol = NULL; xlator_t *dst_subvol = NULL; inode_t *inode = NULL; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", cookie, out); local = frame->local; prev = cookie; /* Needs to be checked only for ftruncate. * ftruncate fails with EBADF/EINVAL if dht has not yet opened the fd * on the cached subvol. This could happen if the file was migrated * and a lookup updated the cached subvol in the inode ctx. * We only check once as this could actually be a valid error. */ if ((local->fop == GF_FOP_FTRUNCATE) && dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if ((op_ret == -1) && !dht_inode_missing(op_errno)) { local->op_errno = op_errno; local->op_ret = -1; gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if (local->call_cnt != 1) { if (local->stbuf.ia_blocks) { dht_iatt_merge(this, postbuf, &local->stbuf); dht_iatt_merge(this, prebuf, &local->prebuf); } goto out; } local->rebalance.target_op_fn = dht_truncate2; local->op_ret = op_ret; local->op_errno = op_errno; /* We might need to pass the stbuf information to the higher DHT * layer for appropriate handling. */ dht_set_local_rebalance(this, local, NULL, prebuf, postbuf, xdata); /* Phase 2 of migration */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(postbuf)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* Check if the rebalance phase1 is true */ if (IS_DHT_MIGRATION_PHASE1(postbuf)) { dht_iatt_merge(this, &local->stbuf, postbuf); dht_iatt_merge(this, &local->prebuf, prebuf); inode = (local->fd) ? local->fd->inode : local->loc.inode; dht_inode_ctx_get_mig_info(this, inode, &src_subvol, &dst_subvol); if (!dht_mig_info_is_invalid(local->cached_subvol, src_subvol, dst_subvol)) { if ((!local->fd) || ((local->fd) && dht_fd_open_on_dst(this, local->fd, dst_subvol))) { dht_truncate2(dst_subvol, frame, 0); return 0; } } ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } out: DHT_STRIP_PHASE1_FLAGS(postbuf); DHT_STRIP_PHASE1_FLAGS(prebuf); DHT_STACK_UNWIND(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); err: return 0; } static int dht_truncate2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if (!frame || !frame->local) goto out; local = frame->local; op_errno = local->op_errno; /* This dht xlator is not migrating the file */ if (we_are_not_migrating(ret)) { DHT_STACK_UNWIND(truncate, frame, local->op_ret, local->op_errno, &local->rebalance.prebuf, &local->rebalance.postbuf, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ if (local->fop == GF_FOP_TRUNCATE) { STACK_WIND_COOKIE(frame, dht_truncate_cbk, subvol, subvol, subvol->fops->truncate, &local->loc, local->rebalance.offset, local->xattr_req); } else { STACK_WIND_COOKIE(frame, dht_truncate_cbk, subvol, subvol, subvol->fops->ftruncate, local->fd, local->rebalance.offset, local->xattr_req); } return 0; out: DHT_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); local = dht_local_init(frame, loc, NULL, GF_FOP_TRUNCATE); if (!local) { op_errno = ENOMEM; goto err; } local->rebalance.offset = offset; local->call_cnt = 1; subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for gfid=%s", uuid_utoa(loc->inode->gfid)); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); STACK_WIND_COOKIE(frame, dht_truncate_cbk, subvol, subvol, subvol->fops->truncate, loc, offset, xdata); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_FTRUNCATE); if (!local) { op_errno = ENOMEM; goto err; } local->rebalance.offset = offset; local->call_cnt = 1; subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); STACK_WIND_COOKIE(frame, dht_truncate_cbk, subvol, subvol, subvol->fops->ftruncate, fd, local->rebalance.offset, local->xattr_req); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = -1; xlator_t *src_subvol = NULL; xlator_t *dst_subvol = NULL; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", cookie, out); local = frame->local; prev = cookie; /* fallocate fails with EBADF if dht has not yet opened the fd * on the cached subvol. This could happen if the file was migrated * and a lookup updated the cached subvol in the inode ctx. * We only check once as this could actually be a valid error. */ if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if ((op_ret == -1) && !dht_inode_missing(op_errno)) { local->op_errno = op_errno; local->op_ret = -1; gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if (local->call_cnt != 1) { if (local->stbuf.ia_blocks) { dht_iatt_merge(this, postbuf, &local->stbuf); dht_iatt_merge(this, prebuf, &local->prebuf); } goto out; } local->op_ret = op_ret; local->op_errno = op_errno; local->rebalance.target_op_fn = dht_fallocate2; dht_set_local_rebalance(this, local, NULL, prebuf, postbuf, xdata); /* Phase 2 of migration */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(postbuf)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* Check if the rebalance phase1 is true */ if (IS_DHT_MIGRATION_PHASE1(postbuf)) { dht_iatt_merge(this, &local->stbuf, postbuf); dht_iatt_merge(this, &local->prebuf, prebuf); dht_inode_ctx_get_mig_info(this, local->fd->inode, &src_subvol, &dst_subvol); if (!dht_mig_info_is_invalid(local->cached_subvol, src_subvol, dst_subvol)) { if (dht_fd_open_on_dst(this, local->fd, dst_subvol)) { dht_fallocate2(dst_subvol, frame, 0); return 0; } } ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } out: DHT_STRIP_PHASE1_FLAGS(postbuf); DHT_STRIP_PHASE1_FLAGS(prebuf); DHT_STACK_UNWIND(fallocate, frame, op_ret, op_errno, prebuf, postbuf, xdata); err: return 0; } static int dht_fallocate2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if (!frame || !frame->local) goto out; local = frame->local; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(fallocate, frame, local->op_ret, local->op_errno, &local->rebalance.prebuf, &local->rebalance.postbuf, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ STACK_WIND_COOKIE(frame, dht_fallocate_cbk, subvol, subvol, subvol->fops->fallocate, local->fd, local->rebalance.flags, local->rebalance.offset, local->rebalance.size, local->xattr_req); return 0; out: DHT_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_FALLOCATE); if (!local) { op_errno = ENOMEM; goto err; } local->rebalance.flags = mode; local->rebalance.offset = offset; local->rebalance.size = len; local->call_cnt = 1; subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); STACK_WIND_COOKIE(frame, dht_fallocate_cbk, subvol, subvol, subvol->fops->fallocate, fd, local->rebalance.flags, local->rebalance.offset, local->rebalance.size, local->xattr_req); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = -1; xlator_t *src_subvol = NULL; xlator_t *dst_subvol = NULL; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", cookie, out); local = frame->local; prev = cookie; /* discard fails with EBADF if dht has not yet opened the fd * on the cached subvol. This could happen if the file was migrated * and a lookup updated the cached subvol in the inode ctx. * We only check once as this could actually be a valid error. */ if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if ((op_ret == -1) && !dht_inode_missing(op_errno)) { local->op_errno = op_errno; local->op_ret = -1; gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if (local->call_cnt != 1) { if (local->stbuf.ia_blocks) { dht_iatt_merge(this, postbuf, &local->stbuf); dht_iatt_merge(this, prebuf, &local->prebuf); } goto out; } local->rebalance.target_op_fn = dht_discard2; local->op_ret = op_ret; local->op_errno = op_errno; dht_set_local_rebalance(this, local, NULL, prebuf, postbuf, xdata); /* Phase 2 of migration */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(postbuf)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* Check if the rebalance phase1 is true */ if (IS_DHT_MIGRATION_PHASE1(postbuf)) { dht_iatt_merge(this, &local->stbuf, postbuf); dht_iatt_merge(this, &local->prebuf, prebuf); dht_inode_ctx_get_mig_info(this, local->fd->inode, &src_subvol, &dst_subvol); if (!dht_mig_info_is_invalid(local->cached_subvol, src_subvol, dst_subvol)) { if (dht_fd_open_on_dst(this, local->fd, dst_subvol)) { dht_discard2(dst_subvol, frame, 0); return 0; } } ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } out: DHT_STRIP_PHASE1_FLAGS(postbuf); DHT_STRIP_PHASE1_FLAGS(prebuf); DHT_STACK_UNWIND(discard, frame, op_ret, op_errno, prebuf, postbuf, xdata); err: return 0; } static int dht_discard2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if (!frame || !frame->local) goto out; local = frame->local; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(discard, frame, local->op_ret, local->op_errno, &local->rebalance.prebuf, &local->rebalance.postbuf, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ STACK_WIND_COOKIE(frame, dht_discard_cbk, subvol, subvol, subvol->fops->discard, local->fd, local->rebalance.offset, local->rebalance.size, local->xattr_req); return 0; out: DHT_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_DISCARD); if (!local) { op_errno = ENOMEM; goto err; } local->rebalance.offset = offset; local->rebalance.size = len; local->call_cnt = 1; subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); STACK_WIND_COOKIE(frame, dht_discard_cbk, subvol, subvol, subvol->fops->discard, fd, local->rebalance.offset, local->rebalance.size, local->xattr_req); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = -1; xlator_t *subvol1 = NULL, *subvol2 = NULL; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); GF_VALIDATE_OR_GOTO("dht", cookie, out); local = frame->local; prev = cookie; /* zerofill fails with EBADF if dht has not yet opened the fd * on the cached subvol. This could happen if the file was migrated * and a lookup updated the cached subvol in the inode ctx. * We only check once as this could actually be a valid error. */ if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if ((op_ret == -1) && !dht_inode_missing(op_errno)) { local->op_errno = op_errno; local->op_ret = -1; gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if (local->call_cnt != 1) { if (local->stbuf.ia_blocks) { dht_iatt_merge(this, postbuf, &local->stbuf); dht_iatt_merge(this, prebuf, &local->prebuf); } goto out; } local->rebalance.target_op_fn = dht_zerofill2; local->op_ret = op_ret; local->op_errno = op_errno; dht_set_local_rebalance(this, local, NULL, prebuf, postbuf, xdata); /* Phase 2 of migration */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(postbuf)) { ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* Check if the rebalance phase1 is true */ if (IS_DHT_MIGRATION_PHASE1(postbuf)) { dht_iatt_merge(this, &local->stbuf, postbuf); dht_iatt_merge(this, &local->prebuf, prebuf); ret = dht_inode_ctx_get_mig_info(this, local->fd->inode, &subvol1, &subvol2); if (!dht_mig_info_is_invalid(local->cached_subvol, subvol1, subvol2)) { if (dht_fd_open_on_dst(this, local->fd, subvol2)) { dht_zerofill2(subvol2, frame, 0); return 0; } } ret = dht_rebalance_in_progress_check(this, frame); if (!ret) return 0; } out: DHT_STRIP_PHASE1_FLAGS(postbuf); DHT_STRIP_PHASE1_FLAGS(prebuf); DHT_STACK_UNWIND(zerofill, frame, op_ret, op_errno, prebuf, postbuf, xdata); err: return 0; } static int dht_zerofill2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if (!frame || !frame->local) goto out; local = frame->local; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(zerofill, frame, local->op_ret, local->op_errno, &local->rebalance.prebuf, &local->rebalance.postbuf, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ STACK_WIND_COOKIE(frame, dht_zerofill_cbk, subvol, subvol, subvol->fops->zerofill, local->fd, local->rebalance.offset, local->rebalance.size, local->xattr_req); return 0; out: DHT_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { xlator_t *subvol = NULL; int op_errno = -1; dht_local_t *local = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_ZEROFILL); if (!local) { op_errno = ENOMEM; goto err; } local->rebalance.offset = offset; local->rebalance.size = len; local->call_cnt = 1; subvol = local->cached_subvol; if (!subvol) { gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); STACK_WIND_COOKIE(frame, dht_zerofill_cbk, subvol, subvol, subvol->fops->zerofill, fd, local->rebalance.offset, local->rebalance.size, local->xattr_req); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* handle cases of migration here for 'setattr()' calls */ int dht_file_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int ret = -1; local = frame->local; prev = cookie; local->op_errno = op_errno; if ((local->fop == GF_FOP_FSETATTR) && dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { ret = dht_check_and_open_fd_on_subvol(this, frame); if (ret) goto out; return 0; } if ((op_ret == -1) && !dht_inode_missing(op_errno)) { gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } if (local->call_cnt != 1) goto out; local->op_ret = op_ret; local->op_errno = op_errno; local->rebalance.target_op_fn = dht_setattr2; /* Phase 2 of migration */ if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(postbuf)) { dht_set_local_rebalance(this, local, NULL, prebuf, postbuf, xdata); ret = dht_rebalance_complete_check(this, frame); if (!ret) return 0; } /* At the end of the migration process, whatever 'attr' we have on source file will be migrated to destination file in one shot, hence we don't need to check for in progress state here (ie, PHASE1) */ out: DHT_STRIP_PHASE1_FLAGS(postbuf); DHT_STRIP_PHASE1_FLAGS(prebuf); DHT_STACK_UNWIND(setattr, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } static int dht_setattr2(xlator_t *subvol, call_frame_t *frame, int ret) { dht_local_t *local = NULL; int32_t op_errno = EINVAL; if (!frame || !frame->local) goto out; local = frame->local; op_errno = local->op_errno; if (we_are_not_migrating(ret)) { /* This dht xlator is not migrating the file. Unwind and * pass on the original mode bits so the higher DHT layer * can handle this. */ DHT_STACK_UNWIND(setattr, frame, local->op_ret, local->op_errno, &local->rebalance.prebuf, &local->rebalance.postbuf, local->rebalance.xdata); return 0; } if (subvol == NULL) goto out; local->call_cnt = 2; /* This is the second attempt */ if (local->fop == GF_FOP_SETATTR) { STACK_WIND_COOKIE(frame, dht_file_setattr_cbk, subvol, subvol, subvol->fops->setattr, &local->loc, &local->rebalance.stbuf, local->rebalance.flags, local->xattr_req); } else { STACK_WIND_COOKIE(frame, dht_file_setattr_cbk, subvol, subvol, subvol->fops->fsetattr, local->fd, &local->rebalance.stbuf, local->rebalance.flags, local->xattr_req); } return 0; out: DHT_STACK_UNWIND(setattr, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* Keep the existing code same for all the cases other than regular file */ int dht_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; local = frame->local; prev = cookie; LOCK(&frame->lock); { if (op_ret == -1) { local->op_errno = op_errno; UNLOCK(&frame->lock); gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto post_unlock; } dht_iatt_merge(this, &local->prebuf, statpre); dht_iatt_merge(this, &local->stbuf, statpost); local->op_ret = 0; local->op_errno = 0; } UNLOCK(&frame->lock); post_unlock: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if (local->op_ret == 0) dht_inode_ctx_time_set(local->loc.inode, this, &local->stbuf); DHT_STACK_UNWIND(setattr, frame, local->op_ret, local->op_errno, &local->prebuf, &local->stbuf, xdata); } return 0; } /* Keep the existing code same for all the cases other than regular file */ int dht_non_mds_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; local = frame->local; prev = cookie; if (op_ret == -1) { gf_msg(this->name, op_errno, 0, 0, "subvolume %s returned -1", prev->name); goto post_unlock; } LOCK(&frame->lock); { dht_iatt_merge(this, &local->prebuf, statpre); dht_iatt_merge(this, &local->stbuf, statpost); local->op_ret = 0; local->op_errno = 0; } UNLOCK(&frame->lock); post_unlock: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { dht_inode_ctx_time_set(local->loc.inode, this, &local->stbuf); DHT_STACK_UNWIND(setattr, frame, 0, 0, &local->prebuf, &local->stbuf, xdata); } return 0; } int dht_mds_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; xlator_t *prev = NULL; xlator_t *mds_subvol = NULL; struct iatt loc_stbuf = { 0, }; int i = 0; local = frame->local; prev = cookie; conf = this->private; mds_subvol = local->mds_subvol; if (op_ret == -1) { local->op_ret = op_ret; local->op_errno = op_errno; gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", prev->name); goto out; } local->op_ret = 0; loc_stbuf = local->stbuf; dht_iatt_merge(this, &local->prebuf, statpre); dht_iatt_merge(this, &local->stbuf, statpost); local->call_cnt = conf->subvolume_cnt - 1; for (i = 0; i < conf->subvolume_cnt; i++) { if (mds_subvol == conf->subvolumes[i]) continue; STACK_WIND_COOKIE(frame, dht_non_mds_setattr_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->setattr, &local->loc, &loc_stbuf, local->valid, local->xattr_req); } return 0; out: DHT_STACK_UNWIND(setattr, frame, local->op_ret, local->op_errno, &local->prebuf, &local->stbuf, xdata); return 0; } int dht_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { xlator_t *subvol = NULL; xlator_t *mds_subvol = NULL; dht_layout_t *layout = NULL; dht_local_t *local = NULL; int op_errno = -1; int i = -1; int ret = -1; int call_cnt = 0; dht_conf_t *conf = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(loc->path, err); conf = this->private; local = dht_local_init(frame, loc, NULL, GF_FOP_SETATTR); if (!local) { op_errno = ENOMEM; goto err; } layout = local->layout; if (!layout) { gf_msg_debug(this->name, 0, "no layout for path=%s", loc->path); op_errno = EINVAL; goto err; } if (!layout_is_sane(layout)) { gf_msg_debug(this->name, 0, "layout is not sane for path=%s", loc->path); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); if (IA_ISREG(loc->inode->ia_type)) { /* in the regular file _cbk(), we need to check for migration possibilities */ local->rebalance.stbuf = *stbuf; local->rebalance.flags = valid; local->call_cnt = 1; subvol = local->cached_subvol; STACK_WIND_COOKIE(frame, dht_file_setattr_cbk, subvol, subvol, subvol->fops->setattr, loc, stbuf, valid, xdata); return 0; } local->call_cnt = call_cnt = layout->cnt; if (IA_ISDIR(loc->inode->ia_type) && !__is_root_gfid(loc->inode->gfid) && call_cnt != 1) { ret = dht_inode_ctx_mdsvol_get(loc->inode, this, &mds_subvol); if (ret || !mds_subvol) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "Failed to get mds subvol for path %s", local->loc.path); op_errno = EINVAL; goto err; } local->mds_subvol = mds_subvol; for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == mds_subvol) { if (!conf->subvolume_status[i]) { gf_msg(this->name, GF_LOG_WARNING, layout->list[i].err, DHT_MSG_HASHED_SUBVOL_DOWN, "MDS subvol is down for path " " %s Unable to set attr ", local->loc.path); op_errno = ENOTCONN; goto err; } } } local->valid = valid; local->stbuf = *stbuf; STACK_WIND_COOKIE(frame, dht_mds_setattr_cbk, local->mds_subvol, local->mds_subvol, local->mds_subvol->fops->setattr, loc, stbuf, valid, xdata); return 0; } else { for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, dht_setattr_cbk, layout->list[i].xlator, layout->list[i].xlator, layout->list[i].xlator->fops->setattr, loc, stbuf, valid, xdata); } } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(setattr, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int dht_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { xlator_t *subvol = NULL; dht_layout_t *layout = NULL; dht_local_t *local = NULL; int op_errno = -1; int i = -1; int call_cnt = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); local = dht_local_init(frame, NULL, fd, GF_FOP_FSETATTR); if (!local) { op_errno = ENOMEM; goto err; } layout = local->layout; if (!layout) { gf_msg_debug(this->name, 0, "no layout for fd=%p", fd); op_errno = EINVAL; goto err; } if (!layout_is_sane(layout)) { gf_msg_debug(this->name, 0, "layout is not sane for fd=%p", fd); op_errno = EINVAL; goto err; } if (xdata) local->xattr_req = dict_ref(xdata); if (IA_ISREG(fd->inode->ia_type)) { /* in the regular file _cbk(), we need to check for migration possibilities */ local->rebalance.stbuf = *stbuf; local->rebalance.flags = valid; local->call_cnt = 1; subvol = local->cached_subvol; STACK_WIND_COOKIE(frame, dht_file_setattr_cbk, subvol, subvol, subvol->fops->fsetattr, fd, &local->rebalance.stbuf, local->rebalance.flags, local->xattr_req); return 0; } local->call_cnt = call_cnt = layout->cnt; for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, dht_setattr_cbk, layout->list[i].xlator, layout->list[i].xlator, layout->list[i].xlator->fops->fsetattr, fd, stbuf, valid, xdata); } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(fsetattr, frame, -1, op_errno, NULL, NULL, NULL); return 0; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-diskusage.c0000644000000000000000000000013214522202451024003 xustar000000000000000030 mtime=1699284265.624027302 30 atime=1699284265.624027302 30 ctime=1699284301.229134544 glusterfs-11.1/xlators/cluster/dht/src/dht-diskusage.c0000664000175100017510000003657614522202451024303 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ /* TODO: add NS locking */ #include "dht-common.h" #include #include static int dht_du_info_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct statvfs *statvfs, dict_t *xdata) { dht_conf_t *conf = NULL; xlator_t *prev = NULL; int this_call_cnt = 0; int i = 0; double percent = 0; double percent_inodes = 0; uint64_t bytes = 0; uint32_t bpc; /* blocks per chunk */ uint32_t chunks = 0; conf = this->private; prev = cookie; if (op_ret == -1 || !statvfs) { gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_GET_DISK_INFO_ERROR, "failed to get disk info from %s", prev->name); goto out; } if (statvfs->f_blocks) { percent = (statvfs->f_bavail * 100) / statvfs->f_blocks; bytes = (statvfs->f_bavail * statvfs->f_frsize); /* * A 32-bit count of 1MB chunks allows a maximum brick size of * ~4PB. It's possible that we could see a single local FS * bigger than that some day, but this code is likely to be * irrelevant by then. Meanwhile, it's more important to keep * the chunk size small so the layout-calculation code that * uses this value can be tested on normal machines. */ bpc = (1 << 20) / statvfs->f_bsize; chunks = (statvfs->f_blocks + bpc - 1) / bpc; } if (statvfs->f_files) { percent_inodes = (statvfs->f_ffree * 100) / statvfs->f_files; } else { /* * Set percent inodes to 100 for dynamically allocated inode * filesystems. The rationale is that distribute need not * worry about total inodes; rather, let the 'create()' be * scheduled on the hashed subvol regardless of the total * inodes. */ percent_inodes = 100; } LOCK(&conf->subvolume_lock); { for (i = 0; i < conf->subvolume_cnt; i++) if (prev == conf->subvolumes[i]) { conf->du_stats[i].avail_percent = percent; conf->du_stats[i].avail_space = bytes; conf->du_stats[i].avail_inodes = percent_inodes; conf->du_stats[i].chunks = chunks; conf->du_stats[i].total_blocks = statvfs->f_blocks; conf->du_stats[i].avail_blocks = statvfs->f_bavail; conf->du_stats[i].frsize = statvfs->f_frsize; gf_msg_debug(this->name, 0, "subvolume '%s': avail_percent " "is: %.2f and avail_space " "is: %" PRIu64 " and avail_inodes" " is: %.2f", prev->name, conf->du_stats[i].avail_percent, conf->du_stats[i].avail_space, conf->du_stats[i].avail_inodes); break; /* no point in looping further */ } } UNLOCK(&conf->subvolume_lock); out: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) DHT_STACK_DESTROY(frame); return 0; } int dht_get_du_info_for_subvol(xlator_t *this, int subvol_idx) { dht_conf_t *conf = NULL; call_frame_t *statfs_frame = NULL; dht_local_t *statfs_local = NULL; call_pool_t *pool = NULL; loc_t tmp_loc = { 0, }; conf = this->private; pool = this->ctx->pool; statfs_frame = create_frame(this, pool); if (!statfs_frame) { goto err; } /* local->fop value is not used in this case */ statfs_local = dht_local_init(statfs_frame, NULL, NULL, GF_FOP_MAXVALUE); if (!statfs_local) { goto err; } /* make it root gfid, should be enough to get the proper info back */ tmp_loc.gfid[15] = 1; statfs_local->call_cnt = 1; STACK_WIND_COOKIE( statfs_frame, dht_du_info_cbk, conf->subvolumes[subvol_idx], conf->subvolumes[subvol_idx], conf->subvolumes[subvol_idx]->fops->statfs, &tmp_loc, NULL); return 0; err: if (statfs_frame) DHT_STACK_DESTROY(statfs_frame); return -1; } int dht_get_du_info(call_frame_t *frame, xlator_t *this, loc_t *loc) { int i = 0; int ret = -1; dht_conf_t *conf = NULL; call_frame_t *statfs_frame = NULL; dht_local_t *statfs_local = NULL; loc_t tmp_loc = { 0, }; time_t now; conf = this->private; now = gf_time(); /* make it root gfid, should be enough to get the proper info back */ tmp_loc.gfid[15] = 1; if (now > (conf->refresh_interval + conf->last_stat_fetch)) { statfs_frame = copy_frame(frame); if (!statfs_frame) { goto err; } /* In this case, 'local->fop' is not used */ statfs_local = dht_local_init(statfs_frame, loc, NULL, GF_FOP_MAXVALUE); if (!statfs_local) { goto err; } statfs_local->params = dict_new(); if (!statfs_local->params) goto err; ret = dict_set_int8(statfs_local->params, GF_INTERNAL_IGNORE_DEEM_STATFS, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set " GF_INTERNAL_IGNORE_DEEM_STATFS " in dict"); goto err; } statfs_local->call_cnt = conf->subvolume_cnt; for (i = 0; i < conf->subvolume_cnt; i++) { STACK_WIND_COOKIE(statfs_frame, dht_du_info_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->statfs, &tmp_loc, statfs_local->params); } conf->last_stat_fetch = now; } return 0; err: if (statfs_frame) DHT_STACK_DESTROY(statfs_frame); return -1; } gf_boolean_t dht_is_subvol_filled(xlator_t *this, xlator_t *subvol) { int i = 0; char vol_name[256]; dht_conf_t *conf = NULL; gf_boolean_t subvol_filled_inodes = _gf_false; gf_boolean_t subvol_filled_space = _gf_false; gf_boolean_t is_subvol_filled = _gf_false; double usage = 0; conf = this->private; /* Check for values above specified percent or free disk */ LOCK(&conf->subvolume_lock); { for (i = 0; i < conf->subvolume_cnt; i++) { if (subvol == conf->subvolumes[i]) { if (conf->disk_unit_percent) { if (conf->du_stats[i].avail_percent < conf->min_free_disk) { subvol_filled_space = _gf_true; break; } } else { if (conf->du_stats[i].avail_space < conf->min_free_disk) { subvol_filled_space = _gf_true; break; } } if (conf->du_stats[i].avail_inodes < conf->min_free_inodes) { subvol_filled_inodes = _gf_true; break; } } } } UNLOCK(&conf->subvolume_lock); if (subvol_filled_space && conf->subvolume_status[i]) { if (!(conf->du_stats[i].log++ % (GF_UNIVERSAL_ANSWER * 10))) { usage = 100 - conf->du_stats[i].avail_percent; gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_SUBVOL_INSUFF_SPACE, "disk space on subvolume '%s' is getting " "full (%.2f %%), consider adding more bricks", subvol->name, usage); (void)snprintf(vol_name, sizeof(vol_name), "%s", this->name); vol_name[(strlen(this->name) - 4)] = '\0'; gf_event(EVENT_DHT_DISK_USAGE, "volume=%s;subvol=%s;usage=%.2f %%", vol_name, subvol->name, usage); } } if (subvol_filled_inodes && conf->subvolume_status[i]) { if (!(conf->du_stats[i].log++ % (GF_UNIVERSAL_ANSWER * 10))) { usage = 100 - conf->du_stats[i].avail_inodes; gf_msg(this->name, GF_LOG_CRITICAL, 0, DHT_MSG_SUBVOL_INSUFF_INODES, "inodes on subvolume '%s' are at " "(%.2f %%), consider adding more bricks", subvol->name, usage); (void)snprintf(vol_name, sizeof(vol_name), "%s", this->name); vol_name[(strlen(this->name) - 4)] = '\0'; gf_event(EVENT_DHT_INODES_USAGE, "volume=%s;subvol=%s;usage=%.2f %%", vol_name, subvol->name, usage); } } is_subvol_filled = (subvol_filled_space || subvol_filled_inodes); return is_subvol_filled; } /*Get the best subvolume to create the file in*/ xlator_t * dht_free_disk_available_subvol(xlator_t *this, xlator_t *subvol, dht_local_t *local) { xlator_t *avail_subvol = NULL; dht_conf_t *conf = NULL; dht_layout_t *layout = NULL; loc_t *loc = NULL; conf = this->private; if (!local) goto out; loc = &local->loc; if (!local->layout) { layout = dht_layout_get(this, loc->parent); if (!layout) { gf_msg_debug(this->name, 0, "Missing layout. path=%s," " parent gfid = %s", loc->path, uuid_utoa(loc->parent->gfid)); goto out; } } else { layout = dht_layout_ref(local->layout); } LOCK(&conf->subvolume_lock); { avail_subvol = dht_subvol_with_free_space_inodes(this, subvol, NULL, layout, 0); if (!avail_subvol) { avail_subvol = dht_subvol_maxspace_nonzeroinode(this, subvol, layout); } } UNLOCK(&conf->subvolume_lock); out: if (!avail_subvol) { gf_msg_debug(this->name, 0, "No subvolume has enough free space \ and/or inodes to create"); avail_subvol = subvol; } if (layout) dht_layout_unref(layout); return avail_subvol; } static inline int32_t dht_subvol_has_err(dht_conf_t *conf, xlator_t *this, xlator_t *ignore, dht_layout_t *layout) { int ret = -1; int i = 0; if (!this || !layout) goto out; /* this check is meant for rebalance process. The source of the file * should be ignored for space check */ if (this == ignore) { goto out; } /* check if subvol has layout errors, before selecting it */ for (i = 0; i < layout->cnt; i++) { if (!strcmp(layout->list[i].xlator->name, this->name) && (layout->list[i].err != 0)) { ret = -1; goto out; } } /* discard decommissioned subvol */ if (conf->decommission_subvols_cnt) { for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->decommissioned_bricks[i] && conf->decommissioned_bricks[i] == this) { ret = -1; goto out; } } } ret = 0; out: return ret; } /*Get subvolume which has both space and inodes more than the min criteria*/ xlator_t * dht_subvol_with_free_space_inodes(xlator_t *this, xlator_t *subvol, xlator_t *ignore, dht_layout_t *layout, uint64_t filesize) { int i = 0; double max = 0; double max_inodes = 0; int ignore_subvol = 0; uint64_t total_blocks = 0; uint64_t avail_blocks = 0; uint64_t frsize = 0; double post_availspace = 0; double post_percent = 0; xlator_t *avail_subvol = NULL; dht_conf_t *conf = NULL; conf = this->private; for (i = 0; i < conf->subvolume_cnt; i++) { /* check if subvol has layout errors and also it is not a * decommissioned brick, before selecting it */ ignore_subvol = dht_subvol_has_err(conf, conf->subvolumes[i], ignore, layout); if (ignore_subvol) continue; if ((conf->disk_unit_percent) && (conf->du_stats[i].avail_percent > conf->min_free_disk) && (conf->du_stats[i].avail_inodes > conf->min_free_inodes)) { if ((conf->du_stats[i].avail_inodes > max_inodes) || (conf->du_stats[i].avail_percent > max)) { max = conf->du_stats[i].avail_percent; max_inodes = conf->du_stats[i].avail_inodes; avail_subvol = conf->subvolumes[i]; total_blocks = conf->du_stats[i].total_blocks; avail_blocks = conf->du_stats[i].avail_blocks; frsize = conf->du_stats[i].frsize; } } if ((!conf->disk_unit_percent) && (conf->du_stats[i].avail_space > conf->min_free_disk) && (conf->du_stats[i].avail_inodes > conf->min_free_inodes)) { if ((conf->du_stats[i].avail_inodes > max_inodes) || (conf->du_stats[i].avail_space > max)) { max = conf->du_stats[i].avail_space; max_inodes = conf->du_stats[i].avail_inodes; avail_subvol = conf->subvolumes[i]; } } } if (avail_subvol) { if (conf->disk_unit_percent) { if (filesize) { post_availspace = (avail_blocks * frsize) - filesize; post_percent = (post_availspace * 100) / (total_blocks * frsize); } else { post_availspace = avail_blocks; post_percent = (post_availspace * 100) / (total_blocks); } if (post_percent < conf->min_free_disk) avail_subvol = NULL; } else { if ((max - filesize) < conf->min_free_disk) avail_subvol = NULL; } } return avail_subvol; } /* Get subvol which has at least one inode and maximum space */ xlator_t * dht_subvol_maxspace_nonzeroinode(xlator_t *this, xlator_t *subvol, dht_layout_t *layout) { int i = 0; double max = 0; int ignore_subvol = 0; xlator_t *avail_subvol = NULL; dht_conf_t *conf = NULL; conf = this->private; for (i = 0; i < conf->subvolume_cnt; i++) { /* check if subvol has layout errors and also it is not a * decommissioned brick, before selecting it*/ ignore_subvol = dht_subvol_has_err(conf, conf->subvolumes[i], NULL, layout); if (ignore_subvol) continue; if (conf->disk_unit_percent) { if ((conf->du_stats[i].avail_percent > max) && (conf->du_stats[i].avail_inodes > 0)) { max = conf->du_stats[i].avail_percent; avail_subvol = conf->subvolumes[i]; } } else { if ((conf->du_stats[i].avail_space > max) && (conf->du_stats[i].avail_inodes > 0)) { max = conf->du_stats[i].avail_space; avail_subvol = conf->subvolumes[i]; } } } return avail_subvol; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202462023152 xustar000000000000000030 mtime=1699284274.547054179 30 atime=1699284289.088097976 30 ctime=1699284301.210134487 glusterfs-11.1/xlators/cluster/dht/src/Makefile.in0000664000175100017510000012116614522202462023440 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @UNITTEST_TRUE@am__append_1 = *.gcda *.gcno *_xunit.xml noinst_PROGRAMS = TESTS = subdir = xlators/cluster/dht/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) \ $(top_srcdir)/test-driver ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) dht_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am__objects_1 = dht-layout.lo dht-helper.lo dht-linkfile.lo \ dht-rebalance.lo dht-selfheal.lo dht-rename.lo dht-hashfn.lo \ dht-diskusage.lo dht-common.lo dht-inode-write.lo \ dht-inode-read.lo dht-shared.lo dht-lock.lo libxlator.lo am_dht_la_OBJECTS = $(am__objects_1) dht.lo dht_la_OBJECTS = $(am_dht_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = dht_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(dht_la_LDFLAGS) $(LDFLAGS) -o $@ nufa_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_nufa_la_OBJECTS = $(am__objects_1) nufa.lo nufa_la_OBJECTS = $(am_nufa_la_OBJECTS) nufa_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(nufa_la_LDFLAGS) $(LDFLAGS) -o $@ switch_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_switch_la_OBJECTS = $(am__objects_1) switch.lo switch_la_OBJECTS = $(am_switch_la_OBJECTS) switch_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(switch_la_LDFLAGS) $(LDFLAGS) -o $@ PROGRAMS = $(noinst_PROGRAMS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(dht_la_SOURCES) $(nufa_la_SOURCES) $(switch_la_SOURCES) DIST_SOURCES = $(dht_la_SOURCES) $(nufa_la_SOURCES) \ $(switch_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = dht.la nufa.la switch.la AM_CFLAGS = -Wall $(GF_CFLAGS) xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster dht_common_source = dht-layout.c dht-helper.c dht-linkfile.c dht-rebalance.c \ dht-selfheal.c dht-rename.c dht-hashfn.c dht-diskusage.c \ dht-common.c dht-inode-write.c dht-inode-read.c dht-shared.c \ dht-lock.c $(top_builddir)/xlators/lib/src/libxlator.c dht_la_SOURCES = $(dht_common_source) dht.c nufa_la_SOURCES = $(dht_common_source) nufa.c switch_la_SOURCES = $(dht_common_source) switch.c dht_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) dht_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la nufa_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) nufa_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la switch_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) switch_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = dht-common.h dht-mem-types.h dht-messages.h \ dht-lock.h $(top_builddir)/xlators/lib/src/libxlator.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/xlators/lib/src \ -DDATADIR=\"$(localstatedir)\" \ -DLIBDIR=\"$(libdir)\" CLEANFILES = $(am__append_1) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/cluster/dht/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/cluster/dht/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } dht.la: $(dht_la_OBJECTS) $(dht_la_DEPENDENCIES) $(EXTRA_dht_la_DEPENDENCIES) $(AM_V_CCLD)$(dht_la_LINK) -rpath $(xlatordir) $(dht_la_OBJECTS) $(dht_la_LIBADD) $(LIBS) nufa.la: $(nufa_la_OBJECTS) $(nufa_la_DEPENDENCIES) $(EXTRA_nufa_la_DEPENDENCIES) $(AM_V_CCLD)$(nufa_la_LINK) -rpath $(xlatordir) $(nufa_la_OBJECTS) $(nufa_la_LIBADD) $(LIBS) switch.la: $(switch_la_OBJECTS) $(switch_la_DEPENDENCIES) $(EXTRA_switch_la_DEPENDENCIES) $(AM_V_CCLD)$(switch_la_LINK) -rpath $(xlatordir) $(switch_la_OBJECTS) $(switch_la_LIBADD) $(LIBS) clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-diskusage.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-hashfn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-helper.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-inode-read.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-inode-write.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-layout.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-linkfile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-lock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-rebalance.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-rename.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-selfheal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht-shared.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxlator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nufa.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/switch.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libxlator.lo: $(top_builddir)/xlators/lib/src/libxlator.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxlator.lo -MD -MP -MF $(DEPDIR)/libxlator.Tpo -c -o libxlator.lo `test -f '$(top_builddir)/xlators/lib/src/libxlator.c' || echo '$(srcdir)/'`$(top_builddir)/xlators/lib/src/libxlator.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxlator.Tpo $(DEPDIR)/libxlator.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_builddir)/xlators/lib/src/libxlator.c' object='libxlator.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxlator.lo `test -f '$(top_builddir)/xlators/lib/src/libxlator.c' || echo '$(srcdir)/'`$(top_builddir)/xlators/lib/src/libxlator.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ else \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ clean-xlatorLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-xlatorLTLIBRARIES .MAKE: check-am install-am install-data-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-generic clean-libtool clean-noinstPROGRAMS \ clean-xlatorLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-hook install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ uninstall uninstall-am uninstall-local \ uninstall-xlatorLTLIBRARIES uninstall-local: rm -f $(DESTDIR)$(xlatordir)/distribute.so install-data-hook: ln -sf dht.so $(DESTDIR)$(xlatordir)/distribute.so # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-shared.c0000644000000000000000000000013114522202451023271 xustar000000000000000029 mtime=1699284265.63002732 30 atime=1699284265.629027317 30 ctime=1699284301.235134562 glusterfs-11.1/xlators/cluster/dht/src/dht-shared.c0000664000175100017510000010423014522202451023551 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ /* TODO: add NS locking */ #include #include "dht-common.h" #include "dht-messages.h" /* TODO: - use volumename in xattr instead of "dht" - use NS locks - handle all cases in self heal layout reconstruction - complete linkfile selfheal */ static void dht_layout_dump(dht_layout_t *layout, const char *prefix) { char key[GF_DUMP_MAX_BUF_LEN]; int i = 0; if (!layout) goto out; gf_proc_dump_build_key(key, prefix, "cnt"); gf_proc_dump_write(key, "%d", layout->cnt); gf_proc_dump_build_key(key, prefix, "preset"); gf_proc_dump_write(key, "%d", layout->preset); gf_proc_dump_build_key(key, prefix, "gen"); gf_proc_dump_write(key, "%d", layout->gen); if (layout->type != IA_INVAL) { gf_proc_dump_build_key(key, prefix, "inode type"); gf_proc_dump_write(key, "%d", layout->type); } if (!IA_ISDIR(layout->type)) goto out; for (i = 0; i < layout->cnt; i++) { gf_proc_dump_build_key(key, prefix, "list[%d].err", i); gf_proc_dump_write(key, "%d", layout->list[i].err); gf_proc_dump_build_key(key, prefix, "list[%d].start", i); gf_proc_dump_write(key, "0x%x", layout->list[i].start); gf_proc_dump_build_key(key, prefix, "list[%d].stop", i); gf_proc_dump_write(key, "0x%x", layout->list[i].stop); if (layout->list[i].xlator) { gf_proc_dump_build_key(key, prefix, "list[%d].xlator.type", i); gf_proc_dump_write(key, "%s", layout->list[i].xlator->type); gf_proc_dump_build_key(key, prefix, "list[%d].xlator.name", i); gf_proc_dump_write(key, "%s", layout->list[i].xlator->name); } } out: return; } int32_t dht_priv_dump(xlator_t *this) { char key_prefix[GF_DUMP_MAX_BUF_LEN]; char key[GF_DUMP_MAX_BUF_LEN]; int i = 0; dht_conf_t *conf = NULL; int ret = -1; if (!this) goto out; conf = this->private; if (!conf) goto out; ret = TRY_LOCK(&conf->subvolume_lock); if (ret != 0) { return ret; } gf_proc_dump_add_section("xlator.cluster.dht.%s.priv", this->name); gf_proc_dump_build_key(key_prefix, "xlator.cluster.dht", "%s.priv", this->name); gf_proc_dump_write("subvol_cnt", "%d", conf->subvolume_cnt); for (i = 0; i < conf->subvolume_cnt; i++) { snprintf(key, sizeof(key), "subvolumes[%d]", i); gf_proc_dump_write(key, "%s.%s", conf->subvolumes[i]->type, conf->subvolumes[i]->name); if (conf->file_layouts && conf->file_layouts[i]) { snprintf(key, sizeof(key), "file_layouts[%d]", i); dht_layout_dump(conf->file_layouts[i], key); } if (conf->dir_layouts && conf->dir_layouts[i]) { snprintf(key, sizeof(key), "dir_layouts[%d]", i); dht_layout_dump(conf->dir_layouts[i], key); } if (conf->subvolume_status) { snprintf(key, sizeof(key), "subvolume_status[%d]", i); gf_proc_dump_write(key, "%d", (int)conf->subvolume_status[i]); } } gf_proc_dump_write("search_unhashed", "%d", conf->search_unhashed); gf_proc_dump_write("gen", "%d", conf->gen); gf_proc_dump_write("min_free_disk", "%lf", conf->min_free_disk); gf_proc_dump_write("min_free_inodes", "%lf", conf->min_free_inodes); gf_proc_dump_write("disk_unit percentage", "%d", conf->disk_unit_percent); gf_proc_dump_write("refresh_interval", "%d", conf->refresh_interval); gf_proc_dump_write("unhashed_sticky_bit", "%d", conf->unhashed_sticky_bit); gf_proc_dump_write("use-readdirp", "%d", conf->use_readdirp); if (conf->du_stats && conf->subvolume_status) { for (i = 0; i < conf->subvolume_cnt; i++) { if (!conf->subvolume_status[i]) continue; snprintf(key, sizeof(key), "subvolumes[%d]", i); gf_proc_dump_write(key, "%s", conf->subvolumes[i]->name); snprintf(key, sizeof(key), "du_stats[%d].avail_percent", i); gf_proc_dump_write(key, "%lf", conf->du_stats[i].avail_percent); snprintf(key, sizeof(key), "du_stats[%d].avail_space", i); gf_proc_dump_write(key, "%" PRIu64, conf->du_stats[i].avail_space); snprintf(key, sizeof(key), "du_stats[%d].avail_inodes", i); gf_proc_dump_write(key, "%lf", conf->du_stats[i].avail_inodes); snprintf(key, sizeof(key), "du_stats[%d].log", i); gf_proc_dump_write(key, "%" PRIu32, conf->du_stats[i].log); } } if (conf->last_stat_fetch) gf_proc_dump_write("last_stat_fetch", "%s", ctime(&conf->last_stat_fetch)); UNLOCK(&conf->subvolume_lock); out: return ret; } int32_t dht_inodectx_dump(xlator_t *this, inode_t *inode) { int ret = -1; dht_layout_t *layout = NULL; if (!this) goto out; if (!inode) goto out; ret = dht_inode_ctx_layout_get(inode, this, &layout); if ((ret != 0) || !layout) return ret; gf_proc_dump_add_section("xlator.cluster.dht.%s.inode", this->name); dht_layout_dump(layout, "layout"); if (!ret) dht_layout_unref(layout); out: return ret; } void dht_fini(xlator_t *this) { int i = 0; dht_conf_t *conf = NULL; GF_VALIDATE_OR_GOTO("dht", this, out); conf = this->private; this->private = NULL; if (conf) { if (conf->file_layouts) { for (i = 0; i < conf->subvolume_cnt; i++) { GF_FREE(conf->file_layouts[i]); } GF_FREE(conf->file_layouts); } dict_unref(conf->leaf_to_subvol); /* allocated in dht_init_subvolumes() */ GF_FREE(conf->subvolumes); GF_FREE(conf->subvolume_status); GF_FREE(conf->last_event); GF_FREE(conf->subvol_up_time); GF_FREE(conf->du_stats); GF_FREE(conf->decommissioned_bricks); /* allocated in dht_init() */ GF_FREE(conf->mds_xattr_key); GF_FREE(conf->link_xattr_name); GF_FREE(conf->commithash_xattr_name); GF_FREE(conf->wild_xattr_name); /* allocated in dht_init_regex() */ if (conf->rsync_regex_valid) regfree(&conf->rsync_regex); if (conf->extra_regex_valid) regfree(&conf->extra_regex); synclock_destroy(&conf->link_lock); if (conf->lock_pool) mem_pool_destroy(conf->lock_pool); GF_FREE(conf); } out: return; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; GF_VALIDATE_OR_GOTO("dht", this, out); ret = xlator_mem_acct_init(this, gf_dht_mt_end); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_NO_MEMORY, "Memory accounting init failed"); return ret; } out: return ret; } static int dht_parse_decommissioned_bricks(xlator_t *this, dht_conf_t *conf, const char *bricks) { int i = 0; int ret = -1; char *tmpstr = NULL; char *dup_brick = NULL; char *node = NULL; if (!conf || !bricks) goto out; dup_brick = gf_strdup(bricks); if (dup_brick == NULL) { goto out; } node = strtok_r(dup_brick, ",", &tmpstr); while (node) { for (i = 0; i < conf->subvolume_cnt; i++) { if (!strcmp(conf->subvolumes[i]->name, node)) { conf->decommissioned_bricks[i] = conf->subvolumes[i]; conf->decommission_subvols_cnt++; gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_DECOMMISSION_INFO, "decommissioning subvolume %s", conf->subvolumes[i]->name); break; } } if (i == conf->subvolume_cnt) { /* Wrong node given. */ goto out; } node = strtok_r(NULL, ",", &tmpstr); } ret = 0; conf->decommission_in_progress = 1; out: GF_FREE(dup_brick); return ret; } static void dht_decommissioned_remove(xlator_t *this, dht_conf_t *conf) { int i = 0; for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->decommissioned_bricks[i]) { conf->decommissioned_bricks[i] = NULL; conf->decommission_subvols_cnt--; } } conf->decommission_in_progress = 0; } static void dht_init_regex(xlator_t *this, dict_t *odict, char *name, regex_t *re, gf_boolean_t *re_valid, dht_conf_t *conf) { char *temp_str = NULL; if (dict_get_str(odict, name, &temp_str) != 0) { if (strcmp(name, "rsync-hash-regex")) { return; } temp_str = "^\\.(.+)\\.[^.]+$"; } LOCK(&conf->lock); { if (*re_valid) { regfree(re); *re_valid = _gf_false; } if (!strcmp(temp_str, "none")) { goto unlock; } if (regcomp(re, temp_str, REG_EXTENDED) == 0) { gf_msg_debug(this->name, 0, "using regex %s = %s", name, temp_str); *re_valid = _gf_true; } else { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_REGEX_INFO, "compiling regex %s failed", temp_str); } } unlock: UNLOCK(&conf->lock); } int dht_set_subvol_range(xlator_t *this) { int ret = -1; dht_conf_t *conf = NULL; conf = this->private; if (!conf) goto out; conf->leaf_to_subvol = dict_new(); if (!conf->leaf_to_subvol) goto out; ret = glusterfs_reachable_leaves(this, conf->leaf_to_subvol); out: return ret; } static int dht_configure_throttle(xlator_t *this, dht_conf_t *conf, char *temp_str) { char *errmsg = NULL; int ret, count = gf_rebalance_thread_count(temp_str, &errmsg); if (count > 0) { pthread_mutex_lock(&conf->defrag->dfq_mutex); conf->defrag->recon_thread_count = count; pthread_mutex_unlock(&conf->defrag->dfq_mutex); gf_msg(this->name, GF_LOG_INFO, 0, 0, "rebalance " "thread count configured to %d", count); ret = 0; } else { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INVALID_OPTION, "%s", errmsg ? errmsg : ""); if (errmsg) GF_FREE(errmsg); ret = -1; } return ret; } int dht_reconfigure(xlator_t *this, dict_t *options) { dht_conf_t *conf = NULL; char *temp_str = NULL; gf_boolean_t search_unhashed; int ret = -1; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", options, out); conf = this->private; if (!conf) return 0; if (dict_get_str(options, "lookup-unhashed", &temp_str) == 0) { /* If option is not "auto", other options _should_ be boolean*/ if (strcasecmp(temp_str, "auto")) { if (!gf_string2boolean(temp_str, &search_unhashed)) { gf_msg_debug(this->name, 0, "Reconfigure: " "lookup-unhashed reconfigured(%s)", temp_str); conf->search_unhashed = search_unhashed; } else { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INVALID_OPTION, "Invalid option: Reconfigure: " "lookup-unhashed should be boolean," " not (%s), defaulting to (%d)", temp_str, conf->search_unhashed); ret = -1; goto out; } } else { gf_msg_debug(this->name, 0, "Reconfigure:" " lookup-unhashed reconfigured auto "); conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO; } } GF_OPTION_RECONF("lookup-optimize", conf->lookup_optimize, options, bool, out); GF_OPTION_RECONF("rmdir-optimize", conf->rmdir_optimize, options, bool, out); GF_OPTION_RECONF("min-free-disk", conf->min_free_disk, options, percent_or_size, out); /* option can be any one of percent or bytes */ conf->disk_unit_percent = _gf_false; if (conf->min_free_disk < 100.0) conf->disk_unit_percent = _gf_true; GF_OPTION_RECONF("min-free-inodes", conf->min_free_inodes, options, percent, out); GF_OPTION_RECONF("directory-layout-spread", conf->dir_spread_cnt, options, uint32, out); GF_OPTION_RECONF("readdir-optimize", conf->readdir_optimize, options, bool, out); GF_OPTION_RECONF("randomize-hash-range-by-gfid", conf->randomize_by_gfid, options, bool, out); GF_OPTION_RECONF("lock-migration", conf->lock_migration_enabled, options, bool, out); GF_OPTION_RECONF("force-migration", conf->force_migration, options, bool, out); GF_OPTION_RECONF("ensure-durability", conf->ensure_durability, options, bool, out); if (conf->defrag) { if (dict_get_str(options, "rebal-throttle", &temp_str) == 0) { ret = dht_configure_throttle(this, conf, temp_str); if (ret == -1) goto out; } } if (conf->defrag) { conf->defrag->lock_migration_enabled = conf->lock_migration_enabled; } if (conf->defrag) { GF_OPTION_RECONF("rebalance-stats", conf->defrag->stats, options, bool, out); } if (dict_get_str(options, "decommissioned-bricks", &temp_str) == 0) { if (!(conf->decommission_in_progress)) { ret = dht_parse_decommissioned_bricks(this, conf, temp_str); if (ret == -1) goto out; } } else { dht_decommissioned_remove(this, conf); } dht_init_regex(this, options, "rsync-hash-regex", &conf->rsync_regex, &conf->rsync_regex_valid, conf); dht_init_regex(this, options, "extra-hash-regex", &conf->extra_regex, &conf->extra_regex_valid, conf); GF_OPTION_RECONF("weighted-rebalance", conf->do_weighting, options, bool, out); GF_OPTION_RECONF("use-readdirp", conf->use_readdirp, options, bool, out); ret = 0; out: return ret; } static int gf_defrag_pattern_list_fill(xlator_t *this, gf_defrag_info_t *defrag, char *data) { int ret = -1; char *tmp_str = NULL; char *tmp_str1 = NULL; char *dup_str = NULL; char *num = NULL; char *pattern_str = NULL; char *pattern = NULL; gf_defrag_pattern_list_t *pattern_list = NULL; if (!this || !defrag || !data) goto out; /* Get the pattern for pattern list. "pattern:" * eg: *avi, *pdf:10MB, *:1TB */ pattern_str = strtok_r(data, ",", &tmp_str); while (pattern_str) { dup_str = gf_strdup(pattern_str); if (!dup_str) goto out; pattern_list = GF_CALLOC(1, sizeof(gf_defrag_pattern_list_t), 1); if (!pattern_list) { goto out; } INIT_LIST_HEAD(&pattern_list->list); pattern = strtok_r(dup_str, ":", &tmp_str1); num = strtok_r(NULL, ":", &tmp_str1); if (!pattern) goto out; if (!num) { if (gf_string2bytesize_uint64(pattern, &pattern_list->size) == 0) { pattern = "*"; } } else if (gf_string2bytesize_uint64(num, &pattern_list->size) != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INVALID_OPTION, "Invalid option. Defrag pattern:" " Invalid number format \"%s\"", num); goto out; } pattern_list->path_pattern = pattern; list_add_tail(&pattern_list->list, &defrag->defrag_pattern); pattern_list = NULL; dup_str = NULL; pattern_str = strtok_r(NULL, ",", &tmp_str); } ret = 0; out: if (ret) GF_FREE(pattern_list); GF_FREE(dup_str); return ret; } static int dht_init_methods(xlator_t *this) { int ret = -1; dht_conf_t *conf = NULL; dht_methods_t *methods = NULL; GF_VALIDATE_OR_GOTO("dht", this, err); conf = this->private; methods = &(conf->methods); methods->migration_get_dst_subvol = dht_migration_get_dst_subvol; methods->migration_other = NULL; methods->layout_search = dht_layout_search; ret = 0; err: return ret; } int dht_init(xlator_t *this) { dht_conf_t *conf = NULL; char *temp_str = NULL; int ret = -1; int i = 0; gf_defrag_info_t *defrag = NULL; int cmd = 0; char *node_uuid = NULL; uint32_t commit_hash = 0; GF_VALIDATE_OR_GOTO("dht", this, err); if (!this->children) { gf_msg(this->name, GF_LOG_CRITICAL, 0, DHT_MSG_INVALID_CONFIGURATION, "Distribute needs more than one subvolume"); return -1; } if (!this->parents) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_INVALID_CONFIGURATION, "dangling volume. check volfile"); } conf = GF_CALLOC(1, sizeof(*conf), gf_dht_mt_dht_conf_t); if (!conf) { goto err; } LOCK_INIT(&conf->subvolume_lock); LOCK_INIT(&conf->lock); synclock_init(&conf->link_lock, SYNC_LOCK_DEFAULT); /* We get the commit-hash to set only for rebalance process */ if (dict_get_uint32(this->options, "commit-hash", &commit_hash) == 0) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_COMMIT_HASH_INFO, "%s using commit hash %u", __func__, commit_hash); conf->vol_commit_hash = commit_hash; conf->vch_forced = _gf_true; } ret = dict_get_int32(this->options, "rebalance-cmd", &cmd); if (cmd) { defrag = GF_CALLOC(1, sizeof(gf_defrag_info_t), gf_defrag_info_mt); GF_VALIDATE_OR_GOTO(this->name, defrag, err); LOCK_INIT(&defrag->lock); INIT_LIST_HEAD(&defrag->defrag_pattern); defrag->is_exiting = 0; conf->defrag = defrag; defrag->this = this; ret = dict_get_str(this->options, "node-uuid", &node_uuid); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INVALID_CONFIGURATION, "Invalid volume configuration: " "node-uuid not specified"); goto err; } if (gf_uuid_parse(node_uuid, defrag->node_uuid)) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INVALID_OPTION, "Invalid option:" " Cannot parse glusterd node uuid"); goto err; } defrag->cmd = cmd; defrag->stats = _gf_false; defrag->queue = NULL; defrag->crawl_done = 0; defrag->global_error = 0; defrag->q_entry_count = 0; defrag->wakeup_crawler = 0; pthread_mutex_init(&defrag->dfq_mutex, 0); pthread_cond_init(&defrag->parallel_migration_cond, 0); pthread_cond_init(&defrag->rebalance_crawler_alarm, 0); pthread_cond_init(&defrag->df_wakeup_thread, 0); pthread_mutex_init(&defrag->fc_mutex, 0); pthread_cond_init(&defrag->fc_wakeup_cond, 0); defrag->global_error = 0; } conf->use_fallocate = 1; conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_ON; if (dict_get_str(this->options, "lookup-unhashed", &temp_str) == 0) { /* If option is not "auto", other options _should_ be boolean */ if (strcasecmp(temp_str, "auto")) { gf_boolean_t search_unhashed_bool; ret = gf_string2boolean(temp_str, &search_unhashed_bool); if (ret == -1) { goto err; } conf->search_unhashed = search_unhashed_bool ? GF_DHT_LOOKUP_UNHASHED_ON : GF_DHT_LOOKUP_UNHASHED_OFF; } else { conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO; } } GF_OPTION_INIT("lookup-optimize", conf->lookup_optimize, bool, err); GF_OPTION_INIT("rmdir-optimize", conf->rmdir_optimize, bool, err); GF_OPTION_INIT("unhashed-sticky-bit", conf->unhashed_sticky_bit, bool, err); GF_OPTION_INIT("use-readdirp", conf->use_readdirp, bool, err); GF_OPTION_INIT("min-free-disk", conf->min_free_disk, percent_or_size, err); GF_OPTION_INIT("min-free-inodes", conf->min_free_inodes, percent, err); conf->dir_spread_cnt = conf->subvolume_cnt; GF_OPTION_INIT("directory-layout-spread", conf->dir_spread_cnt, uint32, err); GF_OPTION_INIT("assert-no-child-down", conf->assert_no_child_down, bool, err); GF_OPTION_INIT("readdir-optimize", conf->readdir_optimize, bool, err); GF_OPTION_INIT("lock-migration", conf->lock_migration_enabled, bool, err); GF_OPTION_INIT("force-migration", conf->force_migration, bool, err); GF_OPTION_INIT("ensure-durability", conf->ensure_durability, bool, err); if (defrag) { defrag->lock_migration_enabled = conf->lock_migration_enabled; GF_OPTION_INIT("rebalance-stats", defrag->stats, bool, err); if (dict_get_str(this->options, "rebalance-filter", &temp_str) == 0) { if (gf_defrag_pattern_list_fill(this, defrag, temp_str) == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INVALID_OPTION, "Invalid option:" " Cannot parse rebalance-filter (%s)", temp_str); goto err; } } } /* option can be any one of percent or bytes */ conf->disk_unit_percent = _gf_false; if (conf->min_free_disk < 100) conf->disk_unit_percent = _gf_true; ret = dht_init_subvolumes(this, conf); if (ret == -1) { goto err; } if (cmd) { ret = dht_init_local_subvolumes(this, conf); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INIT_LOCAL_SUBVOL_FAILED, "dht_init_local_subvolumes failed"); goto err; } } if (dict_get_str(this->options, "decommissioned-bricks", &temp_str) == 0) { ret = dht_parse_decommissioned_bricks(this, conf, temp_str); if (ret == -1) goto err; } dht_init_regex(this, this->options, "rsync-hash-regex", &conf->rsync_regex, &conf->rsync_regex_valid, conf); dht_init_regex(this, this->options, "extra-hash-regex", &conf->extra_regex, &conf->extra_regex_valid, conf); ret = dht_layouts_init(this, conf); if (ret == -1) { goto err; } conf->gen = 1; this->local_pool = mem_pool_new(dht_local_t, 512); if (!this->local_pool) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, " DHT initialisation failed. " "failed to create local_t's memory pool"); goto err; } GF_OPTION_INIT("randomize-hash-range-by-gfid", conf->randomize_by_gfid, bool, err); if (defrag) { GF_OPTION_INIT("rebal-throttle", temp_str, str, err); if (temp_str) { ret = dht_configure_throttle(this, conf, temp_str); if (ret == -1) goto err; } } GF_OPTION_INIT("xattr-name", conf->xattr_name, str, err); gf_asprintf(&conf->mds_xattr_key, "%s." DHT_MDS_STR, conf->xattr_name); gf_asprintf(&conf->link_xattr_name, "%s." DHT_LINKFILE_STR, conf->xattr_name); gf_asprintf(&conf->commithash_xattr_name, "%s." DHT_COMMITHASH_STR, conf->xattr_name); gf_asprintf(&conf->wild_xattr_name, "%s*", conf->xattr_name); if (!conf->link_xattr_name || !conf->wild_xattr_name) { goto err; } GF_OPTION_INIT("weighted-rebalance", conf->do_weighting, bool, err); conf->lock_pool = mem_pool_new(dht_lock_t, 512); if (!conf->lock_pool) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INIT_FAILED, "failed to create lock mem_pool, failing " "initialization"); goto err; } this->private = conf; if (dht_set_subvol_range(this)) goto err; if (dht_init_methods(this)) goto err; return 0; err: if (conf) { if (conf->file_layouts) { for (i = 0; i < conf->subvolume_cnt; i++) { GF_FREE(conf->file_layouts[i]); } GF_FREE(conf->file_layouts); } GF_FREE(conf->subvolumes); GF_FREE(conf->subvolume_status); GF_FREE(conf->du_stats); GF_FREE(conf->defrag); GF_FREE(conf->xattr_name); GF_FREE(conf->link_xattr_name); GF_FREE(conf->wild_xattr_name); GF_FREE(conf->mds_xattr_key); if (conf->lock_pool) mem_pool_destroy(conf->lock_pool); GF_FREE(conf); } return -1; } struct volume_options dht_options[] = { { .key = {"lookup-unhashed"}, .value = {"auto", "yes", "no", "enable", "disable", "1", "0", "on", "off"}, .type = GF_OPTION_TYPE_STR, .default_value = "on", .description = "This option if set to ON, does a lookup through " "all the sub-volumes, in case a lookup didn't return any result " "from the hash subvolume. If set to OFF, it does not do a lookup " "on the remaining subvolumes.", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE, .level = OPT_STATUS_BASIC, }, {.key = {"lookup-optimize"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "This option if set to ON enables the optimization " "of -ve lookups, by not doing a lookup on non-hashed subvolumes for " "files, in case the hashed subvolume does not return any result. " "This option disregards the lookup-unhashed setting, when enabled.", .op_version = {GD_OP_VERSION_3_7_2}, .level = OPT_STATUS_ADVANCED, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"rmdir-optimize"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "This option if set to ON enables the optimization " "of rmdir, by not doing a readdirp call to check about linkto files.", .op_version = {GD_OP_VERSION_11_0}, .level = OPT_STATUS_ADVANCED, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"min-free-disk"}, .type = GF_OPTION_TYPE_PERCENT_OR_SIZET, .default_value = "10%", .description = "Percentage/Size of disk space, after which the " "process starts balancing out the cluster, and logs will appear " "in log files", .op_version = {1}, .level = OPT_STATUS_BASIC, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"min-free-inodes"}, .type = GF_OPTION_TYPE_PERCENT, .default_value = "5%", .description = "after system has only N% of inodes, warnings " "starts to appear in log files", .op_version = {1}, .level = OPT_STATUS_BASIC, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, { .key = {"unhashed-sticky-bit"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", }, {.key = {"use-readdirp"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "This option if set to ON, forces the use of " "readdirp, and hence also displays the stats of the files.", .level = OPT_STATUS_ADVANCED, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"assert-no-child-down"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "This option if set to ON, in the event of " "CHILD_DOWN, will call exit."}, { .key = {"directory-layout-spread"}, .type = GF_OPTION_TYPE_INT, .min = 1, .validate = GF_OPT_VALIDATE_MIN, .description = "Specifies the directory layout spread. Takes number " "of subvolumes as default value.", .op_version = {2}, }, { .key = {"decommissioned-bricks"}, .type = GF_OPTION_TYPE_ANY, .description = "This option if set to ON, decommissions " "the brick, so that no new data is allowed to be created " "on that brick.", .level = OPT_STATUS_ADVANCED, }, { .key = {"rebalance-cmd"}, .type = GF_OPTION_TYPE_INT, }, { .key = {"commit-hash"}, .type = GF_OPTION_TYPE_INT, }, { .key = {"node-uuid"}, .type = GF_OPTION_TYPE_STR, }, { .key = {"rebalance-stats"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "This option if set to ON displays and logs the " " time taken for migration of each file, during the rebalance " "process. If set to OFF, the rebalance logs will only display the " "time spent in each directory.", .op_version = {2}, .level = OPT_STATUS_BASIC, }, {.key = {"readdir-optimize"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "This option if set to ON enables the optimization " "that allows DHT to requests non-first subvolumes to filter out " "directory entries.", .op_version = {1}, .level = OPT_STATUS_ADVANCED, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"rsync-hash-regex"}, .type = GF_OPTION_TYPE_STR, /* Setting a default here doesn't work. See dht_init_regex. */ .description = "Regular expression for stripping temporary-file " "suffix and prefix used by rsync, to prevent relocation when the " "file is renamed.", .op_version = {3}, .level = OPT_STATUS_BASIC, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"extra-hash-regex"}, .type = GF_OPTION_TYPE_STR, /* Setting a default here doesn't work. See dht_init_regex. */ .description = "Regular expression for stripping temporary-file " "suffix and prefix used by an application, to prevent relocation when " "the file is renamed.", .op_version = {3}, .level = OPT_STATUS_BASIC, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, { .key = {"rebalance-filter"}, .type = GF_OPTION_TYPE_STR, }, { .key = {"xattr-name"}, .type = GF_OPTION_TYPE_STR, .default_value = "trusted.glusterfs.dht", .description = "Base for extended attributes used by this " "translator instance, to avoid conflicts with others above or " "below it.", .op_version = {3}, }, {.key = {"weighted-rebalance"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "When enabled, files will be allocated to bricks " "with a probability proportional to their size. Otherwise, all " "bricks will have the same probability (legacy behavior).", .op_version = {GD_OP_VERSION_3_6_0}, .level = OPT_STATUS_BASIC, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, /* NUFA option */ {.key = {"local-volume-name"}, .type = GF_OPTION_TYPE_XLATOR}, /* switch option */ {.key = {"pattern.switch.case"}, .type = GF_OPTION_TYPE_ANY}, { .key = {"randomize-hash-range-by-gfid"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "Use gfid of directory to determine the subvolume " "from which hash ranges are allocated starting with 0. " "Note that we still use a directory/file's name to determine the " "subvolume to which it hashes", .op_version = {GD_OP_VERSION_3_6_0}, }, {.key = {"rebal-throttle"}, .type = GF_OPTION_TYPE_STR, .default_value = "normal", .description = " Sets the maximum number of parallel file migrations " "allowed on a node during the rebalance operation. The" " default value is normal and allows 2 files to be " "migrated at a time. Lazy will allow only one file to " "be migrated at a time and aggressive will allow " "max of [($(processing units) - 4) / 2), 4]", .op_version = {GD_OP_VERSION_3_7_0}, .level = OPT_STATUS_BASIC, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC }, {.key = {"lock-migration"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = " If enabled this feature will migrate the posix locks" " associated with a file during rebalance", .op_version = {GD_OP_VERSION_3_8_0}, .level = OPT_STATUS_ADVANCED, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"force-migration"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "If disabled, rebalance will not migrate files that " "are being written to by an application", .op_version = {GD_OP_VERSION_4_0_0}, .level = OPT_STATUS_ADVANCED, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {"ensure-durability"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "If disabled, rebalance will not fsync files after " "migration. Please note that this can lead to bad data if " "the data couldn't be synced by the brick machine's " "kernel, because of hardware failure etc.", .op_version = {GD_OP_VERSION_10_0}, .level = OPT_STATUS_ADVANCED, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, {.key = {NULL}}, }; #define NUM_DHT_OPTIONS (sizeof(dht_options) / sizeof(dht_options[0])) extern struct volume_options options[NUM_DHT_OPTIONS] __attribute__((alias("dht_options"))); glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-rename.c0000644000000000000000000000013214522202451023273 xustar000000000000000030 mtime=1699284265.628027314 30 atime=1699284265.628027314 30 ctime=1699284301.226134535 glusterfs-11.1/xlators/cluster/dht/src/dht-rename.c0000664000175100017510000017777514522202451023602 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ /* TODO: link(oldpath, newpath) fails if newpath already exists. DHT should * delete the newpath if it gets EEXISTS from link() call. */ #include "dht-common.h" #include "dht-lock.h" int32_t dht_rename_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata); int dht_rename_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; dht_set_fixed_dir_stat(&local->preoldparent); dht_set_fixed_dir_stat(&local->postoldparent); dht_set_fixed_dir_stat(&local->preparent); dht_set_fixed_dir_stat(&local->postparent); if (IA_ISREG(local->stbuf.ia_type)) DHT_STRIP_PHASE1_FLAGS(&local->stbuf); DHT_STACK_UNWIND(rename, frame, local->op_ret, local->op_errno, &local->stbuf, &local->preoldparent, &local->postoldparent, &local->preparent, &local->postparent, local->xattr); return 0; } static void dht_rename_dir_unlock_src(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; local = frame->local; dht_unlock_namespace(frame, &local->lock[0]); return; } static void dht_rename_dir_unlock_dst(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; int op_ret = -1; local = frame->local; /* Unlock entrylk */ dht_unlock_entrylk_wrapper(frame, &local->lock[1].ns.directory_ns); /* Unlock inodelk */ op_ret = dht_unlock_inodelk(frame, &local->lock[1].ns.parent_layout, dht_rename_unlock_cbk); if (op_ret < 0) { char src_gfid[GF_UUID_BUF_SIZE]; char dst_gfid[GF_UUID_BUF_SIZE] = {0}; uuid_utoa_r(local->loc.inode->gfid, src_gfid); if (local->loc2.inode) uuid_utoa_r(local->loc2.inode->gfid, dst_gfid); if (IA_ISREG(local->stbuf.ia_type)) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_UNLOCKING_FAILED, "winding unlock inodelk failed " "rename (%s:%s:%s %s:%s:%s), " "stale locks left on bricks", local->loc.path, src_gfid, local->src_cached->name, local->loc2.path, dst_gfid, local->dst_cached ? local->dst_cached->name : NULL); else gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_UNLOCKING_FAILED, "winding unlock inodelk failed " "rename (%s:%s %s:%s), " "stale locks left on bricks", local->loc.path, src_gfid, local->loc2.path, dst_gfid); dht_rename_unlock_cbk(frame, NULL, this, 0, 0, NULL); } return; } static int dht_rename_dir_unlock(call_frame_t *frame, xlator_t *this) { dht_rename_dir_unlock_src(frame, this); dht_rename_dir_unlock_dst(frame, this); return 0; } int dht_rename_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { dht_conf_t *conf = NULL; dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; int i = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; int subvol_cnt = -1; conf = this->private; local = frame->local; prev = cookie; subvol_cnt = dht_subvol_cnt(this, prev); if (subvol_cnt >= 0) local->ret_cache[subvol_cnt] = op_ret; if (op_ret == -1) { gf_uuid_unparse(local->loc.inode->gfid, gfid); gf_msg(this->name, GF_LOG_INFO, op_errno, DHT_MSG_RENAME_FAILED, "Rename %s -> %s on %s failed, (gfid = %s)", local->loc.path, local->loc2.path, prev->name, gfid); local->op_ret = op_ret; local->op_errno = op_errno; goto unwind; } /* TODO: construct proper stbuf for dir */ /* * FIXME: is this the correct way to build stbuf and * parent bufs? */ dht_iatt_merge(this, &local->stbuf, stbuf); dht_iatt_merge(this, &local->preoldparent, preoldparent); dht_iatt_merge(this, &local->postoldparent, postoldparent); dht_iatt_merge(this, &local->preparent, prenewparent); dht_iatt_merge(this, &local->postparent, postnewparent); unwind: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { /* We get here with local->call_cnt == 0. Which means * we are the only one executing this code, there is * no contention. Therefore it's safe to manipulate or * deref local->call_cnt directly (without locking). */ if (local->ret_cache[conf->subvolume_cnt] == 0) { /* count errant subvols in last field of ret_cache */ for (i = 0; i < conf->subvolume_cnt; i++) { if (local->ret_cache[i] != 0) ++local->ret_cache[conf->subvolume_cnt]; } if (local->ret_cache[conf->subvolume_cnt]) { /* undoing the damage: * for all subvolumes, where rename * succeeded, we perform the reverse operation */ for (i = 0; i < conf->subvolume_cnt; i++) { if (local->ret_cache[i] == 0) ++local->call_cnt; } for (i = 0; i < conf->subvolume_cnt; i++) { if (local->ret_cache[i]) continue; STACK_WIND(frame, dht_rename_dir_cbk, conf->subvolumes[i], conf->subvolumes[i]->fops->rename, &local->loc2, &local->loc, NULL); } return 0; } } WIPE(&local->preoldparent); WIPE(&local->postoldparent); WIPE(&local->preparent); WIPE(&local->postparent); dht_rename_dir_unlock(frame, this); } return 0; } static int dht_rename_hashed_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { dht_conf_t *conf = NULL; dht_local_t *local = NULL; int call_cnt = 0; xlator_t *prev = NULL; int i = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; conf = this->private; local = frame->local; prev = cookie; if (op_ret == -1) { gf_uuid_unparse(local->loc.inode->gfid, gfid); gf_msg(this->name, GF_LOG_INFO, op_errno, DHT_MSG_RENAME_FAILED, "rename %s -> %s on %s failed, (gfid = %s) ", local->loc.path, local->loc2.path, prev->name, gfid); local->op_ret = op_ret; local->op_errno = op_errno; goto unwind; } /* TODO: construct proper stbuf for dir */ /* * FIXME: is this the correct way to build stbuf and * parent bufs? */ dht_iatt_merge(this, &local->stbuf, stbuf); dht_iatt_merge(this, &local->preoldparent, preoldparent); dht_iatt_merge(this, &local->postoldparent, postoldparent); dht_iatt_merge(this, &local->preparent, prenewparent); dht_iatt_merge(this, &local->postparent, postnewparent); call_cnt = local->call_cnt = conf->subvolume_cnt - 1; if (!local->call_cnt) goto unwind; for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == local->dst_hashed) continue; STACK_WIND_COOKIE( frame, dht_rename_dir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->rename, &local->loc, &local->loc2, NULL); if (!--call_cnt) break; } return 0; unwind: WIPE(&local->preoldparent); WIPE(&local->postoldparent); WIPE(&local->preparent); WIPE(&local->postparent); dht_rename_dir_unlock(frame, this); return 0; } static int dht_rename_dir_do(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; local = frame->local; if (local->op_ret == -1) goto err; local->op_ret = 0; STACK_WIND_COOKIE(frame, dht_rename_hashed_dir_cbk, local->dst_hashed, local->dst_hashed, local->dst_hashed->fops->rename, &local->loc, &local->loc2, NULL); return 0; err: dht_rename_dir_unlock(frame, this); return 0; } static int dht_rename_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = -1; xlator_t *prev = NULL; local = frame->local; prev = cookie; if (op_ret > 2) { gf_msg_trace(this->name, 0, "readdir on %s for %s returned %d entries", prev->name, local->loc.path, op_ret); local->op_ret = -1; local->op_errno = ENOTEMPTY; } this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { dht_rename_dir_do(frame, this); } return 0; } static int dht_rename_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = -1; xlator_t *prev = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; prev = cookie; if (op_ret == -1) { gf_uuid_unparse(local->loc.inode->gfid, gfid); gf_msg(this->name, GF_LOG_INFO, op_errno, DHT_MSG_OPENDIR_FAILED, "opendir on %s for %s failed,(gfid = %s) ", prev->name, local->loc.path, gfid); goto err; } fd_bind(fd); STACK_WIND_COOKIE(frame, dht_rename_readdir_cbk, prev, prev, prev->fops->readdir, local->fd, 4096, 0, NULL); return 0; err: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { dht_rename_dir_do(frame, this); } return 0; } static int dht_rename_dir_lock2_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; char src_gfid[GF_UUID_BUF_SIZE] = {0}; char dst_gfid[GF_UUID_BUF_SIZE] = {0}; dht_conf_t *conf = NULL; int i = 0; local = frame->local; conf = this->private; if (op_ret < 0) { uuid_utoa_r(local->loc.inode->gfid, src_gfid); if (local->loc2.inode) uuid_utoa_r(local->loc2.inode->gfid, dst_gfid); gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_INODE_LK_ERROR, "acquiring entrylk after inodelk failed" "rename (%s:%s:%s %s:%s:%s)", local->loc.path, src_gfid, local->src_cached->name, local->loc2.path, dst_gfid, local->dst_cached ? local->dst_cached->name : NULL); local->op_ret = -1; local->op_errno = op_errno; goto err; } local->fd = fd_create(local->loc.inode, frame->root->pid); if (!local->fd) { op_errno = ENOMEM; goto err; } local->op_ret = 0; if (!local->dst_cached) { dht_rename_dir_do(frame, this); return 0; } for (i = 0; i < conf->subvolume_cnt; i++) { STACK_WIND_COOKIE(frame, dht_rename_opendir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->opendir, &local->loc2, local->fd, NULL); } return 0; err: /* No harm in calling an extra unlock */ dht_rename_dir_unlock(frame, this); return 0; } static int dht_rename_dir_lock1_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; char src_gfid[GF_UUID_BUF_SIZE] = {0}; char dst_gfid[GF_UUID_BUF_SIZE] = {0}; int ret = 0; loc_t *loc = NULL; xlator_t *subvol = NULL; local = frame->local; if (op_ret < 0) { uuid_utoa_r(local->loc.inode->gfid, src_gfid); if (local->loc2.inode) uuid_utoa_r(local->loc2.inode->gfid, dst_gfid); gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_INODE_LK_ERROR, "acquiring entrylk after inodelk failed" "rename (%s:%s:%s %s:%s:%s)", local->loc.path, src_gfid, local->src_cached->name, local->loc2.path, dst_gfid, local->dst_cached ? local->dst_cached->name : NULL); local->op_ret = -1; local->op_errno = op_errno; goto err; } if (local->current == &local->lock[0]) { loc = &local->loc2; subvol = local->dst_hashed; local->current = &local->lock[1]; } else { loc = &local->loc; subvol = local->src_hashed; local->current = &local->lock[0]; } ret = dht_protect_namespace(frame, loc, subvol, &local->current->ns, dht_rename_dir_lock2_cbk); if (ret < 0) { op_errno = EINVAL; goto err; } return 0; err: /* No harm in calling an extra unlock */ dht_rename_dir_unlock(frame, this); return 0; } /* * If the hashed subvolumes of both source and dst are the different, * lock in dictionary order of hashed subvol->name. This is important * in case the parent directory is the same for both src and dst to * prevent inodelk deadlocks when racing with a fix-layout op on the parent. * * If the hashed subvols are the same, use the gfid/name to determine * the order of taking locks to prevent entrylk deadlocks when the parent * dirs are the same. * */ static int dht_order_rename_lock(call_frame_t *frame, loc_t **loc, xlator_t **subvol) { int ret = 0; int op_ret = 0; dht_local_t *local = NULL; char *src = NULL; char *dst = NULL; local = frame->local; if (local->src_hashed->name == local->dst_hashed->name) { ret = 0; } else { ret = strcmp(local->src_hashed->name, local->dst_hashed->name); } if (ret == 0) { /* hashed subvols are the same for src and dst */ /* Entrylks need to be ordered*/ src = alloca(GF_UUID_BNAME_BUF_SIZE + strlen(local->loc.name) + 1); if (!src) { gf_msg(frame->this->name, GF_LOG_ERROR, ENOMEM, 0, "Insufficient memory for src"); op_ret = -1; goto out; } if (!gf_uuid_is_null(local->loc.pargfid)) uuid_utoa_r(local->loc.pargfid, src); else if (local->loc.parent) uuid_utoa_r(local->loc.parent->gfid, src); else src[0] = '\0'; strcat(src, local->loc.name); dst = alloca(GF_UUID_BNAME_BUF_SIZE + strlen(local->loc2.name) + 1); if (!dst) { gf_msg(frame->this->name, GF_LOG_ERROR, ENOMEM, 0, "Insufficient memory for dst"); op_ret = -1; goto out; } if (!gf_uuid_is_null(local->loc2.pargfid)) uuid_utoa_r(local->loc2.pargfid, dst); else if (local->loc2.parent) uuid_utoa_r(local->loc2.parent->gfid, dst); else dst[0] = '\0'; strcat(dst, local->loc2.name); ret = strcmp(src, dst); } if (ret <= 0) { /*inodelk in dictionary order of hashed subvol names*/ /*entrylk in dictionary order of gfid/basename */ local->current = &local->lock[0]; *loc = &local->loc; *subvol = local->src_hashed; } else { local->current = &local->lock[1]; *loc = &local->loc2; *subvol = local->dst_hashed; } op_ret = 0; out: return op_ret; } int dht_rename_dir(call_frame_t *frame, xlator_t *this) { dht_conf_t *conf = NULL; dht_local_t *local = NULL; loc_t *loc = NULL; xlator_t *subvol = NULL; int i = 0; int ret = 0; int op_errno = -1; conf = frame->this->private; local = frame->local; local->ret_cache = GF_CALLOC(conf->subvolume_cnt + 1, sizeof(int), gf_dht_ret_cache_t); if (local->ret_cache == NULL) { op_errno = ENOMEM; goto err; } local->call_cnt = conf->subvolume_cnt; for (i = 0; i < conf->subvolume_cnt; i++) { if (!conf->subvolume_status[i]) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_RENAME_FAILED, "Rename dir failed: subvolume down (%s)", conf->subvolumes[i]->name); op_errno = ENOTCONN; goto err; } } /* Locks on src and dst needs to ordered which otherwise might cause * deadlocks when rename (src, dst) and rename (dst, src) is done from * two different clients */ ret = dht_order_rename_lock(frame, &loc, &subvol); if (ret) { op_errno = ENOMEM; goto err; } /* Rename must take locks on src to avoid lookup selfheal from * recreating src on those subvols where the rename was successful. * The locks can't be issued parallel as two different clients might * attempt same rename command and be in dead lock. */ ret = dht_protect_namespace(frame, loc, subvol, &local->current->ns, dht_rename_dir_lock1_cbk); if (ret < 0) { op_errno = EINVAL; goto err; } return 0; err: DHT_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } static int dht_rename_track_for_changelog(xlator_t *this, dict_t *xattr, loc_t *oldloc, loc_t *newloc) { int ret = -1; dht_changelog_rename_info_t *info = NULL; char *name = NULL; int len1 = 0; int len2 = 0; int size = 0; if (!xattr || !oldloc || !newloc || !this) return ret; len1 = strlen(oldloc->name) + 1; len2 = strlen(newloc->name) + 1; size = sizeof(dht_changelog_rename_info_t) + len1 + len2; info = GF_CALLOC(size, sizeof(char), gf_common_mt_char); if (!info) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to calloc memory"); return ret; } gf_uuid_copy(info->old_pargfid, oldloc->pargfid); gf_uuid_copy(info->new_pargfid, newloc->pargfid); info->oldname_len = len1; info->newname_len = len2; strncpy(info->buffer, oldloc->name, len1); name = info->buffer + len1; strncpy(name, newloc->name, len2); ret = dict_set_bin(xattr, DHT_CHANGELOG_RENAME_OP_KEY, info, size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value: key = %s," " path = %s", DHT_CHANGELOG_RENAME_OP_KEY, oldloc->name); GF_FREE(info); } return ret; } #define DHT_MARKER_DONT_ACCOUNT(xattr) \ do { \ int tmp = -1; \ if (!xattr) { \ xattr = dict_new(); \ if (!xattr) \ break; \ } \ tmp = dict_set_str(xattr, GLUSTERFS_MARKER_DONT_ACCOUNT_KEY, "yes"); \ if (tmp) { \ gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, \ "Failed to set dictionary value: key = %s," \ " path = %s", \ GLUSTERFS_MARKER_DONT_ACCOUNT_KEY, local->loc.path); \ } \ } while (0) #define DHT_CHANGELOG_TRACK_AS_RENAME(xattr, oldloc, newloc) \ do { \ int tmp = -1; \ if (!xattr) { \ xattr = dict_new(); \ if (!xattr) { \ gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, \ "Failed to create dictionary to " \ "track rename"); \ break; \ } \ } \ \ tmp = dht_rename_track_for_changelog(this, xattr, oldloc, newloc); \ \ if (tmp) { \ gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, \ "Failed to set dictionary value: key = %s," \ " path = %s", \ DHT_CHANGELOG_RENAME_OP_KEY, (oldloc)->path); \ } \ } while (0) int dht_rename_unlock(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; int op_ret = -1; dht_lock_wrap_t inodelk_wrapper; local = frame->local; memset(&inodelk_wrapper, 0, sizeof(dht_lock_wrap_t)); inodelk_wrapper.locks = local->rename_inodelk_backward_compatible; inodelk_wrapper.lk_count = local->rename_inodelk_bc_count; op_ret = dht_unlock_inodelk_wrapper(frame, &inodelk_wrapper); if (op_ret < 0) { char src_gfid[GF_UUID_BUF_SIZE]; char dst_gfid[GF_UUID_BUF_SIZE] = {0}; uuid_utoa_r(local->loc.inode->gfid, src_gfid); if (local->loc2.inode) uuid_utoa_r(local->loc2.inode->gfid, dst_gfid); if (IA_ISREG(local->stbuf.ia_type)) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_UNLOCKING_FAILED, "winding unlock inodelk failed " "rename (%s:%s:%s %s:%s:%s), " "stale locks left on bricks", local->loc.path, src_gfid, local->src_cached->name, local->loc2.path, dst_gfid, local->dst_cached ? local->dst_cached->name : NULL); else gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_UNLOCKING_FAILED, "winding unlock inodelk failed " "rename (%s:%s %s:%s), " "stale locks left on bricks", local->loc.path, src_gfid, local->loc2.path, dst_gfid); } dht_unlock_namespace(frame, &local->lock[0]); dht_unlock_namespace(frame, &local->lock[1]); dht_rename_unlock_cbk(frame, NULL, this, local->op_ret, local->op_errno, NULL); return 0; } int dht_rename_done(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; local = frame->local; if (local->linked == _gf_true) { local->linked = _gf_false; dht_linkfile_attr_heal(frame, this); } dht_rename_unlock(frame, this); return 0; } static int dht_rename_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; int this_call_cnt = 0; local = frame->local; prev = cookie; FRAME_SU_UNDO(frame, dht_local_t); if (!local) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INVALID_VALUE, "!local, should not happen"); goto out; } this_call_cnt = dht_frame_return(frame); if (op_ret == -1) { gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_UNLINK_FAILED, "%s: Rename: unlink on %s failed ", local->loc.path, prev->name); } WIPE(&local->preoldparent); WIPE(&local->postoldparent); WIPE(&local->preparent); WIPE(&local->postparent); if (is_last_call(this_call_cnt)) { dht_rename_done(frame, this); } out: return 0; } int dht_rename_cleanup(call_frame_t *frame) { dht_local_t *local = NULL; xlator_t *this = NULL; xlator_t *src_hashed = NULL; xlator_t *src_cached = NULL; xlator_t *dst_hashed = NULL; xlator_t *dst_cached = NULL; int call_cnt = 0; dict_t *xattr = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; this = frame->this; src_hashed = local->src_hashed; src_cached = local->src_cached; dst_hashed = local->dst_hashed; dst_cached = local->dst_cached; if (src_cached == dst_cached) goto nolinks; if (local->linked && (dst_hashed != src_hashed) && (dst_hashed != src_cached)) { call_cnt++; } if (local->added_link && (src_cached != dst_hashed)) { call_cnt++; } local->call_cnt = call_cnt; if (!call_cnt) goto nolinks; DHT_MARK_FOP_INTERNAL(xattr); gf_uuid_unparse(local->loc.inode->gfid, gfid); if (local->linked && (dst_hashed != src_hashed) && (dst_hashed != src_cached)) { dict_t *xattr_new = NULL; gf_msg_trace(this->name, 0, "unlinking linkfile %s @ %s => %s, (gfid = %s)", local->loc.path, dst_hashed->name, src_cached->name, gfid); xattr_new = dict_copy_with_ref(xattr, NULL); DHT_MARKER_DONT_ACCOUNT(xattr_new); FRAME_SU_DO(frame, dht_local_t); STACK_WIND_COOKIE(frame, dht_rename_unlink_cbk, dst_hashed, dst_hashed, dst_hashed->fops->unlink, &local->loc, 0, xattr_new); dict_unref(xattr_new); xattr_new = NULL; } if (local->added_link && (src_cached != dst_hashed)) { dict_t *xattr_new = NULL; gf_msg_trace(this->name, 0, "unlinking link %s => %s (%s), (gfid = %s)", local->loc.path, local->loc2.path, src_cached->name, gfid); xattr_new = dict_copy_with_ref(xattr, NULL); if (gf_uuid_compare(local->loc.pargfid, local->loc2.pargfid) == 0) { DHT_MARKER_DONT_ACCOUNT(xattr_new); } /* * * The link to file is created using root permission. * Hence deletion should happen using root. Otherwise * it will fail. */ FRAME_SU_DO(frame, dht_local_t); STACK_WIND_COOKIE(frame, dht_rename_unlink_cbk, src_cached, src_cached, src_cached->fops->unlink, &local->loc2, 0, xattr_new); dict_unref(xattr_new); xattr_new = NULL; } if (xattr) dict_unref(xattr); return 0; nolinks: WIPE(&local->preoldparent); WIPE(&local->postoldparent); WIPE(&local->preparent); WIPE(&local->postparent); dht_rename_unlock(frame, this); return 0; } int dht_rename_unlink(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; xlator_t *src_hashed = NULL; xlator_t *src_cached = NULL; xlator_t *dst_hashed = NULL; xlator_t *dst_cached = NULL; xlator_t *rename_subvol = NULL; dict_t *xattr = NULL; local = frame->local; src_hashed = local->src_hashed; src_cached = local->src_cached; dst_hashed = local->dst_hashed; dst_cached = local->dst_cached; local->call_cnt = 0; /* NOTE: rename_subvol is the same subvolume from which dht_rename_cbk * is called. since rename has already happened on rename_subvol, * unlink shouldn't be sent for oldpath (either linkfile or cached-file) * on rename_subvol. */ if (src_cached == dst_cached) rename_subvol = src_cached; else rename_subvol = dst_hashed; /* TODO: delete files in background */ if (src_cached != dst_hashed && src_cached != dst_cached) local->call_cnt++; if (src_hashed != rename_subvol && src_hashed != src_cached) local->call_cnt++; if (dst_cached && dst_cached != dst_hashed && dst_cached != src_cached) local->call_cnt++; if (local->call_cnt == 0) goto unwind; DHT_MARK_FOP_INTERNAL(xattr); if (src_cached != dst_hashed && src_cached != dst_cached) { dict_t *xattr_new = NULL; xattr_new = dict_copy_with_ref(xattr, NULL); gf_msg_trace(this->name, 0, "deleting old src datafile %s @ %s", local->loc.path, src_cached->name); if (gf_uuid_compare(local->loc.pargfid, local->loc2.pargfid) == 0) { DHT_MARKER_DONT_ACCOUNT(xattr_new); } DHT_CHANGELOG_TRACK_AS_RENAME(xattr_new, &local->loc, &local->loc2); STACK_WIND_COOKIE(frame, dht_rename_unlink_cbk, src_cached, src_cached, src_cached->fops->unlink, &local->loc, 0, xattr_new); dict_unref(xattr_new); xattr_new = NULL; } if (src_hashed != rename_subvol && src_hashed != src_cached) { dict_t *xattr_new = NULL; xattr_new = dict_copy_with_ref(xattr, NULL); gf_msg_trace(this->name, 0, "deleting old src linkfile %s @ %s", local->loc.path, src_hashed->name); DHT_MARKER_DONT_ACCOUNT(xattr_new); STACK_WIND_COOKIE(frame, dht_rename_unlink_cbk, src_hashed, src_hashed, src_hashed->fops->unlink, &local->loc, 0, xattr_new); dict_unref(xattr_new); xattr_new = NULL; } if (dst_cached && (dst_cached != dst_hashed) && (dst_cached != src_cached)) { gf_msg_trace(this->name, 0, "deleting old dst datafile %s @ %s", local->loc2.path, dst_cached->name); STACK_WIND_COOKIE(frame, dht_rename_unlink_cbk, dst_cached, dst_cached, dst_cached->fops->unlink, &local->loc2, 0, xattr); } if (xattr) dict_unref(xattr); return 0; unwind: WIPE(&local->preoldparent); WIPE(&local->postoldparent); WIPE(&local->preparent); WIPE(&local->postparent); dht_rename_done(frame, this); return 0; } static int dht_rename_links_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { xlator_t *prev = NULL; dht_local_t *local = NULL; call_frame_t *main_frame = NULL; prev = cookie; local = frame->local; main_frame = local->main_frame; /* TODO: Handle this case in lookup-optimize */ if (op_ret == -1) { gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_CREATE_LINK_FAILED, "link/file %s on %s failed", local->loc.path, prev->name); } if (local->linked == _gf_true) { local->linked = _gf_false; dht_linkfile_attr_heal(frame, this); } dht_rename_unlink(main_frame, this); DHT_STACK_DESTROY(frame); return 0; } int dht_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; xlator_t *src_cached = NULL; xlator_t *dst_hashed = NULL; xlator_t *dst_cached = NULL; call_frame_t *link_frame = NULL; dht_local_t *link_local = NULL; local = frame->local; prev = cookie; src_cached = local->src_cached; dst_hashed = local->dst_hashed; dst_cached = local->dst_cached; if (local->linked == _gf_true) FRAME_SU_UNDO(frame, dht_local_t); /* It is a critical failure iff we fail to rename the cached file * if the rename of the linkto failed, it is not a critical failure, * and we do not want to lose the created hard link for the new * name as that could have been read by other clients. * * NOTE: If another client is attempting the same oldname -> newname * rename, and finds both file names as existing, and are hard links * to each other, then FUSE would send in an unlink for oldname. In * this time duration if we treat the linkto as a critical error and * unlink the newname we created, we would have effectively lost the * file to rename operations. * * Repercussions of treating this as a non-critical error is that * we could leave behind a stale linkto file and/or not create the new * linkto file, the second case would be rectified by a subsequent * lookup, the first case by a rebalance, like for all stale linkto * files */ if (op_ret == -1) { /* Critical failure: unable to rename the cached file */ if (prev == src_cached) { gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_RENAME_FAILED, "%s: Rename on %s failed, (gfid = %s) ", local->loc.path, prev->name, local->loc.inode ? uuid_utoa(local->loc.inode->gfid) : ""); local->op_ret = op_ret; local->op_errno = op_errno; goto cleanup; } else { /* Non-critical failure, unable to rename the linkto * file */ gf_msg(this->name, GF_LOG_INFO, op_errno, DHT_MSG_RENAME_FAILED, "%s: Rename (linkto file) on %s failed, " "(gfid = %s) ", local->loc.path, prev->name, local->loc.inode ? uuid_utoa(local->loc.inode->gfid) : ""); } } if (xdata) { if (!local->xattr) local->xattr = dict_ref(xdata); else local->xattr = dict_copy_with_ref(xdata, local->xattr); } /* Merge attrs only from src_cached. In case there of src_cached != * dst_hashed, this ignores linkfile attrs. */ if (prev == src_cached) { dht_iatt_merge(this, &local->stbuf, stbuf); dht_iatt_merge(this, &local->preoldparent, preoldparent); dht_iatt_merge(this, &local->postoldparent, postoldparent); dht_iatt_merge(this, &local->preparent, prenewparent); dht_iatt_merge(this, &local->postparent, postnewparent); } /* Create the linkto file for the dst file */ if ((src_cached == dst_cached) && (dst_hashed != dst_cached)) { link_frame = copy_frame(frame); if (!link_frame) { goto unlink; } /* fop value sent as maxvalue because it is not used * anywhere in this case */ link_local = dht_local_init(link_frame, &local->loc2, NULL, GF_FOP_MAXVALUE); if (!link_local) { goto unlink; } if (link_local->loc.inode) inode_unref(link_local->loc.inode); link_local->loc.inode = inode_ref(local->loc.inode); link_local->main_frame = frame; link_local->stbuf = local->stbuf; gf_uuid_copy(link_local->gfid, local->loc.inode->gfid); dht_linkfile_create(link_frame, dht_rename_links_create_cbk, this, src_cached, dst_hashed, &link_local->loc); return 0; } unlink: if (link_frame) { DHT_STACK_DESTROY(link_frame); } dht_rename_unlink(frame, this); return 0; cleanup: dht_rename_cleanup(frame); return 0; } int dht_do_rename(call_frame_t *frame) { dht_local_t *local = NULL; xlator_t *dst_hashed = NULL; xlator_t *src_cached = NULL; xlator_t *dst_cached = NULL; xlator_t *this = NULL; xlator_t *rename_subvol = NULL; local = frame->local; this = frame->this; dst_hashed = local->dst_hashed; dst_cached = local->dst_cached; src_cached = local->src_cached; if (src_cached == dst_cached) rename_subvol = src_cached; else rename_subvol = dst_hashed; if ((src_cached != dst_hashed) && (rename_subvol == dst_hashed)) { DHT_MARKER_DONT_ACCOUNT(local->xattr_req); } if (rename_subvol == src_cached) { DHT_CHANGELOG_TRACK_AS_RENAME(local->xattr_req, &local->loc, &local->loc2); } gf_msg_trace(this->name, 0, "renaming %s => %s (%s)", local->loc.path, local->loc2.path, rename_subvol->name); if (local->linked == _gf_true) FRAME_SU_DO(frame, dht_local_t); STACK_WIND_COOKIE(frame, dht_rename_cbk, rename_subvol, rename_subvol, rename_subvol->fops->rename, &local->loc, &local->loc2, local->xattr_req); return 0; } int dht_rename_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; local = frame->local; prev = cookie; if (op_ret == -1) { gf_msg_debug(this->name, op_errno, "link/file on %s failed", prev->name); local->op_ret = -1; local->op_errno = op_errno; local->added_link = _gf_false; } else dht_iatt_merge(this, &local->stbuf, stbuf); if (local->op_ret == -1) goto cleanup; dht_do_rename(frame); return 0; cleanup: dht_rename_cleanup(frame); return 0; } static int dht_rename_linkto_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; xlator_t *src_cached = NULL; dict_t *xattr = NULL; local = frame->local; DHT_MARK_FOP_INTERNAL(xattr); prev = cookie; src_cached = local->src_cached; if (op_ret == -1) { gf_msg_debug(this->name, op_errno, "link/file on %s failed", prev->name); local->op_ret = -1; local->op_errno = op_errno; } /* If linkto creation failed move to failure cleanup code, * instead of continuing with creating the link file */ if (local->op_ret != 0) { goto cleanup; } gf_msg_trace(this->name, 0, "link %s => %s (%s)", local->loc.path, local->loc2.path, src_cached->name); if (gf_uuid_compare(local->loc.pargfid, local->loc2.pargfid) == 0) { DHT_MARKER_DONT_ACCOUNT(xattr); } /* problem: link creation fails if a stale linkto exists for dst in * the src_cached. * handling: populate the FORCE_REPLACE key for "forcing" posix * to unlink the stale file and repeat the link */ if (dict_set_str(xattr, GF_FORCE_REPLACE_KEY, "yes")) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value: key = %s," " path = %s", GF_FORCE_REPLACE_KEY, local->loc.path); goto cleanup; } local->added_link = _gf_true; STACK_WIND_COOKIE(frame, dht_rename_link_cbk, src_cached, src_cached, src_cached->fops->link, &local->loc, &local->loc2, xattr); if (xattr) dict_unref(xattr); return 0; cleanup: dht_rename_cleanup(frame); if (xattr) dict_unref(xattr); return 0; } int dht_rename_unlink_links_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *prev = NULL; local = frame->local; prev = cookie; if ((op_ret == -1) && (op_errno != ENOENT)) { gf_msg_debug(this->name, op_errno, "unlink of %s on %s failed ", local->loc2.path, prev->name); local->op_ret = -1; local->op_errno = op_errno; } if (local->op_ret == -1) goto cleanup; dht_do_rename(frame); return 0; cleanup: dht_rename_cleanup(frame); return 0; } int dht_rename_create_links(call_frame_t *frame) { dht_local_t *local = NULL; xlator_t *this = NULL; xlator_t *src_hashed = NULL; xlator_t *src_cached = NULL; xlator_t *dst_hashed = NULL; xlator_t *dst_cached = NULL; int call_cnt = 0; dict_t *xattr = NULL; int ret = 0; local = frame->local; this = frame->this; src_hashed = local->src_hashed; src_cached = local->src_cached; dst_hashed = local->dst_hashed; dst_cached = local->dst_cached; DHT_MARK_FOP_INTERNAL(xattr); if (src_cached == dst_cached) { dict_t *xattr_new = NULL; if (dst_hashed == dst_cached) goto nolinks; xattr_new = dict_copy_with_ref(xattr, NULL); gf_msg_trace(this->name, 0, "unlinking dst linkfile %s @ %s", local->loc2.path, dst_hashed->name); DHT_MARKER_DONT_ACCOUNT(xattr_new); STACK_WIND_COOKIE(frame, dht_rename_unlink_links_cbk, dst_hashed, dst_hashed, dst_hashed->fops->unlink, &local->loc2, 0, xattr_new); dict_unref(xattr_new); if (xattr) dict_unref(xattr); return 0; } dict_t *xattr_new = NULL; if (src_cached != dst_hashed) { /* needed to create the link file */ call_cnt++; if (dst_hashed != src_hashed) /* needed to create the linkto file */ call_cnt++; /* handle cases of stale linkto files that cause failure to create * linkto/link during rename. * set the FORCE_REPLACE key for unlinking the stale file if it exists. * possible cases of stale linkto: * 1. stale linkto for src is exists in the dst_hash * 2. stale linkto for dst is exists in the src_cache */ xattr_new = dict_copy_with_ref(xattr, NULL); if (!xattr_new) { ret = -1; goto cleanup; } ret = dict_set_str(xattr_new, GF_FORCE_REPLACE_KEY, "yes"); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "Failed to set dictionary value: key = %s," " path = %s", GF_FORCE_REPLACE_KEY, local->loc.path); dict_unref(xattr_new); ret = -1; goto cleanup; } } /* We should not have any failures post the link creation, as this * introduces the newname into the namespace. Clients could have cached * the existence of the newname and may start taking actions based on * the same. Hence create the linkto first, and then attempt the link. * * NOTE: If another client is attempting the same oldname -> newname * rename, and finds both file names as existing, and are hard links * to each other, then FUSE would send in an unlink for oldname. In * this time duration if we treat the linkto as a critical error and * unlink the newname we created, we would have effectively lost the * file to rename operations. */ if (dst_hashed != src_hashed && src_cached != dst_hashed) { gf_msg_trace(this->name, 0, "linkto-file %s @ %s => %s", local->loc.path, dst_hashed->name, src_cached->name); local->params = xattr_new; memcpy(local->gfid, local->loc.inode->gfid, 16); dht_linkfile_create(frame, dht_rename_linkto_cbk, this, src_cached, dst_hashed, &local->loc); } else if (src_cached != dst_hashed) { gf_msg_trace(this->name, 0, "link %s => %s (%s)", local->loc.path, local->loc2.path, src_cached->name); if (gf_uuid_compare(local->loc.pargfid, local->loc2.pargfid) == 0) { DHT_MARKER_DONT_ACCOUNT(xattr_new); } local->added_link = _gf_true; STACK_WIND_COOKIE(frame, dht_rename_link_cbk, src_cached, src_cached, src_cached->fops->link, &local->loc, &local->loc2, xattr_new); dict_unref(xattr_new); } nolinks: if (!call_cnt) { /* skip to next step */ dht_do_rename(frame); } cleanup: if (xattr) dict_unref(xattr); return ret; } static int dht_rename_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { dht_local_t *local = NULL; int call_cnt = 0; dht_conf_t *conf = NULL; char gfid_local[GF_UUID_BUF_SIZE] = {0}; char gfid_server[GF_UUID_BUF_SIZE] = {0}; int child_index = -1; gf_boolean_t is_src = _gf_false; loc_t *loc = NULL; child_index = (long)cookie; local = frame->local; conf = this->private; is_src = (child_index == 0); if (is_src) loc = &local->loc; else loc = &local->loc2; if (op_ret >= 0) { if (is_src) local->src_cached = dht_subvol_get_cached(this, local->loc.inode); else { if (loc->inode) gf_uuid_unparse(loc->inode->gfid, gfid_local); gf_msg_debug(this->name, 0, "dst_cached before lookup: %s, " "(path:%s)(gfid:%s),", local->loc2.path, local->dst_cached ? local->dst_cached->name : NULL, local->dst_cached ? gfid_local : NULL); local->dst_cached = dht_subvol_get_cached(this, local->loc2_copy.inode); gf_uuid_unparse(stbuf->ia_gfid, gfid_local); gf_msg_debug(this->name, GF_LOG_WARNING, "dst_cached after lookup: %s, " "(path:%s)(gfid:%s)", local->loc2.path, local->dst_cached ? local->dst_cached->name : NULL, local->dst_cached ? gfid_local : NULL); if ((local->loc2.inode == NULL) || gf_uuid_compare(stbuf->ia_gfid, local->loc2.inode->gfid)) { if (local->loc2.inode != NULL) { inode_unlink(local->loc2.inode, local->loc2.parent, local->loc2.name); inode_unref(local->loc2.inode); } local->loc2.inode = inode_link(local->loc2_copy.inode, local->loc2_copy.parent, local->loc2_copy.name, stbuf); gf_uuid_copy(local->loc2.gfid, stbuf->ia_gfid); } } } if (op_ret < 0) { if (is_src) { /* The meaning of is_linkfile is overloaded here. For locking * to work properly both rebalance and rename should acquire * lock on datafile. The reason for sending this lookup is to * find out whether we've acquired a lock on data file. * Between the lookup before rename and this rename, the * file could be migrated by a rebalance process and now this * file this might be a linkto file. We verify that by sending * this lookup. However, if this lookup fails we cannot really * say whether we've acquired lock on a datafile or linkto file. * So, we act conservatively and _assume_ * that this is a linkfile and fail the rename operation. */ local->is_linkfile = _gf_true; local->op_errno = op_errno; } else { if (local->dst_cached) gf_msg_debug(this->name, op_errno, "file %s (gfid:%s) was present " "(hashed-subvol=%s, " "cached-subvol=%s) before rename," " but lookup failed", local->loc2.path, uuid_utoa(local->loc2.inode->gfid), local->dst_hashed->name, local->dst_cached->name); if (dht_inode_missing(op_errno)) local->dst_cached = NULL; } } else if (is_src && xattr && check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name)) { local->is_linkfile = _gf_true; /* Found linkto file instead of data file, passdown ENOENT * based on the above comment */ local->op_errno = ENOENT; } if (!local->is_linkfile && (op_ret >= 0) && gf_uuid_compare(loc->gfid, stbuf->ia_gfid)) { gf_uuid_unparse(loc->gfid, gfid_local); gf_uuid_unparse(stbuf->ia_gfid, gfid_server); gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_MISMATCH, "path:%s, received a different gfid, local_gfid= %s" " server_gfid: %s", local->loc.path, gfid_local, gfid_server); /* Will passdown ENOENT anyway since the file we sent on * rename is replaced with a different file */ local->op_errno = ENOENT; /* Since local->is_linkfile is used here to detect failure, * marking this to true */ local->is_linkfile = _gf_true; } call_cnt = dht_frame_return(frame); if (is_last_call(call_cnt)) { if (local->is_linkfile) { local->op_ret = -1; goto fail; } local->op_ret = dht_rename_create_links(frame); if (local->op_ret < 0) { local->op_errno = ENOMEM; goto fail; } } return 0; fail: dht_rename_unlock(frame, this); return 0; } int dht_rename_file_lock1_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; char src_gfid[GF_UUID_BUF_SIZE] = {0}; char dst_gfid[GF_UUID_BUF_SIZE] = {0}; int ret = 0; loc_t *loc = NULL; xlator_t *subvol = NULL; local = frame->local; if (op_ret < 0) { uuid_utoa_r(local->loc.inode->gfid, src_gfid); if (local->loc2.inode) uuid_utoa_r(local->loc2.inode->gfid, dst_gfid); gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_INODE_LK_ERROR, "protecting namespace of %s failed" "rename (%s:%s:%s %s:%s:%s)", local->current == &local->lock[0] ? local->loc.path : local->loc2.path, local->loc.path, src_gfid, local->src_hashed->name, local->loc2.path, dst_gfid, local->dst_hashed ? local->dst_hashed->name : NULL); local->op_ret = -1; local->op_errno = op_errno; goto err; } if (local->current == &local->lock[0]) { loc = &local->loc2; subvol = local->dst_hashed; local->current = &local->lock[1]; } else { loc = &local->loc; subvol = local->src_hashed; local->current = &local->lock[0]; } ret = dht_protect_namespace(frame, loc, subvol, &local->current->ns, dht_rename_lock_cbk); if (ret < 0) { op_errno = EINVAL; goto err; } return 0; err: /* No harm in calling an extra unlock */ dht_rename_unlock(frame, this); return 0; } static int32_t dht_rename_file_protect_namespace(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; char src_gfid[GF_UUID_BUF_SIZE] = {0}; char dst_gfid[GF_UUID_BUF_SIZE] = {0}; int ret = 0; loc_t *loc = NULL; xlator_t *subvol = NULL; local = frame->local; if (op_ret < 0) { uuid_utoa_r(local->loc.inode->gfid, src_gfid); if (local->loc2.inode) uuid_utoa_r(local->loc2.inode->gfid, dst_gfid); gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_INODE_LK_ERROR, "acquiring inodelk failed " "rename (%s:%s:%s %s:%s:%s)", local->loc.path, src_gfid, local->src_cached->name, local->loc2.path, dst_gfid, local->dst_cached ? local->dst_cached->name : NULL); local->op_ret = -1; local->op_errno = op_errno; goto err; } /* Locks on src and dst needs to ordered which otherwise might cause * deadlocks when rename (src, dst) and rename (dst, src) is done from * two different clients */ ret = dht_order_rename_lock(frame, &loc, &subvol); if (ret) { local->op_errno = ENOMEM; goto err; } ret = dht_protect_namespace(frame, loc, subvol, &local->current->ns, dht_rename_file_lock1_cbk); if (ret < 0) { op_errno = EINVAL; goto err; } return 0; err: /* Its fine to call unlock even when no locks are acquired, as we check * for lock->locked before winding a unlock call. */ dht_rename_unlock(frame, this); return 0; } int32_t dht_rename_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; char src_gfid[GF_UUID_BUF_SIZE] = {0}; char dst_gfid[GF_UUID_BUF_SIZE] = {0}; dict_t *xattr_req = NULL; dht_conf_t *conf = NULL; int i = 0; xlator_t *subvol = NULL; dht_lock_t *lock = NULL; local = frame->local; conf = this->private; if (op_ret < 0) { uuid_utoa_r(local->loc.inode->gfid, src_gfid); if (local->loc2.inode) uuid_utoa_r(local->loc2.inode->gfid, dst_gfid); gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_INODE_LK_ERROR, "protecting namespace of %s failed. " "rename (%s:%s:%s %s:%s:%s)", local->current == &local->lock[0] ? local->loc.path : local->loc2.path, local->loc.path, src_gfid, local->src_hashed->name, local->loc2.path, dst_gfid, local->dst_hashed ? local->dst_hashed->name : NULL); local->op_ret = -1; local->op_errno = op_errno; goto done; } xattr_req = dict_new(); if (xattr_req == NULL) { local->op_ret = -1; local->op_errno = ENOMEM; goto done; } op_ret = dict_set_uint32(xattr_req, conf->link_xattr_name, 256); if (op_ret < 0) { local->op_ret = -1; local->op_errno = -op_ret; goto done; } /* dst_cached might've changed. This normally happens for two reasons: * 1. rebalance migrated dst * 2. Another parallel rename was done overwriting dst * * Doing a lookup on local->loc2 when dst exists, but is associated * with a different gfid will result in an ESTALE error. So, do a fresh * lookup with a new inode on dst-path and handle change of dst-cached * in the cbk. Also, to identify dst-cached changes we do a lookup on * "this" rather than the subvol. */ loc_copy(&local->loc2_copy, &local->loc2); inode_unref(local->loc2_copy.inode); local->loc2_copy.inode = inode_new(local->loc.inode->table); /* Why not use local->lock.locks[?].loc for lookup post lock phase * --------------------------------------------------------------- * "layout.parent_layout.locks[?].loc" does not have the name and pargfid * populated. * Reason: If we had populated the name and pargfid, server might * resolve to a successful lookup even if there is a file with same name * with a different gfid(unlink & create) as server does name based * resolution on first priority. And this can result in operating on a * different inode entirely. * * Now consider a scenario where source file was renamed by some other * client to a new name just before this lock was granted. So if a * lookup would be done on local->lock[0].layout.parent_layout.locks[?].loc, * server will send success even if the entry was renamed (since server will * do a gfid based resolution). So once a lock is granted, make sure the * file exists with the name that the client requested with. * */ local->call_cnt = 2; for (i = 0; i < 2; i++) { if (i == 0) { lock = local->rename_inodelk_backward_compatible[0]; if (gf_uuid_compare(local->loc.gfid, lock->loc.gfid) == 0) subvol = lock->xl; else { lock = local->rename_inodelk_backward_compatible[1]; subvol = lock->xl; } } else { subvol = this; } STACK_WIND_COOKIE(frame, dht_rename_lookup_cbk, (void *)(long)i, subvol, subvol->fops->lookup, (i == 0) ? &local->loc : &local->loc2_copy, xattr_req); } dict_unref(xattr_req); return 0; done: /* Its fine to call unlock even when no locks are acquired, as we check * for lock->locked before winding a unlock call. */ dht_rename_unlock(frame, this); if (xattr_req) dict_unref(xattr_req); return 0; } int dht_rename_lock(call_frame_t *frame) { dht_local_t *local = NULL; int count = 1, ret = -1; dht_lock_t **lk_array = NULL; local = frame->local; if (local->dst_cached) count++; lk_array = GF_CALLOC(count, sizeof(*lk_array), gf_common_mt_pointer); if (lk_array == NULL) goto err; lk_array[0] = dht_lock_new(frame->this, local->src_cached, &local->loc, F_WRLCK, DHT_FILE_MIGRATE_DOMAIN, NULL, FAIL_ON_ANY_ERROR); if (lk_array[0] == NULL) goto err; if (local->dst_cached) { /* dst might be removed by the time inodelk reaches bricks, * which can result in ESTALE errors. POSIX imposes no * restriction for dst to be present for renames to be * successful. So, we'll ignore ESTALE errors. As far as * synchronization on dst goes, we'll achieve the same by * holding entrylk on parent directory of dst in the namespace * of basename(dst). Also, there might not be quorum in cluster * xlators like EC/disperse on errno, in which case they return * EIO. For eg., in a disperse (4 + 2), 3 might return success * and three might return ESTALE. Disperse, having no Quorum * unwinds inodelk with EIO. So, ignore EIO too. */ lk_array[1] = dht_lock_new(frame->this, local->dst_cached, &local->loc2, F_WRLCK, DHT_FILE_MIGRATE_DOMAIN, NULL, IGNORE_ENOENT_ESTALE_EIO); if (lk_array[1] == NULL) goto err; } local->rename_inodelk_backward_compatible = lk_array; local->rename_inodelk_bc_count = count; /* retaining inodelks for the sake of backward compatibility. Please * make sure to remove this inodelk once all of 3.10, 3.12 and 3.13 * reach EOL. Better way of getting synchronization would be to acquire * entrylks on src and dst parent directories in the namespace of * basenames of src and dst */ ret = dht_blocking_inodelk(frame, lk_array, count, dht_rename_file_protect_namespace); if (ret < 0) { local->rename_inodelk_backward_compatible = NULL; local->rename_inodelk_bc_count = 0; goto err; } return 0; err: if (lk_array != NULL) { int tmp_count = 0, i = 0; for (i = 0; (i < count) && (lk_array[i]); i++, tmp_count++) ; dht_lock_array_free(lk_array, tmp_count); GF_FREE(lk_array); } return -1; } int dht_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { xlator_t *src_cached = NULL; xlator_t *src_hashed = NULL; xlator_t *dst_cached = NULL; xlator_t *dst_hashed = NULL; int op_errno = -1; int ret = -1; dht_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; char newgfid[GF_UUID_BUF_SIZE] = {0}; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(oldloc, err); VALIDATE_OR_GOTO(newloc, err); gf_uuid_unparse(oldloc->inode->gfid, gfid); src_hashed = dht_subvol_get_hashed(this, oldloc); if (!src_hashed) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_RENAME_FAILED, "No hashed subvolume in layout for path=%s," "(gfid = %s)", oldloc->path, gfid); op_errno = EINVAL; goto err; } src_cached = dht_subvol_get_cached(this, oldloc->inode); if (!src_cached) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_RENAME_FAILED, "No cached subvolume for path = %s," "(gfid = %s)", oldloc->path, gfid); op_errno = EINVAL; goto err; } dst_hashed = dht_subvol_get_hashed(this, newloc); if (!dst_hashed) { gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_RENAME_FAILED, "No hashed subvolume in layout for path=%s", newloc->path); op_errno = EINVAL; goto err; } if (newloc->inode) dst_cached = dht_subvol_get_cached(this, newloc->inode); local = dht_local_init(frame, oldloc, NULL, GF_FOP_RENAME); if (!local) { op_errno = ENOMEM; goto err; } /* cached_subvol will be set from dht_local_init, reset it to NULL, as the logic of handling rename is different */ local->cached_subvol = NULL; ret = loc_copy(&local->loc2, newloc); if (ret == -1) { op_errno = ENOMEM; goto err; } local->src_hashed = src_hashed; local->src_cached = src_cached; local->dst_hashed = dst_hashed; local->dst_cached = dst_cached; if (xdata) local->xattr_req = dict_ref(xdata); if (newloc->inode) gf_uuid_unparse(newloc->inode->gfid, newgfid); gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_RENAME_INFO, "renaming %s (%s) (hash=%s/cache=%s) => %s (%s) " "(hash=%s/cache=%s) ", oldloc->path, gfid, src_hashed->name, src_cached->name, newloc->path, newloc->inode ? newgfid : NULL, dst_hashed->name, dst_cached ? dst_cached->name : ""); if (IA_ISDIR(oldloc->inode->ia_type)) { dht_rename_dir(frame, this); } else { local->op_ret = 0; ret = dht_rename_lock(frame); if (ret < 0) { op_errno = ENOMEM; goto err; } } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int dht_pt_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { gf_boolean_t free_xdata = _gf_false; /* Just a pass through */ if (!IA_ISDIR(oldloc->inode->ia_type)) { if (!xdata) { free_xdata = _gf_true; } DHT_CHANGELOG_TRACK_AS_RENAME(xdata, oldloc, newloc); } default_rename(frame, this, oldloc, newloc, xdata); if (free_xdata && xdata) { dict_unref(xdata); xdata = NULL; } return 0; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023137 xustar000000000000000030 mtime=1699284265.621027293 30 atime=1699284274.492054013 30 ctime=1699284301.212134493 glusterfs-11.1/xlators/cluster/dht/src/Makefile.am0000664000175100017510000000276214522202451023425 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = dht.la nufa.la switch.la AM_CFLAGS = -Wall $(GF_CFLAGS) xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster dht_common_source = dht-layout.c dht-helper.c dht-linkfile.c dht-rebalance.c \ dht-selfheal.c dht-rename.c dht-hashfn.c dht-diskusage.c \ dht-common.c dht-inode-write.c dht-inode-read.c dht-shared.c \ dht-lock.c $(top_builddir)/xlators/lib/src/libxlator.c dht_la_SOURCES = $(dht_common_source) dht.c nufa_la_SOURCES = $(dht_common_source) nufa.c switch_la_SOURCES = $(dht_common_source) switch.c dht_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) dht_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la nufa_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) nufa_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la switch_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) switch_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = dht-common.h dht-mem-types.h dht-messages.h \ dht-lock.h $(top_builddir)/xlators/lib/src/libxlator.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/xlators/lib/src \ -DDATADIR=\"$(localstatedir)\" \ -DLIBDIR=\"$(libdir)\" CLEANFILES = uninstall-local: rm -f $(DESTDIR)$(xlatordir)/distribute.so install-data-hook: ln -sf dht.so $(DESTDIR)$(xlatordir)/distribute.so if UNITTEST CLEANFILES += *.gcda *.gcno *_xunit.xml noinst_PROGRAMS = TESTS = endif glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-linkfile.c0000644000000000000000000000013114522202451023620 xustar000000000000000030 mtime=1699284265.626027308 30 atime=1699284265.626027308 29 ctime=1699284301.22113452 glusterfs-11.1/xlators/cluster/dht/src/dht-linkfile.c0000664000175100017510000001654114522202451024107 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "dht-common.h" static int dht_linkfile_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { char is_linkfile = 0; dht_conf_t *conf = NULL; dht_local_t *local = NULL; xlator_t *prev = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; prev = cookie; conf = this->private; if (op_ret) goto out; gf_uuid_unparse(local->loc.gfid, gfid); is_linkfile = check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name); if (!is_linkfile) gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_NOT_LINK_FILE_ERROR, "name=%s", prev->name, "path=%s", local->loc.path, "gfid=%s", gfid, NULL); out: local->linkfile.linkfile_cbk(frame, cookie, this, op_ret, op_errno, inode, stbuf, postparent, postparent, xattr); return 0; } static int dht_linkfile_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *subvol = NULL; dict_t *xattrs = NULL; dht_conf_t *conf = NULL; int ret = -1; local = frame->local; if (!op_ret) local->linked = _gf_true; FRAME_SU_UNDO(frame, dht_local_t); if (op_ret && (op_errno == EEXIST)) { conf = this->private; subvol = cookie; if (!subvol) goto out; xattrs = dict_new(); if (!xattrs) goto out; ret = dict_set_uint32(xattrs, conf->link_xattr_name, 256); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "mame=%s", conf->link_xattr_name, NULL); goto out; } STACK_WIND_COOKIE(frame, dht_linkfile_lookup_cbk, subvol, subvol, subvol->fops->lookup, &local->linkfile.loc, xattrs); if (xattrs) dict_unref(xattrs); return 0; } out: local->linkfile.linkfile_cbk(frame, cookie, this, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); if (xattrs) dict_unref(xattrs); return 0; } int dht_linkfile_create(call_frame_t *frame, fop_mknod_cbk_t linkfile_cbk, xlator_t *this, xlator_t *tovol, xlator_t *fromvol, loc_t *loc) { dht_local_t *local = NULL; dict_t *dict = NULL; int need_unref = 0; int ret = 0; dht_conf_t *conf = this->private; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; local->linkfile.linkfile_cbk = linkfile_cbk; local->linkfile.srcvol = tovol; loc_copy(&local->linkfile.loc, loc); local->linked = _gf_false; dict = local->params; if (!dict) { dict = dict_new(); if (!dict) goto out; need_unref = 1; } if (!gf_uuid_is_null(local->gfid)) { gf_uuid_unparse(local->gfid, gfid); ret = dict_set_gfuuid(dict, "gfid-req", local->gfid, true); if (ret) gf_smsg("dht-linkfile", GF_LOG_INFO, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", loc->path, "gfid=%s", gfid, NULL); } else { gf_uuid_unparse(loc->gfid, gfid); } ret = dict_set_str(dict, GLUSTERFS_INTERNAL_FOP_KEY, "yes"); if (ret) gf_smsg("dht-linkfile", GF_LOG_INFO, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", loc->path, "key=%s", GLUSTERFS_INTERNAL_FOP_KEY, "gfid=%s", gfid, NULL); ret = dict_set_str(dict, conf->link_xattr_name, tovol->name); if (ret < 0) { gf_smsg(frame->this->name, GF_LOG_INFO, 0, DHT_MSG_CREATE_LINK_FAILED, "path=%s", loc->path, "gfid=%s", gfid, NULL); goto out; } local->link_subvol = fromvol; /* Always create as root:root. dht_linkfile_attr_heal fixes the * ownsership */ FRAME_SU_DO(frame, dht_local_t); STACK_WIND_COOKIE(frame, dht_linkfile_create_cbk, fromvol, fromvol, fromvol->fops->mknod, loc, S_IFREG | DHT_LINKFILE_MODE, 0, 0, dict); if (need_unref && dict) dict_unref(dict); return 0; out: local->linkfile.linkfile_cbk(frame, frame->this, frame->this, -1, ENOMEM, loc->inode, NULL, NULL, NULL, NULL); if (need_unref && dict) dict_unref(dict); return 0; } xlator_t * dht_linkfile_subvol(xlator_t *this, inode_t *inode, struct iatt *stbuf, dict_t *xattr) { dht_conf_t *conf = NULL; xlator_t *subvol = NULL; void *volname = NULL; int i = 0, ret = 0; conf = this->private; if (!xattr) goto out; ret = dict_get_ptr(xattr, conf->link_xattr_name, &volname); if ((-1 == ret) || !volname) goto out; for (i = 0; i < conf->subvolume_cnt; i++) { if (strcmp(conf->subvolumes[i]->name, (char *)volname) == 0) { subvol = conf->subvolumes[i]; break; } } out: return subvol; } static int dht_linkfile_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { dht_local_t *local = NULL; loc_t *loc = NULL; local = frame->local; loc = &local->loc; if (op_ret) gf_smsg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_SETATTR_FAILED, "path=%s", (loc->path ? loc->path : "NULL"), "gfid=%s", uuid_utoa(local->gfid), NULL); DHT_STACK_DESTROY(frame); return 0; } int dht_linkfile_attr_heal(call_frame_t *frame, xlator_t *this) { int ret = -1; call_frame_t *copy = NULL; dht_local_t *local = NULL; dht_local_t *copy_local = NULL; xlator_t *subvol = NULL; struct iatt stbuf = { 0, }; dict_t *xattr = NULL; local = frame->local; GF_VALIDATE_OR_GOTO("dht", local, out); GF_VALIDATE_OR_GOTO("dht", local->link_subvol, out); if (local->stbuf.ia_type == IA_INVAL) return 0; DHT_MARK_FOP_INTERNAL(xattr); gf_uuid_copy(local->loc.gfid, local->stbuf.ia_gfid); copy = copy_frame(frame); if (!copy) goto out; copy_local = dht_local_init(copy, &local->loc, NULL, 0); if (!copy_local) goto out; stbuf = local->stbuf; subvol = local->link_subvol; copy->local = copy_local; FRAME_SU_DO(copy, dht_local_t); STACK_WIND(copy, dht_linkfile_setattr_cbk, subvol, subvol->fops->setattr, ©_local->loc, &stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID), xattr); ret = 0; out: if ((ret < 0) && (copy)) DHT_STACK_DESTROY(copy); if (xattr) dict_unref(xattr); return ret; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-selfheal.c0000644000000000000000000000013214522202451023607 xustar000000000000000030 mtime=1699284265.629027317 30 atime=1699284265.628027314 30 ctime=1699284301.224134529 glusterfs-11.1/xlators/cluster/dht/src/dht-selfheal.c0000664000175100017510000023205514522202451024075 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-lock.h" #define DHT_SET_LAYOUT_RANGE(layout, i, srt, chunk, path) \ do { \ layout->list[i].start = srt; \ layout->list[i].stop = srt + chunk - 1; \ layout->list[i].commit_hash = layout->commit_hash; \ \ gf_msg_trace(this->name, 0, \ "gave fix: 0x%x - 0x%x, with commit-hash 0x%x" \ " on %s for %s", \ layout->list[i].start, layout->list[i].stop, \ layout->list[i].commit_hash, \ layout->list[i].xlator->name, path); \ } while (0) #define DHT_RESET_LAYOUT_RANGE(layout) \ do { \ int cnt = 0; \ for (cnt = 0; cnt < layout->cnt; cnt++) { \ layout->list[cnt].start = 0; \ layout->list[cnt].stop = 0; \ } \ } while (0) static int dht_selfheal_layout_lock(call_frame_t *frame, dht_layout_t *layout, gf_boolean_t newdir, dht_selfheal_layout_t healer, dht_need_heal_t should_heal); static uint32_t dht_overlap_calc(dht_layout_t *old, int o, dht_layout_t *new, int n) { if (o >= old->cnt || n >= new->cnt) return 0; if (old->list[o].err > 0 || new->list[n].err > 0) return 0; if (old->list[o].start == old->list[o].stop) { return 0; } if (new->list[n].start == new->list[n].stop) { return 0; } if ((old->list[o].start > new->list[n].stop) || (old->list[o].stop < new->list[n].start)) return 0; return min(old->list[o].stop, new->list[n].stop) - max(old->list[o].start, new->list[n].start) + 1; } static int dht_selfheal_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { DHT_STACK_DESTROY(frame); return 0; } int dht_selfheal_dir_finish(call_frame_t *frame, int ret, int invoke_cbk) { dht_local_t *local = NULL, *lock_local = NULL; call_frame_t *lock_frame = NULL; int lock_count = 0; dht_lock_wrap_t *parent_layout, *lock_local_parent_layout; local = frame->local; /* Unlock entrylk */ dht_unlock_entrylk_wrapper(frame, &local->lock[0].ns.directory_ns); /* Unlock inodelk */ parent_layout = &local->lock[0].ns.parent_layout; lock_count = dht_lock_count(parent_layout); if (lock_count == 0) goto done; lock_frame = copy_frame(frame); if (lock_frame == NULL) { goto done; } lock_local = dht_local_init(lock_frame, &local->loc, NULL, lock_frame->root->op); if (lock_local == NULL) { goto done; } lock_local_parent_layout = &lock_local->lock[0].ns.parent_layout; dht_lock_array_copy(parent_layout, lock_local_parent_layout); dht_lock_array_reset(parent_layout); dht_unlock_inodelk(lock_frame, lock_local_parent_layout, dht_selfheal_unlock_cbk); lock_frame = NULL; done: if (invoke_cbk) local->selfheal.dir_cbk(frame, NULL, ret, local->op_errno, NULL); if (lock_frame != NULL) { DHT_STACK_DESTROY(lock_frame); } return 0; } static int dht_refresh_layout_done(call_frame_t *frame) { dht_layout_t *refreshed = NULL, *heal = NULL; dht_local_t *local = NULL; dht_need_heal_t should_heal = NULL; dht_selfheal_layout_t healer = NULL; local = frame->local; refreshed = local->selfheal.refreshed_layout; heal = local->selfheal.layout; healer = local->selfheal.healer; should_heal = local->selfheal.should_heal; dht_layout_sort(refreshed); if (should_heal(frame, &heal, &refreshed)) { healer(frame, &local->loc, heal); } else { local->selfheal.layout = NULL; local->selfheal.refreshed_layout = NULL; local->selfheal.layout = refreshed; dht_layout_unref(heal); dht_selfheal_dir_finish(frame, 0, 1); } return 0; } int dht_refresh_layout_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { dht_local_t *local = NULL; int this_call_cnt = 0; xlator_t *prev = NULL; dht_layout_t *layout = NULL; char gfid[GF_UUID_BUF_SIZE] = { 0, }; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO("dht", this, err); GF_VALIDATE_OR_GOTO("dht", frame->local, err); GF_VALIDATE_OR_GOTO("dht", this->private, err); local = frame->local; prev = cookie; layout = local->selfheal.refreshed_layout; LOCK(&frame->lock); { op_ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, xattr); dht_iatt_merge(this, &local->stbuf, stbuf); if (op_ret == -1) { gf_uuid_unparse(local->loc.gfid, gfid); local->op_errno = op_errno; gf_smsg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_FILE_LOOKUP_FAILED, "path=%s", local->loc.path, "name=%s", prev->name, "gfid=%s", gfid, NULL); goto unlock; } local->op_ret = 0; } unlock: UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if (local->op_ret == 0) { local->refresh_layout_done(frame); } else { goto err; } } return 0; err: if (local) { local->refresh_layout_unlock(frame, -1, 1); } return 0; } int dht_refresh_layout(call_frame_t *frame) { int call_cnt = 0; int i = 0, ret = -1; dht_conf_t *conf = NULL; dht_local_t *local = NULL; xlator_t *this = NULL; char gfid[GF_UUID_BUF_SIZE] = { 0, }; GF_VALIDATE_OR_GOTO("dht", frame, out); GF_VALIDATE_OR_GOTO("dht", frame->local, out); this = frame->this; conf = this->private; local = frame->local; call_cnt = conf->subvolume_cnt; local->call_cnt = call_cnt; local->op_ret = -1; if (local->selfheal.refreshed_layout) { dht_layout_unref(local->selfheal.refreshed_layout); local->selfheal.refreshed_layout = NULL; } local->selfheal.refreshed_layout = dht_layout_new(this, conf->subvolume_cnt); if (!local->selfheal.refreshed_layout) { gf_uuid_unparse(local->loc.gfid, gfid); gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_MEM_ALLOC_FAILED, "path=%s", local->loc.path, "gfid=%s", gfid, NULL); goto out; } if (local->xattr != NULL) { dict_del(local->xattr, conf->xattr_name); } if (local->xattr_req == NULL) { gf_uuid_unparse(local->loc.gfid, gfid); local->xattr_req = dict_new(); if (local->xattr_req == NULL) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, "path=%s", local->loc.path, "gfid=%s", gfid, NULL); goto out; } } if (dict_get(local->xattr_req, conf->xattr_name) == 0) { ret = dict_set_uint32(local->xattr_req, conf->xattr_name, 4 * 4); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", local->loc.path, "key=%s", conf->xattr_name, NULL); } for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, dht_refresh_layout_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, &local->loc, local->xattr_req); } return 0; out: if (local) { local->refresh_layout_unlock(frame, -1, 1); } return 0; } static int32_t dht_selfheal_layout_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (!local) { goto err; } if (op_ret < 0) { local->op_errno = op_errno; goto err; } local->refresh_layout_unlock = dht_selfheal_dir_finish; local->refresh_layout_done = dht_refresh_layout_done; dht_refresh_layout(frame); return 0; err: dht_selfheal_dir_finish(frame, -1, 1); return 0; } static gf_boolean_t dht_should_heal_layout(call_frame_t *frame, dht_layout_t **heal, dht_layout_t **ondisk) { gf_boolean_t fixit = _gf_true; dht_local_t *local = NULL; int heal_missing_dirs = 0; local = frame->local; if ((heal == NULL) || (*heal == NULL) || (ondisk == NULL) || (*ondisk == NULL)) goto out; dht_layout_anomalies( frame->this, &local->loc, *ondisk, &local->selfheal.hole_cnt, &local->selfheal.overlaps_cnt, &local->selfheal.missing_cnt, &local->selfheal.down, &local->selfheal.misc, NULL); /* Directories might've been created as part of this self-heal. We've to * sync non-layout xattrs and set range 0-0 on new directories */ heal_missing_dirs = local->selfheal.force_mkdir ? local->selfheal.force_mkdir : dht_layout_missing_dirs(*heal); if ((local->selfheal.hole_cnt == 0) && (local->selfheal.overlaps_cnt == 0) && heal_missing_dirs) { dht_layout_t *tmp = NULL; /* Just added a brick and need to set 0-0 range on this brick. * But ondisk layout is well-formed. So, swap layouts "heal" and * "ondisk". Now "ondisk" layout will be used for healing * xattrs. If there are any non-participating subvols in * "ondisk" layout, dht_selfheal_dir_xattr_persubvol will set * 0-0 and non-layout xattrs. This way we won't end up in * "corrupting" already set and well-formed "ondisk" layout. */ tmp = *heal; *heal = *ondisk; *ondisk = tmp; /* Current selfheal code, heals non-layout xattrs only after * an add-brick. In fact non-layout xattrs are considered as * secondary citizens which are healed only if layout xattrs * need to be healed. This is wrong, since for eg., quota can be * set when layout is well-formed, but a node is down. Also, * just for healing non-layout xattrs, we don't need locking. * This issue is _NOT FIXED_ by this patch. */ } fixit = (local->selfheal.hole_cnt || local->selfheal.overlaps_cnt || heal_missing_dirs); out: return fixit; } int dht_layout_span(dht_layout_t *layout) { int i = 0, count = 0; for (i = 0; i < layout->cnt; i++) { if (layout->list[i].err) continue; if (layout->list[i].start != layout->list[i].stop) count++; } return count; } static int dht_decommissioned_bricks_in_layout(xlator_t *this, dht_layout_t *layout) { dht_conf_t *conf = NULL; int count = 0, i = 0, j = 0; if ((this == NULL) || (layout == NULL)) goto out; conf = this->private; for (i = 0; i < layout->cnt; i++) { for (j = 0; j < conf->subvolume_cnt; j++) { if (conf->decommissioned_bricks[j] && conf->decommissioned_bricks[j] == layout->list[i].xlator) { count++; } } } out: return count; } dht_distribution_type_t dht_distribution_type(xlator_t *this, dht_layout_t *layout) { dht_distribution_type_t type = GF_DHT_EQUAL_DISTRIBUTION; int i = 0; uint32_t start_range = 0, range = 0, diff = 0; if ((this == NULL) || (layout == NULL) || (layout->cnt < 1)) { goto out; } for (i = 0; i < layout->cnt; i++) { if (start_range == 0) { start_range = layout->list[i].stop - layout->list[i].start; continue; } range = layout->list[i].stop - layout->list[i].start; diff = (range >= start_range) ? range - start_range : start_range - range; if ((range != 0) && (diff > layout->cnt)) { type = GF_DHT_WEIGHTED_DISTRIBUTION; break; } } out: return type; } gf_boolean_t dht_should_fix_layout(call_frame_t *frame, dht_layout_t **inmem, dht_layout_t **ondisk) { gf_boolean_t fixit = _gf_true; dht_local_t *local = NULL; int layout_span = 0; int decommissioned_bricks = 0; dht_conf_t *conf = NULL; dht_distribution_type_t inmem_dist_type = 0; dht_distribution_type_t ondisk_dist_type = 0; conf = frame->this->private; local = frame->local; if ((inmem == NULL) || (*inmem == NULL) || (ondisk == NULL) || (*ondisk == NULL)) goto out; dht_layout_anomalies(frame->this, &local->loc, *ondisk, &local->selfheal.hole_cnt, &local->selfheal.overlaps_cnt, NULL, &local->selfheal.down, &local->selfheal.misc, NULL); if (local->selfheal.down || local->selfheal.misc) { fixit = _gf_false; goto out; } if (local->selfheal.hole_cnt || local->selfheal.overlaps_cnt) goto out; /* If commit hashes are being updated, let it through */ if ((*inmem)->commit_hash != (*ondisk)->commit_hash) goto out; layout_span = dht_layout_span(*ondisk); decommissioned_bricks = dht_decommissioned_bricks_in_layout(frame->this, *ondisk); inmem_dist_type = dht_distribution_type(frame->this, *inmem); ondisk_dist_type = dht_distribution_type(frame->this, *ondisk); if ((decommissioned_bricks == 0) && (layout_span == (conf->subvolume_cnt - conf->decommission_subvols_cnt)) && (inmem_dist_type == ondisk_dist_type)) fixit = _gf_false; out: return fixit; } static int dht_selfheal_layout_lock(call_frame_t *frame, dht_layout_t *layout, gf_boolean_t newdir, dht_selfheal_layout_t healer, dht_need_heal_t should_heal) { dht_local_t *local = NULL; int count = 1, ret = -1, i = 0; dht_lock_t **lk_array = NULL; dht_conf_t *conf = NULL; dht_layout_t *tmp = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; dht_lock_wrap_t *my_layout; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO(frame->this->name, frame->local, err); local = frame->local; conf = frame->this->private; local->selfheal.healer = healer; local->selfheal.should_heal = should_heal; tmp = local->selfheal.layout; local->selfheal.layout = dht_layout_ref(layout); dht_layout_unref(tmp); if (!newdir) { count = conf->subvolume_cnt; lk_array = GF_MALLOC(count * sizeof(*lk_array), gf_common_mt_char); if (lk_array == NULL) { gf_uuid_unparse(local->stbuf.ia_gfid, gfid); gf_smsg("dht", GF_LOG_ERROR, ENOMEM, DHT_MSG_MEM_ALLOC_FAILED, "lk_array-gfid=%s", gfid, "path=%s", local->loc.path, NULL); goto err; } for (i = 0; i < count; i++) { lk_array[i] = dht_lock_new( frame->this, conf->subvolumes[i], &local->loc, F_WRLCK, DHT_LAYOUT_HEAL_DOMAIN, NULL, FAIL_ON_ANY_ERROR); if (lk_array[i] == NULL) { gf_uuid_unparse(local->stbuf.ia_gfid, gfid); gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_MEM_ALLOC_FAILED, "lk_array-gfid=%s", gfid, "path=%s", local->loc.path, NULL); goto err; } } } else { count = 1; lk_array = GF_CALLOC(count, sizeof(*lk_array), gf_common_mt_char); if (lk_array == NULL) { gf_uuid_unparse(local->stbuf.ia_gfid, gfid); gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_MEM_ALLOC_FAILED, "lk_array-gfid=%s", gfid, "path=%s", local->loc.path, NULL); goto err; } lk_array[0] = dht_lock_new(frame->this, local->hashed_subvol, &local->loc, F_WRLCK, DHT_LAYOUT_HEAL_DOMAIN, NULL, FAIL_ON_ANY_ERROR); if (lk_array[0] == NULL) { gf_uuid_unparse(local->stbuf.ia_gfid, gfid); gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_MEM_ALLOC_FAILED, "lk_array-gfid=%s", gfid, "path=%s", local->loc.path, NULL); goto err; } } my_layout = &local->lock[0].layout.my_layout; my_layout->locks = lk_array; my_layout->lk_count = count; ret = dht_blocking_inodelk(frame, lk_array, count, dht_selfheal_layout_lock_cbk); if (ret < 0) { dht_lock_array_reset(my_layout); goto err; } return 0; err: if (lk_array != NULL) { dht_lock_array_free(lk_array, count); GF_FREE(lk_array); } return -1; } static int dht_selfheal_dir_xattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; xlator_t *subvol = NULL; struct iatt *stbuf = NULL; int i = 0; int ret = 0; dht_layout_t *layout = NULL; int err = 0; int this_call_cnt = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; layout = local->selfheal.layout; subvol = cookie; if (op_ret == 0) { err = 0; } else { gf_uuid_unparse(local->loc.gfid, gfid); gf_smsg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_DIR_SELFHEAL_XATTR_FAILED, "name=%s", subvol->name, "path=%s", local->loc.path, "gfid=%s", gfid, NULL); err = op_errno; } ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf); if (ret < 0) { gf_uuid_unparse(local->loc.gfid, gfid); gf_msg_debug(this->name, 0, "key = %s not present in dict" ", path:%s gfid:%s", DHT_IATT_IN_XDATA_KEY, local->loc.path, gfid); } for (i = 0; i < layout->cnt; i++) { if (layout->list[i].xlator == subvol) { layout->list[i].err = err; break; } } LOCK(&frame->lock); { dht_iatt_merge(this, &local->stbuf, stbuf); } UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { dht_selfheal_dir_finish(frame, 0, 1); } return 0; } /* Code is required to set user xattr to local->xattr */ int dht_set_user_xattr(dict_t *dict, char *k, data_t *v, void *data) { dict_t *set_xattr = data; int ret = -1; ret = dict_set(set_xattr, k, v); return ret; } static int dht_selfheal_dir_xattr_persubvol(call_frame_t *frame, loc_t *loc, dht_layout_t *layout, int i, xlator_t *req_subvol) { xlator_t *subvol = NULL; dict_t *xattr = NULL; dict_t *xdata = NULL; int ret = 0; xlator_t *this = NULL; int32_t *disk_layout = NULL; dht_local_t *local = NULL; dht_conf_t *conf = NULL; data_t *data = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; if (req_subvol) subvol = req_subvol; else subvol = layout->list[i].xlator; this = frame->this; GF_VALIDATE_OR_GOTO("", this, err); GF_VALIDATE_OR_GOTO(this->name, layout, err); GF_VALIDATE_OR_GOTO(this->name, local, err); GF_VALIDATE_OR_GOTO(this->name, subvol, err); VALIDATE_OR_GOTO(this->private, err); conf = this->private; xattr = dict_new(); if (!xattr) { goto err; } xdata = dict_new(); if (!xdata) goto err; ret = dict_set_str(xdata, GLUSTERFS_INTERNAL_FOP_KEY, "yes"); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", loc->path, "key=%s", GLUSTERFS_INTERNAL_FOP_KEY, "gfid=%s", gfid, NULL); goto err; } ret = dict_set_int8(xdata, DHT_IATT_IN_XDATA_KEY, 1); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", loc->path, "key=%s", DHT_IATT_IN_XDATA_KEY, "gfid=%s", gfid, NULL); goto err; } gf_uuid_unparse(loc->inode->gfid, gfid); ret = dht_disk_layout_extract(this, layout, i, &disk_layout); if (ret == -1) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DIR_SELFHEAL_XATTR_FAILED, "extract-disk-layout-failed, path=%s", loc->path, "subvol=%s", subvol->name, "gfid=%s", gfid, NULL); goto err; } ret = dict_set_bin(xattr, conf->xattr_name, disk_layout, 4 * 4); if (ret == -1) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DIR_SELFHEAL_XATTR_FAILED, "path=%s", loc->path, "subvol=%s", subvol->name, "set-xattr-dictionary-failed" "gfid=%s", gfid, NULL); goto err; } disk_layout = NULL; gf_msg_trace(this->name, 0, "setting hash range 0x%x - 0x%x (type %d) on subvolume %s" " for %s", layout->list[i].start, layout->list[i].stop, layout->type, subvol->name, loc->path); if (local->xattr) { data = dict_get(local->xattr, QUOTA_LIMIT_KEY); if (data) { ret = dict_add(xattr, QUOTA_LIMIT_KEY, data); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", loc->path, "key=%s", QUOTA_LIMIT_KEY, NULL); } } data = dict_get(local->xattr, QUOTA_LIMIT_OBJECTS_KEY); if (data) { ret = dict_add(xattr, QUOTA_LIMIT_OBJECTS_KEY, data); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", loc->path, "key=%s", QUOTA_LIMIT_OBJECTS_KEY, NULL); } } } if (!gf_uuid_is_null(local->gfid)) gf_uuid_copy(loc->gfid, local->gfid); STACK_WIND_COOKIE(frame, dht_selfheal_dir_xattr_cbk, (void *)subvol, subvol, subvol->fops->setxattr, loc, xattr, 0, xdata); dict_unref(xattr); dict_unref(xdata); return 0; err: if (xattr) dict_unref(xattr); if (xdata) dict_unref(xdata); GF_FREE(disk_layout); dht_selfheal_dir_xattr_cbk(frame, (void *)subvol, frame->this, -1, ENOMEM, NULL); return 0; } static int dht_fix_dir_xattr(call_frame_t *frame, loc_t *loc, dht_layout_t *layout) { dht_local_t *local = NULL; int i = 0; int count = 0; xlator_t *this = NULL; dht_conf_t *conf = NULL; dht_layout_t *dummy = NULL; local = frame->local; this = frame->this; conf = this->private; gf_msg_debug(this->name, 0, "%s: Writing the new range for all subvolumes", loc->path); local->call_cnt = count = conf->subvolume_cnt; if (gf_log_get_loglevel() >= GF_LOG_DEBUG) dht_log_new_layout_for_dir_selfheal(this, loc, layout); for (i = 0; i < layout->cnt; i++) { dht_selfheal_dir_xattr_persubvol(frame, loc, layout, i, NULL); if (--count == 0) goto out; } /* if we are here, subvolcount > layout_count. subvols-per-directory * option might be set here. We need to clear out layout from the * non-participating subvolumes, else it will result in overlaps */ dummy = dht_layout_new(this, 1); if (!dummy) goto out; dummy->commit_hash = layout->commit_hash; for (i = 0; i < conf->subvolume_cnt; i++) { if (_gf_false == dht_is_subvol_in_layout(layout, conf->subvolumes[i])) { dht_selfheal_dir_xattr_persubvol(frame, loc, dummy, 0, conf->subvolumes[i]); if (--count == 0) break; } } dht_layout_unref(dummy); out: return 0; } static int dht_selfheal_dir_xattr(call_frame_t *frame, loc_t *loc, dht_layout_t *layout) { dht_local_t *local = NULL; int missing_xattr = 0; int i = 0; xlator_t *this = NULL; dht_conf_t *conf = NULL; dht_layout_t *dummy = NULL; char gfid[GF_UUID_BUF_SIZE] = { 0, }; local = frame->local; this = frame->this; conf = this->private; for (i = 0; i < layout->cnt; i++) { if (layout->list[i].err != -1 || !layout->list[i].stop) { /* err != -1 would mean xattr present on the directory * or the directory is non existent. * !layout->list[i].stop would mean layout absent */ continue; } missing_xattr++; } /* Also account for subvolumes with no-layout. Used for zero'ing out * the layouts and for setting quota key's if present */ for (i = 0; i < conf->subvolume_cnt; i++) { if (_gf_false == dht_is_subvol_in_layout(layout, conf->subvolumes[i])) { missing_xattr++; } } gf_msg_trace(this->name, 0, "%d subvolumes missing xattr for %s", missing_xattr, loc->path); if (missing_xattr == 0) { dht_selfheal_dir_finish(frame, 0, 1); return 0; } local->call_cnt = missing_xattr; if (gf_log_get_loglevel() >= GF_LOG_DEBUG) dht_log_new_layout_for_dir_selfheal(this, loc, layout); for (i = 0; i < layout->cnt; i++) { if (layout->list[i].err != -1 || !layout->list[i].stop) continue; dht_selfheal_dir_xattr_persubvol(frame, loc, layout, i, NULL); if (--missing_xattr == 0) break; } dummy = dht_layout_new(this, 1); if (!dummy) { gf_uuid_unparse(loc->gfid, gfid); gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DUMMY_ALLOC_FAILED, "path=%s", loc->path, "gfid=%s", gfid, NULL); goto out; } for (i = 0; i < conf->subvolume_cnt && missing_xattr; i++) { if (_gf_false == dht_is_subvol_in_layout(layout, conf->subvolumes[i])) { dht_selfheal_dir_xattr_persubvol(frame, loc, dummy, 0, conf->subvolumes[i]); missing_xattr--; } } dht_layout_unref(dummy); out: return 0; } int dht_selfheal_dir_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { dht_local_t *local = NULL; dht_layout_t *layout = NULL; int this_call_cnt = 0, ret = -1; local = frame->local; layout = local->selfheal.layout; this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if (!local->heal_layout) { gf_msg_trace(this->name, 0, "Skip heal layout for %s gfid = %s ", local->loc.path, uuid_utoa(local->gfid)); dht_selfheal_dir_finish(frame, 0, 1); return 0; } ret = dht_selfheal_layout_lock(frame, layout, _gf_false, dht_selfheal_dir_xattr, dht_should_heal_layout); if (ret < 0) { dht_selfheal_dir_finish(frame, -1, 1); } } return 0; } int dht_selfheal_dir_setattr(call_frame_t *frame, loc_t *loc, struct iatt *stbuf, int32_t valid, dht_layout_t *layout) { int missing_attr = 0; int i = 0, ret = -1; dht_local_t *local = NULL; dht_conf_t *conf = NULL; xlator_t *this = NULL; int cnt = 0; local = frame->local; this = frame->this; conf = this->private; /* We need to heal the attrs if: * 1. Any directories were missing - the newly created dirs will need * to have the correct attrs set * 2. An existing dir does not have the correct permissions -they may * have been changed when a brick was down. */ for (i = 0; i < layout->cnt; i++) { if (layout->list[i].err == -1) missing_attr++; } if ((missing_attr == 0) && (local->need_attrheal == 0)) { if (!local->heal_layout) { gf_msg_trace(this->name, 0, "Skip heal layout for %s gfid = %s ", loc->path, uuid_utoa(loc->gfid)); dht_selfheal_dir_finish(frame, 0, 1); return 0; } ret = dht_selfheal_layout_lock(frame, layout, _gf_false, dht_selfheal_dir_xattr, dht_should_heal_layout); if (ret < 0) { dht_selfheal_dir_finish(frame, -1, 1); } return 0; } cnt = local->call_cnt = conf->subvolume_cnt; for (i = 0; i < cnt; i++) { STACK_WIND(frame, dht_selfheal_dir_setattr_cbk, layout->list[i].xlator, layout->list[i].xlator->fops->setattr, loc, stbuf, valid, NULL); } return 0; } static int dht_selfheal_dir_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; dht_layout_t *layout = NULL; xlator_t *prev = NULL; xlator_t *subvol = NULL; int i = 0, ret = -1; int this_call_cnt = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; layout = local->selfheal.layout; prev = cookie; subvol = prev; if ((op_ret == 0) || ((op_ret == -1) && (op_errno == EEXIST))) { for (i = 0; i < layout->cnt; i++) { if (layout->list[i].xlator == subvol) { layout->list[i].err = -1; break; } } } if (op_ret) { gf_uuid_unparse(local->loc.gfid, gfid); gf_smsg(this->name, ((op_errno == EEXIST) ? GF_LOG_DEBUG : GF_LOG_WARNING), op_errno, DHT_MSG_DIR_SELFHEAL_FAILED, "path=%s", local->loc.path, "gfid=%s", gfid, NULL); goto out; } dht_iatt_merge(this, &local->preparent, preparent); dht_iatt_merge(this, &local->postparent, postparent); ret = 0; out: this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { dht_selfheal_dir_finish(frame, ret, 0); dht_selfheal_dir_setattr(frame, &local->loc, &local->stbuf, 0xffffff, layout); } return 0; } static int dht_selfheal_dir_mkdir_lookup_done(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; int i = 0; dict_t *dict = NULL; dht_layout_t *layout = NULL; loc_t *loc = NULL; int cnt = 0; int ret = -1; VALIDATE_OR_GOTO(this->private, err); local = frame->local; layout = local->layout; loc = &local->loc; if (!gf_uuid_is_null(local->gfid)) { dict = dict_new(); if (!dict) return -1; ret = dict_set_gfuuid(dict, "gfid-req", local->gfid, true); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", loc->path, "key=gfid-req", NULL); } else if (local->params) { /* Send the dictionary from higher layers directly */ dict = dict_ref(local->params); } /* Code to update all extended attributed from local->xattr to dict */ dht_dir_set_heal_xattr(this, local, dict, local->xattr, NULL, NULL); if (!dict) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_IS_NULL, NULL); dict = dict_new(); if (!dict) return -1; } ret = dict_set_flag(dict, GF_INTERNAL_CTX_KEY, GF_DHT_HEAL_DIR); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "key=%s", GF_INTERNAL_CTX_KEY, "path=%s", loc->path, NULL); /* We can still continue. As heal can still happen * unless quota limits have reached for the dir. */ } cnt = layout->cnt; for (i = 0; i < cnt; i++) { if (layout->list[i].err == ESTALE || layout->list[i].err == ENOENT || local->selfheal.force_mkdir) { gf_msg_debug(this->name, 0, "Creating directory %s on subvol %s", loc->path, layout->list[i].xlator->name); STACK_WIND_COOKIE( frame, dht_selfheal_dir_mkdir_cbk, layout->list[i].xlator, layout->list[i].xlator, layout->list[i].xlator->fops->mkdir, loc, st_mode_from_ia(local->stbuf.ia_prot, local->stbuf.ia_type), 0, dict); } } if (dict) dict_unref(dict); return 0; err: dht_selfheal_dir_finish(frame, -1, 1); return 0; } static int dht_selfheal_dir_mkdir_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { dht_local_t *local = NULL; int i = 0; int this_call_cnt = 0; int missing_dirs = 0; dht_layout_t *layout = NULL; xlator_t *prev = 0; loc_t *loc = NULL; char gfid_local[GF_UUID_BUF_SIZE] = {0}; int index = -1; VALIDATE_OR_GOTO(this->private, err); local = frame->local; layout = local->layout; loc = &local->loc; prev = cookie; if (!gf_uuid_is_null(local->gfid)) gf_uuid_unparse(local->gfid, gfid_local); LOCK(&frame->lock); { index = dht_layout_index_for_subvol(layout, prev); if ((op_ret < 0) && (op_errno == ENOENT || op_errno == ESTALE)) { local->selfheal.hole_cnt = !local->selfheal.hole_cnt ? 1 : local->selfheal.hole_cnt + 1; /* the status might have changed. Update the layout with the * new status */ if (index >= 0) { layout->list[index].err = op_errno; } } if (!op_ret) { dht_iatt_merge(this, &local->stbuf, stbuf); if (prev == local->mds_subvol) { dict_unref(local->xattr); local->xattr = dict_ref(xattr); } /* the status might have changed. Update the layout with the * new status */ if (index >= 0) { layout->list[index].err = -1; } } } UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { if (local->selfheal.hole_cnt == layout->cnt) { gf_msg_debug(this->name, op_errno, "Lookup failed, an rmdir could have " "deleted this entry %s", loc->name); local->op_errno = op_errno; goto err; } else { for (i = 0; i < layout->cnt; i++) { if (layout->list[i].err == ENOENT || layout->list[i].err == ESTALE || local->selfheal.force_mkdir) missing_dirs++; } if (missing_dirs == 0) { dht_selfheal_dir_finish(frame, 0, 0); dht_selfheal_dir_setattr(frame, loc, &local->stbuf, 0xffffffff, layout); return 0; } local->call_cnt = missing_dirs; dht_selfheal_dir_mkdir_lookup_done(frame, this); } } return 0; err: dht_selfheal_dir_finish(frame, -1, 1); return 0; } static int dht_selfheal_dir_mkdir_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; int i = 0; int ret = -1; xlator_t *mds_subvol = NULL; VALIDATE_OR_GOTO(this->private, err); conf = this->private; local = frame->local; mds_subvol = local->mds_subvol; local->call_cnt = conf->subvolume_cnt; if (op_ret < 0) { if (op_errno == EINVAL) { local->call_cnt = 1; dht_selfheal_dir_mkdir_lookup_done(frame, this); return 0; } gf_smsg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_ENTRYLK_ERROR, "path=%s", local->loc.path, NULL); local->op_errno = op_errno; goto err; } /* After getting locks, perform lookup again to ensure that the directory was not deleted by a racing rmdir */ if (!local->xattr_req) local->xattr_req = dict_new(); ret = dict_set_int32(local->xattr_req, "list-xattr", 1); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", local->loc.path, NULL); for (i = 0; i < conf->subvolume_cnt; i++) { if (mds_subvol && conf->subvolumes[i] == mds_subvol) { STACK_WIND_COOKIE(frame, dht_selfheal_dir_mkdir_lookup_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, &local->loc, local->xattr_req); } else { STACK_WIND_COOKIE(frame, dht_selfheal_dir_mkdir_lookup_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, &local->loc, NULL); } } return 0; err: dht_selfheal_dir_finish(frame, -1, 1); return 0; } static int dht_selfheal_dir_mkdir(call_frame_t *frame, loc_t *loc, dht_layout_t *layout, int force) { int missing_dirs = 0; int i = 0; int op_errno = 0; int ret = -1; dht_local_t *local = NULL; xlator_t *this = NULL; dht_conf_t *conf = NULL; local = frame->local; this = frame->this; conf = this->private; local->selfheal.force_mkdir = force; local->selfheal.hole_cnt = 0; for (i = 0; i < layout->cnt; i++) { if (layout->list[i].err == ENOENT || force) missing_dirs++; } if (missing_dirs == 0) { /* We don't need to create any directories. Proceed to heal the * attrs and xattrs */ if (!__is_root_gfid(local->stbuf.ia_gfid)) { if (local->need_xattr_heal) { local->need_xattr_heal = 0; ret = dht_dir_xattr_heal(this, local, &op_errno); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_DIR_XATTR_HEAL_FAILED, "path=%s", local->loc.path, "gfid=%s", uuid_utoa(local->gfid), NULL); } } else { if (!gf_uuid_is_null(local->gfid)) gf_uuid_copy(loc->gfid, local->gfid); ret = dht_common_mark_mdsxattr(frame, NULL, 0); if (!ret) return 0; gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_SET_XATTR_FAILED, "path=%s", local->loc.path, "gfid=%s", uuid_utoa(local->gfid), NULL); } } dht_selfheal_dir_setattr(frame, loc, &local->stbuf, 0xffffffff, layout); return 0; } /* MDS xattr is populated only while DHT is having more than one subvol.In case of graph switch while adding more dht subvols need to consider hash subvol as a MDS to avoid MDS check failure at the time of running fop on directory */ if (!dict_get(local->xattr, conf->mds_xattr_key) && (conf->subvolume_cnt > 1)) { if (local->hashed_subvol == NULL) { local->hashed_subvol = dht_subvol_get_hashed(this, loc); if (local->hashed_subvol == NULL) { local->op_errno = EINVAL; gf_smsg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "gfid=%s", loc->pargfid, "name=%s", loc->name, "path=%s", loc->path, NULL); goto err; } } ret = dht_inode_ctx_mdsvol_set(local->inode, this, local->hashed_subvol); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, "Failed to set hashed subvol for %s on inode vol is %s", local->loc.path, local->hashed_subvol ? local->hashed_subvol->name : "NULL"); goto err; } } if (local->hashed_subvol == NULL) { local->hashed_subvol = dht_subvol_get_hashed(this, loc); if (local->hashed_subvol == NULL) { local->op_errno = EINVAL; gf_smsg(this->name, GF_LOG_WARNING, local->op_errno, DHT_MSG_HASHED_SUBVOL_GET_FAILED, "gfid=%s", loc->pargfid, "name=%s", loc->name, "path=%s", loc->path, NULL); goto err; } } local->current = &local->lock[0]; ret = dht_protect_namespace(frame, loc, local->hashed_subvol, &local->current->ns, dht_selfheal_dir_mkdir_lock_cbk); if (ret < 0) goto err; return 0; err: return -1; } static int dht_selfheal_layout_alloc_start(xlator_t *this, loc_t *loc, dht_layout_t *layout) { int start = 0; uint32_t hashval = 0; int ret = 0; const char *str = NULL; dht_conf_t *conf = NULL; char buf[UUID_CANONICAL_FORM_LEN + 1] = { 0, }; conf = this->private; if (conf->randomize_by_gfid) { str = uuid_utoa_r(loc->gfid, buf); } else { str = loc->path; } ret = dht_hash_compute(this, layout->type, str, &hashval); if (ret == 0) { start = (hashval % layout->cnt); } return start; } static int dht_get_layout_count(xlator_t *this, dht_layout_t *layout, int new_layout) { int i = 0; int j = 0; int err = 0; int count = 0; dht_conf_t *conf = NULL; /* Gets in use only for replace-brick, remove-brick */ conf = this->private; for (i = 0; i < layout->cnt; i++) { for (j = 0; j < conf->subvolume_cnt; j++) { if (conf->decommissioned_bricks[j] && conf->decommissioned_bricks[j] == layout->list[i].xlator) { layout->list[i].err = EINVAL; break; } } } for (i = 0; i < layout->cnt; i++) { err = layout->list[i].err; if (err == -1 || err == 0 || err == ENOENT) { /* Take this with a pinch of salt. The behaviour seems * to be slightly different when this function is * invoked from mkdir codepath. For eg., err == 0 in * mkdir codepath means directory created but xattr * is not set yet. */ /* Setting list[i].err = -1 is an indication for dht_selfheal_layout_new_directory() to assign a range. We set it to -1 based on any one of the three criteria: - err == -1 already, which means directory existed but layout was not set on it. - err == 0, which means directory exists and has an old layout piece which will be overwritten now. - err == ENOENT, which means directory does not exist (possibly racing with mkdir or finishing half done mkdir). The missing directory will be attempted to be recreated. */ count++; if (!err) layout->list[i].err = -1; } } /* no subvolume has enough space, but can't stop directory creation */ if (!count || !new_layout) { for (i = 0; i < layout->cnt; i++) { err = layout->list[i].err; if (err == ENOSPC) { layout->list[i].err = -1; count++; } } } /* if layout->spread_cnt is set, check if it is <= available * subvolumes (down brick and decommissioned bricks are considered * un-available). Else return count (available up bricks) */ count = ((layout->spread_cnt && (layout->spread_cnt <= count)) ? layout->spread_cnt : ((count) ? count : 1)); return count; } void dht_selfheal_layout_new_directory(call_frame_t *frame, loc_t *loc, dht_layout_t *new_layout); void dht_layout_range_swap(dht_layout_t *layout, int i, int j); /* * It's a bit icky using local variables in a macro, but it makes the rest * of the code a lot clearer. */ #define OV_ENTRY(x, y) table[x * new->cnt + y] static void dht_selfheal_layout_maximize_overlap(call_frame_t *frame, loc_t *loc, dht_layout_t *new, dht_layout_t *old) { int i = 0; int j = 0; uint32_t curr_overlap = 0; uint32_t max_overlap = 0; int max_overlap_idx = -1; uint32_t overlap = 0; uint32_t *table = NULL; dht_layout_sort_volname(old); /* Now both old_layout->list[] and new_layout->list[] are match the same xlators/subvolumes. i.e, old_layout->[i] and new_layout->[i] are referring to the same subvolumes */ /* Build a table of overlaps between new[i] and old[j]. */ table = alloca(sizeof(overlap) * old->cnt * new->cnt); if (!table) { return; } memset(table, 0, sizeof(overlap) * old->cnt * new->cnt); for (i = 0; i < new->cnt; ++i) { for (j = 0; j < old->cnt; ++j) { OV_ENTRY(i, j) = dht_overlap_calc(old, j, new, i); } } for (i = 0; i < new->cnt; i++) { if (new->list[i].err > 0) { /* Subvol might be marked for decommission with EINVAL, or some other serious error marked with positive errno. */ continue; } max_overlap = 0; max_overlap_idx = i; for (j = (i + 1); j < new->cnt; ++j) { if (new->list[j].err > 0) { /* Subvol might be marked for decommission with EINVAL, or some other serious error marked with positive errno. */ continue; } /* Calculate the overlap now. */ curr_overlap = OV_ENTRY(i, i) + OV_ENTRY(j, j); /* Calculate the overlap after the proposed swap. */ overlap = OV_ENTRY(i, j) + OV_ENTRY(j, i); /* Are we better than status quo? */ if (overlap > curr_overlap) { overlap -= curr_overlap; /* Are we better than the previous choice? */ if (overlap > max_overlap) { max_overlap = overlap; max_overlap_idx = j; } } } if (max_overlap_idx != i) { dht_layout_range_swap(new, i, max_overlap_idx); /* Need to swap the table values too. */ for (j = 0; j < old->cnt; ++j) { overlap = OV_ENTRY(i, j); OV_ENTRY(i, j) = OV_ENTRY(max_overlap_idx, j); OV_ENTRY(max_overlap_idx, j) = overlap; } } } } static dht_layout_t * dht_fix_layout_of_directory(call_frame_t *frame, loc_t *loc, dht_layout_t *layout) { int i = 0; xlator_t *this = NULL; dht_layout_t *new_layout = NULL; dht_conf_t *priv = NULL; dht_local_t *local = NULL; uint32_t subvol_down = 0; gf_boolean_t maximize_overlap = _gf_true; char gfid[GF_UUID_BUF_SIZE] = {0}; this = frame->this; priv = this->private; local = frame->local; if (layout->type == DHT_HASH_TYPE_DM_USER) { gf_msg_debug(THIS->name, 0, "leaving %s alone", loc->path); goto done; } new_layout = dht_layout_new(this, priv->subvolume_cnt); if (!new_layout) { gf_uuid_unparse(loc->gfid, gfid); gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_MEM_ALLOC_FAILED, "new_layout, path=%s", loc->path, "gfid=%s", gfid, NULL); goto done; } /* If a subvolume is down, do not re-write the layout. */ dht_layout_anomalies(this, loc, layout, NULL, NULL, NULL, &subvol_down, NULL, NULL); if (subvol_down) { gf_uuid_unparse(loc->gfid, gfid); gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_FIX_FAILED, "subvol-down=%u", subvol_down, "Skipping-fix-layout", "path=%s", loc->path, "gfid=%s", gfid, NULL); GF_FREE(new_layout); return NULL; } for (i = 0; i < new_layout->cnt; i++) { if (layout->list[i].err != ENOSPC) new_layout->list[i].err = layout->list[i].err; else new_layout->list[i].err = -1; new_layout->list[i].xlator = layout->list[i].xlator; } new_layout->commit_hash = layout->commit_hash; if (priv->du_stats) { for (i = 0; i < priv->subvolume_cnt; ++i) { gf_smsg(this->name, GF_LOG_DEBUG, 0, DHT_MSG_SUBVOL_INFO, "index=%d", i, "name=%s", priv->subvolumes[i]->name, "chunks=%u", priv->du_stats[i].chunks, "path=%s", loc->path, NULL); /* Maximize overlap if the bricks are all the same * size. * This is probably not going to be very common on * live setups but will benefit our regression tests */ if (i && (priv->du_stats[i].chunks != priv->du_stats[0].chunks)) { maximize_overlap = _gf_false; } } } else { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_NO_DISK_USAGE_STATUS, NULL); } /* First give it a layout as though it is a new directory. This ensures rotation to kick in */ dht_layout_sort_volname(new_layout); dht_selfheal_layout_new_directory(frame, loc, new_layout); /* Maximize overlap if weighted-rebalance is disabled */ if (!priv->do_weighting) maximize_overlap = _gf_true; /* Now selectively re-assign ranges only when it helps */ if (maximize_overlap) { dht_selfheal_layout_maximize_overlap(frame, loc, new_layout, layout); } done: if (new_layout) { /* Make sure the extra 'ref' for existing layout is removed */ dht_layout_unref(local->layout); local->layout = new_layout; } return local->layout; } /* * Having to call this 2x for each entry in the layout is pretty horrible, but * that's what all of this layout-sorting nonsense gets us. */ static uint32_t dht_get_chunks_from_xl(xlator_t *parent, xlator_t *child) { dht_conf_t *priv = parent->private; xlator_list_t *trav; uint32_t index = 0; if (!priv->du_stats) { return 0; } for (trav = parent->children; trav; trav = trav->next) { if (trav->xlator == child) { return priv->du_stats[index].chunks; } ++index; } return 0; } void dht_selfheal_layout_new_directory(call_frame_t *frame, loc_t *loc, dht_layout_t *layout) { xlator_t *this = NULL; double chunk = 0; int i = 0; uint32_t start = 0; int bricks_to_use = 0; int err = 0; int start_subvol = 0; uint32_t curr_size; uint32_t range_size; uint64_t total_size = 0; int real_i; dht_conf_t *priv; gf_boolean_t weight_by_size; int bricks_used = 0; this = frame->this; priv = this->private; weight_by_size = priv->do_weighting; bricks_to_use = dht_get_layout_count(this, layout, 1); GF_ASSERT(bricks_to_use > 0); bricks_used = 0; for (i = 0; i < layout->cnt; ++i) { err = layout->list[i].err; if ((err != -1) && (err != ENOENT)) { continue; } curr_size = dht_get_chunks_from_xl(this, layout->list[i].xlator); if (!curr_size) { weight_by_size = _gf_false; break; } total_size += curr_size; if (++bricks_used >= bricks_to_use) { break; } } if (weight_by_size && total_size) { /* We know total_size is not zero. */ chunk = ((double)0xffffffff) / ((double)total_size); gf_msg_debug(this->name, 0, "chunk size = 0xffffffff / %" PRIu64 " = %f", total_size, chunk); } else { weight_by_size = _gf_false; chunk = ((double)0xffffffff) / ((double)bricks_to_use); } start_subvol = dht_selfheal_layout_alloc_start(this, loc, layout); /* clear out the range, as we are re-computing here */ DHT_RESET_LAYOUT_RANGE(layout); /* * OK, what's this "real_i" stuff about? This used to be two loops - * from start_subvol to layout->cnt-1, then from 0 to start_subvol-1. * That way is practically an open invitation to bugs when only one * of the loops is updated. Using real_i and modulo operators to make * it one loop avoids this problem. Remember, folks: it's everyone's * responsibility to help stamp out copy/paste abuse. */ bricks_used = 0; for (real_i = 0; real_i < layout->cnt; real_i++) { i = (real_i + start_subvol) % layout->cnt; err = layout->list[i].err; if ((err != -1) && (err != ENOENT)) { continue; } if (weight_by_size) { curr_size = dht_get_chunks_from_xl(this, layout->list[i].xlator); if (!curr_size) { continue; } } else { curr_size = 1; } range_size = chunk * curr_size; gf_msg_debug(this->name, 0, "assigning range size 0x%x to %s", range_size, layout->list[i].xlator->name); DHT_SET_LAYOUT_RANGE(layout, i, start, range_size, loc->path); if (++bricks_used >= bricks_to_use) { layout->list[i].stop = 0xffffffff; goto done; } start += range_size; } done: return; } static int dht_selfheal_dir_getafix(call_frame_t *frame, loc_t *loc, dht_layout_t *layout) { dht_local_t *local = NULL; uint32_t holes = 0; int ret = -1; int i = -1; uint32_t overlaps = 0; local = frame->local; holes = local->selfheal.hole_cnt; overlaps = local->selfheal.overlaps_cnt; if (holes || overlaps) { /* If the layout has anomalies which would change the hash * ranges, then we need to reset the commit_hash for this * directory, as the layout would change and things may not * be in place as expected */ layout->commit_hash = DHT_LAYOUT_HASH_INVALID; dht_selfheal_layout_new_directory(frame, loc, layout); ret = 0; } for (i = 0; i < layout->cnt; i++) { /* directory not present */ if (layout->list[i].err == ENOENT) { ret = 0; break; } } /* TODO: give a fix to these non-virgins */ return ret; } int dht_selfheal_new_directory(call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk, dht_layout_t *layout) { dht_local_t *local = NULL; int ret = 0; inode_t *linked_inode = NULL, *inode = NULL; loc_t *loc = NULL; char pgfid[GF_UUID_BUF_SIZE] = {0}; char gfid[GF_UUID_BUF_SIZE] = {0}; int32_t op_errno = EIO; local = frame->local; loc = &local->loc; gf_uuid_unparse(local->stbuf.ia_gfid, gfid); gf_uuid_unparse(loc->parent->gfid, pgfid); linked_inode = inode_link(loc->inode, loc->parent, loc->name, &local->stbuf); if (!linked_inode) { gf_smsg(frame->this->name, GF_LOG_WARNING, 0, DHT_MSG_LINK_INODE_FAILED, "pgfid=%s", pgfid, "name=%s", loc->name, "gfid=%s", gfid, NULL); ret = -1; goto out; } inode = loc->inode; loc->inode = linked_inode; inode_unref(inode); local->selfheal.dir_cbk = dir_cbk; local->selfheal.layout = dht_layout_ref(layout); dht_layout_sort_volname(layout); dht_selfheal_layout_new_directory(frame, &local->loc, layout); op_errno = ENOMEM; ret = dht_selfheal_layout_lock(frame, layout, _gf_true, dht_selfheal_dir_xattr, dht_should_heal_layout); out: if (ret < 0) { dir_cbk(frame, NULL, -1, op_errno, NULL); } return 0; } int dht_fix_directory_layout(call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk, dht_layout_t *layout) { dht_local_t *local = NULL; dht_layout_t *tmp_layout = NULL; int ret = 0; local = frame->local; local->selfheal.dir_cbk = dir_cbk; local->selfheal.layout = dht_layout_ref(layout); /* No layout sorting required here */ tmp_layout = dht_fix_layout_of_directory(frame, &local->loc, layout); if (!tmp_layout) { return -1; } ret = dht_selfheal_layout_lock(frame, tmp_layout, _gf_false, dht_fix_dir_xattr, dht_should_fix_layout); return ret; } int dht_selfheal_directory(call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk, loc_t *loc, dht_layout_t *layout) { dht_local_t *local = NULL; xlator_t *this = NULL; uint32_t down = 0; uint32_t misc = 0; int ret = 0; char pgfid[GF_UUID_BUF_SIZE] = {0}; char gfid[GF_UUID_BUF_SIZE] = {0}; inode_t *linked_inode = NULL, *inode = NULL; FRAME_SU_DO(frame, dht_local_t); local = frame->local; this = frame->this; local->selfheal.dir_cbk = dir_cbk; local->selfheal.layout = dht_layout_ref(layout); if (local->need_attrheal) { if (__is_root_gfid(local->stbuf.ia_gfid)) { local->stbuf.ia_gid = local->prebuf.ia_gid; local->stbuf.ia_uid = local->prebuf.ia_uid; local->stbuf.ia_ctime = local->prebuf.ia_ctime; local->stbuf.ia_ctime_nsec = local->prebuf.ia_ctime_nsec; local->stbuf.ia_prot = local->prebuf.ia_prot; } else if (!IA_ISINVAL(local->mds_stbuf.ia_type)) { local->stbuf = local->mds_stbuf; } } if (!__is_root_gfid(local->stbuf.ia_gfid)) { gf_uuid_unparse(local->stbuf.ia_gfid, gfid); gf_uuid_unparse(loc->parent->gfid, pgfid); linked_inode = inode_link(loc->inode, loc->parent, loc->name, &local->stbuf); if (!linked_inode) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LINK_INODE_FAILED, "pgfid=%s", pgfid, "name=%s", loc->name, "gfid=%s", gfid, NULL); ret = 0; goto sorry_no_fix; } inode = loc->inode; loc->inode = linked_inode; inode_unref(inode); } if (local->need_xattr_heal && (local->mds_xattr)) { dht_dir_set_heal_xattr(this, local, local->xattr, local->mds_xattr, NULL, NULL); dict_unref(local->mds_xattr); local->mds_xattr = NULL; } dht_layout_anomalies(this, loc, layout, &local->selfheal.hole_cnt, &local->selfheal.overlaps_cnt, &local->selfheal.missing_cnt, &local->selfheal.down, &local->selfheal.misc, NULL); down = local->selfheal.down; misc = local->selfheal.misc; if (down) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_SELFHEAL_FAILED, "path=%s", loc->path, "subvol-down=%d", down, "Not-fixing", "gfid=%s", gfid, NULL); ret = 0; goto sorry_no_fix; } if (misc) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_SELFHEAL_FAILED, "path=%s", loc->path, "misc=%d", misc, "unrecoverable-errors", "gfid=%s", gfid, NULL); ret = 0; goto sorry_no_fix; } dht_layout_sort_volname(layout); local->heal_layout = _gf_true; /* Ignore return value as it can be inferred from result of * dht_layout_anomalies */ dht_selfheal_dir_getafix(frame, loc, layout); if (!(local->selfheal.hole_cnt || local->selfheal.overlaps_cnt || local->selfheal.missing_cnt)) { local->heal_layout = _gf_false; } ret = dht_selfheal_dir_mkdir(frame, loc, layout, 0); if (ret < 0) { ret = 0; goto sorry_no_fix; } return 0; sorry_no_fix: /* TODO: need to put appropriate local->op_errno */ dht_selfheal_dir_finish(frame, ret, 1); return 0; } int dht_selfheal_restore(call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk, loc_t *loc, dht_layout_t *layout) { int ret = 0; dht_local_t *local = NULL; local = frame->local; local->selfheal.dir_cbk = dir_cbk; local->selfheal.layout = dht_layout_ref(layout); ret = dht_selfheal_dir_mkdir(frame, loc, layout, 1); return ret; } int dht_dir_heal_xattrs(void *data) { call_frame_t *frame = NULL; dht_local_t *local = NULL; xlator_t *subvol = NULL; xlator_t *mds_subvol = NULL; xlator_t *this = NULL; dht_conf_t *conf = NULL; dict_t *user_xattr = NULL; dict_t *internal_xattr = NULL; dict_t *mds_xattr = NULL; dict_t *xdata = NULL; int call_cnt = 0; int ret = -1; int uret = 0; int uflag = 0; int i = 0; int xattr_hashed = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; int32_t allzero[1] = {0}; GF_VALIDATE_OR_GOTO("dht", data, out); frame = data; local = frame->local; this = frame->this; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, local, out); mds_subvol = local->mds_subvol; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); gf_uuid_unparse(local->loc.gfid, gfid); if (!mds_subvol) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_NO_MDS_SUBVOL, "path=%s", local->loc.path, "gfid=%s", gfid, NULL); goto out; } if ((local->loc.inode && gf_uuid_is_null(local->loc.inode->gfid)) || gf_uuid_is_null(local->loc.gfid)) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_NOT_PRESENT, "skip-heal path=%s", local->loc.path, "gfid=%s", gfid, NULL); goto out; } internal_xattr = dict_new(); if (!internal_xattr) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_CREATE_FAILED, "dictionary", NULL); goto out; } xdata = dict_new(); if (!xdata) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_CREATE_FAILED, "dictionary", NULL); goto out; } call_cnt = conf->subvolume_cnt; user_xattr = dict_new(); if (!user_xattr) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_CREATE_FAILED, "dictionary", NULL); goto out; } ret = syncop_listxattr(local->mds_subvol, &local->loc, &mds_xattr, NULL, NULL); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_LIST_XATTRS_FAILED, "path=%s", local->loc.path, "name=%s", local->mds_subvol->name, NULL); } if (!mds_xattr) goto out; dht_dir_set_heal_xattr(this, local, user_xattr, mds_xattr, &uret, &uflag); /* To set quota related xattr need to set GLUSTERFS_INTERNAL_FOP_KEY * key value to 1 */ if (dict_get(user_xattr, QUOTA_LIMIT_KEY) || dict_get(user_xattr, QUOTA_LIMIT_OBJECTS_KEY)) { ret = dict_set_int32(xdata, GLUSTERFS_INTERNAL_FOP_KEY, 1); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, "key=%s", GLUSTERFS_INTERNAL_FOP_KEY, "path=%s", local->loc.path, NULL); goto out; } } if (uret <= 0 && !uflag) goto out; for (i = 0; i < call_cnt; i++) { subvol = conf->subvolumes[i]; if (subvol == mds_subvol) continue; if (uret || uflag) { /* Custom xattr heal is required - let posix handle it */ ret = dict_set_int8(xdata, "sync_backend_xattrs", _gf_true); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "path=%s", local->loc.path, "key=%s", "sync_backend_xattrs", NULL); goto out; } ret = syncop_setxattr(subvol, &local->loc, user_xattr, 0, xdata, NULL); if (ret) { xattr_hashed = 1; gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_DIR_XATTR_HEAL_FAILED, "set-user-xattr-failed path=%s", local->loc.path, "subvol=%s", subvol->name, "gfid=%s", gfid, NULL); } else { dict_del(xdata, "sync_backend_xattrs"); } } } /* After heal all custom xattr reset internal MDS xattr to 0 */ if (!xattr_hashed) { ret = dht_dict_set_array(internal_xattr, conf->mds_xattr_key, allzero, 1); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, "key=%s", conf->mds_xattr_key, "path=%s", local->loc.path, NULL); goto out; } ret = syncop_setxattr(mds_subvol, &local->loc, internal_xattr, 0, NULL, NULL); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_DIR_XATTR_HEAL_FAILED, "path=%s", local->loc.path, "subvol=%s", mds_subvol->name, "gfid=%s", gfid, NULL); } } out: if (user_xattr) dict_unref(user_xattr); if (mds_xattr) dict_unref(mds_xattr); if (internal_xattr) dict_unref(internal_xattr); if (xdata) dict_unref(xdata); return 0; } int dht_dir_heal_xattrs_done(int ret, call_frame_t *sync_frame, void *data) { DHT_STACK_DESTROY(sync_frame); return 0; } int dht_dir_attr_heal(void *data) { call_frame_t *frame = NULL; dht_local_t *local = NULL; xlator_t *subvol = NULL; xlator_t *mds_subvol = NULL; xlator_t *this = NULL; dht_conf_t *conf = NULL; int call_cnt = 0; int ret = -1; int i = 0; char gfid[GF_UUID_BUF_SIZE] = {0}; GF_VALIDATE_OR_GOTO("dht", data, out); frame = data; local = frame->local; this = frame->this; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO("dht", local, out); conf = this->private; GF_VALIDATE_OR_GOTO("dht", conf, out); mds_subvol = local->mds_subvol; call_cnt = conf->subvolume_cnt; if (!__is_root_gfid(local->stbuf.ia_gfid) && (!mds_subvol)) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_NO_MDS_SUBVOL, "path=%s", local->loc.path, "gfid=%s", gfid, NULL); goto out; } if (!__is_root_gfid(local->stbuf.ia_gfid)) { for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == mds_subvol) { if (!conf->subvolume_status[i]) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_MDS_DOWN_UNABLE_TO_SET, "path=%s", local->loc.path, "gfid=%s", gfid, NULL); goto out; } } } } for (i = 0; i < call_cnt; i++) { subvol = conf->subvolumes[i]; if (!subvol || subvol == mds_subvol) continue; if (__is_root_gfid(local->stbuf.ia_gfid)) { ret = syncop_setattr( subvol, &local->loc, &local->stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID | GF_SET_ATTR_MODE), NULL, NULL, NULL, NULL); } else { ret = syncop_setattr( subvol, &local->loc, &local->mds_stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID | GF_SET_ATTR_MODE), NULL, NULL, NULL, NULL); } if (ret) { gf_uuid_unparse(local->loc.gfid, gfid); gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_DIR_ATTR_HEAL_FAILED, "path=%s", local->loc.path, "subvol=%s", subvol->name, "gfid=%s", gfid, NULL); } } out: return 0; } int dht_dir_attr_heal_done(int ret, call_frame_t *sync_frame, void *data) { DHT_STACK_DESTROY(sync_frame); return 0; } /* EXIT: dht_update_commit_hash_for_layout */ static int dht_update_commit_hash_for_layout_done(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; /* preserve oldest error */ if (op_ret && !local->op_ret) { local->op_ret = op_ret; local->op_errno = op_errno; } DHT_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, NULL); return 0; } static int dht_update_commit_hash_for_layout_unlock(call_frame_t *frame, xlator_t *this) { dht_local_t *local = NULL; int ret = 0; local = frame->local; ret = dht_unlock_inodelk(frame, &local->lock[0].layout.my_layout, dht_update_commit_hash_for_layout_done); if (ret < 0) { /* preserve oldest error, just ... */ if (!local->op_ret) { local->op_errno = errno; local->op_ret = -1; } gf_smsg(this->name, GF_LOG_WARNING, errno, DHT_MSG_WIND_UNLOCK_FAILED, "path=%s", local->loc.path, NULL); dht_update_commit_hash_for_layout_done(frame, NULL, this, 0, 0, NULL); } return 0; } static int dht_update_commit_hash_for_layout_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { dht_local_t *local = NULL; int this_call_cnt = 0; local = frame->local; LOCK(&frame->lock); /* store first failure, just because */ if (op_ret && !local->op_ret) { local->op_ret = op_ret; local->op_errno = op_errno; } UNLOCK(&frame->lock); this_call_cnt = dht_frame_return(frame); if (is_last_call(this_call_cnt)) { dht_update_commit_hash_for_layout_unlock(frame, this); } return 0; } static int dht_update_commit_hash_for_layout_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { dht_local_t *local = NULL; int count = 1, ret = -1, i = 0, j = 0; dht_conf_t *conf = NULL; dht_layout_t *layout = NULL; int32_t *disk_layout = NULL; dict_t **xattr = NULL; local = frame->local; conf = frame->this->private; count = conf->local_subvols_cnt; layout = local->layout; if (op_ret < 0) { goto err_done; } /* We precreate the xattr list as we cannot change call count post the * first wind as we may never continue from there. So we finish prep * work before winding the setxattrs */ xattr = GF_CALLOC(count, sizeof(*xattr), gf_common_mt_char); if (!xattr) { local->op_errno = errno; gf_smsg(this->name, GF_LOG_WARNING, errno, DHT_MSG_COMMIT_HASH_FAILED, "allocation-failed path=%s", local->loc.path, NULL); goto err; } for (i = 0; i < count; i++) { /* find the layout index for the subvolume */ ret = dht_layout_index_for_subvol(layout, conf->local_subvols[i]); if (ret < 0) { local->op_errno = ENOENT; gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_COMMIT_HASH_FAILED, "path=%s", local->loc.path, "subvol=%s", conf->local_subvols[i]->name, "find-disk-layout-failed", NULL); goto err; } j = ret; /* update the commit hash for the layout */ layout->list[j].commit_hash = layout->commit_hash; /* extract the current layout */ ret = dht_disk_layout_extract(this, layout, j, &disk_layout); if (ret == -1) { local->op_errno = errno; gf_smsg(this->name, GF_LOG_WARNING, errno, DHT_MSG_COMMIT_HASH_FAILED, "path=%s", local->loc.path, "subvol=%s", conf->local_subvols[i]->name, "extract-disk-layout-failed", NULL); goto err; } xattr[i] = dict_new(); if (!xattr[i]) { local->op_errno = errno; gf_smsg(this->name, GF_LOG_WARNING, errno, DHT_MSG_COMMIT_HASH_FAILED, "path=%s Allocation-failed", local->loc.path, NULL); goto err; } ret = dict_set_bin(xattr[i], conf->xattr_name, disk_layout, 4 * 4); if (ret != 0) { local->op_errno = ENOMEM; gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DIR_SELFHEAL_XATTR_FAILED, "path=%s", local->loc.path, "subvol=%s", conf->local_subvols[i]->name, "set-xattr-failed", NULL); goto err; } disk_layout = NULL; gf_msg_trace(this->name, 0, "setting commit hash %u on subvolume %s" " for %s", layout->list[j].commit_hash, conf->local_subvols[i]->name, local->loc.path); } /* wind the setting of the commit hash across the local subvols */ local->call_cnt = count; local->op_ret = 0; local->op_errno = 0; for (i = 0; i < count; i++) { STACK_WIND(frame, dht_update_commit_hash_for_layout_cbk, conf->local_subvols[i], conf->local_subvols[i]->fops->setxattr, &local->loc, xattr[i], 0, NULL); } for (i = 0; i < count; i++) dict_unref(xattr[i]); GF_FREE(xattr); return 0; err: if (xattr) { for (i = 0; i < count; i++) { if (xattr[i]) dict_unref(xattr[i]); } GF_FREE(xattr); } GF_FREE(disk_layout); local->op_ret = -1; dht_update_commit_hash_for_layout_unlock(frame, this); return 0; err_done: local->op_ret = -1; dht_update_commit_hash_for_layout_done(frame, NULL, this, 0, 0, NULL); return 0; } /* ENTER: dht_update_commit_hash_for_layout (see EXIT above) * This function is invoked from rebalance only. * As a result, the check here is simple enough to see if defrag is present * in the conf, as other data would be populated appropriately if so. * If ever this was to be used in other code paths, checks would need to * change. * * Functional details: * - Lock the inodes on the subvols that we want the commit hash updated * - Update each layout with the inode layout, modified to take in the new * commit hash. * - Unlock and return. */ int dht_update_commit_hash_for_layout(call_frame_t *frame) { dht_local_t *local = NULL; int count = 1, ret = -1, i = 0; dht_lock_t **lk_array = NULL; dht_conf_t *conf = NULL; dht_lock_wrap_t *my_layout; GF_VALIDATE_OR_GOTO("dht", frame, err); GF_VALIDATE_OR_GOTO(frame->this->name, frame->local, err); local = frame->local; conf = frame->this->private; if (!conf->defrag) goto err; count = conf->local_subvols_cnt; lk_array = GF_MALLOC(count * sizeof(*lk_array), gf_common_mt_char); if (lk_array == NULL) goto err; for (i = 0; i < count; i++) { lk_array[i] = dht_lock_new(frame->this, conf->local_subvols[i], &local->loc, F_WRLCK, DHT_LAYOUT_HEAL_DOMAIN, NULL, FAIL_ON_ANY_ERROR); if (lk_array[i] == NULL) goto err; } my_layout = &local->lock[0].layout.my_layout; my_layout->locks = lk_array; my_layout->lk_count = count; ret = dht_blocking_inodelk(frame, lk_array, count, dht_update_commit_hash_for_layout_resume); if (ret < 0) { dht_lock_array_reset(my_layout); goto err; } return 0; err: if (lk_array != NULL) { dht_lock_array_free(lk_array, count); GF_FREE(lk_array); } return -1; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-mem-types.h0000644000000000000000000000013214522202451023751 xustar000000000000000030 mtime=1699284265.627027311 30 atime=1699284265.627027311 30 ctime=1699284301.214134499 glusterfs-11.1/xlators/cluster/dht/src/dht-mem-types.h0000664000175100017510000000176714522202451024243 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __DHT_MEM_TYPES_H__ #define __DHT_MEM_TYPES_H__ #include enum gf_dht_mem_types_ { gf_dht_mt_dht_du_t = gf_common_mt_end + 1, gf_dht_mt_dht_conf_t, gf_dht_mt_char, gf_dht_mt_int32_t, gf_dht_mt_xlator_t, gf_dht_mt_dht_layout_t, gf_switch_mt_switch_sched_array, gf_switch_mt_switch_struct, gf_dht_mt_subvol_time, gf_dht_mt_loc_t, gf_defrag_info_mt, gf_dht_mt_inode_ctx_t, gf_dht_mt_dirent_t, gf_dht_mt_container_t, gf_dht_mt_octx_t, gf_dht_mt_miginfo_t, gf_dht_mt_fd_ctx_t, gf_dht_ret_cache_t, gf_dht_nodeuuids_t, gf_dht_mt_end }; #endif glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/switch.c0000644000000000000000000000012714522202451022554 xustar000000000000000029 mtime=1699284265.63002732 29 atime=1699284265.63002732 29 ctime=1699284301.24113458 glusterfs-11.1/xlators/cluster/dht/src/switch.c0000664000175100017510000006402014522202451023031 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-common.h" #include "dht-mem-types.h" #include #include #include #include extern struct volume_options dht_options[]; struct switch_sched_array { xlator_t *xl; int32_t eligible; int32_t considered; }; /* Select one of this struct based on the path's pattern match */ struct switch_struct { struct switch_struct *next; struct switch_sched_array *array; int32_t node_index; /* Index of the node in this pattern. */ int32_t num_child; /* Total num of child nodes with this pattern. */ char path_pattern[256]; }; /* TODO: all 'TODO's in dht.c holds good */ /* This function should return child node as '*:subvolumes' is inserterd */ static int32_t gf_switch_valid_child(xlator_t *this, const char *child) { xlator_list_t *children = NULL; int32_t ret = 0; children = this->children; while (children) { if (!strcmp(child, children->xlator->name)) { ret = 1; break; } children = children->next; } return ret; } static xlator_t * get_switch_matching_subvol(const char *path, dht_conf_t *conf, xlator_t *hashed_subvol) { struct switch_struct *cond = NULL; struct switch_struct *trav = NULL; char *pathname = NULL; int idx = 0; xlator_t *subvol = NULL; cond = conf->private; subvol = hashed_subvol; if (!cond) goto out; pathname = gf_strdup(path); if (!pathname) goto out; trav = cond; while (trav) { if (fnmatch(trav->path_pattern, pathname, FNM_NOESCAPE) == 0) { for (idx = 0; idx < trav->num_child; idx++) { if (trav->array[idx].xl == hashed_subvol) goto out; } idx = trav->node_index++; trav->node_index %= trav->num_child; subvol = trav->array[idx].xl; goto out; } trav = trav->next; } out: GF_FREE(pathname); return subvol; } int switch_local_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { xlator_t *subvol = NULL; char is_linkfile = 0; char is_dir = 0; dht_conf_t *conf = NULL; dht_local_t *local = NULL; loc_t *loc = NULL; int i = 0; xlator_t *prev = NULL; int call_cnt = 0; int ret = 0; conf = this->private; prev = cookie; local = frame->local; loc = &local->loc; if (ENTRY_MISSING(op_ret, op_errno)) { if (conf->search_unhashed) { local->op_errno = ENOENT; dht_lookup_everywhere(frame, this, loc); return 0; } } if (op_ret == -1) goto out; is_linkfile = check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name); is_dir = check_is_dir(inode, stbuf, xattr); if (!is_dir && !is_linkfile) { /* non-directory and not a linkfile */ ret = dht_layout_preset(this, prev, inode); if (ret < 0) { gf_msg_debug(this->name, 0, "could not set pre-set layout " "for subvol %s", prev->name); op_ret = -1; op_errno = EINVAL; goto err; } goto out; } if (is_dir) { call_cnt = conf->subvolume_cnt; local->call_cnt = call_cnt; local->inode = inode_ref(inode); local->xattr = dict_ref(xattr); local->op_ret = 0; local->op_errno = 0; local->layout = dht_layout_new(this, conf->subvolume_cnt); if (!local->layout) { op_ret = -1; op_errno = ENOMEM; gf_msg_debug(this->name, 0, "memory allocation failed :("); goto err; } for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, dht_lookup_dir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, &local->loc, local->xattr_req); } } if (is_linkfile) { subvol = dht_linkfile_subvol(this, inode, stbuf, xattr); if (!subvol) { gf_msg_debug(this->name, 0, "linkfile has no link subvolume.path=%s", loc->path); dht_lookup_everywhere(frame, this, loc); return 0; } STACK_WIND_COOKIE(frame, dht_lookup_linkfile_cbk, subvol, subvol, subvol->fops->lookup, &local->loc, local->xattr_req); } return 0; out: if (!local->hashed_subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", local->loc.path); local->op_errno = ENOENT; dht_lookup_everywhere(frame, this, loc); return 0; } STACK_WIND_COOKIE(frame, dht_lookup_cbk, local->hashed_subvol, local->hashed_subvol, local->hashed_subvol->fops->lookup, &local->loc, local->xattr_req); return 0; err: DHT_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, stbuf, xattr, NULL); return 0; } int switch_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { xlator_t *hashed_subvol = NULL; xlator_t *cached_subvol = NULL; xlator_t *subvol = NULL; dht_local_t *local = NULL; dht_conf_t *conf = NULL; int ret = -1; int op_errno = -1; dht_layout_t *layout = NULL; int i = 0; int call_cnt = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); VALIDATE_OR_GOTO(loc->path, err); conf = this->private; local = dht_local_init(frame, loc, NULL, GF_FOP_LOOKUP); if (!local) { op_errno = ENOMEM; goto err; } if (xattr_req) { local->xattr_req = dict_ref(xattr_req); } else { local->xattr_req = dict_new(); } hashed_subvol = dht_subvol_get_hashed(this, &local->loc); cached_subvol = local->cached_subvol; local->hashed_subvol = hashed_subvol; if (is_revalidate(loc)) { layout = local->layout; if (!layout) { gf_msg_debug(this->name, 0, "revalidate lookup without cache. path=%s", loc->path); op_errno = EINVAL; goto err; } if (layout->gen && (layout->gen < conf->gen)) { gf_msg_debug(this->name, 0, "incomplete layout failure for path=%s", loc->path); dht_layout_unref(local->layout); goto do_fresh_lookup; } local->inode = inode_ref(loc->inode); local->call_cnt = layout->cnt; call_cnt = local->call_cnt; /* NOTE: we don't require 'trusted.glusterfs.dht.linkto' * attribute, revalidates directly go to the cached-subvolume. */ ret = dict_set_uint32(local->xattr_req, conf->xattr_name, 4 * 4); if (ret < 0) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "failed to set dict value for %s", conf->xattr_name); for (i = 0; i < layout->cnt; i++) { subvol = layout->list[i].xlator; STACK_WIND_COOKIE(frame, dht_revalidate_cbk, subvol, subvol, subvol->fops->lookup, loc, local->xattr_req); if (!--call_cnt) break; } } else { do_fresh_lookup: ret = dict_set_uint32(local->xattr_req, conf->xattr_name, 4 * 4); if (ret < 0) gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, "failed to set dict value for %s", conf->xattr_name); ret = dict_set_uint32(local->xattr_req, conf->link_xattr_name, 256); if (ret < 0) gf_msg(this->name, GF_LOG_WARNING, EINVAL, DHT_MSG_DICT_SET_FAILED, "failed to set dict value for %s", conf->link_xattr_name); if (!hashed_subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s, " "checking on all the subvols to see if " "it is a directory", loc->path); call_cnt = conf->subvolume_cnt; local->call_cnt = call_cnt; local->layout = dht_layout_new(this, conf->subvolume_cnt); if (!local->layout) { op_errno = ENOMEM; goto err; } for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, dht_lookup_dir_cbk, conf->subvolumes[i], conf->subvolumes[i], conf->subvolumes[i]->fops->lookup, &local->loc, local->xattr_req); } return 0; } /* */ cached_subvol = get_switch_matching_subvol(loc->path, conf, hashed_subvol); if (cached_subvol == hashed_subvol) { STACK_WIND_COOKIE(frame, dht_lookup_cbk, hashed_subvol, hashed_subvol, hashed_subvol->fops->lookup, loc, local->xattr_req); } else { STACK_WIND_COOKIE(frame, switch_local_lookup_cbk, cached_subvol, cached_subvol, cached_subvol->fops->lookup, loc, local->xattr_req); } } return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } int switch_create_linkfile_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (op_ret == -1) goto err; STACK_WIND_COOKIE(frame, dht_create_cbk, local->cached_subvol, local->cached_subvol, local->cached_subvol->fops->create, &local->loc, local->flags, local->mode, local->umask, local->fd, local->params); return 0; err: DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int switch_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *params) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; xlator_t *subvol = NULL; xlator_t *avail_subvol = NULL; int op_errno = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); conf = this->private; dht_get_du_info(frame, this, loc); local = dht_local_init(frame, loc, fd, GF_FOP_CREATE); if (!local) { op_errno = ENOMEM; goto err; } subvol = dht_subvol_get_hashed(this, loc); if (!subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", loc->path); op_errno = ENOENT; goto err; } avail_subvol = get_switch_matching_subvol(loc->path, conf, subvol); if (dht_is_subvol_filled(this, avail_subvol)) { avail_subvol = dht_free_disk_available_subvol(this, avail_subvol, local); } if (subvol != avail_subvol) { /* create a link file instead of actual file */ local->mode = mode; local->flags = flags; local->umask = umask; local->cached_subvol = avail_subvol; dht_linkfile_create(frame, switch_create_linkfile_create_cbk, this, avail_subvol, subvol, loc); return 0; } gf_msg_trace(this->name, 0, "creating %s on %s", loc->path, subvol->name); STACK_WIND_COOKIE(frame, dht_create_cbk, subvol, subvol, subvol->fops->create, loc, flags, mode, umask, fd, params); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int switch_mknod_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { dht_local_t *local = NULL; local = frame->local; if (!local || !local->cached_subvol) { op_errno = EINVAL; op_ret = -1; goto err; } if (op_ret >= 0) { STACK_WIND_COOKIE( frame, dht_newfile_cbk, (void *)local->cached_subvol, local->cached_subvol, local->cached_subvol->fops->mknod, &local->loc, local->mode, local->rdev, local->umask, local->params); return 0; } err: DHT_STACK_UNWIND(link, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); return 0; } int switch_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *params) { dht_local_t *local = NULL; dht_conf_t *conf = NULL; xlator_t *subvol = NULL; xlator_t *avail_subvol = NULL; int op_errno = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); conf = this->private; dht_get_du_info(frame, this, loc); local = dht_local_init(frame, loc, NULL, GF_FOP_MKNOD); if (!local) { op_errno = ENOMEM; goto err; } subvol = dht_subvol_get_hashed(this, loc); if (!subvol) { gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", loc->path); op_errno = ENOENT; goto err; } /* Consider the disksize in consideration */ avail_subvol = get_switch_matching_subvol(loc->path, conf, subvol); if (dht_is_subvol_filled(this, avail_subvol)) { avail_subvol = dht_free_disk_available_subvol(this, avail_subvol, local); } if (avail_subvol != subvol) { /* Create linkfile first */ local->params = dict_ref(params); local->mode = mode; local->umask = umask; local->rdev = rdev; local->cached_subvol = avail_subvol; dht_linkfile_create(frame, switch_mknod_linkfile_cbk, this, avail_subvol, subvol, loc); return 0; } gf_msg_trace(this->name, 0, "creating %s on %s", loc->path, subvol->name); STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)subvol, subvol, subvol->fops->mknod, loc, mode, rdev, umask, params); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; DHT_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } void switch_fini(xlator_t *this) { dht_conf_t *conf = NULL; struct switch_struct *trav = NULL; struct switch_struct *prev = NULL; conf = this->private; if (conf) { trav = (struct switch_struct *)conf->private; conf->private = NULL; while (trav) { GF_FREE(trav->array); prev = trav; trav = trav->next; GF_FREE(prev); } } dht_fini(this); } int set_switch_pattern(xlator_t *this, dht_conf_t *conf, const char *pattern_str) { int flag = 0; int idx = 0; int index = 0; int child_count = 0; char *tmp = NULL; char *tmp1 = NULL; char *child = NULL; char *tmp_str = NULL; char *tmp_str1 = NULL; char *dup_str = NULL; char *dup_childs = NULL; char *switch_str = NULL; char *pattern = NULL; char *childs = NULL; char *option_string = NULL; size_t pattern_length; struct switch_struct *switch_buf = NULL; struct switch_struct *switch_opt = NULL; struct switch_struct *trav = NULL; struct switch_sched_array *switch_buf_array = NULL; xlator_list_t *trav_xl = NULL; trav_xl = this->children; while (trav_xl) { index++; trav_xl = trav_xl->next; } child_count = index; switch_buf_array = GF_CALLOC((index + 1), sizeof(struct switch_sched_array), gf_switch_mt_switch_sched_array); if (!switch_buf_array) goto err; trav_xl = this->children; index = 0; while (trav_xl) { switch_buf_array[index].xl = trav_xl->xlator; switch_buf_array[index].eligible = 1; trav_xl = trav_xl->next; index++; } /* *jpg:child1,child2;*mpg:child3;*:child4,child5,child6 */ /* Get the pattern for considering switch case. "option block-size *avi:10MB" etc */ option_string = gf_strdup(pattern_str); if (option_string == NULL) { goto err; } switch_str = strtok_r(option_string, ";", &tmp_str); while (switch_str) { dup_str = gf_strdup(switch_str); if (dup_str == NULL) { goto err; } switch_opt = GF_CALLOC(1, sizeof(struct switch_struct), gf_switch_mt_switch_struct); if (!switch_opt) { GF_FREE(dup_str); goto err; } pattern = strtok_r(dup_str, ":", &tmp_str1); childs = strtok_r(NULL, ":", &tmp_str1); if (strncmp(pattern, "*", 2) == 0) { gf_msg("switch", GF_LOG_INFO, 0, DHT_MSG_SWITCH_PATTERN_INFO, "'*' pattern will be taken by default " "for all the unconfigured child nodes," " hence neglecting current option"); switch_str = strtok_r(NULL, ";", &tmp_str); GF_FREE(switch_opt); switch_opt = NULL; GF_FREE(dup_str); continue; } GF_FREE(dup_str); pattern_length = strlen(pattern); if (pattern_length >= (sizeof(switch_opt->path_pattern))) { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_SWITCH_PATTERN_ERROR, "Pattern (%s) too long", pattern); goto err; } memcpy(switch_opt->path_pattern, pattern, pattern_length); switch_opt->path_pattern[pattern_length] = '\0'; if (childs) { dup_childs = gf_strdup(childs); if (dup_childs == NULL) { goto err; } child = strtok_r(dup_childs, ",", &tmp); while (child) { if (gf_switch_valid_child(this, child)) { idx++; child = strtok_r(NULL, ",", &tmp); } else { gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SUBVOL_ERROR, "%s is not a subvolume of %s. " "pattern can only be scheduled " "only to a subvolume of %s", child, this->name, this->name); GF_FREE(dup_childs); goto err; } } GF_FREE(dup_childs); child = strtok_r(childs, ",", &tmp1); switch_opt->num_child = idx; switch_opt->array = GF_CALLOC( 1, (idx * sizeof(struct switch_sched_array)), gf_switch_mt_switch_sched_array); if (!switch_opt->array) goto err; idx = 0; while (child) { for (index = 0; index < child_count; index++) { if (strcmp(switch_buf_array[index].xl->name, child) == 0) { gf_msg_debug("switch", 0, "'%s' pattern will be " "scheduled to \"%s\"", switch_opt->path_pattern, child); /* if (switch_buf_array[index-1].considered) { gf_msg_debug ("switch", 0, "ambiguity found, exiting"); return -1; } */ switch_opt->array[idx].xl = switch_buf_array[index].xl; switch_buf_array[index].considered = 1; idx++; break; } } child = strtok_r(NULL, ",", &tmp1); } } else { /* error */ gf_msg("switch", GF_LOG_ERROR, 0, DHT_MSG_SET_SWITCH_PATTERN_ERROR, "Check \"scheduler.switch.case\" " "option in unify volume. Exiting"); goto err; } /* Link it to the main structure */ if (switch_buf) { /* there are already few entries */ trav = switch_buf; while (trav->next) trav = trav->next; trav->next = switch_opt; } else { /* First entry */ switch_buf = switch_opt; } switch_opt = NULL; switch_str = strtok_r(NULL, ";", &tmp_str); } /* Now, all the pattern based considerations done, so for all the * remaining pattern, '*' to all the remaining child nodes */ { for (index = 0; index < child_count; index++) { /* check for considered flag */ if (switch_buf_array[index].considered) continue; flag++; } if (!flag) { gf_msg("switch", GF_LOG_ERROR, 0, DHT_MSG_SET_SWITCH_PATTERN_ERROR, "No nodes left for pattern '*'. Exiting"); goto err; } switch_opt = GF_CALLOC(1, sizeof(struct switch_struct), gf_switch_mt_switch_struct); if (!switch_opt) goto err; /* Add the '*' pattern to the array */ memcpy(switch_opt->path_pattern, "*", 2); switch_opt->num_child = flag; switch_opt->array = GF_CALLOC(1, flag * sizeof(struct switch_sched_array), gf_switch_mt_switch_sched_array); if (!switch_opt->array) goto err; flag = 0; for (index = 0; index < child_count; index++) { /* check for considered flag */ if (switch_buf_array[index].considered) continue; gf_msg_debug("switch", 0, "'%s'" " pattern will be scheduled to \"%s\"", switch_opt->path_pattern, switch_buf_array[index].xl->name); switch_opt->array[flag].xl = switch_buf_array[index].xl; switch_buf_array[index].considered = 1; flag++; } if (switch_buf) { /* there are already few entries */ trav = switch_buf; while (trav->next) trav = trav->next; trav->next = switch_opt; } else { /* First entry */ switch_buf = switch_opt; } switch_opt = NULL; } /* */ conf->private = switch_buf; GF_FREE(option_string); return 0; err: GF_FREE(switch_buf_array); GF_FREE(switch_opt); GF_FREE(option_string); if (switch_buf) { trav = switch_buf; while (trav) { GF_FREE(trav->array); switch_opt = trav; trav = trav->next; GF_FREE(switch_opt); } } return -1; } int32_t switch_init(xlator_t *this) { dht_conf_t *conf = NULL; data_t *data = NULL; int ret = -1; ret = dht_init(this); if (ret) { return ret; } conf = this->private; data = dict_get(this->options, "pattern.switch.case"); if (data) { /* TODO: */ ret = set_switch_pattern(this, conf, data->data); if (ret) { goto err; } } this->private = conf; return 0; err: dht_fini(this); return -1; } struct xlator_fops fops = { .lookup = switch_lookup, .create = switch_create, .mknod = switch_mknod, .stat = dht_stat, .fstat = dht_fstat, .truncate = dht_truncate, .ftruncate = dht_ftruncate, .access = dht_access, .readlink = dht_readlink, .setxattr = dht_setxattr, .getxattr = dht_getxattr, .removexattr = dht_removexattr, .open = dht_open, .readv = dht_readv, .writev = dht_writev, .flush = dht_flush, .fsync = dht_fsync, .statfs = dht_statfs, .lk = dht_lk, .opendir = dht_opendir, .readdir = dht_readdir, .readdirp = dht_readdirp, .fsyncdir = dht_fsyncdir, .symlink = dht_symlink, .unlink = dht_unlink, .link = dht_link, .mkdir = dht_mkdir, .rmdir = dht_rmdir, .rename = dht_rename, .inodelk = dht_inodelk, .finodelk = dht_finodelk, .entrylk = dht_entrylk, .fentrylk = dht_fentrylk, .xattrop = dht_xattrop, .fxattrop = dht_fxattrop, .setattr = dht_setattr, }; struct xlator_cbks cbks = {.forget = dht_forget}; extern int32_t mem_acct_init(xlator_t *this); xlator_api_t xlator_api = { .init = switch_init, .fini = switch_fini, .notify = dht_notify, .reconfigure = dht_reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = dht_options, .identifier = "switch", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-messages.h0000644000000000000000000000013214522202451023640 xustar000000000000000030 mtime=1699284265.627027311 30 atime=1699284265.627027311 30 ctime=1699284301.216134505 glusterfs-11.1/xlators/cluster/dht/src/dht-messages.h0000664000175100017510000005664314522202451024135 0ustar00jenkinsjenkins00000000000000/*Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _DHT_MESSAGES_H_ #define _DHT_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID( DHT, DHT_MSG_CACHED_SUBVOL_GET_FAILED, DHT_MSG_CREATE_LINK_FAILED, DHT_MSG_DICT_SET_FAILED, DHT_MSG_DIR_ATTR_HEAL_FAILED, DHT_MSG_DIR_SELFHEAL_FAILED, DHT_MSG_DIR_SELFHEAL_XATTR_FAILED, DHT_MSG_FILE_ON_MULT_SUBVOL, DHT_MSG_FILE_TYPE_MISMATCH, DHT_MSG_GFID_MISMATCH, DHT_MSG_GFID_NULL, DHT_MSG_HASHED_SUBVOL_GET_FAILED, DHT_MSG_INIT_FAILED, DHT_MSG_INVALID_CONFIGURATION, DHT_MSG_INVALID_DISK_LAYOUT, DHT_MSG_INVALID_OPTION, DHT_MSG_LAYOUT_FIX_FAILED, DHT_MSG_LAYOUT_MERGE_FAILED, DHT_MSG_LAYOUT_MISMATCH, DHT_MSG_LAYOUT_NULL, DHT_MSG_MIGRATE_DATA_COMPLETE, DHT_MSG_MIGRATE_DATA_FAILED, DHT_MSG_MIGRATE_FILE_COMPLETE, DHT_MSG_MIGRATE_FILE_FAILED, DHT_MSG_NO_MEMORY, DHT_MSG_OPENDIR_FAILED, DHT_MSG_REBALANCE_FAILED, DHT_MSG_REBALANCE_START_FAILED, DHT_MSG_REBALANCE_STATUS, DHT_MSG_REBALANCE_STOPPED, DHT_MSG_RENAME_FAILED, DHT_MSG_SETATTR_FAILED, DHT_MSG_SUBVOL_INSUFF_INODES, DHT_MSG_SUBVOL_INSUFF_SPACE, DHT_MSG_UNLINK_FAILED, DHT_MSG_LAYOUT_SET_FAILED, DHT_MSG_LOG_FIXED_LAYOUT, DHT_MSG_GET_XATTR_FAILED, DHT_MSG_FILE_LOOKUP_FAILED, DHT_MSG_OPEN_FD_FAILED, DHT_MSG_SET_INODE_CTX_FAILED, DHT_MSG_UNLOCKING_FAILED, DHT_MSG_DISK_LAYOUT_NULL, DHT_MSG_SUBVOL_INFO, DHT_MSG_CHUNK_SIZE_INFO, DHT_MSG_LAYOUT_FORM_FAILED, DHT_MSG_SUBVOL_ERROR, DHT_MSG_REGEX_INFO, DHT_MSG_FOPEN_FAILED, DHT_MSG_SET_HOSTNAME_FAILED, DHT_MSG_BRICK_ERROR, DHT_MSG_SYNCOP_FAILED, DHT_MSG_MIGRATE_INFO, DHT_MSG_UNUSED_PLACEHOLDER, DHT_MSG_CREATE_FD_FAILED, DHT_MSG_READDIR_ERROR, DHT_MSG_CHILD_LOC_BUILD_FAILED, DHT_MSG_SET_SWITCH_PATTERN_ERROR, DHT_MSG_COMPUTE_HASH_FAILED, DHT_MSG_FIND_LAYOUT_ANOMALIES_ERROR, DHT_MSG_ANOMALIES_INFO, DHT_MSG_LAYOUT_INFO, DHT_MSG_INODE_LK_ERROR, DHT_MSG_RENAME_INFO, DHT_MSG_DATA_NULL, DHT_MSG_AGGREGATE_QUOTA_XATTR_FAILED, DHT_MSG_UNLINK_LOOKUP_INFO, DHT_MSG_LINK_FILE_LOOKUP_INFO, DHT_MSG_OPERATION_NOT_SUP, DHT_MSG_NOT_LINK_FILE_ERROR, DHT_MSG_CHILD_DOWN, DHT_MSG_UUID_PARSE_ERROR, DHT_MSG_GET_DISK_INFO_ERROR, DHT_MSG_INVALID_VALUE, DHT_MSG_SWITCH_PATTERN_INFO, DHT_MSG_SUBVOL_OP_FAILED, DHT_MSG_LAYOUT_PRESET_FAILED, DHT_MSG_INVALID_LINKFILE, DHT_MSG_FIX_LAYOUT_INFO, DHT_MSG_GET_HOSTNAME_FAILED, DHT_MSG_WRITE_FAILED, DHT_MSG_MIGRATE_HARDLINK_FILE_FAILED, DHT_MSG_FSYNC_FAILED, DHT_MSG_SUBVOL_DECOMMISSION_INFO, DHT_MSG_BRICK_QUERY_FAILED, DHT_MSG_SUBVOL_NO_LAYOUT_INFO, DHT_MSG_OPEN_FD_ON_DST_FAILED, DHT_MSG_SUBVOL_NOT_FOUND, DHT_MSG_FILE_LOOKUP_ON_DST_FAILED, DHT_MSG_DISK_LAYOUT_MISSING, DHT_MSG_DICT_GET_FAILED, DHT_MSG_REVALIDATE_CBK_INFO, DHT_MSG_UPGRADE_BRICKS, DHT_MSG_LK_ARRAY_INFO, DHT_MSG_RENAME_NOT_LOCAL, DHT_MSG_RECONFIGURE_INFO, DHT_MSG_INIT_LOCAL_SUBVOL_FAILED, DHT_MSG_SYS_CALL_GET_TIME_FAILED, DHT_MSG_NO_DISK_USAGE_STATUS, DHT_MSG_SUBVOL_DOWN_ERROR, DHT_MSG_REBAL_THROTTLE_INFO, DHT_MSG_COMMIT_HASH_INFO, DHT_MSG_REBAL_STRUCT_SET, DHT_MSG_HAS_MIGINFO, DHT_MSG_SETTLE_HASH_FAILED, DHT_MSG_DEFRAG_PROCESS_DIR_FAILED, DHT_MSG_FD_CTX_SET_FAILED, DHT_MSG_STALE_LOOKUP, DHT_MSG_PARENT_LAYOUT_CHANGED, DHT_MSG_LOCK_MIGRATION_FAILED, DHT_MSG_LOCK_INODE_UNREF_FAILED, DHT_MSG_ASPRINTF_FAILED, DHT_MSG_DIR_LOOKUP_FAILED, DHT_MSG_INODELK_FAILED, DHT_MSG_LOCK_FRAME_FAILED, DHT_MSG_LOCAL_LOCK_INIT_FAILED, DHT_MSG_ENTRYLK_ERROR, DHT_MSG_INODELK_ERROR, DHT_MSG_LOC_FAILED, DHT_MSG_UNKNOWN_FOP, DHT_MSG_MIGRATE_FILE_SKIPPED, DHT_MSG_DIR_XATTR_HEAL_FAILED, DHT_MSG_HASHED_SUBVOL_DOWN, DHT_MSG_NON_HASHED_SUBVOL_DOWN, DHT_MSG_SYNCTASK_CREATE_FAILED, DHT_MSG_DIR_HEAL_ABORT, DHT_MSG_MIGRATE_SKIP, DHT_MSG_FD_CREATE_FAILED, DHT_MSG_DICT_NEW_FAILED, DHT_MSG_FAILED_TO_OPEN, DHT_MSG_CREATE_FAILED, DHT_MSG_FILE_NOT_EXIST, DHT_MSG_CHOWN_FAILED, DHT_MSG_FALLOCATE_FAILED, DHT_MSG_FTRUNCATE_FAILED, DHT_MSG_STATFS_FAILED, DHT_MSG_WRITE_CROSS, DHT_MSG_NEW_TARGET_FOUND, DHT_MSG_INSUFF_MEMORY, DHT_MSG_SET_XATTR_FAILED, DHT_MSG_SET_MODE_FAILED, DHT_MSG_FILE_EXISTS_IN_DEST, DHT_MSG_SYMLINK_FAILED, DHT_MSG_LINKFILE_DEL_FAILED, DHT_MSG_MKNOD_FAILED, DHT_MSG_MIGRATE_CLEANUP_FAILED, DHT_MSG_LOCK_MIGRATE, DHT_MSG_PARENT_BUILD_FAILED, DHT_MSG_HASHED_SUBVOL_NOT_FOUND, DHT_MSG_ACQUIRE_ENTRYLK_FAILED, DHT_MSG_CREATE_DST_FAILED, DHT_MSG_MIGRATION_EXIT, DHT_MSG_CHANGED_DST, DHT_MSG_TRACE_FAILED, DHT_MSG_WRITE_LOCK_FAILED, DHT_MSG_GETACTIVELK_FAILED, DHT_MSG_STAT_FAILED, DHT_MSG_UNLINK_PERFORM_FAILED, DHT_MSG_CLANUP_SOURCE_FILE_FAILED, DHT_MSG_UNLOCK_FILE_FAILED, DHT_MSG_REMOVE_XATTR_FAILED, DHT_MSG_DATA_MIGRATE_ABORT, DHT_MSG_DEFRAG_NULL, DHT_MSG_PARENT_NULL, DHT_MSG_GFID_NOT_PRESENT, DHT_MSG_CHILD_LOC_FAILED, DHT_MSG_SET_LOOKUP_FAILED, DHT_MSG_DIR_REMOVED, DHT_MSG_FIX_NOT_COMP, DHT_MSG_SUBVOL_DETER_FAILED, DHT_MSG_LOCAL_SUBVOL, DHT_MSG_NODE_UUID, DHT_MSG_SIZE_FILE, DHT_MSG_GET_DATA_SIZE_FAILED, DHT_MSG_PTHREAD_JOIN_FAILED, DHT_MSG_COUNTER_THREAD_CREATE_FAILED, DHT_MSG_MIGRATION_INIT_QUEUE_FAILED, DHT_MSG_PAUSED_TIMEOUT, DHT_MSG_WOKE, DHT_MSG_ABORT_REBALANCE, DHT_MSG_CREATE_TASK_REBAL_FAILED, DHT_MSG_REBAL_ESTIMATE_NOT_AVAIL, DHT_MSG_ADD_CHOICES_ERROR, DHT_MSG_GET_CHOICES_ERROR, DHT_MSG_PREPARE_STATUS_ERROR, DHT_MSG_SET_CHOICE_FAILED, DHT_MSG_SET_HASHED_SUBVOL_FAILED, DHT_MSG_XATTR_HEAL_NOT_POSS, DHT_MSG_LINKTO_FILE_FAILED, DHT_MSG_STALE_LINKFILE_DELETE, DHT_MSG_NO_SUBVOL_FOR_LINKTO, DHT_MSG_SUBVOL_RETURNED, DHT_MSG_UNKNOWN_LOCAL_XSEL, DHT_MSG_GET_XATTR_ERR, DHT_MSG_ALLOC_OR_FILL_FAILED, DHT_MSG_GET_REAL_NAME_FAILED, DHT_MSG_COPY_UUID_FAILED, DHT_MSG_MDS_DETER_FAILED, DHT_MSG_CREATE_REBAL_FAILED, DHT_MSG_LINK_LAYOUT_FAILED, DHT_MSG_NO_SUBVOL_IN_LAYOUT, DHT_MSG_MEM_ALLOC_FAILED, DHT_MSG_SET_IN_PARAMS_DICT_FAILED, DHT_MSG_LOC_COPY_FAILED, DHT_MSG_PARENT_LOC_FAILED, DHT_MSG_CREATE_LOCK_FAILED, DHT_MSG_PREV_ATTEMPT_FAILED, DHT_MSG_REFRESH_ATTEMPT, DHT_MSG_ACQUIRE_LOCK_FAILED, DHT_MSG_CREATE_STUB_FAILED, DHT_MSG_WIND_LOCK_REQ_FAILED, DHT_MSG_REFRESH_FAILED, DHT_MSG_CACHED_SUBVOL_ERROR, DHT_MSG_NO_LINK_SUBVOL, DHT_MSG_SET_KEY_FAILED, DHT_MSG_REMOVE_LINKTO_FAILED, DHT_MSG_LAYOUT_DICT_SET_FAILED, DHT_MSG_XATTR_DICT_NULL, DHT_MSG_DUMMY_ALLOC_FAILED, DHT_MSG_DICT_IS_NULL, DHT_MSG_LINK_INODE_FAILED, DHT_MSG_SELFHEAL_FAILED, DHT_MSG_NO_MDS_SUBVOL, DHT_MSG_LIST_XATTRS_FAILED, DHT_MSG_RESET_INTER_XATTR_FAILED, DHT_MSG_MDS_DOWN_UNABLE_TO_SET, DHT_MSG_WIND_UNLOCK_FAILED, DHT_MSG_COMMIT_HASH_FAILED, DHT_MSG_UNLOCK_GFID_FAILED, DHT_MSG_UNLOCK_FOLLOW_ENTRYLK, DHT_MSG_COPY_FRAME_FAILED, DHT_MSG_UNLOCK_FOLLOW_LOCKS, DHT_MSG_ENTRYLK_FAILED_AFT_INODELK, DHT_MSG_CALLOC_FAILED, DHT_MSG_LOCK_ALLOC_FAILED, DHT_MSG_BLOCK_INODELK_FAILED, DHT_MSG_LOCAL_LOCKS_STORE_FAILED_UNLOCKING_FOLLOWING_ENTRYLK, DHT_MSG_ALLOC_FRAME_FAILED_NOT_UNLOCKING_FOLLOWING_ENTRYLKS, DHT_MSG_DST_NULL_SET_FAILED); #define DHT_MSG_FD_CTX_SET_FAILED_STR "Failed to set fd ctx" #define DHT_MSG_INVALID_VALUE_STR "Different dst found in the fd ctx" #define DHT_MSG_UNKNOWN_FOP_STR "Unknown FOP on file" #define DHT_MSG_OPEN_FD_ON_DST_FAILED_STR "Failed to open the fd on file" #define DHT_MSG_SYNCTASK_CREATE_FAILED_STR "Failed to create synctask" #define DHT_MSG_ASPRINTF_FAILED_STR \ "asprintf failed while fetching subvol from the id" #define DHT_MSG_HAS_MIGINFO_STR "Found miginfo in the inode ctx" #define DHT_MSG_FILE_LOOKUP_FAILED_STR "failed to lookup the file" #define DHT_MSG_INVALID_LINKFILE_STR \ "linkto target is different from cached-subvol. treating as destination " \ "subvol" #define DHT_MSG_GFID_MISMATCH_STR "gfid different on the target file" #define DHT_MSG_GET_XATTR_FAILED_STR "failed to get 'linkto' xattr" #define DHT_MSG_SET_INODE_CTX_FAILED_STR "failed to set inode-ctx target file" #define DHT_MSG_DIR_SELFHEAL_FAILED_STR "Healing of path failed" #define DHT_MSG_DIR_HEAL_ABORT_STR \ "Failed to get path from subvol. Aborting directory healing" #define DHT_MSG_DIR_XATTR_HEAL_FAILED_STR "xattr heal failed for directory" #define DHT_MSG_LOCK_INODE_UNREF_FAILED_STR \ "Found a NULL inode. Failed to unref the inode" #define DHT_MSG_DICT_SET_FAILED_STR "Failed to set dictionary value" #define DHT_MSG_NOT_LINK_FILE_ERROR_STR "got non-linkfile" #define DHT_MSG_CREATE_LINK_FAILED_STR "failed to initialize linkfile data" #define DHT_MSG_UNLINK_FAILED_STR "Unlinking linkfile on subvolume failed" #define DHT_MSG_MIGRATE_FILE_FAILED_STR "Migrate file failed" #define DHT_MSG_NO_MEMORY_STR "could not allocate memory for dict" #define DHT_MSG_SUBVOL_ERROR_STR "Failed to get linkto subvol" #define DHT_MSG_MIGRATE_HARDLINK_FILE_FAILED_STR "link failed on subvol" #define DHT_MSG_MIGRATE_FILE_SKIPPED_STR "Migration skipped" #define DHT_MSG_FD_CREATE_FAILED_STR "fd create failed" #define DHT_MSG_DICT_NEW_FAILED_STR "dict_new failed" #define DHT_MSG_FAILED_TO_OPEN_STR "failed to open" #define DHT_MSG_CREATE_FAILED_STR "failed to create" #define DHT_MSG_FILE_NOT_EXIST_STR "file does not exist" #define DHT_MSG_CHOWN_FAILED_STR "chown failed" #define DHT_MSG_FALLOCATE_FAILED_STR "fallocate failed" #define DHT_MSG_FTRUNCATE_FAILED_STR "ftruncate failed" #define DHT_MSG_STATFS_FAILED_STR "failed to get statfs" #define DHT_MSG_WRITE_CROSS_STR \ "write will cross min-fre-disk for file on subvol. looking for new subvol" #define DHT_MSG_SUBVOL_INSUFF_SPACE_STR \ "Could not find any subvol with space accommodating the file. Cosider " \ "adding bricks" #define DHT_MSG_NEW_TARGET_FOUND_STR "New target found for file" #define DHT_MSG_INSUFF_MEMORY_STR "insufficient memory" #define DHT_MSG_SET_XATTR_FAILED_STR "failed to set xattr" #define DHT_MSG_SET_MODE_FAILED_STR "failed to set mode" #define DHT_MSG_FILE_EXISTS_IN_DEST_STR "file exists in destination" #define DHT_MSG_LINKFILE_DEL_FAILED_STR "failed to delete the linkfile" #define DHT_MSG_SYMLINK_FAILED_STR "symlink failed" #define DHT_MSG_MKNOD_FAILED_STR "mknod failed" #define DHT_MSG_SETATTR_FAILED_STR "failed to perform setattr" #define DHT_MSG_MIGRATE_CLEANUP_FAILED_STR \ "Migrate file cleanup failed: failed to fstat file" #define DHT_MSG_LOCK_MIGRATE_STR "locks will be migrated for file" #define DHT_MSG_PARENT_BUILD_FAILED_STR \ "failed to build parent loc, which is needed to acquire entrylk to " \ "synchronize with renames on this path. Skipping migration" #define DHT_MSG_HASHED_SUBVOL_NOT_FOUND_STR \ "cannot find hashed subvol which is needed to synchronize with renames " \ "on this path. Skipping migration" #define DHT_MSG_ACQUIRE_ENTRYLK_FAILED_STR "failed to acquire entrylk on subvol" #define DHT_MSG_CREATE_DST_FAILED_STR "create dst failed for file" #define DHT_MSG_MIGRATION_EXIT_STR "Exiting migration" #define DHT_MSG_CHANGED_DST_STR "destination changed fo file" #define DHT_MSG_TRACE_FAILED_STR "Trace failed" #define DHT_MSG_WRITE_LOCK_FAILED_STR "write lock failed" #define DHT_MSG_GETACTIVELK_FAILED_STR "getactivelk failed for file" #define DHT_MSG_STAT_FAILED_STR "failed to do a stat" #define DHT_MSG_UNLINK_PERFORM_FAILED_STR "failed to perform unlink" #define DHT_MSG_MIGRATE_FILE_COMPLETE_STR "completed migration" #define DHT_MSG_CLANUP_SOURCE_FILE_FAILED_STR "failed to cleanup source file" #define DHT_MSG_UNLOCK_FILE_FAILED_STR "failed to unlock file" #define DHT_MSG_REMOVE_XATTR_FAILED_STR "remove xattr failed" #define DHT_MSG_HASHED_SUBVOL_GET_FAILED_STR "Failed to get hashed subvolume" #define DHT_MSG_CACHED_SUBVOL_GET_FAILED_STR "Failed to get cached subvolume" #define DHT_MSG_MIGRATE_DATA_FAILED_STR "migrate-data failed" #define DHT_MSG_DEFRAG_NULL_STR "defrag is NULL" #define DHT_MSG_DATA_MIGRATE_ABORT_STR \ "Readdirp failed. Aborting data migration for dict" #define DHT_MSG_LAYOUT_FIX_FAILED_STR "fix layout failed" #define DHT_MSG_PARENT_NULL_STR "parent is NULL" #define DHT_MSG_GFID_NOT_PRESENT_STR "gfid not present" #define DHT_MSG_CHILD_LOC_FAILED_STR "Child loc build failed" #define DHT_MSG_SET_LOOKUP_FAILED_STR "Failed to set lookup" #define DHT_MSG_DIR_LOOKUP_FAILED_STR "lookup failed" #define DHT_MSG_DIR_REMOVED_STR "Dir renamed or removed. Skipping" #define DHT_MSG_READDIR_ERROR_STR "readdir failed, Aborting fix-layout" #define DHT_MSG_SETTLE_HASH_FAILED_STR "Settle hash failed" #define DHT_MSG_DEFRAG_PROCESS_DIR_FAILED_STR "gf_defrag_process_dir failed" #define DHT_MSG_FIX_NOT_COMP_STR \ "Unable to retrieve fixlayout xattr. Assume background fix layout not " \ "complete" #define DHT_MSG_SUBVOL_DETER_FAILED_STR \ "local subvolume determination failed with error" #define DHT_MSG_LOCAL_SUBVOL_STR "local subvol" #define DHT_MSG_NODE_UUID_STR "node uuid" #define DHT_MSG_SIZE_FILE_STR "Total size files" #define DHT_MSG_GET_DATA_SIZE_FAILED_STR \ "Failed to get the total data size. Unable to estimate time to complete " \ "rebalance" #define DHT_MSG_PTHREAD_JOIN_FAILED_STR \ "file_counter_thread: pthread_join failed" #define DHT_MSG_COUNTER_THREAD_CREATE_FAILED_STR \ "Failed to create the file counter thread" #define DHT_MSG_MIGRATION_INIT_QUEUE_FAILED_STR \ "Failed to initialise migration queue" #define DHT_MSG_REBALANCE_STOPPED_STR "Received stop command on rebalance" #define DHT_MSG_PAUSED_TIMEOUT_STR "Request pause timer timeout" #define DHT_MSG_WOKE_STR "woken" #define DHT_MSG_ABORT_REBALANCE_STR "Aborting rebalance" #define DHT_MSG_REBALANCE_START_FAILED_STR \ "Failed to start rebalance: look up on / failed" #define DHT_MSG_CREATE_TASK_REBAL_FAILED_STR \ "Could not create task for rebalance" #define DHT_MSG_REBAL_ESTIMATE_NOT_AVAIL_STR \ "Rebalance estimates will not be available" #define DHT_MSG_REBALANCE_STATUS_STR "Rebalance status" #define DHT_MSG_DATA_NULL_STR "data value is NULL" #define DHT_MSG_ADD_CHOICES_ERROR_STR "Error to add choices in buffer" #define DHT_MSG_GET_CHOICES_ERROR_STR "Error to get choices" #define DHT_MSG_PREPARE_STATUS_ERROR_STR "Error to prepare status" #define DHT_MSG_SET_CHOICE_FAILED_STR "Failed to set full choice" #define DHT_MSG_AGGREGATE_QUOTA_XATTR_FAILED_STR \ "Failed to aggregate quota xattr" #define DHT_MSG_FILE_TYPE_MISMATCH_STR \ "path exists as a file on one subvolume and directory on another. Please " \ "fix it manually" #define DHT_MSG_LAYOUT_SET_FAILED_STR "failed to set layout for subvolume" #define DHT_MSG_LAYOUT_MERGE_FAILED_STR "failed to merge layouts for subvolume" #define DHT_MSG_SET_HASHED_SUBVOL_FAILED_STR "Failed to set hashed subvolume" #define DHT_MSG_XATTR_HEAL_NOT_POSS_STR \ "No gfid exists for path. so healing xattr is not possible" #define DHT_MSG_REVALIDATE_CBK_INFO_STR "Revalidate: subvolume returned -1" #define DHT_MSG_LAYOUT_MISMATCH_STR "Mismatching layouts" #define DHT_MSG_UNLINK_LOOKUP_INFO_STR "lookup_unlink retuened" #define DHT_MSG_LINKTO_FILE_FAILED_STR \ "Could not unlink the linkto file as either fd is open and/or linkto " \ "xattr is set" #define DHT_MSG_LAYOUT_PRESET_FAILED_STR \ "Could not set pre-set layout for subvolume" #define DHT_MSG_FILE_ON_MULT_SUBVOL_STR \ "multiple subvolumes have file (preferably rename the file in the " \ "backend, and do a fresh lookup" #define DHT_MSG_STALE_LINKFILE_DELETE_STR \ "attempting deletion of stale linkfile" #define DHT_MSG_LINK_FILE_LOOKUP_INFO_STR "Lookup on following linkfile" #define DHT_MSG_NO_SUBVOL_FOR_LINKTO_STR "No link subvolume for linkto" #define DHT_MSG_SUBVOL_RETURNED_STR "Subvolume returned -1" #define DHT_MSG_UNKNOWN_LOCAL_XSEL_STR "Unknown local->xsel" #define DHT_MSG_DICT_GET_FAILED_STR "Failed to get" #define DHT_MSG_UUID_PARSE_ERROR_STR "Failed to parse uuid" #define DHT_MSG_GET_XATTR_ERR_STR "getxattr err for dir" #define DHT_MSG_ALLOC_OR_FILL_FAILED_STR "alloc or fill failed" #define DHT_MSG_UPGRADE_BRICKS_STR \ "At least one of the bricks does not support this operation. Please " \ "upgrade all bricks" #define DHT_MSG_GET_REAL_NAME_FAILED_STR "Failed to get real filename" #define DHT_MSG_LAYOUT_NULL_STR "Layout is NULL" #define DHT_MSG_COPY_UUID_FAILED_STR "Failed to copy node uuid key" #define DHT_MSG_MDS_DETER_FAILED_STR \ "Cannot determine MDS, fetching xattr randomly from a subvol" #define DHT_MSG_HASHED_SUBVOL_DOWN_STR \ "MDS is down for path, so fetching xattr randomly from subvol" #define DHT_MSG_CREATE_REBAL_FAILED_STR \ "failed to create a new rebalance synctask" #define DHT_MSG_FIX_LAYOUT_INFO_STR "fixing the layout" #define DHT_MSG_OPERATION_NOT_SUP_STR "wrong directory-spread-count value" #define DHT_MSG_LINK_LAYOUT_FAILED_STR "failed to link the layout in inode" #define DHT_MSG_NO_SUBVOL_IN_LAYOUT_STR "no subvolume in layout for path" #define DHT_MSG_INODE_LK_ERROR_STR "mknod lock failed for file" #define DHT_MSG_MEM_ALLOC_FAILED_STR "mem allocation failed" #define DHT_MSG_PARENT_LAYOUT_CHANGED_STR \ "extracting in-memory layout of parent failed" #define DHT_MSG_SET_IN_PARAMS_DICT_FAILED_STR \ "setting in params dictionary failed" #define DHT_MSG_LOC_COPY_FAILED_STR "loc_copy failed" #define DHT_MSG_LOC_FAILED_STR "parent loc build failed" #define DHT_MSG_PARENT_LOC_FAILED_STR "locking parent failed" #define DHT_MSG_CREATE_LOCK_FAILED_STR "Create lock failed" #define DHT_MSG_PREV_ATTEMPT_FAILED_STR \ "mkdir loop detected. parent layout didn't change even though previous " \ "attempt of mkdir failed because of in-memory layout not matching with " \ "that on disk." #define DHT_MSG_REFRESH_ATTEMPT_STR \ "mkdir parent layout changed. Attempting a refresh and then a retry" #define DHT_MSG_ACQUIRE_LOCK_FAILED_STR \ "Acquiring lock on parent to guard against layout-change failed" #define DHT_MSG_CREATE_STUB_FAILED_STR "creating stub failed" #define DHT_MSG_WIND_LOCK_REQ_FAILED_STR \ "cannot wind lock request to guard parent layout" #define DHT_MSG_REFRESH_FAILED_STR "refreshing parent layout failed." #define DHT_MSG_CACHED_SUBVOL_ERROR_STR "On cached subvol" #define DHT_MSG_NO_LINK_SUBVOL_STR "Linkfile does not have link subvolume" #define DHT_MSG_SET_KEY_FAILED_STR "failed to set key" #define DHT_MSG_CHILD_DOWN_STR "Received CHILD_DOWN. Exiting" #define DHT_MSG_LOG_FIXED_LAYOUT_STR "log layout fixed" #define DHT_MSG_REBAL_STRUCT_SET_STR "local->rebalance already set" #define DHT_MSG_REMOVE_LINKTO_FAILED_STR "Removal of linkto failed at subvol" #define DHT_MSG_LAYOUT_DICT_SET_FAILED_STR "dht layout dict set failed" #define DHT_MSG_SUBVOL_INFO_STR "creating subvolume" #define DHT_MSG_COMPUTE_HASH_FAILED_STR "hash computation failed" #define DHT_MSG_INVALID_DISK_LAYOUT_STR \ "Invalid disk layout: Catastrophic error layout with unknown type found" #define DHT_MSG_ANOMALIES_INFO_STR "Found anomalies" #define DHT_MSG_XATTR_DICT_NULL_STR "xattr dictionary is NULL" #define DHT_MSG_DISK_LAYOUT_MISSING_STR "Disk layout missing" #define DHT_MSG_LAYOUT_INFO_STR "layout info" #define DHT_MSG_SUBVOL_NO_LAYOUT_INFO_STR "no pre-set layout for subvol" #define DHT_MSG_SELFHEAL_XATTR_FAILED_STR "layout setxattr failed" #define DHT_MSG_DIR_SELFHEAL_XATTR_FAILED_STR "Directory self heal xattr failed" #define DHT_MSG_DUMMY_ALLOC_FAILED_STR "failed to allocate dummy layout" #define DHT_MSG_DICT_IS_NULL_STR \ "dict is NULL, need to make sure gfids are same" #define DHT_MSG_ENTRYLK_ERROR_STR "acquiring entrylk after inodelk failed" #define DHT_MSG_NO_DISK_USAGE_STATUS_STR "no du stats" #define DHT_MSG_LINK_INODE_FAILED_STR "linking inode failed" #define DHT_MSG_SELFHEAL_FAILED_STR "Directory selfheal failed" #define DHT_MSG_NO_MDS_SUBVOL_STR "No mds subvol" #define DHT_MSG_LIST_XATTRS_FAILED_STR "failed to list xattrs" #define DHT_MSG_RESET_INTER_XATTR_FAILED_STR "Failed to reset internal xattr" #define DHT_MSG_MDS_DOWN_UNABLE_TO_SET_STR \ "mds subvol is down, unable to set xattr" #define DHT_MSG_DIR_ATTR_HEAL_FAILED_STR \ "Directory attr heal failed. Failed to set uid/gid" #define DHT_MSG_WIND_UNLOCK_FAILED_STR \ "Winding unlock failed: stale locks left on brick" #define DHT_MSG_COMMIT_HASH_FAILED_STR "Directory commit hash updaten failed" #define DHT_MSG_LK_ARRAY_INFO_STR "lk info" #define DHT_MSG_UNLOCK_GFID_FAILED_STR \ "unlock failed on gfid: stale lock might be left" #define DHT_MSG_UNLOCKING_FAILED_STR "unlocking failed" #define DHT_MSG_UNLOCK_FOLLOW_ENTRYLK_STR "not unlocking following entrylks" #define DHT_MSG_COPY_FRAME_FAILED_STR "copy frame failed" #define DHT_MSG_UNLOCK_FOLLOW_LOCKS_STR "not unlocking following locks" #define DHT_MSG_INODELK_FAILED_STR "inodelk failed on subvol" #define DHT_MSG_LOCK_FRAME_FAILED_STR "memory allocation failed for lock_frame" #define DHT_MSG_LOCAL_LOCK_INIT_FAILED_STR "dht_local_lock_init failed" #define DHT_MSG_ENTRYLK_FAILED_AFT_INODELK_STR \ "dht_blocking_entrylk failed after taking inodelk" #define DHT_MSG_BLOCK_INODELK_FAILED_STR "dht_blocking_inodelk failed" #define DHT_MSG_CALLOC_FAILED_STR "calloc failed" #define DHT_MSG_LOCK_ALLOC_FAILED_STR "lock allocation failed" #define DHT_MSG_ALLOC_FRAME_FAILED_NOT_UNLOCKING_FOLLOWING_ENTRYLKS_STR \ "cannot allocate a frame, not unlocking following entrylks" #define DHT_MSG_LOCAL_LOCKS_STORE_FAILED_UNLOCKING_FOLLOWING_ENTRYLK_STR \ "storing locks in local failed, not unlocking following entrylks" #define DHT_MSG_DST_NULL_SET_FAILED_STR \ "src or dst is NULL, Failed to set dictionary value" #endif /* _DHT_MESSAGES_H_ */ glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-helper.c0000644000000000000000000000013214522202451023303 xustar000000000000000030 mtime=1699284265.625027305 30 atime=1699284265.624027302 30 ctime=1699284301.220134517 glusterfs-11.1/xlators/cluster/dht/src/dht-helper.c0000664000175100017510000017335114522202451023574 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-common.h" #include "dht-lock.h" #include "glusterfs/compat-errno.h" // for ENODATA on BSD static void dht_free_fd_ctx(dht_fd_ctx_t *fd_ctx) { GF_FREE(fd_ctx); } int32_t dht_fd_ctx_destroy(xlator_t *this, fd_t *fd) { dht_fd_ctx_t *fd_ctx = NULL; int32_t ret = -1; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); ret = 0; fd_ctx = fd_ctx_del_ptr(fd, this); if (fd_ctx) { GF_REF_PUT(fd_ctx); } out: return ret; } static int __dht_fd_ctx_set(xlator_t *this, fd_t *fd, xlator_t *dst) { dht_fd_ctx_t *fd_ctx = NULL; uint64_t value = 0; int ret = -1; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); fd_ctx = GF_CALLOC(1, sizeof(*fd_ctx), gf_dht_mt_fd_ctx_t); if (!fd_ctx) { goto out; } fd_ctx->opened_on_dst = (uint64_t)(uintptr_t)dst; GF_REF_INIT(fd_ctx, dht_free_fd_ctx); value = (uint64_t)(uintptr_t)fd_ctx; ret = __fd_ctx_set(fd, this, value); if (ret < 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_FD_CTX_SET_FAILED, "fd=0x%p", fd, NULL); GF_REF_PUT(fd_ctx); } out: return ret; } int dht_fd_ctx_set(xlator_t *this, fd_t *fd, xlator_t *dst) { dht_fd_ctx_t *fd_ctx = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); ret = 0; LOCK(&fd->lock); { fd_ctx = __fd_ctx_get_ptr(fd, this); if (fd_ctx) { if (fd_ctx->opened_on_dst == (uint64_t)(uintptr_t)dst) { /* This could happen due to racing * check_progress tasks*/ goto unlock; } else { /* This would be a big problem*/ /* Overwrite and hope for the best*/ fd_ctx->opened_on_dst = (uint64_t)(uintptr_t)dst; UNLOCK(&fd->lock); gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_INVALID_VALUE, NULL); goto out; } } ret = __dht_fd_ctx_set(this, fd, dst); } unlock: UNLOCK(&fd->lock); out: return ret; } static dht_fd_ctx_t * dht_fd_ctx_get(xlator_t *this, fd_t *fd) { dht_fd_ctx_t *fd_ctx = NULL; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); LOCK(&fd->lock); { fd_ctx = __fd_ctx_get_ptr(fd, this); if (fd_ctx) { GF_REF_GET(fd_ctx); } } UNLOCK(&fd->lock); out: return fd_ctx; } gf_boolean_t dht_fd_open_on_dst(xlator_t *this, fd_t *fd, xlator_t *dst) { dht_fd_ctx_t *fd_ctx = NULL; gf_boolean_t opened = _gf_false; fd_ctx = dht_fd_ctx_get(this, fd); if (fd_ctx) { if (fd_ctx->opened_on_dst == (uint64_t)(uintptr_t)dst) { opened = _gf_true; } GF_REF_PUT(fd_ctx); } return opened; } void dht_free_mig_info(void *data) { dht_migrate_info_t *miginfo = NULL; miginfo = data; GF_FREE(miginfo); return; } static int dht_inode_ctx_set_mig_info(xlator_t *this, inode_t *inode, xlator_t *src_subvol, xlator_t *dst_subvol) { dht_migrate_info_t *miginfo = NULL; uint64_t value = 0; int ret = -1; miginfo = GF_CALLOC(1, sizeof(*miginfo), gf_dht_mt_miginfo_t); if (miginfo == NULL) goto out; miginfo->src_subvol = src_subvol; miginfo->dst_subvol = dst_subvol; GF_REF_INIT(miginfo, dht_free_mig_info); value = (uint64_t)(uintptr_t)miginfo; ret = inode_ctx_set1(inode, this, &value); if (ret < 0) { GF_REF_PUT(miginfo); } out: return ret; } int dht_inode_ctx_get_mig_info(xlator_t *this, inode_t *inode, xlator_t **src_subvol, xlator_t **dst_subvol) { int ret = -1; uint64_t tmp_miginfo = 0; dht_migrate_info_t *miginfo = NULL; LOCK(&inode->lock); { ret = __inode_ctx_get1(inode, this, &tmp_miginfo); if ((ret < 0) || (tmp_miginfo == 0)) { UNLOCK(&inode->lock); goto out; } miginfo = (dht_migrate_info_t *)(uintptr_t)tmp_miginfo; GF_REF_GET(miginfo); } UNLOCK(&inode->lock); if (src_subvol) *src_subvol = miginfo->src_subvol; if (dst_subvol) *dst_subvol = miginfo->dst_subvol; GF_REF_PUT(miginfo); out: return ret; } gf_boolean_t dht_mig_info_is_invalid(xlator_t *current, xlator_t *src_subvol, xlator_t *dst_subvol) { /* Not set */ if (!src_subvol || !dst_subvol) return _gf_true; /* Invalid scenarios: * The src_subvol does not match the subvol on which the current op was sent * so the cached subvol has changed between the last mig_info_set and now. * src_subvol == dst_subvol. The file was migrated without any FOP detecting * a P2 so the old dst is now the current subvol. * * There is still one scenario where the info could be outdated - if * file has undergone multiple migrations and ends up on the same src_subvol * on which the mig_info was first set. */ if ((current == dst_subvol) || (current != src_subvol)) return _gf_true; return _gf_false; } /* Used to check if fd fops have the fd opened on the cached subvol * This is required when: * 1. an fd is opened on FILE1 on subvol1 * 2. the file is migrated to subvol2 * 3. a lookup updates the cached subvol in the inode_ctx to subvol2 * 4. a write comes on the fd * The write is sent to subvol2 on an fd which has been opened only on fd1 * Since the migration phase checks don't kick in, the fop fails with EBADF * */ static int dht_check_and_open_fd_on_subvol_complete(int ret, call_frame_t *frame, void *data) { glusterfs_fop_t fop = 0; dht_local_t *local = NULL; xlator_t *subvol = NULL; xlator_t *this = NULL; fd_t *fd = NULL; int op_errno = -1; local = frame->local; this = frame->this; fop = local->fop; subvol = local->cached_subvol; fd = local->fd; if (ret) { op_errno = local->op_errno; goto handle_err; } switch (fop) { case GF_FOP_WRITE: STACK_WIND_COOKIE(frame, dht_writev_cbk, subvol, subvol, subvol->fops->writev, fd, local->rebalance.vector, local->rebalance.count, local->rebalance.offset, local->rebalance.flags, local->rebalance.iobref, local->xattr_req); break; case GF_FOP_FLUSH: STACK_WIND(frame, dht_flush_cbk, subvol, subvol->fops->flush, fd, local->xattr_req); break; case GF_FOP_FSETATTR: STACK_WIND_COOKIE(frame, dht_file_setattr_cbk, subvol, subvol, subvol->fops->fsetattr, fd, &local->rebalance.stbuf, local->rebalance.flags, local->xattr_req); break; case GF_FOP_ZEROFILL: STACK_WIND_COOKIE(frame, dht_zerofill_cbk, subvol, subvol, subvol->fops->zerofill, fd, local->rebalance.offset, local->rebalance.size, local->xattr_req); break; case GF_FOP_DISCARD: STACK_WIND_COOKIE(frame, dht_discard_cbk, subvol, subvol, subvol->fops->discard, local->fd, local->rebalance.offset, local->rebalance.size, local->xattr_req); break; case GF_FOP_FALLOCATE: STACK_WIND_COOKIE(frame, dht_fallocate_cbk, subvol, subvol, subvol->fops->fallocate, fd, local->rebalance.flags, local->rebalance.offset, local->rebalance.size, local->xattr_req); break; case GF_FOP_FTRUNCATE: STACK_WIND_COOKIE(frame, dht_truncate_cbk, subvol, subvol, subvol->fops->ftruncate, fd, local->rebalance.offset, local->xattr_req); break; case GF_FOP_FSYNC: STACK_WIND_COOKIE(frame, dht_fsync_cbk, subvol, subvol, subvol->fops->fsync, local->fd, local->rebalance.flags, local->xattr_req); break; case GF_FOP_READ: STACK_WIND(frame, dht_readv_cbk, subvol, subvol->fops->readv, local->fd, local->rebalance.size, local->rebalance.offset, local->rebalance.flags, local->xattr_req); break; case GF_FOP_FSTAT: STACK_WIND_COOKIE(frame, dht_file_attr_cbk, subvol, subvol, subvol->fops->fstat, fd, local->xattr_req); break; case GF_FOP_FSETXATTR: STACK_WIND_COOKIE(frame, dht_file_setxattr_cbk, subvol, subvol, subvol->fops->fsetxattr, local->fd, local->rebalance.xattr, local->rebalance.flags, local->xattr_req); break; case GF_FOP_FREMOVEXATTR: STACK_WIND_COOKIE(frame, dht_file_removexattr_cbk, subvol, subvol, subvol->fops->fremovexattr, local->fd, local->key, local->xattr_req); break; case GF_FOP_FXATTROP: STACK_WIND(frame, dht_common_xattrop_cbk, subvol, subvol->fops->fxattrop, local->fd, local->rebalance.flags, local->rebalance.xattr, local->xattr_req); break; case GF_FOP_FGETXATTR: STACK_WIND(frame, dht_getxattr_cbk, subvol, subvol->fops->fgetxattr, local->fd, local->key, NULL); break; case GF_FOP_FINODELK: STACK_WIND(frame, dht_finodelk_cbk, subvol, subvol->fops->finodelk, local->key, local->fd, local->rebalance.lock_cmd, &local->rebalance.flock, local->xattr_req); break; case GF_FOP_SEEK: STACK_WIND_COOKIE(frame, dht_seek_cbk, subvol, subvol, subvol->fops->seek, local->fd, local->rebalance.offset, local->rebalance.flags, local->xattr_req); break; default: gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_UNKNOWN_FOP, "fd=%p", fd, "gfid=%s", uuid_utoa(fd->inode->gfid), "name=%s", subvol->name, NULL); break; } goto out; /* Could not open the fd on the dst. Unwind */ handle_err: switch (fop) { case GF_FOP_WRITE: DHT_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); break; case GF_FOP_FLUSH: DHT_STACK_UNWIND(flush, frame, -1, op_errno, NULL); break; case GF_FOP_FSETATTR: DHT_STACK_UNWIND(fsetattr, frame, -1, op_errno, NULL, NULL, NULL); break; case GF_FOP_ZEROFILL: DHT_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL); break; case GF_FOP_DISCARD: DHT_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); break; case GF_FOP_FALLOCATE: DHT_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); break; case GF_FOP_FTRUNCATE: DHT_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); break; case GF_FOP_FSYNC: DHT_STACK_UNWIND(fsync, frame, -1, op_errno, NULL, NULL, NULL); break; case GF_FOP_READ: DHT_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); break; case GF_FOP_FSTAT: DHT_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, NULL); break; case GF_FOP_FSETXATTR: DHT_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); break; case GF_FOP_FREMOVEXATTR: DHT_STACK_UNWIND(fremovexattr, frame, -1, op_errno, NULL); break; case GF_FOP_FXATTROP: DHT_STACK_UNWIND(fxattrop, frame, -1, op_errno, NULL, NULL); break; case GF_FOP_FGETXATTR: DHT_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL); break; case GF_FOP_FINODELK: DHT_STACK_UNWIND(finodelk, frame, -1, op_errno, NULL); break; default: gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_UNKNOWN_FOP, "fd=%p", fd, "gfid=%s", uuid_utoa(fd->inode->gfid), "name=%s", subvol->name, NULL); break; } out: return 0; } /* Check once again if the fd has been opened on the cached subvol. * If not, open and update the fd_ctx. */ static int dht_check_and_open_fd_on_subvol_task(void *data) { loc_t loc = { 0, }; int ret = -1; call_frame_t *frame = NULL; dht_local_t *local = NULL; fd_t *fd = NULL; xlator_t *this = NULL; xlator_t *subvol = NULL; frame = data; local = frame->local; this = THIS; fd = local->fd; subvol = local->cached_subvol; local->fd_checked = _gf_true; if (fd_is_anonymous(fd) || dht_fd_open_on_dst(this, fd, subvol)) { ret = 0; goto out; } gf_msg_debug(this->name, 0, "Opening fd (%p, flags=0%o) on file %s @ %s", fd, fd->flags, uuid_utoa(fd->inode->gfid), subvol->name); loc.inode = inode_ref(fd->inode); gf_uuid_copy(loc.gfid, fd->inode->gfid); /* Open this on the dst subvol */ SYNCTASK_SETID(0, 0); ret = syncop_open(subvol, &loc, (fd->flags & ~(O_CREAT | O_EXCL | O_TRUNC)), fd, NULL, NULL); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_OPEN_FD_ON_DST_FAILED, "fd=%p", fd, "flags=0%o", fd->flags, "gfid=%s", uuid_utoa(fd->inode->gfid), "name=%s", subvol->name, NULL); /* This can happen if the cached subvol was updated in the * inode_ctx and the fd was opened on the new cached suvol * after this fop was wound on the old cached subvol. * As we do not close the fd on the old subvol (a leak) * don't treat ENOENT as an error and allow the phase1/phase2 * checks to handle it. */ if ((-ret != ENOENT) && (-ret != ESTALE)) { local->op_errno = -ret; ret = -1; } else { ret = 0; } local->op_errno = -ret; ret = -1; } else { dht_fd_ctx_set(this, fd, subvol); } SYNCTASK_SETID(frame->root->uid, frame->root->gid); out: loc_wipe(&loc); return ret; } int dht_check_and_open_fd_on_subvol(xlator_t *this, call_frame_t *frame) { int ret = -1; dht_local_t *local = NULL; /* if (dht_fd_open_on_dst (this, fd, subvol)) goto out; */ local = frame->local; ret = synctask_new(this->ctx->env, dht_check_and_open_fd_on_subvol_task, dht_check_and_open_fd_on_subvol_complete, frame, frame); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SYNCTASK_CREATE_FAILED, "to-check-and-open fd=%p", local->fd, NULL); } return ret; } int dht_frame_return(call_frame_t *frame) { dht_local_t *local = NULL; int this_call_cnt = -1; if (!frame) return -1; local = frame->local; LOCK(&frame->lock); { this_call_cnt = --local->call_cnt; } UNLOCK(&frame->lock); return this_call_cnt; } /* * Use this function to specify which subvol you want the file created * on - this need not be the hashed subvol. * Format: @name>: * Eg: file-1@vol1-dht:vol1-client-0 * where vol1 is a pure distribute volume * will create file-1 on vol1-client-0 */ int dht_filter_loc_subvol_key(xlator_t *this, loc_t *loc, loc_t *new_loc, xlator_t **subvol) { char *new_name = NULL; char *new_path = NULL; xlator_list_t *trav = NULL; char key[1024] = { 0, }; int ret = 0; /* not found */ int keylen = 0; int name_len = 0; int path_len = 0; /* Why do other tasks if first required 'char' itself is not there */ if (!new_loc || !loc || !loc->name || !strchr(loc->name, '@')) { /* Skip the GF_FREE checks here */ return ret; } trav = this->children; while (trav) { keylen = snprintf(key, sizeof(key), "*@%s:%s", this->name, trav->xlator->name); /* Ignore '*' */ keylen = keylen - 1; if (fnmatch(key, loc->name, FNM_NOESCAPE) == 0) { name_len = strlen(loc->name) - keylen; new_name = GF_MALLOC(name_len + 1, gf_common_mt_char); if (!new_name) goto out; if (fnmatch(key, loc->path, FNM_NOESCAPE) == 0) { path_len = strlen(loc->path) - keylen; new_path = GF_MALLOC(path_len + 1, gf_common_mt_char); if (!new_path) goto out; snprintf(new_path, path_len + 1, "%s", loc->path); } snprintf(new_name, name_len + 1, "%s", loc->name); if (new_loc) { new_loc->path = ((new_path) ? new_path : gf_strdup(loc->path)); new_loc->name = new_name; new_loc->inode = inode_ref(loc->inode); new_loc->parent = inode_ref(loc->parent); } *subvol = trav->xlator; ret = 1; /* success */ goto out; } trav = trav->next; } out: if (!ret) { /* !success */ GF_FREE(new_path); GF_FREE(new_name); } return ret; } static xlator_t * dht_get_subvol_from_id(xlator_t *this, int client_id) { xlator_t *xl = NULL; dht_conf_t *conf = NULL; char *sid = NULL; int32_t ret = -1; conf = this->private; ret = gf_asprintf(&sid, "%d", client_id); if (ret == -1) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_ASPRINTF_FAILED, NULL); goto out; } if (dict_get_ptr(conf->leaf_to_subvol, sid, (void **)&xl)) xl = NULL; GF_FREE(sid); out: return xl; } int dht_deitransform(xlator_t *this, uint64_t y, xlator_t **subvol_p) { int client_id = 0; xlator_t *subvol = 0; dht_conf_t *conf = NULL; if (!this->private) return -1; conf = this->private; client_id = gf_deitransform(this, y); subvol = dht_get_subvol_from_id(this, client_id); if (!subvol) subvol = conf->subvolumes[0]; if (subvol_p) *subvol_p = subvol; return 0; } void dht_local_wipe(dht_local_t *local) { int i = 0; if (!local) return; loc_wipe(&local->loc); loc_wipe(&local->loc2); loc_wipe(&local->loc2_copy); if (local->xattr) dict_unref(local->xattr); if (local->inode) inode_unref(local->inode); if (local->layout) { dht_layout_unref(local->layout); local->layout = NULL; } loc_wipe(&local->linkfile.loc); if (local->linkfile.xattr) dict_unref(local->linkfile.xattr); if (local->linkfile.inode) inode_unref(local->linkfile.inode); if (local->fd) { fd_unref(local->fd); local->fd = NULL; } if (local->params) { dict_unref(local->params); local->params = NULL; } if (local->xattr_req) dict_unref(local->xattr_req); if (local->mds_xattr) dict_unref(local->mds_xattr); if (local->xdata) dict_unref(local->xdata); if (local->selfheal.layout) { dht_layout_unref(local->selfheal.layout); local->selfheal.layout = NULL; } if (local->selfheal.refreshed_layout) { dht_layout_unref(local->selfheal.refreshed_layout); local->selfheal.refreshed_layout = NULL; } for (i = 0; i < 2; i++) { dht_lock_array_free(local->lock[i].ns.parent_layout.locks, local->lock[i].ns.parent_layout.lk_count); GF_FREE(local->lock[i].ns.parent_layout.locks); dht_lock_array_free(local->lock[i].ns.directory_ns.locks, local->lock[i].ns.directory_ns.lk_count); GF_FREE(local->lock[i].ns.directory_ns.locks); } GF_FREE(local->key); if (local->rebalance.xdata) dict_unref(local->rebalance.xdata); if (local->rebalance.xattr) dict_unref(local->rebalance.xattr); if (local->rebalance.dict) dict_unref(local->rebalance.dict); GF_FREE(local->rebalance.vector); if (local->rebalance.iobref) iobref_unref(local->rebalance.iobref); if (local->stub) { call_stub_destroy(local->stub); local->stub = NULL; } if (local->ret_cache) GF_FREE(local->ret_cache); mem_put(local); } dht_local_t * dht_local_init(call_frame_t *frame, loc_t *loc, fd_t *fd, glusterfs_fop_t fop) { dht_local_t *local = NULL; inode_t *inode = NULL; int ret = 0; local = mem_get0(frame->this->local_pool); if (!local) goto out; if (loc) { ret = loc_copy(&local->loc, loc); if (ret) goto out; inode = loc->inode; } if (fd) { local->fd = fd_ref(fd); if (!inode) inode = fd->inode; } local->op_ret = -1; local->op_errno = EUCLEAN; local->fop = fop; if (inode) { local->layout = dht_layout_get(frame->this, inode); if (local->layout) { local->cached_subvol = local->layout->list[0].xlator; } } frame->local = local; out: if (ret) { if (local) mem_put(local); local = NULL; } return local; } xlator_t * dht_first_up_subvol(xlator_t *this) { dht_conf_t *conf = NULL; xlator_t *child = NULL; int i = 0; time_t time = 0; conf = this->private; if (!conf) goto out; LOCK(&conf->subvolume_lock); { for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvol_up_time[i]) { if (!time) { time = conf->subvol_up_time[i]; child = conf->subvolumes[i]; } else if (time > conf->subvol_up_time[i]) { time = conf->subvol_up_time[i]; child = conf->subvolumes[i]; } } } } UNLOCK(&conf->subvolume_lock); out: return child; } xlator_t * dht_last_up_subvol(xlator_t *this) { dht_conf_t *conf = NULL; xlator_t *child = NULL; int i = 0; conf = this->private; if (!conf) goto out; LOCK(&conf->subvolume_lock); { for (i = conf->subvolume_cnt - 1; i >= 0; i--) { if (conf->subvolume_status[i]) { child = conf->subvolumes[i]; break; } } } UNLOCK(&conf->subvolume_lock); out: return child; } xlator_t * dht_subvol_get_hashed(xlator_t *this, loc_t *loc) { dht_layout_t *layout = NULL; xlator_t *subvol = NULL; dht_conf_t *conf = NULL; dht_methods_t *methods = NULL; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); methods = &(conf->methods); if (__is_root_gfid(loc->gfid)) { subvol = dht_first_up_subvol(this); goto out; } GF_VALIDATE_OR_GOTO(this->name, loc->parent, out); GF_VALIDATE_OR_GOTO(this->name, loc->name, out); layout = dht_layout_get(this, loc->parent); if (!layout) { gf_msg_debug(this->name, 0, "Missing layout. path=%s, parent gfid =%s", loc->path, uuid_utoa(loc->parent->gfid)); goto out; } subvol = methods->layout_search(this, layout, loc->name); if (!subvol) { gf_msg_debug(this->name, 0, "No hashed subvolume for path=%s", loc->path); goto out; } out: if (layout) { dht_layout_unref(layout); } return subvol; } xlator_t * dht_subvol_get_cached(xlator_t *this, inode_t *inode) { dht_layout_t *layout = NULL; xlator_t *subvol = NULL; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); layout = dht_layout_get(this, inode); if (!layout) { goto out; } subvol = layout->list[0].xlator; out: if (layout) { dht_layout_unref(layout); } return subvol; } xlator_t * dht_subvol_next(xlator_t *this, xlator_t *prev) { dht_conf_t *conf = NULL; int i = 0; xlator_t *next = NULL; conf = this->private; if (!conf) goto out; for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == prev) { if ((i + 1) < conf->subvolume_cnt) next = conf->subvolumes[i + 1]; break; } } out: return next; } /* This func wraps around, if prev is actually the last subvol. */ xlator_t * dht_subvol_next_available(xlator_t *this, xlator_t *prev) { dht_conf_t *conf = NULL; int i = 0; xlator_t *next = NULL; conf = this->private; if (!conf) goto out; for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == prev) { /* if prev is last in conf->subvolumes, then wrap * around. */ if ((i + 1) < conf->subvolume_cnt) { next = conf->subvolumes[i + 1]; } else { next = conf->subvolumes[0]; } break; } } out: return next; } int dht_subvol_cnt(xlator_t *this, xlator_t *subvol) { int i = 0; int ret = -1; dht_conf_t *conf = NULL; conf = this->private; if (!conf) goto out; for (i = 0; i < conf->subvolume_cnt; i++) { if (subvol == conf->subvolumes[i]) { ret = i; break; } } out: return ret; } #define set_if_greater(a, b) \ do { \ if ((a) < (b)) \ (a) = (b); \ } while (0) #define set_if_greater_time(a, an, b, bn) \ do { \ if (((a) < (b)) || (((a) == (b)) && ((an) < (bn)))) { \ (a) = (b); \ (an) = (bn); \ } \ } while (0) int dht_iatt_merge(xlator_t *this, struct iatt *to, struct iatt *from) { if (!from || !to) return 0; to->ia_dev = from->ia_dev; gf_uuid_copy(to->ia_gfid, from->ia_gfid); to->ia_ino = from->ia_ino; to->ia_prot = from->ia_prot; to->ia_type = from->ia_type; to->ia_nlink = from->ia_nlink; to->ia_rdev = from->ia_rdev; to->ia_size += from->ia_size; to->ia_blksize = from->ia_blksize; to->ia_blocks += from->ia_blocks; if (IA_ISDIR(from->ia_type)) { to->ia_blocks = DHT_DIR_STAT_BLOCKS; to->ia_size = DHT_DIR_STAT_SIZE; } set_if_greater(to->ia_uid, from->ia_uid); set_if_greater(to->ia_gid, from->ia_gid); set_if_greater_time(to->ia_atime, to->ia_atime_nsec, from->ia_atime, from->ia_atime_nsec); set_if_greater_time(to->ia_mtime, to->ia_mtime_nsec, from->ia_mtime, from->ia_mtime_nsec); set_if_greater_time(to->ia_ctime, to->ia_ctime_nsec, from->ia_ctime, from->ia_ctime_nsec); return 0; } int dht_build_child_loc(xlator_t *this, loc_t *child, loc_t *parent, char *name) { if (!child) { goto err; } if (strcmp(parent->path, "/") == 0) gf_asprintf((char **)&child->path, "/%s", name); else gf_asprintf((char **)&child->path, "%s/%s", parent->path, name); if (!child->path) { goto err; } child->name = strrchr(child->path, '/'); if (child->name) child->name++; child->parent = inode_ref(parent->inode); child->inode = inode_new(parent->inode->table); if (!child->inode) { goto err; } return 0; err: if (child) { loc_wipe(child); } return -1; } int dht_init_local_subvolumes(xlator_t *this, dht_conf_t *conf) { xlator_list_t *subvols = NULL; int cnt = 0; if (!conf) return -1; for (subvols = this->children; subvols; subvols = subvols->next) cnt++; conf->local_subvols = GF_CALLOC(cnt, sizeof(xlator_t *), gf_dht_mt_xlator_t); /* FIX FIX : do this dynamically*/ conf->local_nodeuuids = GF_CALLOC(cnt, sizeof(subvol_nodeuuids_info_t), gf_dht_nodeuuids_t); if (!conf->local_subvols || !conf->local_nodeuuids) { return -1; } conf->local_subvols_cnt = 0; return 0; } int dht_init_subvolumes(xlator_t *this, dht_conf_t *conf) { xlator_list_t *subvols = NULL; int cnt = 0; if (!conf) return -1; for (subvols = this->children; subvols; subvols = subvols->next) cnt++; conf->subvolumes = GF_CALLOC(cnt, sizeof(xlator_t *), gf_dht_mt_xlator_t); if (!conf->subvolumes) { return -1; } conf->subvolume_cnt = cnt; /* Doesn't make sense to do any dht layer tasks if the subvol count is 1. Set it as pass_through */ if (cnt == 1) this->pass_through = _gf_true; conf->local_subvols_cnt = 0; dht_set_subvol_range(this); cnt = 0; for (subvols = this->children; subvols; subvols = subvols->next) conf->subvolumes[cnt++] = subvols->xlator; conf->subvolume_status = GF_CALLOC(cnt, sizeof(char), gf_dht_mt_char); if (!conf->subvolume_status) { return -1; } conf->last_event = GF_CALLOC(cnt, sizeof(int), gf_dht_mt_char); if (!conf->last_event) { return -1; } conf->subvol_up_time = GF_CALLOC(cnt, sizeof(time_t), gf_dht_mt_subvol_time); if (!conf->subvol_up_time) { return -1; } conf->du_stats = GF_CALLOC(conf->subvolume_cnt, sizeof(dht_du_t), gf_dht_mt_dht_du_t); if (!conf->du_stats) { return -1; } conf->decommissioned_bricks = GF_CALLOC(cnt, sizeof(xlator_t *), gf_dht_mt_xlator_t); if (!conf->decommissioned_bricks) { return -1; } return 0; } /* op_ret values : 0 : Success. -1 : Failure. 1 : File is being migrated but not by this DHT layer. */ static int dht_migration_complete_check_done(int op_ret, call_frame_t *frame, void *data) { dht_local_t *local = NULL; xlator_t *subvol = NULL; local = frame->local; if (op_ret != 0) goto out; if (local->cached_subvol == NULL) { local->op_errno = EINVAL; goto out; } subvol = local->cached_subvol; out: local->rebalance.target_op_fn(subvol, frame, op_ret); return 0; } static int dht_migration_complete_check_task(void *data) { int ret = -1; xlator_t *src_node = NULL; xlator_t *dst_node = NULL, *linkto_target = NULL; dht_local_t *local = NULL; dict_t *dict = NULL; struct iatt stbuf = { 0, }; xlator_t *this = NULL; call_frame_t *frame = NULL; loc_t tmp_loc = { 0, }; char *path = NULL; dht_conf_t *conf = NULL; inode_t *inode = NULL; fd_t *iter_fd = NULL; fd_t *tmp = NULL; uint64_t tmp_miginfo = 0; dht_migrate_info_t *miginfo = NULL; gf_boolean_t skip_open = _gf_false; int open_failed = 0; this = THIS; frame = data; local = frame->local; conf = this->private; src_node = local->cached_subvol; if (!local->loc.inode && !local->fd) { local->op_errno = EINVAL; goto out; } inode = (!local->fd) ? local->loc.inode : local->fd->inode; /* getxattr on cached_subvol for 'linkto' value. Do path based getxattr * as root:root. If a fd is already open, access check won't be done*/ if (!local->loc.inode) { ret = syncop_fgetxattr(src_node, local->fd, &dict, conf->link_xattr_name, NULL, NULL); } else { SYNCTASK_SETID(0, 0); ret = syncop_getxattr(src_node, &local->loc, &dict, conf->link_xattr_name, NULL, NULL); SYNCTASK_SETID(frame->root->uid, frame->root->gid); } /* * Each DHT xlator layer has its own name for the linkto xattr. * If the file mode bits indicate the the file is being migrated but * this layer's linkto xattr is not set, it means that another * DHT layer is migrating the file. In this case, return 1 so * the mode bits can be passed on to the higher layer for appropriate * action. */ if (-ret == ENODATA) { /* This DHT translator is not migrating this file */ ret = inode_ctx_reset1(inode, this, &tmp_miginfo); if (tmp_miginfo) { /* This can be a problem if the file was * migrated by two different layers. Raise * a warning here. */ gf_smsg( this->name, GF_LOG_WARNING, 0, DHT_MSG_HAS_MIGINFO, "tmp=%s", tmp_loc.path ? tmp_loc.path : uuid_utoa(tmp_loc.gfid), NULL); miginfo = (void *)(uintptr_t)tmp_miginfo; GF_REF_PUT(miginfo); } ret = 1; goto out; } if (!ret) linkto_target = dht_linkfile_subvol(this, NULL, NULL, dict); if (local->loc.inode) { loc_copy(&tmp_loc, &local->loc); } else { tmp_loc.inode = inode_ref(inode); gf_uuid_copy(tmp_loc.gfid, inode->gfid); } ret = syncop_lookup(this, &tmp_loc, &stbuf, 0, 0, 0); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_FILE_LOOKUP_FAILED, "tmp=%s", tmp_loc.path ? tmp_loc.path : uuid_utoa(tmp_loc.gfid), "name=%s", this->name, NULL); local->op_errno = -ret; ret = -1; goto out; } dst_node = dht_subvol_get_cached(this, tmp_loc.inode); if (linkto_target && dst_node != linkto_target) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_INVALID_LINKFILE, "linkto_target_name=%s", linkto_target->name, "dst_name=%s", dst_node->name, NULL); } if (gf_uuid_compare(stbuf.ia_gfid, tmp_loc.inode->gfid)) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_GFID_MISMATCH, "tmp=%s", tmp_loc.path ? tmp_loc.path : uuid_utoa(tmp_loc.gfid), "dst_name=%s", dst_node->name, NULL); ret = -1; local->op_errno = EIO; goto out; } /* update local. A layout is set in inode-ctx in lookup already */ dht_layout_unref(local->layout); local->layout = dht_layout_get(frame->this, inode); local->cached_subvol = dst_node; ret = 0; /* once we detect the migration complete, the inode-ctx2 is no more required.. delete the ctx and also, it means, open() already done on all the fd of inode */ ret = inode_ctx_reset1(inode, this, &tmp_miginfo); if (tmp_miginfo) { miginfo = (void *)(uintptr_t)tmp_miginfo; GF_REF_PUT(miginfo); goto out; } /* perform 'open()' on all the fd's present on the inode */ if (tmp_loc.path == NULL) { inode_path(inode, NULL, &path); if (path) tmp_loc.path = path; } LOCK(&inode->lock); if (list_empty(&inode->fd_list)) goto unlock; /* perform open as root:root. There is window between linkfile * creation(root:root) and setattr with the correct uid/gid */ SYNCTASK_SETID(0, 0); /* It's possible that we are the last user of iter_fd after each * iteration. In this case the fd_unref() of iter_fd at the end of * the loop will cause the destruction of the fd. So we need to * iterate the list safely because iter_fd cannot be trusted. */ iter_fd = list_entry((&inode->fd_list)->next, typeof(*iter_fd), inode_list); while (&iter_fd->inode_list != (&inode->fd_list)) { if (fd_is_anonymous(iter_fd) || (dht_fd_open_on_dst(this, iter_fd, dst_node))) { if (!tmp) { iter_fd = list_entry(iter_fd->inode_list.next, typeof(*iter_fd), inode_list); continue; } skip_open = _gf_true; } /* We need to release the inode->lock before calling * syncop_open() to avoid possible deadlocks. However this * can cause the iter_fd to be released by other threads. * To avoid this, we take a reference before releasing the * lock. */ fd_ref(iter_fd); UNLOCK(&inode->lock); if (tmp) { fd_unref(tmp); tmp = NULL; } if (skip_open) goto next; /* flags for open are stripped down to allow following the * new location of the file, otherwise we can get EEXIST or * truncate the file again as rebalance is moving the data */ ret = syncop_open(dst_node, &tmp_loc, (iter_fd->flags & ~(O_CREAT | O_EXCL | O_TRUNC)), iter_fd, NULL, NULL); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_OPEN_FD_ON_DST_FAILED, "id=%p", iter_fd, "flags=0%o", iter_fd->flags, "path=%s", path, "name=%s", dst_node->name, NULL); open_failed = 1; local->op_errno = -ret; ret = -1; } else { dht_fd_ctx_set(this, iter_fd, dst_node); } next: LOCK(&inode->lock); skip_open = _gf_false; tmp = iter_fd; iter_fd = list_entry(tmp->inode_list.next, typeof(*tmp), inode_list); } SYNCTASK_SETID(frame->root->uid, frame->root->gid); if (open_failed) { ret = -1; goto unlock; } ret = 0; unlock: UNLOCK(&inode->lock); if (tmp) { fd_unref(tmp); tmp = NULL; } out: if (dict) { dict_unref(dict); } loc_wipe(&tmp_loc); return ret; } int dht_rebalance_complete_check(xlator_t *this, call_frame_t *frame) { int ret = -1; ret = synctask_new(this->ctx->env, dht_migration_complete_check_task, dht_migration_complete_check_done, frame, frame); return ret; } /* During 'in-progress' state, both nodes should have the file */ /* op_ret values : 0 : Success -1 : Failure. 1 : File is being migrated but not by this DHT layer. */ static int dht_inprogress_check_done(int op_ret, call_frame_t *frame, void *data) { dht_local_t *local = NULL; xlator_t *dst_subvol = NULL, *src_subvol = NULL; inode_t *inode = NULL; local = frame->local; if (op_ret != 0) goto out; inode = local->loc.inode ? local->loc.inode : local->fd->inode; dht_inode_ctx_get_mig_info(THIS, inode, &src_subvol, &dst_subvol); if (dht_mig_info_is_invalid(local->cached_subvol, src_subvol, dst_subvol)) { dst_subvol = dht_subvol_get_cached(THIS, inode); if (!dst_subvol) { local->op_errno = EINVAL; goto out; } } out: local->rebalance.target_op_fn(dst_subvol, frame, op_ret); return 0; } static int dht_rebalance_inprogress_task(void *data) { int ret = -1; xlator_t *src_node = NULL; xlator_t *dst_node = NULL; dht_local_t *local = NULL; dict_t *dict = NULL; call_frame_t *frame = NULL; xlator_t *this = NULL; char *path = NULL; struct iatt stbuf = { 0, }; loc_t tmp_loc = { 0, }; dht_conf_t *conf = NULL; inode_t *inode = NULL; fd_t *iter_fd = NULL; fd_t *tmp = NULL; int open_failed = 0; uint64_t tmp_miginfo = 0; dht_migrate_info_t *miginfo = NULL; gf_boolean_t skip_open = _gf_false; this = THIS; frame = data; local = frame->local; conf = this->private; src_node = local->cached_subvol; if (!local->loc.inode && !local->fd) goto out; inode = (!local->fd) ? local->loc.inode : local->fd->inode; /* getxattr on cached_subvol for 'linkto' value. Do path based getxattr * as root:root. If a fd is already open, access check won't be done*/ if (local->loc.inode) { SYNCTASK_SETID(0, 0); ret = syncop_getxattr(src_node, &local->loc, &dict, conf->link_xattr_name, NULL, NULL); SYNCTASK_SETID(frame->root->uid, frame->root->gid); } else { ret = syncop_fgetxattr(src_node, local->fd, &dict, conf->link_xattr_name, NULL, NULL); } /* * Each DHT xlator layer has its own name for the linkto xattr. * If the file mode bits indicate the the file is being migrated but * this layer's linkto xattr is not present, it means that another * DHT layer is migrating the file. In this case, return 1 so * the mode bits can be passed on to the higher layer for appropriate * action. */ if (-ret == ENODATA) { /* This DHT layer is not migrating this file */ ret = inode_ctx_reset1(inode, this, &tmp_miginfo); if (tmp_miginfo) { /* This can be a problem if the file was * migrated by two different layers. Raise * a warning here. */ gf_smsg( this->name, GF_LOG_WARNING, 0, DHT_MSG_HAS_MIGINFO, "tmp=%s", tmp_loc.path ? tmp_loc.path : uuid_utoa(tmp_loc.gfid), NULL); miginfo = (void *)(uintptr_t)tmp_miginfo; GF_REF_PUT(miginfo); } ret = 1; goto out; } if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_GET_XATTR_FAILED, "path=%s", local->loc.path, NULL); ret = -1; goto out; } dst_node = dht_linkfile_subvol(this, NULL, NULL, dict); if (!dst_node) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_GET_XATTR_FAILED, "path=%s", local->loc.path, NULL); ret = -1; goto out; } local->rebalance.target_node = dst_node; if (local->loc.inode) { loc_copy(&tmp_loc, &local->loc); } else { tmp_loc.inode = inode_ref(inode); gf_uuid_copy(tmp_loc.gfid, inode->gfid); } /* lookup on dst */ ret = syncop_lookup(dst_node, &tmp_loc, &stbuf, NULL, NULL, NULL); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_FILE_LOOKUP_FAILED, "tmp=%s", tmp_loc.path ? tmp_loc.path : uuid_utoa(tmp_loc.gfid), "name=%s", dst_node->name, NULL); ret = -1; goto out; } if (gf_uuid_compare(stbuf.ia_gfid, tmp_loc.inode->gfid)) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_GFID_MISMATCH, "tmp=%s", tmp_loc.path ? tmp_loc.path : uuid_utoa(tmp_loc.gfid), "name=%s", dst_node->name, NULL); ret = -1; goto out; } ret = 0; if (tmp_loc.path == NULL) { inode_path(inode, NULL, &path); if (path) tmp_loc.path = path; } LOCK(&inode->lock); if (list_empty(&inode->fd_list)) goto unlock; /* perform open as root:root. There is window between linkfile * creation(root:root) and setattr with the correct uid/gid */ SYNCTASK_SETID(0, 0); /* It's possible that we are the last user of iter_fd after each * iteration. In this case the fd_unref() of iter_fd at the end of * the loop will cause the destruction of the fd. So we need to * iterate the list safely because iter_fd cannot be trusted. */ iter_fd = list_entry((&inode->fd_list)->next, typeof(*iter_fd), inode_list); while (&iter_fd->inode_list != (&inode->fd_list)) { /* We need to release the inode->lock before calling * syncop_open() to avoid possible deadlocks. However this * can cause the iter_fd to be released by other threads. * To avoid this, we take a reference before releasing the * lock. */ if (fd_is_anonymous(iter_fd) || (dht_fd_open_on_dst(this, iter_fd, dst_node))) { if (!tmp) { iter_fd = list_entry(iter_fd->inode_list.next, typeof(*iter_fd), inode_list); continue; } skip_open = _gf_true; } /* Yes, this is ugly but there isn't a cleaner way to do this * the fd_ref is an atomic increment so not too bad. We want to * reduce the number of inode locks and unlocks. */ fd_ref(iter_fd); UNLOCK(&inode->lock); if (tmp) { fd_unref(tmp); tmp = NULL; } if (skip_open) goto next; /* flags for open are stripped down to allow following the * new location of the file, otherwise we can get EEXIST or * truncate the file again as rebalance is moving the data */ ret = syncop_open(dst_node, &tmp_loc, (iter_fd->flags & ~(O_CREAT | O_EXCL | O_TRUNC)), iter_fd, NULL, NULL); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, -ret, DHT_MSG_OPEN_FD_ON_DST_FAILED, "fd=%p", iter_fd, "flags=0%o", iter_fd->flags, "path=%s", path, "name=%s", dst_node->name, NULL); ret = -1; open_failed = 1; } else { /* Potential fd leak if this fails here as it will be reopened at the next Phase1/2 check */ dht_fd_ctx_set(this, iter_fd, dst_node); } next: LOCK(&inode->lock); skip_open = _gf_false; tmp = iter_fd; iter_fd = list_entry(tmp->inode_list.next, typeof(*tmp), inode_list); } SYNCTASK_SETID(frame->root->uid, frame->root->gid); unlock: UNLOCK(&inode->lock); if (tmp) { fd_unref(tmp); tmp = NULL; } if (open_failed) { ret = -1; goto out; } ret = dht_inode_ctx_set_mig_info(this, inode, src_node, dst_node); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, "path=%s", local->loc.path, "name=%s", dst_node->name, NULL); goto out; } ret = 0; out: if (dict) { dict_unref(dict); } loc_wipe(&tmp_loc); return ret; } int dht_rebalance_in_progress_check(xlator_t *this, call_frame_t *frame) { int ret = -1; ret = synctask_new(this->ctx->env, dht_rebalance_inprogress_task, dht_inprogress_check_done, frame, frame); return ret; } int dht_inode_ctx_layout_set(inode_t *inode, xlator_t *this, dht_layout_t *layout_int) { dht_inode_ctx_t *ctx = NULL; int ret = -1; uint64_t ctx_int = 0; dht_layout_t *old_layout = NULL; LOCK(&inode->lock); { ret = __inode_ctx_get(inode, this, &ctx_int); if (!ret) { ctx = (dht_inode_ctx_t *)(uintptr_t)ctx_int; if (ctx) { old_layout = ctx->layout; ctx->layout = layout_int; } } if (!ctx) { ctx = GF_CALLOC(1, sizeof(*ctx), gf_dht_mt_inode_ctx_t); if (ctx) { ctx->layout = layout_int; ctx_int = (long)ctx; ret = __inode_ctx_set0(inode, this, &ctx_int); if (ret) GF_FREE(ctx); } else { ret = -1; } } if (!ret && layout_int) dht_layout_ref(ctx->layout); } UNLOCK(&inode->lock); if (old_layout) dht_layout_unref(old_layout); return ret; } void dht_inode_ctx_time_set(inode_t *inode, xlator_t *this, struct iatt *stat) { dht_inode_ctx_t *ctx = NULL; dht_stat_time_t *time = 0; int ret = -1; ret = dht_inode_ctx_get(inode, this, &ctx); if (ret) return; time = &ctx->time; time->mtime = stat->ia_mtime; time->mtime_nsec = stat->ia_mtime_nsec; time->ctime = stat->ia_ctime; time->ctime_nsec = stat->ia_ctime_nsec; time->atime = stat->ia_atime; time->atime_nsec = stat->ia_atime_nsec; return; } int dht_inode_ctx_time_update(inode_t *inode, xlator_t *this, struct iatt *prestat, struct iatt *poststat) { dht_inode_ctx_t *ctx = NULL; dht_stat_time_t *time = 0; int ret; GF_VALIDATE_OR_GOTO(this->name, inode, out); if (!prestat && !poststat) goto out; ret = dht_inode_ctx_get(inode, this, &ctx); if (ret) { ctx = GF_CALLOC(1, sizeof(*ctx), gf_dht_mt_inode_ctx_t); if (!ctx) return -1; } time = &ctx->time; LOCK(&inode->lock); { if (prestat) { DHT_UPDATE_TIME(time->mtime, time->mtime_nsec, prestat->ia_mtime, prestat->ia_mtime_nsec, 0); DHT_UPDATE_TIME(time->ctime, time->ctime_nsec, prestat->ia_ctime, prestat->ia_ctime_nsec, 0); DHT_UPDATE_TIME(time->atime, time->atime_nsec, prestat->ia_atime, prestat->ia_atime_nsec, 0); } if (poststat) { DHT_UPDATE_TIME(time->mtime, time->mtime_nsec, poststat->ia_mtime, poststat->ia_mtime_nsec, 1); DHT_UPDATE_TIME(time->ctime, time->ctime_nsec, poststat->ia_ctime, poststat->ia_ctime_nsec, 1); DHT_UPDATE_TIME(time->atime, time->atime_nsec, poststat->ia_atime, poststat->ia_atime_nsec, 1); } } UNLOCK(&inode->lock); ret = dht_inode_ctx_set(inode, this, ctx); out: return 0; } int dht_inode_ctx_get(inode_t *inode, xlator_t *this, dht_inode_ctx_t **ctx) { int ret = -1; uint64_t ctx_int = 0; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); ret = inode_ctx_get(inode, this, &ctx_int); if (ret) return ret; if (ctx) *ctx = (dht_inode_ctx_t *)(uintptr_t)ctx_int; out: return ret; } int dht_inode_ctx_set(inode_t *inode, xlator_t *this, dht_inode_ctx_t *ctx) { int ret = -1; uint64_t ctx_int = 0; GF_VALIDATE_OR_GOTO("dht", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); GF_VALIDATE_OR_GOTO(this->name, ctx, out); ctx_int = (long)ctx; ret = inode_ctx_set(inode, this, &ctx_int); out: return ret; } int dht_subvol_status(dht_conf_t *conf, xlator_t *subvol) { int i; for (i = 0; i < conf->subvolume_cnt; i++) { if (conf->subvolumes[i] == subvol) { return conf->subvolume_status[i]; } } return 0; } inode_t * dht_heal_path(xlator_t *this, char *path, inode_table_t *itable) { int ret = -1; struct iatt iatt = { 0, }; inode_t *linked_inode = NULL; loc_t loc = { 0, }; char *bname = NULL; char *save_ptr = NULL; static uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; char *tmp_path = NULL; tmp_path = gf_strdup(path); if (!tmp_path) { goto out; } gf_uuid_copy(loc.pargfid, gfid); loc.parent = inode_ref(itable->root); bname = strtok_r(tmp_path, "/", &save_ptr); /* sending a lookup on parent directory, * Eg: if path is like /a/b/c/d/e/f/g/ * then we will send a lookup on a first and then b,c,d,etc */ while (bname) { linked_inode = NULL; loc.inode = inode_grep(itable, loc.parent, bname); if (loc.inode == NULL) { loc.inode = inode_new(itable); if (loc.inode == NULL) { ret = -ENOMEM; goto out; } } else { /* * Inode is already populated in the inode table. * Which means we already looked up the inode and * linked with a dentry. So that we will skip * lookup on this entry, and proceed to next. */ linked_inode = loc.inode; bname = strtok_r(NULL, "/", &save_ptr); if (!bname) { goto out; } inode_unref(loc.parent); loc.parent = loc.inode; gf_uuid_copy(loc.pargfid, loc.inode->gfid); loc.inode = NULL; continue; } loc.name = bname; ret = loc_path(&loc, bname); ret = syncop_lookup(this, &loc, &iatt, NULL, NULL, NULL); if (ret) { gf_smsg(this->name, GF_LOG_INFO, -ret, DHT_MSG_DIR_SELFHEAL_FAILED, "path=%s", path, "subvolume=%s", this->name, "bname=%s", bname, NULL); goto out; } linked_inode = inode_link(loc.inode, loc.parent, bname, &iatt); if (!linked_inode) goto out; loc_wipe(&loc); gf_uuid_copy(loc.pargfid, linked_inode->gfid); loc.inode = NULL; bname = strtok_r(NULL, "/", &save_ptr); if (bname) loc.parent = linked_inode; } out: inode_ref(linked_inode); loc_wipe(&loc); GF_FREE(tmp_path); return linked_inode; } int dht_heal_full_path(void *data) { call_frame_t *heal_frame = data; dht_local_t *local = NULL; loc_t loc = { 0, }; dict_t *dict = NULL; char *path = NULL; int ret = -1; xlator_t *source = NULL; xlator_t *this = NULL; inode_table_t *itable = NULL; inode_t *inode = NULL; inode_t *tmp_inode = NULL; GF_VALIDATE_OR_GOTO("DHT", heal_frame, out); local = heal_frame->local; this = heal_frame->this; source = heal_frame->cookie; heal_frame->cookie = NULL; gf_uuid_copy(loc.gfid, local->gfid); if (local->loc.inode) loc.inode = inode_ref(local->loc.inode); else goto out; itable = loc.inode->table; ret = syncop_getxattr(source, &loc, &dict, GET_ANCESTRY_PATH_KEY, NULL, NULL); if (ret) { gf_smsg(this->name, GF_LOG_INFO, -ret, DHT_MSG_DIR_HEAL_ABORT, "subvol=%s", source->name, NULL); goto out; } ret = dict_get_str(dict, GET_ANCESTRY_PATH_KEY, &path); if (path) { inode = dht_heal_path(this, path, itable); if (inode && inode != local->inode) { /* * if inode returned by heal function is different * from what we passed, which means a racing thread * already linked a different inode for dentry. * So we will update our local->inode, so that we can * retrurn proper inode. */ tmp_inode = local->inode; local->inode = inode; inode_unref(tmp_inode); tmp_inode = NULL; } else { inode_unref(inode); } } out: loc_wipe(&loc); if (dict) dict_unref(dict); return 0; } int dht_heal_full_path_done(int op_ret, call_frame_t *heal_frame, void *data) { call_frame_t *main_frame = NULL; dht_local_t *local = NULL; xlator_t *this = NULL; int ret = -1; int op_errno = 0; local = heal_frame->local; main_frame = local->main_frame; local->main_frame = NULL; this = heal_frame->this; dht_set_fixed_dir_stat(&local->postparent); if (local->need_xattr_heal) { local->need_xattr_heal = 0; ret = dht_dir_xattr_heal(this, local, &op_errno); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_DIR_XATTR_HEAL_FAILED, "path=%s", local->loc.path, NULL); } } DHT_STACK_UNWIND(lookup, main_frame, 0, 0, local->inode, &local->stbuf, local->xattr, &local->postparent); DHT_STACK_DESTROY(heal_frame); return 0; } /* This function must be called inside an inode lock */ int __dht_lock_subvol_set(inode_t *inode, xlator_t *this, xlator_t *lock_subvol) { dht_inode_ctx_t *ctx = NULL; int ret = -1; uint64_t value = 0; GF_VALIDATE_OR_GOTO(this->name, inode, out); ret = __inode_ctx_get0(inode, this, &value); if (ret || !value) { return -1; } ctx = (dht_inode_ctx_t *)(uintptr_t)value; ctx->lock_subvol = lock_subvol; out: return ret; } xlator_t * dht_get_lock_subvolume(xlator_t *this, struct gf_flock *lock, dht_local_t *local) { xlator_t *subvol = NULL; inode_t *inode = NULL; int32_t ret = -1; uint64_t value = 0; xlator_t *cached_subvol = NULL; dht_inode_ctx_t *ctx = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; GF_VALIDATE_OR_GOTO(this->name, lock, out); GF_VALIDATE_OR_GOTO(this->name, local, out); cached_subvol = local->cached_subvol; if (local->loc.inode || local->fd) { inode = local->loc.inode ? local->loc.inode : local->fd->inode; } if (!inode) goto out; if (!(IA_ISDIR(inode->ia_type) || IA_ISINVAL(inode->ia_type))) { /* * We may get non-linked inode for directories as part * of the selfheal code path. So checking for IA_INVAL * type also. This will only happen for directory. */ subvol = local->cached_subvol; goto out; } if (lock->l_type != F_UNLCK) { /* * inode purging might happen on NFS between a lk * and unlk. Due to this lk and unlk might be sent * to different subvols. * So during a lock request, taking a ref on inode * to prevent inode purging. inode unref will happen * in unlock cbk code path. */ inode_ref(inode); } LOCK(&inode->lock); ret = __inode_ctx_get0(inode, this, &value); if (!ret && value) { ctx = (dht_inode_ctx_t *)(uintptr_t)value; subvol = ctx->lock_subvol; } if (!subvol && lock->l_type != F_UNLCK && cached_subvol) { ret = __dht_lock_subvol_set(inode, this, cached_subvol); if (ret) { gf_uuid_unparse(inode->gfid, gfid); UNLOCK(&inode->lock); gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_SET_INODE_CTX_FAILED, "lock_subvol gfid=%s", gfid, NULL); goto post_unlock; } subvol = cached_subvol; } UNLOCK(&inode->lock); post_unlock: if (!subvol && inode && lock->l_type != F_UNLCK) { inode_unref(inode); } out: return subvol; } int dht_lk_inode_unref(call_frame_t *frame, int32_t op_ret) { int ret = -1; dht_local_t *local = NULL; inode_t *inode = NULL; xlator_t *this = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; this = frame->this; if (local->loc.inode || local->fd) { inode = local->loc.inode ? local->loc.inode : local->fd->inode; } if (!inode) { gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LOCK_INODE_UNREF_FAILED, NULL); goto out; } if (!(IA_ISDIR(inode->ia_type) || IA_ISINVAL(inode->ia_type))) { ret = 0; goto out; } switch (local->lock_type) { case F_RDLCK: case F_WRLCK: if (op_ret) { gf_uuid_unparse(inode->gfid, gfid); gf_msg_debug(this->name, 0, "lock request failed for gfid %s", gfid); inode_unref(inode); goto out; } break; case F_UNLCK: if (!op_ret) { inode_unref(inode); } else { gf_uuid_unparse(inode->gfid, gfid); gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LOCK_INODE_UNREF_FAILED, "gfid=%s", gfid, NULL); goto out; } default: break; } ret = 0; out: return ret; } /* Code to update custom extended attributes from src dict to dst dict */ void dht_dir_set_heal_xattr(xlator_t *this, dht_local_t *local, dict_t *dst, dict_t *src, int *uret, int *uflag) { int ret = -1; data_t *keyval = NULL; int luret = -1; int luflag = -1; int i = 0; char **xattrs_to_heal; if (!src || !dst) { gf_smsg(this->name, GF_LOG_WARNING, EINVAL, DHT_MSG_DST_NULL_SET_FAILED, "path=%s", local->loc.path, NULL); return; } /* Check if any user xattr present in src dict and set it to dst dict */ luret = dict_foreach_fnmatch(src, "user.*", dht_set_user_xattr, dst); /* Check if any other custom xattr present in src dict and set it to dst dict, here index start from 1 because user xattr already checked in previous statement */ xattrs_to_heal = get_xattrs_to_heal(); for (i = 1; xattrs_to_heal[i]; i++) { keyval = dict_get(src, xattrs_to_heal[i]); if (keyval) { luflag = 1; ret = dict_set(dst, xattrs_to_heal[i], keyval); if (ret) gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, "key=%s", xattrs_to_heal[i], "path=%s", local->loc.path, NULL); keyval = NULL; } } if (uret) (*uret) = luret; if (uflag) (*uflag) = luflag; } glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-common.h0000644000000000000000000000013214522202451023321 xustar000000000000000030 mtime=1699284265.623027299 30 atime=1699284265.623027299 30 ctime=1699284301.213134496 glusterfs-11.1/xlators/cluster/dht/src/dht-common.h0000664000175100017510000012160714522202451023607 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "cli1-xdr.h" #include "dht-mem-types.h" #include "dht-messages.h" #include #include #include #include #ifndef _DHT_H #define _DHT_H #define GF_XATTR_FIX_LAYOUT_KEY "distribute.fix.layout" #define GF_XATTR_FILE_MIGRATE_KEY "trusted.distribute.migrate-data" #define DHT_MDS_STR "mds" #define GF_DHT_LOOKUP_UNHASHED_OFF 0 #define GF_DHT_LOOKUP_UNHASHED_ON 1 #define GF_DHT_LOOKUP_UNHASHED_AUTO 2 #define DHT_PATHINFO_HEADER "DISTRIBUTE:" #define DHT_FILE_MIGRATE_DOMAIN "dht.file.migrate" /* Layout synchronization */ #define DHT_LAYOUT_HEAL_DOMAIN "dht.layout.heal" /* Namespace synchronization */ #define DHT_ENTRY_SYNC_DOMAIN "dht.entry.sync" #define DHT_LAYOUT_HASH_INVALID 1 #define DHT_DIR_STAT_BLOCKS 8 #define DHT_DIR_STAT_SIZE 4096 /* Virtual xattr for subvols status */ #define DHT_SUBVOL_STATUS_KEY "dht.subvol.status" /* Virtual xattrs for debugging */ #define DHT_DBG_HASHED_SUBVOL_PATTERN "dht.file.hashed-subvol.*" #define DHT_DBG_HASHED_SUBVOL_KEY "dht.file.hashed-subvol." /* Rebalance nodeuuid flags */ #define REBAL_NODEUUID_MINE 0x01 typedef int (*dht_selfheal_dir_cbk_t)(call_frame_t *frame, void *cookie, int32_t op_ret, int32_t op_errno, dict_t *xdata); typedef int (*dht_defrag_cbk_fn_t)(xlator_t *subvol, call_frame_t *frame, int ret); typedef int (*dht_refresh_layout_unlock_t)(call_frame_t *frame, int op_ret, int invoke_cbk); typedef int (*dht_refresh_layout_done_handle)(call_frame_t *frame); struct dht_layout_entry { int err; /* 0 = normal -1 = dir exists and no xattr >0 = dir lookup failed with errno */ uint32_t start; uint32_t stop; uint32_t commit_hash; xlator_t *xlator; }; typedef struct dht_layout_entry dht_layout_entry_t; struct dht_layout { int spread_cnt; /* layout spread count per directory, is controlled by 'setxattr()' with special key */ int cnt; int preset; /* * The last *configuration* state for which this directory was known * to be in balance. The corresponding vol_commit_hash changes * whenever bricks are added or removed. This value changes when a * (full) rebalance is complete. If they match, it's safe to assume * that every file is where it should be and there's no need to do * lookups for files elsewhere. If they don't, then we have to do a * global lookup to be sure. */ uint32_t commit_hash; /* * The *runtime* state of the volume, changes when connections to * bricks are made or lost. */ int gen; int type; gf_atomic_t ref; /* use with dht_conf_t->layout_lock */ uint32_t search_unhashed; dht_layout_entry_t list[]; }; typedef struct dht_layout dht_layout_t; struct dht_stat_time { uint64_t atime; uint32_t atime_nsec; uint32_t ctime_nsec; uint64_t ctime; uint64_t mtime; uint32_t mtime_nsec; }; typedef struct dht_stat_time dht_stat_time_t; struct dht_inode_ctx { dht_layout_t *layout; dht_stat_time_t time; xlator_t *lock_subvol; xlator_t *mds_subvol; /* This is only used for directories */ }; typedef struct dht_inode_ctx dht_inode_ctx_t; typedef enum { DHT_HASH_TYPE_DM, DHT_HASH_TYPE_DM_USER, } dht_hashfn_type_t; typedef enum { DHT_INODELK, DHT_ENTRYLK, } dht_lock_type_t; /* rebalance related */ struct dht_rebalance_ { xlator_t *from_subvol; xlator_t *target_node; off_t offset; size_t size; int32_t flags; int count; struct iobref *iobref; struct iovec *vector; struct iatt stbuf; struct iatt prebuf; struct iatt postbuf; dht_defrag_cbk_fn_t target_op_fn; dict_t *xdata; dict_t *xattr; dict_t *dict; struct gf_flock flock; int32_t set; int lock_cmd; }; /** * Enum to store decided action based on the qdstatfs (quota-deem-statfs) * events **/ typedef enum { qdstatfs_action_OFF = 0, qdstatfs_action_REPLACE, qdstatfs_action_NEGLECT, qdstatfs_action_COMPARE, } qdstatfs_action_t; typedef enum { REACTION_INVALID, FAIL_ON_ANY_ERROR, IGNORE_ENOENT_ESTALE, IGNORE_ENOENT_ESTALE_EIO, } dht_reaction_type_t; struct dht_skip_linkto_unlink { xlator_t *hash_links_to; uuid_t cached_gfid; uuid_t hashed_gfid; int opend_fd_count; gf_boolean_t handle_valid_link; }; typedef struct { xlator_t *xl; loc_t loc; /* contains/points to inode to lock on. */ char *domain; /* Only locks within a single domain * contend with each other */ char *basename; /* Required for entrylk */ gf_boolean_t locked; dht_reaction_type_t do_on_failure; short type; /* read/write lock. */ gf_lkowner_t lk_owner; } dht_lock_t; /* The lock structure represents inodelk or entrylk. */ typedef struct { union { fop_inodelk_cbk_t inodelk_cbk; fop_entrylk_cbk_t entrylk_cbk; }; dht_lock_t **locks; int lk_count; dht_reaction_type_t reaction; /* whether locking failed on _any_ of the "locks" above */ int op_ret; int op_errno; } dht_lock_wrap_t; static inline void dht_lock_array_reset(dht_lock_wrap_t *_array) { _array->locks = NULL; _array->lk_count = 0; } static inline void dht_lock_array_copy(dht_lock_wrap_t *_src, dht_lock_wrap_t *_dst) { _dst->locks = _src->locks; _dst->lk_count = _src->lk_count; } /* The first member of dht_dir_transaction_t should be of type dht_lock_wrap_t. * Otherwise it can result in subtle memory corruption issues as in most of the * places we use lock[0].layout.my_layout or lock[0].layout.parent_layout and * lock[0].ns.parent_layout (like in dht_local_wipe). */ typedef union { union { dht_lock_wrap_t my_layout; dht_lock_wrap_t parent_layout; } layout; struct dht_namespace { dht_lock_wrap_t parent_layout; dht_lock_wrap_t directory_ns; fop_entrylk_cbk_t ns_cbk; } ns; } dht_dir_transaction_t; typedef int (*dht_selfheal_layout_t)(call_frame_t *frame, loc_t *loc, dht_layout_t *layout); typedef gf_boolean_t (*dht_need_heal_t)(call_frame_t *frame, dht_layout_t **inmem, dht_layout_t **ondisk); struct dht_local { loc_t loc; loc_t loc2; int call_cnt; int op_ret; int op_errno; int layout_mismatch; /* Use stbuf as the postbuf, when we require both * pre and post attrs */ struct iatt stbuf; struct iatt mds_stbuf; struct iatt prebuf; struct iatt preoldparent; struct iatt postoldparent; struct iatt preparent; struct iatt postparent; struct statvfs statvfs; fd_t *fd; inode_t *inode; dict_t *params; dict_t *xattr; dict_t *mds_xattr; dict_t *xdata; /* dict used to save xdata response by xattr fop */ dict_t *xattr_req; dht_layout_t *layout; size_t size; ino_t ia_ino; xlator_t *src_hashed, *src_cached; xlator_t *dst_hashed, *dst_cached; xlator_t *cached_subvol; xlator_t *hashed_subvol; xlator_t *mds_subvol; /* This is use for dir only */ int file_count; int dir_count; call_frame_t *main_frame; int fop_succeeded; struct { fop_mknod_cbk_t linkfile_cbk; struct iatt stbuf; loc_t loc; inode_t *inode; dict_t *xattr; xlator_t *srcvol; } linkfile; struct { uint32_t hole_cnt; uint32_t overlaps_cnt; uint32_t down; uint32_t misc; dht_selfheal_dir_cbk_t dir_cbk; dht_selfheal_layout_t healer; dht_need_heal_t should_heal; dht_layout_t *layout, *refreshed_layout; uint32_t missing_cnt; gf_boolean_t force_mkdir; } selfheal; dht_refresh_layout_unlock_t refresh_layout_unlock; dht_refresh_layout_done_handle refresh_layout_done; uint32_t uid; uint32_t gid; pid_t pid; glusterfs_fop_t fop; /* need for file-info */ char *xattr_val; char *key; /* needed by nufa */ int32_t flags; mode_t mode; dev_t rdev; mode_t umask; /* which xattr request? */ char xsel[256]; int32_t alloc_len; /* gfid related */ uuid_t gfid; uuid_t gfid_req; xlator_t *link_subvol; struct dht_rebalance_ rebalance; xlator_t *first_up_subvol; struct dht_skip_linkto_unlink skip_unlink; dht_dir_transaction_t lock[2], *current; /* for nested readdirs */ xlator_t *queue_xl; off_t queue_offset; int32_t queue; int32_t mds_heal_fresh_lookup; /* inodelks during filerename for backward compatibility */ dht_lock_t **rename_inodelk_backward_compatible; call_stub_t *stub; int32_t parent_disk_layout[4]; /* rename rollback */ int *ret_cache; loc_t loc2_copy; int rename_inodelk_bc_count; /* This is use only for directory operation */ int32_t valid; short lock_type; char need_selfheal; char need_xattr_heal; char need_attrheal; /* flag used to make sure we need to return estale in {lookup,revalidate}_cbk */ char return_estale; char need_lookup_everywhere; /* fd open check */ gf_boolean_t fd_checked; gf_boolean_t linked; gf_boolean_t added_link; gf_boolean_t is_linkfile; gf_boolean_t quota_deem_statfs; gf_boolean_t heal_layout; gf_boolean_t locked; gf_boolean_t dont_create_linkto; gf_boolean_t gfid_missing; bool simple_quota; }; typedef struct dht_local dht_local_t; /* du - disk-usage */ struct dht_du { double avail_percent; double avail_inodes; uint64_t avail_space; uint32_t log; uint32_t chunks; uint32_t total_blocks; uint32_t avail_blocks; uint32_t frsize; /*fragment size*/ }; typedef struct dht_du dht_du_t; typedef struct gf_defrag_pattern_list gf_defrag_pattern_list_t; struct gf_defrag_pattern_list { struct list_head list; char *path_pattern; uint64_t size; }; typedef struct dht_container { union { struct list_head list; struct { struct _gf_dirent_t *next; struct _gf_dirent_t *prev; }; }; gf_dirent_t *df_entry; loc_t *parent_loc; dict_t *migrate_data; int local_subvol_index; } dht_container_t; typedef struct nodeuuid_info { char info; /* Set to 1 is this is my node's uuid*/ uuid_t uuid; /* Store the nodeuuid as well for debugging*/ } nodeuuid_info_t; typedef struct subvol_nodeuuids_info { nodeuuid_info_t *elements; int count; } subvol_nodeuuids_info_t; struct gf_defrag_info_ { uint64_t total_files; uint64_t total_data; uint64_t num_files_lookedup; uint64_t total_failures; uint64_t skipped; uint64_t num_dirs_processed; uint64_t size_processed; uint64_t total_size; gf_lock_t lock; pthread_t th; struct rpc_clnt *rpc; uint32_t connected; uint32_t is_exiting; pid_t pid; int cmd; inode_t *root_inode; uuid_t node_uuid; time_t start_time; uint32_t new_commit_hash; gf_defrag_status_t defrag_status; struct list_head defrag_pattern; pthread_cond_t parallel_migration_cond; pthread_mutex_t dfq_mutex; pthread_cond_t rebalance_crawler_alarm; int32_t q_entry_count; int32_t global_error; dht_container_t *queue; int32_t crawl_done; int32_t abort; int32_t wakeup_crawler; /*Throttle params*/ /*stands for reconfigured thread count*/ int32_t recon_thread_count; pthread_cond_t df_wakeup_thread; /* backpointer to make it easier to write functions for rebalance */ xlator_t *this; pthread_cond_t fc_wakeup_cond; pthread_mutex_t fc_mutex; /*stands for current running thread count*/ int32_t current_thread_count; gf_boolean_t stats; /* lock migration flag */ gf_boolean_t lock_migration_enabled; }; typedef struct gf_defrag_info_ gf_defrag_info_t; struct dht_methods_s { int32_t (*migration_get_dst_subvol)(xlator_t *this, dht_local_t *local); int32_t (*migration_other)(xlator_t *this, gf_defrag_info_t *defrag); xlator_t *(*layout_search)(xlator_t *this, dht_layout_t *layout, const char *name); }; typedef struct dht_methods_s dht_methods_t; struct dht_conf { xlator_t **subvolumes; char *subvolume_status; int *last_event; dht_layout_t **file_layouts; dht_layout_t **dir_layouts; unsigned int search_unhashed; int gen; dht_du_t *du_stats; double min_free_disk; double min_free_inodes; int subvolume_cnt; int32_t refresh_interval; gf_lock_t subvolume_lock; time_t last_stat_fetch; dict_t *leaf_to_subvol; void *private; /* Can be used by wrapper xlators over dht */ time_t *subvol_up_time; /* to keep track of nodes which are decommissioned */ xlator_t **decommissioned_bricks; int decommission_in_progress; int decommission_subvols_cnt; /* defrag related */ gf_defrag_info_t *defrag; /* Support regex-based name reinterpretation. */ regex_t rsync_regex; regex_t extra_regex; /* Support variable xattr names. */ char *xattr_name; char *mds_xattr_key; char *link_xattr_name; char *commithash_xattr_name; char *wild_xattr_name; dht_methods_t methods; struct mem_pool *lock_pool; /*local subvol storage for rebalance*/ xlator_t **local_subvols; subvol_nodeuuids_info_t *local_nodeuuids; int32_t local_subvols_cnt; /* Hard link handle requirement for migration triggered from client*/ synclock_t link_lock; /* lock migration */ gf_lock_t lock; /* This is the count used as the distribute layout for a directory */ /* Will be a global flag to control the layout spread count */ uint32_t dir_spread_cnt; /* * "Commit hash" for this volume topology. Changed whenever bricks * are added or removed. */ uint32_t vol_commit_hash; char vol_uuid[GF_UUID_BUF_SIZE]; gf_boolean_t disk_unit_percent; gf_boolean_t lock_migration_enabled; gf_boolean_t vch_forced; gf_boolean_t use_fallocate; gf_boolean_t force_migration; gf_boolean_t lookup_optimize; gf_boolean_t rmdir_optimize; gf_boolean_t unhashed_sticky_bit; gf_boolean_t assert_no_child_down; gf_boolean_t use_readdirp; /* Request to filter directory entries in readdir request */ gf_boolean_t readdir_optimize; gf_boolean_t rsync_regex_valid; gf_boolean_t extra_regex_valid; /* Support size-weighted rebalancing (heterogeneous bricks). */ gf_boolean_t do_weighting; gf_boolean_t randomize_by_gfid; gf_boolean_t ensure_durability; }; typedef struct dht_conf dht_conf_t; typedef struct dht_dfoffset_ctx { off_t offset; int32_t readdir_done; } dht_dfoffset_ctx_t; typedef enum { GF_DHT_MIGRATE_DATA, GF_DHT_MIGRATE_DATA_EVEN_IF_LINK_EXISTS, GF_DHT_MIGRATE_HARDLINK, GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS } gf_dht_migrate_data_type_t; typedef enum { GF_DHT_EQUAL_DISTRIBUTION, GF_DHT_WEIGHTED_DISTRIBUTION } dht_distribution_type_t; struct dir_dfmeta { gf_dirent_t *equeue; dht_dfoffset_ctx_t *offset_var; struct list_head **head; struct list_head **iterator; int *fetch_entries; /* fds corresponding to local subvols only */ fd_t **lfd; }; typedef struct dht_migrate_info { xlator_t *src_subvol; xlator_t *dst_subvol; GF_REF_DECL; } dht_migrate_info_t; typedef struct dht_fd_ctx { uint64_t opened_on_dst; GF_REF_DECL; } dht_fd_ctx_t; #define ENTRY_MISSING(op_ret, op_errno) (op_ret == -1 && op_errno == ENOENT) #define is_revalidate(loc) \ (dht_inode_ctx_layout_get((loc)->inode, this, NULL) == 0) #define is_last_call(cnt) (cnt == 0) #define DHT_MIGRATION_IN_PROGRESS 1 #define DHT_MIGRATION_COMPLETED 2 #define check_is_linkfile(i, s, x, n) \ (IS_DHT_LINKFILE_MODE(s) && dict_get(x, n)) #define IS_DHT_MIGRATION_PHASE2(buf) \ (IA_ISREG((buf)->ia_type) && \ ((st_mode_from_ia((buf)->ia_prot, (buf)->ia_type) & ~S_IFMT) == \ DHT_LINKFILE_MODE)) #define IS_DHT_MIGRATION_PHASE1(buf) \ (IA_ISREG((buf)->ia_type) && ((buf)->ia_prot.sticky == 1) && \ ((buf)->ia_prot.sgid == 1)) #define DHT_STRIP_PHASE1_FLAGS(buf) \ do { \ if ((buf) && IS_DHT_MIGRATION_PHASE1(buf)) { \ (buf)->ia_prot.sticky = 0; \ (buf)->ia_prot.sgid = 0; \ } \ } while (0) #define dht_inode_missing(op_errno) (op_errno == ENOENT || op_errno == ESTALE) #define check_is_dir(i, s, x) (IA_ISDIR(s->ia_type)) #define layout_is_sane(layout) ((layout) && (layout->cnt > 0)) #define we_are_not_migrating(x) ((x) == 1) #define DHT_STACK_UNWIND(fop, frame, params...) \ do { \ dht_local_t *__local = NULL; \ if (frame) { \ __local = frame->local; \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ dht_local_wipe(__local); \ } while (0) #define DHT_STACK_DESTROY(frame) \ do { \ dht_local_t *__local = NULL; \ __local = frame->local; \ frame->local = NULL; \ STACK_DESTROY(frame->root); \ dht_local_wipe(__local); \ } while (0) #define DHT_UPDATE_TIME(ctx_sec, ctx_nsec, new_sec, new_nsec, post) \ do { \ if (ctx_sec == new_sec) \ new_nsec = max(new_nsec, ctx_nsec); \ else if (ctx_sec > new_sec) { \ new_sec = ctx_sec; \ new_nsec = ctx_nsec; \ } \ if (post) { \ ctx_sec = new_sec; \ ctx_nsec = new_nsec; \ } \ } while (0) #define is_greater_time(a, an, b, bn) \ (((a) < (b)) || (((a) == (b)) && ((an) < (bn)))) #define DHT_MARK_FOP_INTERNAL(xattr) \ do { \ int tmp = -1; \ if (!xattr) { \ xattr = dict_new(); \ if (!xattr) \ break; \ } \ tmp = dict_set_str(xattr, GLUSTERFS_INTERNAL_FOP_KEY, "yes"); \ if (tmp) { \ gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, \ "Failed to set dictionary value: key = %s," \ " path = %s", \ GLUSTERFS_INTERNAL_FOP_KEY, local->loc.path); \ } \ } while (0) dht_layout_t * dht_layout_new(xlator_t *this, int cnt); dht_layout_t * dht_layout_get(xlator_t *this, inode_t *inode); dht_layout_t * dht_layout_for_subvol(xlator_t *this, xlator_t *subvol); xlator_t * dht_layout_search(xlator_t *this, dht_layout_t *layout, const char *name); int32_t dht_migration_get_dst_subvol(xlator_t *this, dht_local_t *local); int dht_layout_normalize(xlator_t *this, loc_t *loc, dht_layout_t *layout); void dht_layout_anomalies(xlator_t *this, loc_t *loc, dht_layout_t *layout, uint32_t *holes_p, uint32_t *overlaps_p, uint32_t *missing_p, uint32_t *down_p, uint32_t *misc_p, uint32_t *no_space_p); int dht_layout_dir_mismatch(xlator_t *this, dht_layout_t *layout, xlator_t *subvol, loc_t *loc, dict_t *xattr); xlator_t * dht_linkfile_subvol(xlator_t *this, inode_t *inode, struct iatt *buf, dict_t *xattr); int dht_layouts_init(xlator_t *this, dht_conf_t *conf); int dht_layout_merge(xlator_t *this, dht_layout_t *layout, xlator_t *subvol, int op_ret, int op_errno, dict_t *xattr); int dht_disk_layout_extract(xlator_t *this, dht_layout_t *layout, int pos, int32_t **disk_layout_p); int dht_disk_layout_extract_for_subvol(xlator_t *this, dht_layout_t *layout, xlator_t *subvol, int32_t **disk_layout_p); int dht_frame_return(call_frame_t *frame); int dht_deitransform(xlator_t *this, uint64_t y, xlator_t **subvol); void dht_local_wipe(dht_local_t *local); dht_local_t * dht_local_init(call_frame_t *frame, loc_t *loc, fd_t *fd, glusterfs_fop_t fop); int dht_iatt_merge(xlator_t *this, struct iatt *to, struct iatt *from); xlator_t * dht_subvol_get_hashed(xlator_t *this, loc_t *loc); xlator_t * dht_subvol_get_cached(xlator_t *this, inode_t *inode); xlator_t * dht_subvol_next(xlator_t *this, xlator_t *prev); xlator_t * dht_subvol_next_available(xlator_t *this, xlator_t *prev); int dht_subvol_cnt(xlator_t *this, xlator_t *subvol); int dht_hash_compute(xlator_t *this, int type, const char *name, uint32_t *hash_p); int dht_linkfile_create(call_frame_t *frame, fop_mknod_cbk_t linkfile_cbk, xlator_t *this, xlator_t *tovol, xlator_t *fromvol, loc_t *loc); int dht_lookup_everywhere(call_frame_t *frame, xlator_t *this, loc_t *loc); int dht_selfheal_directory(call_frame_t *frame, dht_selfheal_dir_cbk_t cbk, loc_t *loc, dht_layout_t *layout); int dht_selfheal_new_directory(call_frame_t *frame, dht_selfheal_dir_cbk_t cbk, dht_layout_t *layout); int dht_selfheal_restore(call_frame_t *frame, dht_selfheal_dir_cbk_t cbk, loc_t *loc, dht_layout_t *layout); void dht_layout_sort_volname(dht_layout_t *layout); int dht_get_du_info(call_frame_t *frame, xlator_t *this, loc_t *loc); gf_boolean_t dht_is_subvol_filled(xlator_t *this, xlator_t *subvol); xlator_t * dht_free_disk_available_subvol(xlator_t *this, xlator_t *subvol, dht_local_t *layout); int dht_get_du_info_for_subvol(xlator_t *this, int subvol_idx); int dht_layout_preset(xlator_t *this, xlator_t *subvol, inode_t *inode); int dht_layout_set(xlator_t *this, inode_t *inode, dht_layout_t *layout); ; void dht_layout_unref(dht_layout_t *layout); dht_layout_t * dht_layout_ref(dht_layout_t *layout); int dht_layout_index_for_subvol(dht_layout_t *layout, xlator_t *subvol); xlator_t * dht_first_up_subvol(xlator_t *this); xlator_t * dht_last_up_subvol(xlator_t *this); int dht_build_child_loc(xlator_t *this, loc_t *child, loc_t *parent, char *name); int dht_filter_loc_subvol_key(xlator_t *this, loc_t *loc, loc_t *new_loc, xlator_t **subvol); int dht_rename_cleanup(call_frame_t *frame); int dht_rename_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata); int dht_update_commit_hash_for_layout(call_frame_t *frame); int dht_fix_directory_layout(call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk, dht_layout_t *layout); int dht_init_subvolumes(xlator_t *this, dht_conf_t *conf); /* migration/rebalance */ int dht_start_rebalance_task(xlator_t *this, call_frame_t *frame); int dht_rebalance_in_progress_check(xlator_t *this, call_frame_t *frame); int dht_rebalance_complete_check(xlator_t *this, call_frame_t *frame); int dht_init_local_subvolumes(xlator_t *this, dht_conf_t *conf); /* FOPS */ int32_t dht_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req); int32_t dht_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata); int32_t dht_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata); int32_t dht_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata); int32_t dht_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata); int32_t dht_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata); int32_t dht_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata); int32_t dht_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata); int32_t dht_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata); int32_t dht_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata); int32_t dht_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata); int32_t dht_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata); int32_t dht_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata); int32_t dht_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata); int32_t dht_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *params); int32_t dht_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata); int32_t dht_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata); int32_t dht_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata); int32_t dht_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata); int32_t dht_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata); int32_t dht_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata); int32_t dht_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata); int32_t dht_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata); int32_t dht_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata); int32_t dht_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata); int32_t dht_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata); int32_t dht_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata); int32_t dht_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata); int32_t dht_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata); int32_t dht_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata); int32_t dht_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata); int32_t dht_lease(call_frame_t *frame, xlator_t *this, loc_t *loc, struct gf_lease *lease, dict_t *xdata); int32_t dht_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata); int32_t dht_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata); int32_t dht_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata); int32_t dht_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata); int32_t dht_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata); int32_t dht_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *dict); int32_t dht_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata); int32_t dht_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata); int32_t dht_forget(xlator_t *this, inode_t *inode); int32_t dht_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata); int32_t dht_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata); int32_t dht_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata); int32_t dht_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata); int32_t dht_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata); int32_t dht_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata); int dht_set_subvol_range(xlator_t *this); int32_t dht_init(xlator_t *this); void dht_fini(xlator_t *this); int dht_reconfigure(xlator_t *this, dict_t *options); int32_t dht_notify(xlator_t *this, int32_t event, void *data, ...); /* definitions for nufa/switch */ int dht_revalidate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent); int dht_lookup_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent); int dht_lookup_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent); int dht_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent); int dht_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata); int dht_newfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata); int dht_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata); int dht_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata); int dht_common_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata); int gf_defrag_status_get(xlator_t *this, dht_conf_t *conf, dict_t *dict, gf_boolean_t log_status); int gf_defrag_stop(dht_conf_t *conf, gf_defrag_status_t status, dict_t *output); void * gf_defrag_start(void *this); int32_t gf_defrag_handle_hardlink(xlator_t *this, loc_t *loc, int *fop_errno); int dht_inode_ctx_layout_get(inode_t *inode, xlator_t *this, dht_layout_t **layout_int); int dht_inode_ctx_layout_set(inode_t *inode, xlator_t *this, dht_layout_t *layout_int); int dht_inode_ctx_time_update(inode_t *inode, xlator_t *this, struct iatt *prestat, struct iatt *poststat); void dht_inode_ctx_time_set(inode_t *inode, xlator_t *this, struct iatt *stat); int dht_inode_ctx_get(inode_t *inode, xlator_t *this, dht_inode_ctx_t **ctx); int dht_inode_ctx_set(inode_t *inode, xlator_t *this, dht_inode_ctx_t *ctx); int dht_dir_attr_heal(void *data); int dht_dir_attr_heal_done(int ret, call_frame_t *sync_frame, void *data); xlator_t * dht_subvol_with_free_space_inodes(xlator_t *this, xlator_t *subvol, xlator_t *ignore, dht_layout_t *layout, uint64_t filesize); xlator_t * dht_subvol_maxspace_nonzeroinode(xlator_t *this, xlator_t *subvol, dht_layout_t *layout); int dht_dir_has_layout(dict_t *xattr, char *name); int dht_linkfile_attr_heal(call_frame_t *frame, xlator_t *this); int32_t dht_priv_dump(xlator_t *this); int32_t dht_inodectx_dump(xlator_t *this, inode_t *inode); gf_boolean_t dht_is_subvol_in_layout(dht_layout_t *layout, xlator_t *xlator); int dht_inode_ctx_get_mig_info(xlator_t *this, inode_t *inode, xlator_t **src_subvol, xlator_t **dst_subvol); gf_boolean_t dht_mig_info_is_invalid(xlator_t *current, xlator_t *src_subvol, xlator_t *dst_subvol); int dht_subvol_status(dht_conf_t *conf, xlator_t *subvol); void dht_log_new_layout_for_dir_selfheal(xlator_t *this, loc_t *loc, dht_layout_t *layout); void dht_layout_sort(dht_layout_t *layout); int dht_heal_full_path(void *data); int dht_heal_full_path_done(int op_ret, call_frame_t *frame, void *data); int dht_layout_missing_dirs(dht_layout_t *layout); int dht_refresh_layout(call_frame_t *frame); int dht_build_parent_loc(xlator_t *this, loc_t *parent, loc_t *child, int32_t *op_errno); int32_t dht_set_local_rebalance(xlator_t *this, dht_local_t *local, struct iatt *stbuf, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); void dht_build_root_loc(inode_t *inode, loc_t *loc); gf_boolean_t dht_fd_open_on_dst(xlator_t *this, fd_t *fd, xlator_t *dst); int32_t dht_fd_ctx_destroy(xlator_t *this, fd_t *fd); int32_t dht_release(xlator_t *this, fd_t *fd); int32_t dht_set_fixed_dir_stat(struct iatt *stat); xlator_t * dht_get_lock_subvolume(xlator_t *this, struct gf_flock *lock, dht_local_t *local); int dht_lk_inode_unref(call_frame_t *frame, int32_t op_ret); int dht_fd_ctx_set(xlator_t *this, fd_t *fd, xlator_t *subvol); int dht_check_and_open_fd_on_subvol(xlator_t *this, call_frame_t *frame); /* FD fop callbacks */ int dht_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); int dht_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata); int dht_file_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); int dht_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); int dht_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); int dht_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); int dht_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); int dht_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); int dht_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iovec *vector, int count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata); int dht_file_attr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *stbuf, dict_t *xdata); int dht_file_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata); int dht_file_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata); /* All custom xattr heal functions */ int dht_dir_heal_xattrs(void *data); int dht_dir_heal_xattrs_done(int ret, call_frame_t *sync_frame, void *data); int32_t dht_dict_set_array(dict_t *dict, char *key, int32_t value[], int32_t size); int dht_set_user_xattr(dict_t *dict, char *k, data_t *v, void *data); void dht_dir_set_heal_xattr(xlator_t *this, dht_local_t *local, dict_t *dst, dict_t *src, int *uret, int *uflag); int dht_dir_xattr_heal(xlator_t *this, dht_local_t *local, int *op_errno); int dht_common_mark_mdsxattr(call_frame_t *frame, int *errst, int flag); int dht_inode_ctx_mdsvol_get(inode_t *inode, xlator_t *this, xlator_t **mdsvol); int dht_selfheal_dir_setattr(call_frame_t *frame, loc_t *loc, struct iatt *stbuf, int32_t valid, dht_layout_t *layout); /* Abstract out the DHT-IATT-IN-DICT */ void dht_selfheal_layout_new_directory(call_frame_t *frame, loc_t *loc, dht_layout_t *new_layout); int dht_pt_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key, dict_t *xdata); int dht_pt_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, dict_t *xdata); int32_t dht_pt_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata); int dht_pt_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata); int32_t dht_check_remote_fd_failed_error(dht_local_t *local, int op_ret, int op_errno); int dht_common_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata); int32_t dht_create_lock(call_frame_t *frame, xlator_t *subvol); int dht_set_parent_layout_in_dict(loc_t *loc, xlator_t *this, dht_local_t *local); int dht_dir_layout_error_check(xlator_t *this, inode_t *inode); int dht_inode_ctx_mdsvol_set(inode_t *inode, xlator_t *this, xlator_t *mds_subvol); int dht_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, off_t offset, dict_t *xdata); #endif /* _DHT_H */ glusterfs-11.1/xlators/cluster/dht/src/PaxHeaders.9031/dht-hashfn.c0000644000000000000000000000013214522202451023273 xustar000000000000000030 mtime=1699284265.624027302 30 atime=1699284265.624027302 30 ctime=1699284301.227134538 glusterfs-11.1/xlators/cluster/dht/src/dht-hashfn.c0000664000175100017510000000527514522202451023563 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "dht-common.h" #include static int dht_hash_compute_internal(int type, const char *name, const int len, uint32_t *hash_p) { int ret = 0; uint32_t hash = 0; switch (type) { case DHT_HASH_TYPE_DM: case DHT_HASH_TYPE_DM_USER: hash = gf_dm_hashfn(name, len); break; default: ret = -1; break; } if (ret == 0) { *hash_p = hash; } return ret; } /* The function returns: * 0 : in case no munge took place * >0 : the length (inc. terminating NULL!) of the newly modified string, * if it was munged. */ static int dht_munge_name(const char *original, char *modified, size_t len, regex_t *re) { regmatch_t matches[2] = { {0}, }; size_t new_len = 0; int ret = 0; ret = regexec(re, original, 2, matches, 0); if (ret == 0) { if (matches[1].rm_so != -1) { new_len = matches[1].rm_eo - matches[1].rm_so; /* Equal would fail due to the NUL at the end. */ if (new_len < len) { memcpy(modified, original + matches[1].rm_so, new_len); modified[new_len] = '\0'; return new_len + 1; } } } return 0; } int dht_hash_compute(xlator_t *this, int type, const char *name, uint32_t *hash_p) { char *rsync_friendly_name = NULL; dht_conf_t *priv = NULL; size_t len = 0; int munged = 0; if (caa_unlikely(name == NULL)) return -1; len = strlen(name) + 1; rsync_friendly_name = alloca(len); priv = this->private; LOCK(&priv->lock); { if (priv->extra_regex_valid) { munged = dht_munge_name(name, rsync_friendly_name, len, &priv->extra_regex); } if (!munged && priv->rsync_regex_valid) { munged = dht_munge_name(name, rsync_friendly_name, len, &priv->rsync_regex); } } UNLOCK(&priv->lock); if (munged) { gf_msg_debug(this->name, 0, "munged down to %s", rsync_friendly_name); len = munged; } else { rsync_friendly_name = (char *)name; } return dht_hash_compute_internal(type, rsync_friendly_name, len - 1, hash_p); } glusterfs-11.1/xlators/cluster/dht/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202462022363 xustar000000000000000030 mtime=1699284274.482053983 30 atime=1699284289.065097907 30 ctime=1699284301.166134355 glusterfs-11.1/xlators/cluster/dht/Makefile.in0000664000175100017510000005261114522202462022647 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/cluster/dht DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/cluster/dht/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/cluster/dht/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/cluster/dht/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451022350 xustar000000000000000030 mtime=1699284265.621027293 30 atime=1699284274.457053908 30 ctime=1699284301.167134358 glusterfs-11.1/xlators/cluster/dht/Makefile.am0000664000175100017510000000001514522202451022623 0ustar00jenkinsjenkins00000000000000SUBDIRS = srcglusterfs-11.1/xlators/cluster/PaxHeaders.9031/afr0000644000000000000000000000013214522202515020231 xustar000000000000000030 mtime=1699284301.049134002 30 atime=1699284309.685160013 30 ctime=1699284301.049134002 glusterfs-11.1/xlators/cluster/afr/0002775000175100017510000000000014522202515020567 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/cluster/afr/PaxHeaders.9031/src0000644000000000000000000000013214522202515021020 xustar000000000000000030 mtime=1699284301.132134252 30 atime=1699284309.685160013 30 ctime=1699284301.132134252 glusterfs-11.1/xlators/cluster/afr/src/0002775000175100017510000000000014522202515021356 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-read-txn.c0000644000000000000000000000013214522202451023530 xustar000000000000000030 mtime=1699284265.616027278 30 atime=1699284265.616027278 30 ctime=1699284301.120134216 glusterfs-11.1/xlators/cluster/afr/src/afr-read-txn.c0000664000175100017510000003374614522202451024024 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "afr-transaction.h" #include "afr-messages.h" void afr_pending_read_increment(afr_private_t *priv, int child_index) { if (child_index < 0 || child_index > priv->child_count) return; GF_ATOMIC_INC(priv->pending_reads[child_index]); } void afr_pending_read_decrement(afr_private_t *priv, int child_index) { if (child_index < 0 || child_index > priv->child_count) return; GF_ATOMIC_DEC(priv->pending_reads[child_index]); } void afr_read_txn_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; afr_pending_read_decrement(priv, local->read_subvol); local->read_subvol = subvol; afr_pending_read_increment(priv, subvol); local->readfn(frame, this, subvol); } static int afr_read_txn_next_subvol(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; int subvol = -1; local = frame->local; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!local->readable[i]) { /* don't even bother trying here. just mark as attempted and move on. */ local->read_attempted[i] = 1; continue; } if (!local->read_attempted[i]) { subvol = i; break; } } /* If no more subvols were available for reading, we leave @subvol as -1, which is an indication we have run out of readable subvols. */ if (subvol != -1) local->read_attempted[subvol] = 1; afr_read_txn_wind(frame, this, subvol); return 0; } static int afr_ta_read_txn_done(int ret, call_frame_t *ta_frame, void *opaque) { STACK_DESTROY(ta_frame->root); return 0; } static int afr_ta_read_txn(void *opaque) { call_frame_t *frame = NULL; xlator_t *this = NULL; int read_subvol = -1; int query_child = AFR_CHILD_UNKNOWN; int possible_bad_child = AFR_CHILD_UNKNOWN; int ret = 0; int op_errno = ENOMEM; afr_local_t *local = NULL; afr_private_t *priv = NULL; struct gf_flock flock = { 0, }; dict_t *xdata_req = NULL; dict_t *xdata_rsp = NULL; int **pending = NULL; loc_t loc = { 0, }; frame = (call_frame_t *)opaque; this = frame->this; local = frame->local; priv = this->private; query_child = local->read_txn_query_child; if (query_child == AFR_CHILD_ZERO) { possible_bad_child = AFR_CHILD_ONE; } else if (query_child == AFR_CHILD_ONE) { possible_bad_child = AFR_CHILD_ZERO; } else { /*read_txn_query_child is AFR_CHILD_UNKNOWN*/ goto out; } /* Ask the query_child to see if it blames the possibly bad one. */ xdata_req = dict_new(); if (!xdata_req) goto out; pending = afr_matrix_create(priv->child_count, AFR_NUM_CHANGE_LOGS); if (!pending) goto out; ret = afr_set_pending_dict(priv, xdata_req, pending); if (ret < 0) goto out; if (local->fd) { ret = syncop_fxattrop(priv->children[query_child], local->fd, GF_XATTROP_ADD_ARRAY, xdata_req, NULL, &xdata_rsp, NULL); } else { ret = syncop_xattrop(priv->children[query_child], &local->loc, GF_XATTROP_ADD_ARRAY, xdata_req, NULL, &xdata_rsp, NULL); } if (ret || !xdata_rsp) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed xattrop for gfid %s on %s", uuid_utoa(local->inode->gfid), priv->children[query_child]->name); op_errno = -ret; goto out; } if (afr_ta_dict_contains_pending_xattr(xdata_rsp, priv, possible_bad_child)) { read_subvol = query_child; goto out; } dict_unref(xdata_rsp); xdata_rsp = NULL; /* It doesn't. So query thin-arbiter to see if it blames any data brick. */ ret = afr_fill_ta_loc(this, &loc, _gf_true); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to populate thin-arbiter loc for: %s.", loc.name); goto out; } flock.l_type = F_WRLCK; /*start and length are already zero. */ ret = syncop_inodelk(priv->children[THIN_ARBITER_BRICK_INDEX], AFR_TA_DOM_MODIFY, &loc, F_SETLKW, &flock, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "gfid:%s: Failed to get AFR_TA_DOM_MODIFY lock on %s.", uuid_utoa(local->inode->gfid), priv->pending_key[THIN_ARBITER_BRICK_INDEX]); op_errno = -ret; goto out; } ret = syncop_xattrop(priv->children[THIN_ARBITER_BRICK_INDEX], &loc, GF_XATTROP_ADD_ARRAY, xdata_req, NULL, &xdata_rsp, NULL); if (ret || !xdata_rsp) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "gfid:%s: Failed xattrop on %s.", uuid_utoa(local->inode->gfid), priv->pending_key[THIN_ARBITER_BRICK_INDEX]); op_errno = -ret; goto unlock; } if (!afr_ta_dict_contains_pending_xattr(xdata_rsp, priv, query_child)) { read_subvol = query_child; } else { gf_msg(this->name, GF_LOG_ERROR, EIO, AFR_MSG_THIN_ARB, "Failing read for gfid %s since good brick %s is down", uuid_utoa(local->inode->gfid), priv->children[possible_bad_child]->name); op_errno = EIO; } unlock: flock.l_type = F_UNLCK; ret = syncop_inodelk(priv->children[THIN_ARBITER_BRICK_INDEX], AFR_TA_DOM_MODIFY, &loc, F_SETLK, &flock, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "gfid:%s: Failed to unlock AFR_TA_DOM_MODIFY lock on " "%s.", uuid_utoa(local->inode->gfid), priv->pending_key[THIN_ARBITER_BRICK_INDEX]); } out: if (xdata_req) dict_unref(xdata_req); if (xdata_rsp) dict_unref(xdata_rsp); if (pending) afr_matrix_cleanup(pending, priv->child_count); loc_wipe(&loc); if (read_subvol == -1) { local->op_ret = -1; local->op_errno = op_errno; } afr_read_txn_wind(frame, this, read_subvol); return ret; } static void afr_ta_read_txn_synctask(call_frame_t *frame, xlator_t *this) { call_frame_t *ta_frame = NULL; afr_local_t *local = NULL; int ret = 0; local = frame->local; ta_frame = afr_ta_frame_create(this); if (!ta_frame) { local->op_ret = -1; local->op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_THIN_ARB, "Failed to create ta_frame"); goto out; } ret = synctask_new(this->ctx->env, afr_ta_read_txn, afr_ta_read_txn_done, ta_frame, frame); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_THIN_ARB, "Failed to launch " "afr_ta_read_txn synctask for gfid %s.", uuid_utoa(local->inode->gfid)); local->op_ret = -1; local->op_errno = ENOMEM; STACK_DESTROY(ta_frame->root); goto out; } return; out: afr_read_txn_wind(frame, this, -1); } static int afr_read_txn_refresh_done(call_frame_t *frame, xlator_t *this, int err) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int read_subvol = -1; inode_t *inode = NULL; int ret = -1; int spb_subvol = -1; local = frame->local; inode = local->inode; priv = this->private; if (err) { if (!priv->thin_arbiter_count) goto readfn; if (err != EINVAL) goto readfn; /* We need to query the good bricks and/or thin-arbiter.*/ afr_ta_read_txn_synctask(frame, this); return 0; } read_subvol = afr_read_subvol_select_by_policy(inode, this, local->readable, NULL); if (read_subvol == -1) { err = EIO; goto readfn; } if (local->read_attempted[read_subvol]) { afr_read_txn_next_subvol(frame, this); return 0; } local->read_attempted[read_subvol] = 1; readfn: if (read_subvol == -1) { ret = afr_split_brain_read_subvol_get(inode, this, frame, &spb_subvol); if ((ret == 0) && spb_subvol >= 0) read_subvol = spb_subvol; } if (read_subvol == -1) { AFR_SET_ERROR_AND_CHECK_SPLIT_BRAIN(-1, err); } afr_read_txn_wind(frame, this, read_subvol); return 0; } int afr_read_txn_continue(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; local = frame->local; if (!local->refreshed) { local->refreshed = _gf_true; afr_inode_refresh(frame, this, local->inode, NULL, afr_read_txn_refresh_done); } else { afr_read_txn_next_subvol(frame, this); } return 0; } /* afr_read_txn_wipe: clean internal variables in @local in order to make it possible to call afr_read_txn() multiple times from the same frame */ static void afr_read_txn_wipe(call_frame_t *frame, unsigned int child_count) { afr_local_t *local = NULL; int i = 0; local = frame->local; local->readfn = NULL; if (local->inode) inode_unref(local->inode); for (i = 0; i < child_count; i++) { local->read_attempted[i] = 0; local->readable[i] = 0; } } /* afr_read_txn: This is the read transaction function. The way it works: - Determine read-subvolume from inode ctx. - If read-subvolume's generation was stale, refresh ctx once by calling afr_inode_refresh() Else make an attempt to read on read-subvolume. - If attempted read on read-subvolume fails, refresh ctx once by calling afr_inode_refresh() - After ctx refresh, query read-subvolume freshly and attempt read once. - If read fails, try every other readable[] subvolume before finally giving up. readable[] elements are set by afr_inode_refresh() based on dirty and pending flags. - If file is in split brain in the backend, generation will be kept 0 by afr_inode_refresh() and readable[] will be set 0 for all elements. Therefore reads always fail. */ int afr_read_txn(call_frame_t *frame, xlator_t *this, inode_t *inode, afr_read_txn_wind_t readfn, afr_transaction_type type) { afr_local_t *local = NULL; afr_private_t *priv = NULL; unsigned char *data = NULL; unsigned char *metadata = NULL; int read_subvol = -1; int event_generation = 0; int ret = -1; priv = this->private; local = frame->local; data = alloca0(priv->child_count); metadata = alloca0(priv->child_count); afr_read_txn_wipe(frame, priv->child_count); local->readfn = readfn; local->inode = inode_ref(inode); local->is_read_txn = _gf_true; local->transaction.type = type; if (priv->quorum_count && !afr_has_quorum(local->child_up, priv, NULL)) { local->op_ret = -1; local->op_errno = afr_quorum_errno(priv); goto read; } if (!afr_is_consistent_io_possible(local, priv, &local->op_errno)) { local->op_ret = -1; goto read; } if (priv->thin_arbiter_count && !afr_ta_has_quorum(priv, local)) { local->op_ret = -1; local->op_errno = -afr_quorum_errno(priv); goto read; } if (priv->thin_arbiter_count && AFR_COUNT(local->child_up, priv->child_count) != priv->child_count) { if (local->child_up[0]) { local->read_txn_query_child = AFR_CHILD_ZERO; } else if (local->child_up[1]) { local->read_txn_query_child = AFR_CHILD_ONE; } afr_ta_read_txn_synctask(frame, this); return 0; } ret = afr_inode_read_subvol_get(inode, this, data, metadata, &event_generation); if (ret == -1) /* very first transaction on this inode */ goto refresh; AFR_INTERSECT(local->readable, data, metadata, priv->child_count); gf_msg_debug(this->name, 0, "%s: generation now vs cached: %d, " "%d", uuid_utoa(inode->gfid), local->event_generation, event_generation); if (afr_is_inode_refresh_reqd(inode, this, local->event_generation, event_generation)) /* servers have disconnected / reconnected, and possibly rebooted, very likely changing the state of freshness of copies */ goto refresh; read_subvol = afr_read_subvol_select_by_policy(inode, this, local->readable, NULL); if (read_subvol < 0 || read_subvol > priv->child_count) { gf_msg_debug(this->name, 0, "Unreadable subvolume %d found " "with event generation %d for gfid %s.", read_subvol, event_generation, uuid_utoa(inode->gfid)); goto refresh; } if (!local->child_up[read_subvol]) { /* should never happen, just in case */ gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_READ_SUBVOL_ERROR, "subvolume %d is the " "read subvolume in this generation, but is not up", read_subvol); goto refresh; } local->read_attempted[read_subvol] = 1; read: afr_read_txn_wind(frame, this, read_subvol); return 0; refresh: afr_inode_refresh(frame, this, inode, NULL, afr_read_txn_refresh_done); return 0; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-open.c0000644000000000000000000000013214522202451022747 xustar000000000000000030 mtime=1699284265.616027278 30 atime=1699284265.615027275 30 ctime=1699284301.115134201 glusterfs-11.1/xlators/cluster/afr/src/afr-open.c0000664000175100017510000003676714522202451023251 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include "afr-transaction.h" #include "afr-self-heal.h" #include "protocol-common.h" static gf_boolean_t afr_is_fd_fixable(fd_t *fd) { if (!fd || !fd->inode) return _gf_false; else if (fd_is_anonymous(fd)) return _gf_false; else if (gf_uuid_is_null(fd->inode->gfid)) return _gf_false; return _gf_true; } static int afr_open_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { afr_local_t *local = frame->local; AFR_STACK_UNWIND(open, frame, local->op_ret, local->op_errno, local->cont.open.fd, xdata); return 0; } static int afr_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { afr_local_t *local = NULL; int call_count = -1; int child_index = (long)cookie; afr_fd_ctx_t *fd_ctx = NULL; local = frame->local; fd_ctx = local->fd_ctx; local->replies[child_index].valid = 1; local->replies[child_index].op_ret = op_ret; local->replies[child_index].op_errno = op_errno; LOCK(&frame->lock); { if (op_ret == -1) { local->op_errno = op_errno; fd_ctx->opened_on[child_index] = AFR_FD_NOT_OPENED; } else { local->op_ret = op_ret; fd_ctx->opened_on[child_index] = AFR_FD_OPENED; if (!local->xdata_rsp && xdata) local->xdata_rsp = dict_ref(xdata); } call_count = --local->call_count; } UNLOCK(&frame->lock); if (call_count == 0) { afr_handle_replies_quorum(frame, this); if (local->op_ret == -1) { AFR_STACK_UNWIND(open, frame, local->op_ret, local->op_errno, NULL, NULL); } else if (fd_ctx->flags & O_TRUNC) { STACK_WIND(frame, afr_open_ftruncate_cbk, this, this->fops->ftruncate, fd, 0, NULL); } else { AFR_STACK_UNWIND(open, frame, local->op_ret, local->op_errno, local->cont.open.fd, local->xdata_rsp); } } return 0; } static int afr_open_continue(call_frame_t *frame, xlator_t *this, int err) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int call_count = 0; int i = 0; local = frame->local; priv = this->private; if (err) { AFR_STACK_UNWIND(open, frame, -1, err, NULL, NULL); } else { local->call_count = AFR_COUNT(local->child_up, priv->child_count); call_count = local->call_count; for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { STACK_WIND_COOKIE(frame, afr_open_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->open, &local->loc, (local->cont.open.flags & ~O_TRUNC), local->cont.open.fd, local->xdata_req); if (!--call_count) break; } } } return 0; } int afr_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int spb_subvol = 0; int event_generation = 0; int ret = 0; int32_t op_errno = 0; afr_fd_ctx_t *fd_ctx = NULL; // We can't let truncation to happen outside transaction. priv = this->private; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_OPEN; fd_ctx = afr_fd_ctx_get(fd, this); if (!fd_ctx) { op_errno = ENOMEM; goto out; } if (priv->quorum_count && !afr_has_quorum(local->child_up, priv, NULL)) { op_errno = afr_quorum_errno(priv); goto out; } if (!afr_is_consistent_io_possible(local, priv, &op_errno)) goto out; local->inode = inode_ref(loc->inode); loc_copy(&local->loc, loc); local->fd_ctx = fd_ctx; fd_ctx->flags = flags; if (xdata) local->xdata_req = dict_ref(xdata); local->cont.open.flags = flags; local->cont.open.fd = fd_ref(fd); ret = afr_inode_get_readable(frame, local->inode, this, NULL, &event_generation, AFR_DATA_TRANSACTION); if ((ret < 0) && (afr_split_brain_read_subvol_get(local->inode, this, NULL, &spb_subvol) == 0) && spb_subvol < 0) { afr_inode_refresh(frame, this, local->inode, local->inode->gfid, afr_open_continue); } else { afr_open_continue(frame, this, 0); } return 0; out: AFR_STACK_UNWIND(open, frame, -1, op_errno, fd, NULL); return 0; } static int afr_openfd_fix_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; afr_fd_ctx_t *fd_ctx = NULL; int call_count = 0; int child_index = (long)cookie; priv = this->private; local = frame->local; if (op_ret >= 0) { gf_msg_debug(this->name, 0, "fd for %s opened " "successfully on subvolume %s", local->loc.path, priv->children[child_index]->name); } else { gf_smsg(this->name, fop_log_level(GF_FOP_OPEN, op_errno), op_errno, AFR_MSG_OPEN_FAIL, "path=%s", local->loc.path, "subvolume=%s", priv->children[child_index]->name, NULL); } fd_ctx = local->fd_ctx; LOCK(&local->fd->lock); { if (op_ret >= 0) { fd_ctx->opened_on[child_index] = AFR_FD_OPENED; } else { fd_ctx->opened_on[child_index] = AFR_FD_NOT_OPENED; } } UNLOCK(&local->fd->lock); call_count = afr_frame_return(frame); if (call_count == 0) AFR_STACK_DESTROY(frame); return 0; } static void afr_fd_ctx_reset_need_open(fd_t *fd, xlator_t *this, unsigned char *need_open) { afr_fd_ctx_t *fd_ctx = NULL; afr_private_t *priv = NULL; int i = 0; priv = this->private; fd_ctx = afr_fd_ctx_get(fd, this); if (!fd_ctx) return; LOCK(&fd->lock); { for (i = 0; i < priv->child_count; i++) { if (fd_ctx->opened_on[i] == AFR_FD_OPENING && need_open[i]) { fd_ctx->opened_on[i] = AFR_FD_NOT_OPENED; need_open[i] = 0; } } } UNLOCK(&fd->lock); } static int afr_fd_ctx_set_need_open(fd_t *fd, xlator_t *this, unsigned char *need_open) { afr_fd_ctx_t *fd_ctx = NULL; afr_private_t *priv = NULL; int i = 0; int count = 0; priv = this->private; fd_ctx = afr_fd_ctx_get(fd, this); if (!fd_ctx) return 0; LOCK(&fd->lock); { for (i = 0; i < priv->child_count; i++) { if (fd_ctx->opened_on[i] == AFR_FD_NOT_OPENED && priv->child_up[i]) { fd_ctx->opened_on[i] = AFR_FD_OPENING; need_open[i] = 1; count++; } else { need_open[i] = 0; } } } UNLOCK(&fd->lock); return count; } static int afr_do_fix_open(call_frame_t *frame, xlator_t *this) { afr_local_t *local = frame->local; afr_private_t *priv = NULL; int i = 0; int need_open_count = 0; priv = this->private; need_open_count = AFR_COUNT(local->need_open, priv->child_count); if (!need_open_count) { goto out; } gf_msg_debug(this->name, 0, "need open count: %d", need_open_count); local->call_count = need_open_count; for (i = 0; i < priv->child_count; i++) { if (!local->need_open[i]) continue; if (IA_IFDIR == local->fd->inode->ia_type) { gf_msg_debug(this->name, 0, "opening fd for dir %s on subvolume %s", local->loc.path, priv->children[i]->name); STACK_WIND_COOKIE(frame, afr_openfd_fix_open_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->opendir, &local->loc, local->fd, NULL); } else { gf_msg_debug(this->name, 0, "opening fd for file %s on subvolume %s", local->loc.path, priv->children[i]->name); STACK_WIND_COOKIE( frame, afr_openfd_fix_open_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->open, &local->loc, local->fd_ctx->flags & ~(O_CREAT | O_EXCL | O_TRUNC), local->fd, NULL); } if (!--need_open_count) break; } return 0; out: afr_fd_ctx_reset_need_open(local->fd, this, local->need_open); AFR_STACK_DESTROY(frame); return 0; } static int afr_is_reopen_allowed_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { afr_local_t *local = frame->local; afr_private_t *priv = NULL; int ret = -1; int call_count = 0; int i = (long)cookie; int32_t fd_reopen_status = -1; int32_t final_reopen_status = -1; priv = this->private; local->replies[i].valid = 1; local->replies[i].op_ret = op_ret; local->replies[i].op_errno = op_errno; if (op_ret != 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, AFR_MSG_DICT_GET_FAILED, "Failed getlk for %s", uuid_utoa(local->fd->inode->gfid)); } if (xdata) local->replies[i].xdata = dict_ref(xdata); call_count = afr_frame_return(frame); if (call_count) return 0; /* Currently we get 3 values from the lower layer (protocol/client) in the * getlk_cbk. * FD_REOPEN_ALLOWED : No conflicting locks are held and reopen is allowed * FD_REOPEN_NOT_ALLOWED : Conflicting locks are held and reopen is not * allowed * FD_BAD : FD is not valid * * - If we get FD_REOPEN_NOT_ALLOWED from any of the bricks, will block the * reopen taking this as high priority. * - If we get FD_BAD from all the replies, we will not reopen since we do * not know the correct status. * - If we get FD_BAD from few brick and FD_REOPEN_NOT_ALLOWED from one or * more bricks, then we will block reopen. * - If we get FD_BAD from few bricks and FD_REOPEN_ALLOWED from one or * more bricks, then we will allow the reopen. * * We will update the final_reopen_status only when the value returned * from lower layer is >= FD_REOPEN_ALLOWED and < FD_BAD. We will not set * FD_BAD in final_reopen_status, since it can lead to unexpected * behaviours. * * At the end of this loop, if we still have final_reopen_status as -1 * i.e., the init value, it means we failed to get the fd status from any * of the bricks or we do not have a valid fd on any of the bricks. We * will not reopen the fd in this case as well. */ for (i = 0; i < priv->child_count; i++) { if (final_reopen_status != FD_REOPEN_NOT_ALLOWED && local->replies[i].xdata) { ret = dict_get_int32(xdata, "fd-reopen-status", &fd_reopen_status); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_GET_FAILED, "Failed to get whether reopen is allowed or not on fd " "for file %s on subvolume %s.", local->loc.path, priv->children[i]->name); } else if (fd_reopen_status >= FD_REOPEN_ALLOWED && fd_reopen_status < FD_BAD) { final_reopen_status = fd_reopen_status; } } if (final_reopen_status == FD_REOPEN_NOT_ALLOWED) break; } if (final_reopen_status == FD_REOPEN_NOT_ALLOWED) { gf_log(this->name, GF_LOG_INFO, "Conflicting locks held on file %s. FD reopen is not allowed.", local->loc.path); } else if (final_reopen_status == -1) { gf_log(this->name, GF_LOG_INFO, "Failed to get the lock information " "on file %s. FD reopen is not allowed.", local->loc.path); } else { afr_local_replies_wipe(local, priv); afr_do_fix_open(frame, this); return 0; } afr_fd_ctx_reset_need_open(local->fd, this, local->need_open); AFR_STACK_DESTROY(frame); return 0; } static void afr_is_reopen_allowed(xlator_t *this, call_frame_t *frame) { afr_private_t *priv = NULL; afr_local_t *local = NULL; dict_t *xdata = NULL; int i = 0; int call_count = 0; struct gf_flock flock = { 0, }; local = frame->local; priv = this->private; flock.l_type = F_WRLCK; afr_set_lk_owner(frame, this, frame->root); lk_owner_copy(&flock.l_owner, &frame->root->lk_owner); call_count = AFR_COUNT(local->child_up, priv->child_count); if (!call_count) goto out; local->call_count = call_count; xdata = dict_new(); if (xdata == NULL) goto out; if (dict_set_int32(xdata, "fd-reopen-status", -1)) goto out; for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { STACK_WIND_COOKIE(frame, afr_is_reopen_allowed_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->lk, local->fd, F_GETLK, &flock, xdata); } else { continue; } if (!--call_count) break; } dict_unref(xdata); return; out: if (xdata) dict_unref(xdata); afr_fd_ctx_reset_need_open(local->fd, this, local->need_open); AFR_STACK_DESTROY(frame); return; } void afr_fix_open(fd_t *fd, xlator_t *this) { call_frame_t *frame = NULL; afr_local_t *local = NULL; int ret = -1; int32_t op_errno = 0; afr_fd_ctx_t *fd_ctx = NULL; int call_count = 0; if (!afr_is_fd_fixable(fd)) goto out; fd_ctx = afr_fd_ctx_get(fd, this); if (!fd_ctx) goto out; frame = create_frame(this, this->ctx->pool); if (!frame) goto out; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; call_count = afr_fd_ctx_set_need_open(fd, this, local->need_open); if (!call_count) goto out; local->loc.inode = inode_ref(fd->inode); ret = loc_path(&local->loc, NULL); if (ret < 0) goto out; local->fd = fd_ref(fd); local->fd_ctx = fd_ctx; afr_is_reopen_allowed(this, frame); return; out: if (call_count) afr_fd_ctx_reset_need_open(fd, this, local->need_open); if (frame) AFR_STACK_DESTROY(frame); return; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-self-heald.c0000644000000000000000000000013214522202451024012 xustar000000000000000030 mtime=1699284265.619027287 30 atime=1699284265.618027284 30 ctime=1699284301.129134243 glusterfs-11.1/xlators/cluster/afr/src/afr-self-heald.c0000664000175100017510000013165414522202451024303 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "afr.h" #include "afr-self-heal.h" #include "afr-self-heald.h" #include "protocol-common.h" #include #include "afr-messages.h" #define AFR_EH_SPLIT_BRAIN_LIMIT 1024 #define AFR_STATISTICS_HISTORY_SIZE 50 #define ASSERT_LOCAL(this, healer) \ if (!afr_shd_is_subvol_local(this, healer->subvol)) { \ healer->local = _gf_false; \ if (safe_break(healer)) { \ break; \ } else { \ continue; \ } \ } else { \ healer->local = _gf_true; \ } #define NTH_INDEX_HEALER(this, n) \ &((((afr_private_t *)this->private))->shd.index_healers[n]) #define NTH_FULL_HEALER(this, n) \ &((((afr_private_t *)this->private))->shd.full_healers[n]) static char * afr_subvol_name(xlator_t *this, int subvol) { afr_private_t *priv = NULL; priv = this->private; if (subvol < 0 || subvol > priv->child_count) return NULL; return priv->children[subvol]->name; } static void afr_destroy_crawl_event_data(void *data) { return; } static void afr_destroy_shd_event_data(void *data) { shd_event_t *shd_event = data; if (!shd_event) return; GF_FREE(shd_event->path); return; } static gf_boolean_t afr_shd_is_subvol_local(xlator_t *this, int subvol) { afr_private_t *priv = NULL; gf_boolean_t is_local = _gf_false; loc_t loc = { 0, }; loc.inode = this->itable->root; gf_uuid_copy(loc.gfid, loc.inode->gfid); priv = this->private; syncop_is_subvol_local(priv->children[subvol], &loc, &is_local); return is_local; } static int __afr_shd_healer_wait(struct subvol_healer *healer) { afr_private_t *priv = NULL; struct timespec wait_till = { 0, }; int ret = 0; priv = healer->this->private; disabled_loop: wait_till.tv_sec = gf_time() + priv->shd.timeout; while (!healer->rerun) { ret = pthread_cond_timedwait(&healer->cond, &healer->mutex, &wait_till); if (ret == ETIMEDOUT) break; } ret = healer->rerun; healer->rerun = 0; if (!priv->shd.enabled) goto disabled_loop; return ret; } static int afr_shd_healer_wait(struct subvol_healer *healer) { int ret = 0; pthread_mutex_lock(&healer->mutex); { ret = __afr_shd_healer_wait(healer); } pthread_mutex_unlock(&healer->mutex); return ret; } static gf_boolean_t safe_break(struct subvol_healer *healer) { gf_boolean_t ret = _gf_false; pthread_mutex_lock(&healer->mutex); { if (healer->rerun) goto unlock; healer->running = _gf_false; ret = _gf_true; } unlock: pthread_mutex_unlock(&healer->mutex); return ret; } static inode_t * afr_shd_inode_find(xlator_t *this, xlator_t *subvol, uuid_t gfid) { int ret = 0; uint64_t val = IA_INVAL; dict_t *xdata = NULL; dict_t *rsp_dict = NULL; inode_t *inode = NULL; xdata = dict_new(); if (!xdata) goto out; ret = dict_set_int8(xdata, GF_INDEX_IA_TYPE_GET_REQ, 1); if (ret) goto out; ret = syncop_inode_find(this, subvol, gfid, &inode, xdata, &rsp_dict); if (ret < 0) goto out; if (rsp_dict) { ret = dict_get_uint64(rsp_dict, GF_INDEX_IA_TYPE_GET_RSP, &val); if (ret) goto out; } ret = inode_ctx_set2(inode, subvol, 0, &val); out: if (ret && inode) { inode_unref(inode); inode = NULL; } if (xdata) dict_unref(xdata); if (rsp_dict) dict_unref(rsp_dict); return inode; } static inode_t * afr_shd_index_inode(xlator_t *this, xlator_t *subvol, char *vgfid) { loc_t rootloc = { 0, }; inode_t *inode = NULL; int ret = 0; dict_t *xattr = NULL; void *index_gfid = NULL; rootloc.inode = inode_ref(this->itable->root); gf_uuid_copy(rootloc.gfid, rootloc.inode->gfid); ret = syncop_getxattr(subvol, &rootloc, &xattr, vgfid, NULL, NULL); if (ret || !xattr) { errno = -ret; goto out; } ret = dict_get_ptr(xattr, vgfid, &index_gfid); if (ret) goto out; gf_msg_debug(this->name, 0, "%s dir gfid for %s: %s", vgfid, subvol->name, uuid_utoa(index_gfid)); inode = afr_shd_inode_find(this, subvol, index_gfid); out: loc_wipe(&rootloc); if (xattr) dict_unref(xattr); return inode; } int afr_shd_entry_purge(xlator_t *subvol, inode_t *inode, char *name, ia_type_t type) { int ret = 0; loc_t loc = { 0, }; loc.parent = inode_ref(inode); loc.name = name; if (IA_ISDIR(type)) ret = syncop_rmdir(subvol, &loc, 1, NULL, NULL); else ret = syncop_unlink(subvol, &loc, NULL, NULL); loc_wipe(&loc); return ret; } static void afr_shd_zero_xattrop(xlator_t *this, uuid_t gfid) { call_frame_t *frame = NULL; inode_t *inode = NULL; afr_private_t *priv = NULL; dict_t *xattr = NULL; int ret = 0; int i = 0; int raw[AFR_NUM_CHANGE_LOGS] = {0}; priv = this->private; frame = afr_frame_create(this, NULL); if (!frame) goto out; inode = afr_inode_find(this, gfid); if (!inode) goto out; xattr = dict_new(); if (!xattr) goto out; ret = dict_set_static_bin(xattr, AFR_DIRTY, raw, sizeof(int) * AFR_NUM_CHANGE_LOGS); if (ret) goto out; for (i = 0; i < priv->child_count; i++) { ret = dict_set_static_bin(xattr, priv->pending_key[i], raw, sizeof(int) * AFR_NUM_CHANGE_LOGS); if (ret) goto out; } /*Send xattrop to all bricks. Doing a lookup to see if bricks are up or * has valid repies for this gfid seems a bit of an overkill.*/ for (i = 0; i < priv->child_count; i++) afr_selfheal_post_op(frame, this, inode, i, xattr, NULL); out: if (frame) AFR_STACK_DESTROY(frame); if (inode) inode_unref(inode); if (xattr) dict_unref(xattr); return; } static int afr_shd_selfheal_name(struct subvol_healer *healer, int child, uuid_t parent, const char *bname) { int ret = -1; ret = afr_selfheal_name(THIS, parent, bname, NULL, NULL, NULL); return ret; } static int afr_shd_selfheal(struct subvol_healer *healer, int child, uuid_t gfid) { int ret = 0; eh_t *eh = NULL; afr_private_t *priv = NULL; afr_self_heald_t *shd = NULL; shd_event_t *shd_event = NULL; char *path = NULL; xlator_t *subvol = NULL; xlator_t *this = NULL; crawl_event_t *crawl_event = NULL; this = healer->this; priv = this->private; shd = &priv->shd; crawl_event = &healer->crawl_event; subvol = priv->children[child]; // If this fails with ENOENT/ESTALE index is stale ret = syncop_gfid_to_path(this->itable, subvol, gfid, &path); if (ret < 0) return ret; ret = afr_selfheal(this, gfid); LOCK(&priv->lock); { if (ret == -EIO) { eh = shd->split_brain; crawl_event->split_brain_count++; } else if (ret < 0) { crawl_event->heal_failed_count++; } else if (ret == 0) { crawl_event->healed_count++; } } UNLOCK(&priv->lock); if (eh) { shd_event = GF_CALLOC(1, sizeof(*shd_event), gf_afr_mt_shd_event_t); if (!shd_event) goto out; shd_event->child = child; shd_event->path = path; if (eh_save_history(eh, shd_event) < 0) goto out; shd_event = NULL; path = NULL; } out: GF_FREE(shd_event); GF_FREE(path); return ret; } static void afr_shd_sweep_prepare(struct subvol_healer *healer) { crawl_event_t *event = NULL; event = &healer->crawl_event; event->healed_count = 0; event->split_brain_count = 0; event->heal_failed_count = 0; event->start_time = gf_time(); event->end_time = 0; _mask_cancellation(); } static void afr_shd_sweep_done(struct subvol_healer *healer) { crawl_event_t *event = NULL; crawl_event_t *history = NULL; afr_self_heald_t *shd = NULL; event = &healer->crawl_event; shd = &(((afr_private_t *)healer->this->private)->shd); event->end_time = gf_time(); history = gf_memdup(event, sizeof(*event)); event->start_time = 0; if (!history) return; if (eh_save_history(shd->statistics[healer->subvol], history) < 0) GF_FREE(history); _unmask_cancellation(); } int afr_shd_index_heal(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { struct subvol_healer *healer = data; afr_private_t *priv = NULL; uuid_t gfid = {0}; int ret = 0; uint64_t val = IA_INVAL; priv = healer->this->private; if (!priv->shd.enabled) return -EBUSY; gf_msg_debug(healer->this->name, 0, "got entry: %s from %s", entry->d_name, priv->children[healer->subvol]->name); ret = gf_uuid_parse(entry->d_name, gfid); if (ret) return 0; inode_ctx_get2(parent->inode, subvol, NULL, &val); ret = afr_shd_selfheal(healer, healer->subvol, gfid); if (ret == -ENOENT || ret == -ESTALE) afr_shd_entry_purge(subvol, parent->inode, entry->d_name, val); if (ret == 2) /* If bricks crashed in pre-op after creating indices/xattrop * link but before setting afr changelogs, we end up with stale * xattrop links but zero changelogs. Remove such entries by * sending a post-op with zero changelogs. */ afr_shd_zero_xattrop(healer->this, gfid); return 0; } static int afr_shd_index_sweep(struct subvol_healer *healer, char *vgfid) { loc_t loc = {0}; afr_private_t *priv = NULL; int ret = 0; xlator_t *subvol = NULL; dict_t *xdata = NULL; call_frame_t *frame = NULL; priv = healer->this->private; subvol = priv->children[healer->subvol]; frame = afr_frame_create(healer->this, &ret); if (!frame) { ret = -ret; goto out; } loc.inode = afr_shd_index_inode(healer->this, subvol, vgfid); if (!loc.inode) { gf_msg(healer->this->name, GF_LOG_WARNING, 0, AFR_MSG_INDEX_DIR_GET_FAILED, "unable to get index-dir on %s", subvol->name); ret = -errno; goto out; } xdata = dict_new(); if (!xdata || dict_set_int32_sizen(xdata, "get-gfid-type", 1)) { ret = -ENOMEM; goto out; } ret = syncop_mt_dir_scan(frame, subvol, &loc, GF_CLIENT_PID_SELF_HEALD, healer, afr_shd_index_heal, xdata, priv->shd.max_threads, priv->shd.wait_qlength); if (ret == 0) ret = healer->crawl_event.healed_count; out: loc_wipe(&loc); if (xdata) dict_unref(xdata); if (frame) AFR_STACK_DESTROY(frame); return ret; } static int afr_shd_index_sweep_all(struct subvol_healer *healer) { int ret = 0; int count = 0; ret = afr_shd_index_sweep(healer, GF_XATTROP_INDEX_GFID); if (ret < 0) goto out; count = ret; ret = afr_shd_index_sweep(healer, GF_XATTROP_DIRTY_GFID); if (ret < 0) goto out; count += ret; ret = afr_shd_index_sweep(healer, GF_XATTROP_ENTRY_CHANGES_GFID); if (ret < 0) goto out; count += ret; out: if (ret < 0) return ret; else return count; } static int afr_shd_full_heal(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { struct subvol_healer *healer = data; xlator_t *this = healer->this; afr_private_t *priv = NULL; priv = this->private; if (this->cleanup_starting) { return -ENOTCONN; } if (!priv->shd.enabled) return -EBUSY; afr_shd_selfheal_name(healer, healer->subvol, parent->inode->gfid, entry->d_name); afr_shd_selfheal(healer, healer->subvol, entry->d_stat.ia_gfid); return 0; } static int afr_shd_full_sweep(struct subvol_healer *healer, inode_t *inode) { afr_private_t *priv = NULL; loc_t loc = {0}; priv = healer->this->private; loc.inode = inode; return syncop_ftw(priv->children[healer->subvol], &loc, GF_CLIENT_PID_SELF_HEALD, healer, afr_shd_full_heal); } static int afr_shd_fill_ta_loc(xlator_t *this, loc_t *loc) { afr_private_t *priv = NULL; struct iatt stbuf = { 0, }; int ret = -1; priv = this->private; loc->parent = inode_ref(this->itable->root); gf_uuid_copy(loc->pargfid, loc->parent->gfid); loc->name = priv->pending_key[THIN_ARBITER_BRICK_INDEX]; loc->inode = inode_new(loc->parent->table); GF_CHECK_ALLOC(loc->inode, ret, out); if (!gf_uuid_is_null(priv->ta_gfid)) goto assign_gfid; ret = syncop_lookup(priv->children[THIN_ARBITER_BRICK_INDEX], loc, &stbuf, 0, 0, 0); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed lookup on file %s.", loc->name); goto out; } gf_uuid_copy(priv->ta_gfid, stbuf.ia_gfid); assign_gfid: gf_uuid_copy(loc->gfid, priv->ta_gfid); ret = 0; out: if (ret) loc_wipe(loc); return ret; } static int _afr_shd_ta_get_xattrs(xlator_t *this, loc_t *loc, dict_t **xdata) { afr_private_t *priv = NULL; dict_t *xattr = NULL; int raw[AFR_NUM_CHANGE_LOGS] = { 0, }; int ret = -1; int i = 0; priv = this->private; xattr = dict_new(); if (!xattr) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_DICT_GET_FAILED, "Failed to create dict."); goto out; } for (i = 0; i < priv->child_count; i++) { ret = dict_set_static_bin(xattr, priv->pending_key[i], &raw, AFR_NUM_CHANGE_LOGS * sizeof(int)); if (ret) goto out; } ret = syncop_xattrop(priv->children[THIN_ARBITER_BRICK_INDEX], loc, GF_XATTROP_ADD_ARRAY, xattr, NULL, xdata, NULL); if (ret || !(*xdata)) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Xattrop failed on %s.", loc->name); } out: if (xattr) dict_unref(xattr); return ret; } static void afr_shd_ta_get_xattrs(xlator_t *this, loc_t *loc, struct subvol_healer *healer, dict_t **xdata) { int ret = 0; loc_wipe(loc); if (afr_shd_fill_ta_loc(this, loc)) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to populate thin-arbiter loc for: %s.", loc->name); ret = -1; goto out; } ret = afr_ta_post_op_lock(this, loc); if (ret) goto out; ret = _afr_shd_ta_get_xattrs(this, loc, xdata); if (ret) { if (*xdata) { dict_unref(*xdata); *xdata = NULL; } } afr_ta_post_op_unlock(this, loc); out: if (ret) healer->rerun = 1; } static int afr_shd_ta_unset_xattrs(xlator_t *this, loc_t *loc, dict_t **xdata, int healer) { afr_private_t *priv = NULL; dict_t *xattr = NULL; gf_boolean_t need_xattrop = _gf_false; void *pending_raw = NULL; int *raw = NULL; int i = 0; int j = 0; int val = 0; int ret = -1; priv = this->private; xattr = dict_new(); if (!xattr) { goto out; } for (i = 0; i < priv->child_count; i++) { raw = GF_CALLOC(AFR_NUM_CHANGE_LOGS, sizeof(int), gf_afr_mt_int32_t); if (!raw) { goto out; } ret = dict_get_ptr(*xdata, priv->pending_key[i], &pending_raw); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_GET_FAILED, "Error getting value " "of pending key %s", priv->pending_key[i]); GF_FREE(raw); goto out; } for (j = 0; j < AFR_NUM_CHANGE_LOGS; j++) { val = be32toh(*((int *)pending_raw + j)); if (val) { if (i == healer) { gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_THIN_ARB, "I am " "not the good shd. Skipping. " "SHD = %d.", healer); ret = 0; GF_FREE(raw); goto out; } need_xattrop = _gf_true; raw[j] = htobe32(-val); } } ret = dict_set_bin(xattr, priv->pending_key[i], raw, AFR_NUM_CHANGE_LOGS * sizeof(int)); if (ret) { GF_FREE(raw); goto out; } if (need_xattrop) break; } if (!need_xattrop) { ret = 0; goto out; } ret = syncop_xattrop(priv->children[THIN_ARBITER_BRICK_INDEX], loc, GF_XATTROP_ADD_ARRAY, xattr, NULL, NULL, NULL); if (ret) gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Xattrop failed."); out: if (xattr) dict_unref(xattr); return ret; } static void afr_shd_ta_check_and_unset_xattrs(xlator_t *this, loc_t *loc, struct subvol_healer *healer, dict_t *pre_crawl_xdata) { int ret_lock = 0; int ret = 0; dict_t *post_crawl_xdata = NULL; ret_lock = afr_ta_post_op_lock(this, loc); if (ret_lock) goto unref; ret = _afr_shd_ta_get_xattrs(this, loc, &post_crawl_xdata); if (ret) goto unref; if (!are_dicts_equal(pre_crawl_xdata, post_crawl_xdata, NULL, NULL, NULL)) { ret = -1; goto unref; } ret = afr_shd_ta_unset_xattrs(this, loc, &post_crawl_xdata, healer->subvol); unref: if (post_crawl_xdata) { dict_unref(post_crawl_xdata); post_crawl_xdata = NULL; } if (ret || ret_lock) healer->rerun = 1; if (!ret_lock) afr_ta_post_op_unlock(this, loc); } static gf_boolean_t afr_bricks_available_for_heal(afr_private_t *priv) { int up_children = 0; up_children = __afr_get_up_children_count(priv); if (up_children < 2) { return _gf_false; } return _gf_true; } static gf_boolean_t afr_shd_ta_needs_heal(xlator_t *this, struct subvol_healer *healer) { dict_t *xdata = NULL; afr_private_t *priv = NULL; loc_t loc = { 0, }; int ret = -1; int i = 0; gf_boolean_t need_heal = _gf_false; priv = this->private; ret = afr_shd_fill_ta_loc(this, &loc); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to populate thin-arbiter loc for: %s.", loc.name); healer->rerun = 1; goto out; } if (_afr_shd_ta_get_xattrs(this, &loc, &xdata)) { healer->rerun = 1; goto out; } for (i = 0; i < priv->child_count; i++) { if (afr_ta_dict_contains_pending_xattr(xdata, priv, i)) { need_heal = _gf_true; break; } } out: if (xdata) dict_unref(xdata); loc_wipe(&loc); return need_heal; } static int afr_shd_anon_inode_cleaner(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { struct subvol_healer *healer = data; afr_private_t *priv = healer->this->private; call_frame_t *frame = NULL; afr_local_t *local = NULL; int ret = 0; loc_t loc = {0}; int count = 0; int i = 0; int op_errno = 0; struct iatt *iatt = NULL; gf_boolean_t multiple_links = _gf_false; unsigned char *gfid_present = alloca0(priv->child_count); unsigned char *entry_present = alloca0(priv->child_count); char *type = "file"; frame = afr_frame_create(healer->this, &ret); if (!frame) { ret = -ret; goto out; } local = frame->local; if (AFR_COUNT(local->child_up, priv->child_count) != priv->child_count) { gf_msg_debug(healer->this->name, 0, "Not all bricks are up. Skipping " "cleanup of %s on %s", entry->d_name, subvol->name); ret = 0; goto out; } loc.inode = inode_new(parent->inode->table); if (!loc.inode) { ret = -ENOMEM; goto out; } ret = gf_uuid_parse(entry->d_name, loc.gfid); if (ret) { ret = 0; goto out; } AFR_ONLIST(local->child_up, frame, afr_selfheal_discover_cbk, lookup, &loc, NULL); for (i = 0; i < priv->child_count; i++) { if (local->replies[i].op_ret == 0) { count++; gfid_present[i] = 1; iatt = &local->replies[i].poststat; if (iatt->ia_type == IA_IFDIR) { type = "dir"; } if (i == healer->subvol) { if (local->replies[i].poststat.ia_nlink > 1) { multiple_links = _gf_true; } } } else if (local->replies[i].op_errno != ENOENT && local->replies[i].op_errno != ESTALE) { /*We don't have complete view. Skip the entry*/ gf_msg_debug(healer->this->name, local->replies[i].op_errno, "Skipping cleanup of %s on %s", entry->d_name, subvol->name); ret = 0; goto out; } } /*Inode is deleted from subvol*/ if (count == 1 || (iatt && iatt->ia_type != IA_IFDIR && multiple_links)) { gf_msg(healer->this->name, GF_LOG_WARNING, 0, AFR_MSG_EXPUNGING_FILE_OR_DIR, "expunging %s %s/%s on %s", type, priv->anon_inode_name, entry->d_name, subvol->name); ret = afr_shd_entry_purge(subvol, parent->inode, entry->d_name, iatt->ia_type); if (ret == -ENOENT || ret == -ESTALE) ret = 0; } else if (count > 1) { loc_wipe(&loc); loc.parent = inode_ref(parent->inode); loc.name = entry->d_name; loc.inode = inode_new(parent->inode->table); if (!loc.inode) { ret = -ENOMEM; goto out; } AFR_ONLIST(local->child_up, frame, afr_selfheal_discover_cbk, lookup, &loc, NULL); count = 0; for (i = 0; i < priv->child_count; i++) { if (local->replies[i].op_ret == 0) { count++; entry_present[i] = 1; iatt = &local->replies[i].poststat; } else if (local->replies[i].op_errno != ENOENT && local->replies[i].op_errno != ESTALE) { /*We don't have complete view. Skip the entry*/ gf_msg_debug(healer->this->name, local->replies[i].op_errno, "Skipping cleanup of %s on %s", entry->d_name, subvol->name); ret = 0; goto out; } } for (i = 0; i < priv->child_count; i++) { if (gfid_present[i] && !entry_present[i]) { /*Entry is not anonymous on at least one subvol*/ gf_msg_debug(healer->this->name, 0, "Valid entry present on %s " "Skipping cleanup of %s on %s", priv->children[i]->name, entry->d_name, subvol->name); ret = 0; goto out; } } gf_msg(healer->this->name, GF_LOG_WARNING, 0, AFR_MSG_EXPUNGING_FILE_OR_DIR, "expunging %s %s/%s on all subvols", type, priv->anon_inode_name, entry->d_name); ret = 0; for (i = 0; i < priv->child_count; i++) { op_errno = -afr_shd_entry_purge(priv->children[i], loc.parent, entry->d_name, iatt->ia_type); if (op_errno != ENOENT && op_errno != ESTALE) { ret |= -op_errno; } } } out: if (frame) AFR_STACK_DESTROY(frame); loc_wipe(&loc); return ret; } static void afr_cleanup_anon_inode_dir(struct subvol_healer *healer) { int ret = 0; call_frame_t *frame = NULL; afr_private_t *priv = healer->this->private; loc_t loc = {0}; ret = afr_anon_inode_create(healer->this, healer->subvol, &loc.inode); if (ret) goto out; frame = afr_frame_create(healer->this, &ret); if (!frame) { ret = -ret; goto out; } ret = syncop_mt_dir_scan(frame, priv->children[healer->subvol], &loc, GF_CLIENT_PID_SELF_HEALD, healer, afr_shd_anon_inode_cleaner, NULL, priv->shd.max_threads, priv->shd.wait_qlength); out: if (frame) AFR_STACK_DESTROY(frame); loc_wipe(&loc); return; } void * afr_shd_index_healer(void *data) { struct subvol_healer *healer = NULL; xlator_t *this = NULL; int ret = 0; afr_private_t *priv = NULL; dict_t *pre_crawl_xdata = NULL; loc_t loc = { 0, }; gf_lkowner_t lkowner; pid_t pid = GF_CLIENT_PID_SELF_HEALD; healer = data; THIS = this = healer->this; priv = this->private; syncopctx_setfspid(&pid); set_lk_owner_from_ptr(&lkowner, &lkowner); syncopctx_setfslkowner(&lkowner); for (;;) { afr_shd_healer_wait(healer); if (!afr_bricks_available_for_heal(priv)) continue; ASSERT_LOCAL(this, healer); priv->local[healer->subvol] = healer->local; if (priv->thin_arbiter_count) { if (afr_shd_ta_needs_heal(this, healer)) afr_shd_ta_get_xattrs(this, &loc, healer, &pre_crawl_xdata); } do { gf_msg_debug(this->name, 0, "starting index sweep on subvol %s", afr_subvol_name(this, healer->subvol)); afr_shd_sweep_prepare(healer); ret = afr_shd_index_sweep_all(healer); afr_shd_sweep_done(healer); /* As long as at least one gfid was healed, keep retrying. We may have just healed a directory and thereby created entries for other gfids which could not be healed thus far. */ gf_msg_debug(this->name, 0, "finished index sweep on subvol %s", afr_subvol_name(this, healer->subvol)); /* Give a pause before retrying to avoid a busy loop in case the only entry in index is because of an ongoing I/O. */ sleep(1); } while (ret > 0); if (ret == 0) { afr_cleanup_anon_inode_dir(healer); } if (ret == 0 && pre_crawl_xdata && !healer->crawl_event.heal_failed_count) { afr_shd_ta_check_and_unset_xattrs(this, &loc, healer, pre_crawl_xdata); } if (pre_crawl_xdata) { dict_unref(pre_crawl_xdata); pre_crawl_xdata = NULL; } } return NULL; } static void * afr_shd_full_healer(void *data) { struct subvol_healer *healer = NULL; xlator_t *this = NULL; int run = 0; healer = data; THIS = this = healer->this; for (;;) { pthread_mutex_lock(&healer->mutex); { run = __afr_shd_healer_wait(healer); if (!run) healer->running = _gf_false; } pthread_mutex_unlock(&healer->mutex); if (!run) break; ASSERT_LOCAL(this, healer); gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_SELF_HEAL_INFO, "starting full sweep on subvol %s", afr_subvol_name(this, healer->subvol)); afr_shd_sweep_prepare(healer); afr_shd_full_sweep(healer, this->itable->root); afr_shd_sweep_done(healer); gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_SELF_HEAL_INFO, "finished full sweep on subvol %s", afr_subvol_name(this, healer->subvol)); } return NULL; } static int afr_shd_healer_init(xlator_t *this, struct subvol_healer *healer) { int ret = 0; ret = pthread_mutex_init(&healer->mutex, NULL); if (ret) goto out; ret = pthread_cond_init(&healer->cond, NULL); if (ret) goto out; healer->this = this; healer->running = _gf_false; healer->rerun = _gf_false; healer->local = _gf_false; out: return ret; } static int afr_shd_healer_spawn(xlator_t *this, struct subvol_healer *healer, void *(threadfn)(void *)) { int ret = 0; pthread_mutex_lock(&healer->mutex); { if (healer->running) { pthread_cond_signal(&healer->cond); } else { ret = gf_thread_create(&healer->thread, NULL, threadfn, healer, "shdheal"); if (ret) goto unlock; healer->running = 1; } healer->rerun = 1; } unlock: pthread_mutex_unlock(&healer->mutex); return ret; } static int afr_shd_full_healer_spawn(xlator_t *this, int subvol) { return afr_shd_healer_spawn(this, NTH_FULL_HEALER(this, subvol), afr_shd_full_healer); } static int afr_shd_index_healer_spawn(xlator_t *this, int subvol) { return afr_shd_healer_spawn(this, NTH_INDEX_HEALER(this, subvol), afr_shd_index_healer); } static int afr_shd_dict_add_crawl_event(xlator_t *this, dict_t *output, crawl_event_t *crawl_event) { int ret = 0; uint64_t count = 0; char key[128] = {0}; int keylen = 0; char suffix[64] = {0}; int xl_id = 0; uint64_t healed_count = 0; uint64_t split_brain_count = 0; uint64_t heal_failed_count = 0; char *start_time_str = 0; char *end_time_str = NULL; char *crawl_type = NULL; int progress = -1; int child = -1; child = crawl_event->child; healed_count = crawl_event->healed_count; split_brain_count = crawl_event->split_brain_count; heal_failed_count = crawl_event->heal_failed_count; crawl_type = crawl_event->crawl_type; if (!crawl_event->start_time) goto out; start_time_str = gf_strdup(ctime(&crawl_event->start_time)); if (crawl_event->end_time) end_time_str = gf_strdup(ctime(&crawl_event->end_time)); ret = dict_get_int32(output, this->name, &xl_id); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_GET_FAILED, "xl does not have id"); goto out; } snprintf(key, sizeof(key), "statistics-%d-%d-count", xl_id, child); ret = dict_get_uint64(output, key, &count); snprintf(suffix, sizeof(suffix), "%d-%d-%" PRIu64, xl_id, child, count); snprintf(key, sizeof(key), "statistics_healed_cnt-%s", suffix); ret = dict_set_uint64(output, key, healed_count); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Could not add statistics_healed_count to output"); goto out; } snprintf(key, sizeof(key), "statistics_sb_cnt-%s", suffix); ret = dict_set_uint64(output, key, split_brain_count); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Could not add statistics_split_brain_count to output"); goto out; } keylen = snprintf(key, sizeof(key), "statistics_crawl_type-%s", suffix); ret = dict_set_strn(output, key, keylen, crawl_type); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Could not add statistics_crawl_type to output"); goto out; } snprintf(key, sizeof(key), "statistics_heal_failed_cnt-%s", suffix); ret = dict_set_uint64(output, key, heal_failed_count); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Could not add statistics_healed_failed_count to output"); goto out; } keylen = snprintf(key, sizeof(key), "statistics_strt_time-%s", suffix); ret = dict_set_dynstrn(output, key, keylen, start_time_str); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Could not add statistics_crawl_start_time to output"); goto out; } else { start_time_str = NULL; } if (!end_time_str) progress = 1; else progress = 0; keylen = snprintf(key, sizeof(key), "statistics_end_time-%s", suffix); if (!end_time_str) end_time_str = gf_strdup("Could not determine the end time"); ret = dict_set_dynstrn(output, key, keylen, end_time_str); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Could not add statistics_crawl_end_time to output"); goto out; } else { end_time_str = NULL; } keylen = snprintf(key, sizeof(key), "statistics_inprogress-%s", suffix); ret = dict_set_int32n(output, key, keylen, progress); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Could not add statistics_inprogress to output"); goto out; } snprintf(key, sizeof(key), "statistics-%d-%d-count", xl_id, child); ret = dict_set_uint64(output, key, count + 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Could not increment the counter."); goto out; } out: GF_FREE(start_time_str); GF_FREE(end_time_str); return ret; } static void afr_add_crawl_event(circular_buffer_t *cb, void *data) { dict_t *output = NULL; xlator_t *this = THIS; afr_private_t *priv = NULL; afr_self_heald_t *shd = NULL; crawl_event_t *crawl_event = NULL; output = data; priv = this->private; shd = &priv->shd; crawl_event = cb->data; if (shd->index_healers[crawl_event->child].local) afr_shd_dict_add_crawl_event(this, output, crawl_event); } int afr_selfheal_daemon_init(xlator_t *this) { afr_private_t *priv = NULL; afr_self_heald_t *shd = NULL; int ret = -1; int i = 0; priv = this->private; shd = &priv->shd; shd->index_healers = GF_CALLOC(sizeof(*shd->index_healers), priv->child_count, gf_afr_mt_subvol_healer_t); if (!shd->index_healers) goto out; for (i = 0; i < priv->child_count; i++) { shd->index_healers[i].subvol = i; ret = afr_shd_healer_init(this, &shd->index_healers[i]); if (ret) goto out; } shd->full_healers = GF_CALLOC(sizeof(*shd->full_healers), priv->child_count, gf_afr_mt_subvol_healer_t); if (!shd->full_healers) goto out; for (i = 0; i < priv->child_count; i++) { shd->full_healers[i].subvol = i; ret = afr_shd_healer_init(this, &shd->full_healers[i]); if (ret) goto out; } shd->split_brain = eh_new(AFR_EH_SPLIT_BRAIN_LIMIT, _gf_false, afr_destroy_shd_event_data); if (!shd->split_brain) goto out; shd->statistics = GF_CALLOC(sizeof(eh_t *), priv->child_count, gf_common_mt_eh_t); if (!shd->statistics) goto out; for (i = 0; i < priv->child_count; i++) { shd->statistics[i] = eh_new(AFR_STATISTICS_HISTORY_SIZE, _gf_false, afr_destroy_crawl_event_data); if (!shd->statistics[i]) goto out; shd->full_healers[i].crawl_event.child = i; shd->full_healers[i].crawl_event.crawl_type = "FULL"; shd->index_healers[i].crawl_event.child = i; shd->index_healers[i].crawl_event.crawl_type = "INDEX"; } ret = 0; out: return ret; } void afr_selfheal_childup(xlator_t *this, afr_private_t *priv) { int subvol = 0; if (!priv->shd.iamshd) return; for (subvol = 0; subvol < priv->child_count; subvol++) if (priv->child_up[subvol]) afr_shd_index_healer_spawn(this, subvol); return; } static int afr_shd_get_index_count(xlator_t *this, int i, uint64_t *count) { afr_private_t *priv = NULL; xlator_t *subvol = NULL; loc_t rootloc = { 0, }; dict_t *xattr = NULL; int ret = -1; priv = this->private; subvol = priv->children[i]; rootloc.inode = inode_ref(this->itable->root); gf_uuid_copy(rootloc.gfid, rootloc.inode->gfid); ret = syncop_getxattr(subvol, &rootloc, &xattr, GF_XATTROP_INDEX_COUNT, NULL, NULL); if (ret < 0) goto out; ret = dict_get_uint64(xattr, GF_XATTROP_INDEX_COUNT, count); if (ret) goto out; ret = 0; out: if (xattr) dict_unref(xattr); loc_wipe(&rootloc); return ret; } int afr_xl_op(xlator_t *this, dict_t *input, dict_t *output) { gf_xl_afr_op_t op = GF_SHD_OP_INVALID; int ret = 0; int xl_id = 0; afr_private_t *priv = NULL; afr_self_heald_t *shd = NULL; struct subvol_healer *healer = NULL; int i = 0; char key[64]; int keylen = 0; int this_name_len = 0; int op_ret = 0; uint64_t cnt = 0; #define AFR_SET_DICT_AND_LOG(name, output, key, keylen, dict_str, \ dict_str_len) \ { \ int ret; \ \ ret = dict_set_nstrn(output, key, keylen, dict_str, dict_str_len); \ if (ret) { \ gf_smsg(name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, \ "key=%s", key, "value=%s", dict_str, NULL); \ } \ } priv = this->private; shd = &priv->shd; ret = dict_get_int32_sizen(input, "xl-op", (int32_t *)&op); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_GET_FAILED, "key=xl-op", NULL); goto out; } this_name_len = strlen(this->name); ret = dict_get_int32n(input, this->name, this_name_len, &xl_id); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_GET_FAILED, "key=%s", this->name, NULL); goto out; } ret = dict_set_int32n(output, this->name, this_name_len, xl_id); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "key=%s", this->name, NULL); goto out; } switch (op) { case GF_SHD_OP_HEAL_INDEX: op_ret = 0; for (i = 0; i < priv->child_count; i++) { healer = &shd->index_healers[i]; keylen = snprintf(key, sizeof(key), "%d-%d-status", xl_id, i); if (!priv->child_up[i]) { AFR_SET_DICT_AND_LOG(this->name, output, key, keylen, SBRICK_NOT_CONNECTED, SLEN(SBRICK_NOT_CONNECTED)); op_ret = -1; } else if (AFR_COUNT(priv->child_up, priv->child_count) < 2) { AFR_SET_DICT_AND_LOG(this->name, output, key, keylen, SLESS_THAN2_BRICKS_in_REP, SLEN(SLESS_THAN2_BRICKS_in_REP)); op_ret = -1; } else if (!afr_shd_is_subvol_local(this, healer->subvol)) { AFR_SET_DICT_AND_LOG(this->name, output, key, keylen, SBRICK_IS_REMOTE, SLEN(SBRICK_IS_REMOTE)); } else { AFR_SET_DICT_AND_LOG(this->name, output, key, keylen, SSTARTED_SELF_HEAL, SLEN(SSTARTED_SELF_HEAL)); ret = afr_shd_index_healer_spawn(this, i); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_HEALER_SPAWN_FAILED, NULL); } } } break; case GF_SHD_OP_HEAL_FULL: op_ret = -1; for (i = 0; i < priv->child_count; i++) { healer = &shd->full_healers[i]; keylen = snprintf(key, sizeof(key), "%d-%d-status", xl_id, i); if (!priv->child_up[i]) { AFR_SET_DICT_AND_LOG(this->name, output, key, keylen, SBRICK_NOT_CONNECTED, SLEN(SBRICK_NOT_CONNECTED)); } else if (AFR_COUNT(priv->child_up, priv->child_count) < 2) { AFR_SET_DICT_AND_LOG(this->name, output, key, keylen, SLESS_THAN2_BRICKS_in_REP, SLEN(SLESS_THAN2_BRICKS_in_REP)); } else if (!afr_shd_is_subvol_local(this, healer->subvol)) { AFR_SET_DICT_AND_LOG(this->name, output, key, keylen, SBRICK_IS_REMOTE, SLEN(SBRICK_IS_REMOTE)); } else { AFR_SET_DICT_AND_LOG(this->name, output, key, keylen, SSTARTED_SELF_HEAL, SLEN(SSTARTED_SELF_HEAL)); ret = afr_shd_full_healer_spawn(this, i); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_HEALER_SPAWN_FAILED, NULL); } op_ret = 0; } } break; case GF_SHD_OP_INDEX_SUMMARY: case GF_SHD_OP_SPLIT_BRAIN_FILES: /* this case has been handled in glfs-heal.c */ break; case GF_SHD_OP_STATISTICS: for (i = 0; i < priv->child_count; i++) { eh_dump(shd->statistics[i], output, afr_add_crawl_event); ret = afr_shd_dict_add_crawl_event( this, output, &shd->index_healers[i].crawl_event); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_ADD_CRAWL_EVENT_FAILED, NULL); } ret = afr_shd_dict_add_crawl_event( this, output, &shd->full_healers[i].crawl_event); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_ADD_CRAWL_EVENT_FAILED, NULL); } } break; case GF_SHD_OP_STATISTICS_HEAL_COUNT: case GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA: op_ret = -1; for (i = 0; i < priv->child_count; i++) { if (!priv->child_up[i]) { keylen = snprintf(key, sizeof(key), "%d-%d-status", xl_id, i); AFR_SET_DICT_AND_LOG(this->name, output, key, keylen, SBRICK_NOT_CONNECTED, SLEN(SBRICK_NOT_CONNECTED)); } else { snprintf(key, sizeof(key), "%d-%d-hardlinks", xl_id, i); ret = afr_shd_get_index_count(this, i, &cnt); if (ret == 0) { ret = dict_set_uint64(output, key, cnt); } if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, NULL); } op_ret = 0; } } break; default: gf_smsg(this->name, GF_LOG_ERROR, 0, AFR_MSG_INVALID_ARG, "op=%d", op, NULL); break; } out: dict_deln(output, this->name, this_name_len); return op_ret; #undef AFR_SET_DICT_AND_LOG } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-self-heal-entry.c0000644000000000000000000000013214522202451025005 xustar000000000000000030 mtime=1699284265.618027284 30 atime=1699284265.617027281 30 ctime=1699284301.127134237 glusterfs-11.1/xlators/cluster/afr/src/afr-self-heal-entry.c0000664000175100017510000011742414522202451025275 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "afr.h" #include "afr-self-heal.h" #include "afr-transaction.h" #include "afr-messages.h" #include #include static int afr_selfheal_entry_anon_inode(xlator_t *this, inode_t *dir, const char *name, inode_t *inode, int child, struct afr_reply *replies, gf_boolean_t *anon_inode) { afr_private_t *priv = NULL; afr_local_t *local = NULL; xlator_t *subvol = NULL; int ret = 0; int i = 0; char g[64] = {0}; unsigned char *lookup_success = NULL; call_frame_t *frame = NULL; loc_t loc2 = { 0, }; loc_t loc = { 0, }; priv = this->private; subvol = priv->children[child]; lookup_success = alloca0(priv->child_count); uuid_utoa_r(replies[child].poststat.ia_gfid, g); loc.inode = inode_new(inode->table); if (!loc.inode) { ret = -ENOMEM; goto out; } if (replies[child].poststat.ia_type == IA_IFDIR) { /* This directory may have sub-directory hierarchy which may need to * be preserved for subsequent heals. So unconditionally move the * directory to anonymous-inode directory*/ *anon_inode = _gf_true; goto anon_inode; } frame = afr_frame_create(this, &ret); if (!frame) { ret = -ret; goto out; } local = frame->local; gf_uuid_copy(loc.gfid, replies[child].poststat.ia_gfid); AFR_ONLIST(local->child_up, frame, afr_selfheal_discover_cbk, lookup, &loc, NULL); for (i = 0; i < priv->child_count; i++) { if (local->replies[i].op_ret == 0) { lookup_success[i] = 1; } else if (local->replies[i].op_errno != ENOENT && local->replies[i].op_errno != ESTALE) { ret = -local->replies[i].op_errno; } } if (priv->quorum_count) { if (afr_has_quorum(lookup_success, priv, NULL)) { *anon_inode = _gf_true; } } else if (AFR_COUNT(lookup_success, priv->child_count) > 1) { *anon_inode = _gf_true; } else if (ret) { goto out; } anon_inode: if (!*anon_inode) { ret = 0; goto out; } loc.parent = inode_ref(dir); gf_uuid_copy(loc.pargfid, dir->gfid); loc.name = name; ret = afr_anon_inode_create(this, child, &loc2.parent); if (ret < 0) goto out; loc2.name = g; ret = syncop_rename(subvol, &loc, &loc2, NULL, NULL); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -ret, AFR_MSG_EXPUNGING_FILE_OR_DIR, "Rename to %s dir %s/%s (%s) on %s failed", priv->anon_inode_name, uuid_utoa(dir->gfid), name, g, subvol->name); } else { gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_EXPUNGING_FILE_OR_DIR, "Rename to %s dir %s/%s (%s) on %s successful", priv->anon_inode_name, uuid_utoa(dir->gfid), name, g, subvol->name); } out: loc_wipe(&loc); loc_wipe(&loc2); if (frame) { AFR_STACK_DESTROY(frame); } return ret; } int afr_selfheal_entry_delete(xlator_t *this, inode_t *dir, const char *name, inode_t *inode, int child, struct afr_reply *replies) { char g[64] = {0}; afr_private_t *priv = NULL; xlator_t *subvol = NULL; int ret = 0; loc_t loc = { 0, }; gf_boolean_t anon_inode = _gf_false; priv = this->private; subvol = priv->children[child]; if ((!replies[child].valid) || (replies[child].op_ret < 0)) { /*Nothing to do*/ ret = 0; goto out; } if (priv->use_anon_inode) { ret = afr_selfheal_entry_anon_inode(this, dir, name, inode, child, replies, &anon_inode); if (ret < 0 || anon_inode) goto out; } loc.parent = inode_ref(dir); loc.inode = inode_new(inode->table); if (!loc.inode) { ret = -ENOMEM; goto out; } loc.name = name; switch (replies[child].poststat.ia_type) { case IA_IFDIR: gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_EXPUNGING_FILE_OR_DIR, "expunging dir %s/%s (%s) on %s", uuid_utoa(dir->gfid), name, uuid_utoa_r(replies[child].poststat.ia_gfid, g), subvol->name); ret = syncop_rmdir(subvol, &loc, 1, NULL, NULL); break; default: gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_EXPUNGING_FILE_OR_DIR, "expunging file %s/%s (%s) on %s", uuid_utoa(dir->gfid), name, uuid_utoa_r(replies[child].poststat.ia_gfid, g), subvol->name); ret = syncop_unlink(subvol, &loc, NULL, NULL); break; } out: loc_wipe(&loc); return ret; } static int afr_new_entry_mark_status(call_frame_t *frame, loc_t *loc, struct afr_reply *lookup_replies, unsigned char *sources, int source, int dst) { xlator_t *this = frame->this; afr_private_t *priv = this->private; int pending = 0; int metadata_idx = 0; int idx = -1; int ret = 0; int i = 0; if (source == -1) { goto lookup; } if (IA_ISDIR(lookup_replies[source].poststat.ia_type)) { goto lookup; } metadata_idx = afr_index_for_transaction_type(AFR_METADATA_TRANSACTION); if (IA_ISREG(lookup_replies[source].poststat.ia_type)) { idx = afr_index_for_transaction_type(AFR_DATA_TRANSACTION); } for (i = 0; i < priv->child_count; i++) { if (!sources[i]) { continue; } if (uuid_compare(lookup_replies[i].poststat.ia_gfid, loc->gfid)) { /*Future proofing this call's input arguments*/ GF_ASSERT(!"gfids don't match for call to new entry marking"); goto lookup; } afr_selfheal_fill_cell(frame->this->private, lookup_replies[i].xdata, &pending, dst, metadata_idx); if (pending == 0) { goto lookup; } if (idx == -1) { continue; } afr_selfheal_fill_cell(frame->this->private, lookup_replies[i].xdata, &pending, dst, idx); if (pending == 0) { goto lookup; } } /*Pending is marked on all source bricks, we definitely know that new entry * marking is not needed*/ return 0; lookup: ret = syncop_lookup(priv->children[dst], loc, 0, 0, 0, 0); return ret; } int afr_selfheal_recreate_entry(call_frame_t *frame, int dst, int source, unsigned char *sources, inode_t *dir, const char *name, inode_t *inode, struct afr_reply *replies) { int ret = 0; loc_t loc = { 0, }; loc_t srcloc = { 0, }; loc_t anonloc = { 0, }; xlator_t *this = frame->this; afr_private_t *priv = NULL; dict_t *xdata = NULL; struct iatt *iatt = NULL; char *linkname = NULL; mode_t mode = 0; struct iatt newent = { 0, }; unsigned char *newentry = NULL; char iatt_uuid_str[64] = {0}; char dir_uuid_str[64] = {0}; priv = this->private; iatt = &replies[source].poststat; uuid_utoa_r(iatt->ia_gfid, iatt_uuid_str); if (iatt->ia_type == IA_INVAL || gf_uuid_is_null(iatt->ia_gfid)) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SELF_HEAL_FAILED, "Invalid ia_type (%d) or gfid(%s). source brick=%d, " "pargfid=%s, name=%s", iatt->ia_type, iatt_uuid_str, source, uuid_utoa_r(dir->gfid, dir_uuid_str), name); ret = -EINVAL; goto out; } xdata = dict_new(); if (!xdata) return -ENOMEM; newentry = alloca0(priv->child_count); loc.parent = inode_ref(dir); gf_uuid_copy(loc.pargfid, dir->gfid); loc.name = name; loc.inode = inode_ref(inode); ret = afr_selfheal_entry_delete(this, dir, name, inode, dst, replies); if (ret) goto out; ret = dict_set_gfuuid(xdata, "gfid-req", replies[source].poststat.ia_gfid, true); if (ret) goto out; srcloc.inode = inode_ref(inode); gf_uuid_copy(srcloc.gfid, iatt->ia_gfid); ret = afr_new_entry_mark_status(frame, &srcloc, replies, sources, source, dst); if (ret == -ENOENT || ret == -ESTALE) { newentry[dst] = 1; ret = afr_selfheal_newentry_mark(frame, this, inode, source, replies, sources, newentry); if (ret) goto out; } else if (ret == 0 && iatt->ia_type == IA_IFDIR && priv->use_anon_inode) { // Try rename from hidden directory ret = afr_anon_inode_create(this, dst, &anonloc.parent); if (ret < 0) goto out; anonloc.inode = inode_ref(inode); anonloc.name = iatt_uuid_str; ret = syncop_rename(priv->children[dst], &anonloc, &loc, NULL, NULL); if (ret == -ENOENT || ret == -ESTALE) ret = -1; /*This sets 'mismatch' to true*/ goto out; } mode = st_mode_from_ia(iatt->ia_prot, iatt->ia_type); switch (iatt->ia_type) { case IA_IFDIR: ret = syncop_mkdir(priv->children[dst], &loc, mode, 0, xdata, NULL); break; case IA_IFLNK: if (!newentry[dst]) { ret = syncop_link(priv->children[dst], &srcloc, &loc, &newent, NULL, NULL); } else { ret = syncop_readlink(priv->children[source], &srcloc, &linkname, 4096, NULL, NULL); if (ret <= 0) goto out; ret = syncop_symlink(priv->children[dst], &loc, linkname, NULL, xdata, NULL); } break; default: ret = dict_set_int32_sizen(xdata, GLUSTERFS_INTERNAL_FOP_KEY, 1); if (ret) goto out; ret = syncop_mknod( priv->children[dst], &loc, mode, makedev(ia_major(iatt->ia_rdev), ia_minor(iatt->ia_rdev)), &newent, xdata, NULL); break; } out: if (xdata) dict_unref(xdata); GF_FREE(linkname); loc_wipe(&loc); loc_wipe(&srcloc); loc_wipe(&anonloc); return ret; } static int __afr_selfheal_heal_dirent(call_frame_t *frame, xlator_t *this, fd_t *fd, char *name, inode_t *inode, int source, unsigned char *sources, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies) { int ret = 0; afr_private_t *priv = NULL; int i = 0; priv = this->private; if (!replies[source].valid) return -EIO; /* Skip healing this entry if the last lookup on it failed for reasons * other than ENOENT. */ if ((replies[source].op_ret < 0) && (replies[source].op_errno != ENOENT)) return -replies[source].op_errno; if (replies[source].op_ret == 0) { ret = afr_lookup_and_heal_gfid(this, fd->inode, name, inode, replies, source, sources, &replies[source].poststat.ia_gfid, NULL); if (ret) return ret; } for (i = 0; i < priv->child_count; i++) { if (!healed_sinks[i]) continue; if (replies[source].op_ret == -1 && replies[source].op_errno == ENOENT) { ret = afr_selfheal_entry_delete(this, fd->inode, name, inode, i, replies); } else { if (!gf_uuid_compare(replies[i].poststat.ia_gfid, replies[source].poststat.ia_gfid)) { gf_msg_debug(this->name, 0, "skipping %s, no heal needed.", name); continue; } ret = afr_selfheal_recreate_entry(frame, i, source, sources, fd->inode, name, inode, replies); } if (ret < 0) break; } return ret; } static int afr_selfheal_detect_gfid_and_type_mismatch(xlator_t *this, struct afr_reply *replies, inode_t *inode, uuid_t pargfid, char *bname, int src_idx, unsigned char *locked_on, int *src) { int i = 0; int ret = -1; afr_private_t *priv = NULL; void *gfid = NULL; ia_type_t ia_type = IA_INVAL; priv = this->private; gfid = &replies[src_idx].poststat.ia_gfid; ia_type = replies[src_idx].poststat.ia_type; for (i = 0; i < priv->child_count; i++) { if (i == src_idx) continue; if (!replies[i].valid) continue; if (replies[i].op_ret != 0) continue; if (gf_uuid_is_null(replies[i].poststat.ia_gfid)) continue; if (replies[i].poststat.ia_type == IA_INVAL) continue; if (ia_type == IA_INVAL || gf_uuid_is_null(gfid)) { src_idx = i; ia_type = replies[src_idx].poststat.ia_type; gfid = &replies[src_idx].poststat.ia_gfid; continue; } if (gf_uuid_compare(gfid, replies[i].poststat.ia_gfid) && (ia_type == replies[i].poststat.ia_type)) { ret = afr_gfid_split_brain_source(this, replies, inode, pargfid, bname, src_idx, i, locked_on, src, NULL, NULL); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, "Skipping conservative merge on the " "file."); return ret; } if (ia_type != replies[i].poststat.ia_type) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, "Type mismatch detected " "for /%s>, %s on %s and %s on %s. " "Skipping conservative merge on the file.", uuid_utoa(pargfid), bname, gf_inode_type_to_str(replies[i].poststat.ia_type), priv->children[i]->name, gf_inode_type_to_str(replies[src_idx].poststat.ia_type), priv->children[src_idx]->name); gf_event(EVENT_AFR_SPLIT_BRAIN, "client-pid=%d;" "subvol=%s;type=file;" "file=/%s>;count=2;child-%d=%s;type-" "%d=%s;child-%d=%s;type-%d=%s", this->ctx->cmd_args.client_pid, this->name, uuid_utoa(pargfid), bname, i, priv->children[i]->name, i, gf_inode_type_to_str(replies[i].poststat.ia_type), src_idx, priv->children[src_idx]->name, src_idx, gf_inode_type_to_str(replies[src_idx].poststat.ia_type)); return -1; } } return 0; } static int __afr_selfheal_merge_dirent(call_frame_t *frame, xlator_t *this, fd_t *fd, char *name, inode_t *inode, unsigned char *sources, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies) { int ret = 0; int i = 0; int source = -1; int src = -1; afr_private_t *priv = NULL; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (replies[i].valid && replies[i].op_ret == 0) { source = i; break; } } if (source == -1) { /* entry got deleted in the mean time? */ return 0; } /* Set all the sources as 1, otheriwse newentry_mark won't be set */ for (i = 0; i < priv->child_count; i++) { if (replies[i].valid && replies[i].op_ret == 0) { sources[i] = 1; } } ret = afr_lookup_and_heal_gfid(this, fd->inode, name, inode, replies, source, sources, &replies[source].poststat.ia_gfid, NULL); if (ret) return ret; /* In case of type mismatch / unable to resolve gfid mismatch on the * entry, return -EIO.*/ ret = afr_selfheal_detect_gfid_and_type_mismatch( this, replies, inode, fd->inode->gfid, name, source, locked_on, &src); if (ret < 0) return ret; if (src != -1) { source = src; for (i = 0; i < priv->child_count; i++) { if (i != src && replies[i].valid && gf_uuid_compare(replies[src].poststat.ia_gfid, replies[i].poststat.ia_gfid)) { sources[i] = 0; } } } for (i = 0; i < priv->child_count; i++) { if (i == source || !healed_sinks[i]) continue; if (src != -1) { if (!gf_uuid_compare(replies[src].poststat.ia_gfid, replies[i].poststat.ia_gfid)) continue; } else if (replies[i].op_errno != ENOENT) { continue; } ret |= afr_selfheal_recreate_entry(frame, i, source, sources, fd->inode, name, inode, replies); } return ret; } static int __afr_selfheal_entry_dirent(call_frame_t *frame, xlator_t *this, fd_t *fd, char *name, inode_t *inode, int source, unsigned char *sources, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies) { int ret = -1; if (source < 0) ret = __afr_selfheal_merge_dirent(frame, this, fd, name, inode, sources, healed_sinks, locked_on, replies); else ret = __afr_selfheal_heal_dirent(frame, this, fd, name, inode, source, sources, healed_sinks, locked_on, replies); return ret; } static gf_boolean_t is_full_heal_marker_present(xlator_t *this, dict_t *xdata, int idx) { int i = 0; void *pending_raw = NULL; afr_private_t *priv = NULL; priv = this->private; if (!xdata) return _gf_false; /* Iterate over each of the priv->pending_keys[] elements and then * see if any of them have data segment non-zero. If they do, return * true. Else return false. */ for (i = 0; i < priv->child_count; i++) { if (dict_get_ptr(xdata, priv->pending_key[i], &pending_raw)) continue; if (!pending_raw) continue; if (*((int *)pending_raw + idx)) return _gf_true; } return _gf_false; } static gf_boolean_t afr_need_full_heal(xlator_t *this, struct afr_reply *replies, int source, unsigned char *healed_sinks, afr_transaction_type type) { int i = 0; int idx = 0; afr_private_t *priv = NULL; priv = this->private; if (!priv->esh_granular) return _gf_true; if (type != AFR_ENTRY_TRANSACTION) return _gf_true; priv = this->private; idx = afr_index_for_transaction_type(AFR_DATA_TRANSACTION); /* If there is a clear source, check whether the full-heal-indicator * is present in its xdata. Otherwise, we need to examine all the * participating bricks and then figure if *even* one of them has a * full-heal-indicator. */ if (source != -1) { if (is_full_heal_marker_present(this, replies[source].xdata, idx)) return _gf_true; } /* else ..*/ for (i = 0; i < priv->child_count; i++) { if (!healed_sinks[i]) continue; if (is_full_heal_marker_present(this, replies[i].xdata, idx)) return _gf_true; } return _gf_false; } static int __afr_selfheal_entry_finalize_source(xlator_t *this, unsigned char *sources, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies, uint64_t *witness) { afr_private_t *priv = NULL; int source = -1; int sources_count = 0; int i = 0; priv = this->private; sources_count = AFR_COUNT(sources, priv->child_count); if ((AFR_CMP(locked_on, healed_sinks, priv->child_count) == 0) || !sources_count || afr_does_witness_exist(this, witness)) { memset(sources, 0, sizeof(*sources) * priv->child_count); afr_mark_active_sinks(this, sources, locked_on, healed_sinks); return -1; } source = afr_choose_source_by_policy(priv, sources, AFR_ENTRY_TRANSACTION); /*If the selected source does not blame any other brick, then mark * everything as sink to trigger conservative merge. */ if (source != -1 && !AFR_COUNT(healed_sinks, priv->child_count)) { for (i = 0; i < priv->child_count; i++) { if (locked_on[i]) { sources[i] = 0; healed_sinks[i] = 1; } } return -1; } return source; } int __afr_selfheal_entry_prepare(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, struct afr_reply *replies, int *source_p, unsigned char *pflag) { int ret = -1; int source = -1; afr_private_t *priv = NULL; uint64_t *witness = NULL; priv = this->private; ret = afr_selfheal_unlocked_discover(frame, inode, inode->gfid, replies); if (ret) return ret; witness = alloca0(sizeof(*witness) * priv->child_count); ret = afr_selfheal_find_direction(frame, this, replies, AFR_ENTRY_TRANSACTION, locked_on, sources, sinks, witness, pflag); if (ret) return ret; /* Initialize the healed_sinks[] array optimistically to the intersection of to-be-healed (i.e sinks[]) and the list of servers which are up (i.e locked_on[]). As we encounter failures in the healing process, we will unmark the respective servers in the healed_sinks[] array. */ AFR_INTERSECT(healed_sinks, sinks, locked_on, priv->child_count); source = __afr_selfheal_entry_finalize_source(this, sources, healed_sinks, locked_on, replies, witness); if (source < 0) { /* If source is < 0 (typically split-brain), we perform a conservative merge of entries rather than erroring out */ } *source_p = source; return ret; } static int afr_selfheal_entry_dirent(call_frame_t *frame, xlator_t *this, fd_t *fd, char *name, inode_t *parent_idx_inode, xlator_t *subvol, gf_boolean_t full_crawl) { int ret = 0; int source = -1; unsigned char *locked_on = NULL; unsigned char *sources = NULL; unsigned char *sinks = NULL; unsigned char *healed_sinks = NULL; inode_t *inode = NULL; struct afr_reply *replies = NULL; struct afr_reply *par_replies = NULL; afr_private_t *priv = NULL; dict_t *xattr = NULL; priv = this->private; if (__is_root_gfid(fd->inode->gfid) && afr_is_private_directory(priv, name, GF_CLIENT_PID_SELF_HEALD)) { return 0; } xattr = dict_new(); if (!xattr) return -ENOMEM; ret = dict_set_int32_sizen(xattr, GF_GFIDLESS_LOOKUP, 1); if (ret) { dict_unref(xattr); return -1; } sources = alloca0(priv->child_count); sinks = alloca0(priv->child_count); healed_sinks = alloca0(priv->child_count); locked_on = alloca0(priv->child_count); replies = alloca0(priv->child_count * sizeof(*replies)); par_replies = alloca0(priv->child_count * sizeof(*par_replies)); ret = afr_selfheal_entrylk(frame, this, fd->inode, this->name, NULL, locked_on); { if (ret < priv->child_count) { gf_msg_debug(this->name, 0, "%s: Skipping " "entry self-heal as only %d sub-volumes " " could be locked in %s domain", uuid_utoa(fd->inode->gfid), ret, this->name); ret = -ENOTCONN; goto unlock; } ret = __afr_selfheal_entry_prepare(frame, this, fd->inode, locked_on, sources, sinks, healed_sinks, par_replies, &source, NULL); if (ret < 0) goto unlock; inode = afr_selfheal_unlocked_lookup_on(frame, fd->inode, name, replies, locked_on, xattr); if (!inode) { ret = -ENOMEM; goto unlock; } ret = __afr_selfheal_entry_dirent(frame, this, fd, name, inode, source, sources, healed_sinks, locked_on, replies); if ((ret == 0) && (priv->esh_granular) && parent_idx_inode) { ret = afr_shd_entry_purge(subvol, parent_idx_inode, name, inode->ia_type); /* Why is ret force-set to 0? We do not care about * index purge failing for full heal as it is quite * possible during replace-brick that not all files * and directories have their name indices present in * entry-changes/. */ ret = 0; } } unlock: afr_selfheal_unentrylk(frame, this, fd->inode, this->name, NULL, locked_on, NULL); if (inode) inode_unref(inode); if (replies) afr_replies_wipe(replies, priv->child_count); if (par_replies) afr_replies_wipe(par_replies, priv->child_count); if (xattr) dict_unref(xattr); return ret; } static inode_t * afr_shd_entry_changes_index_inode(xlator_t *this, xlator_t *subvol, uuid_t pargfid) { int ret = -1; void *index_gfid = NULL; loc_t rootloc = { 0, }; loc_t loc = { 0, }; dict_t *xattr = NULL; inode_t *inode = NULL; struct iatt iatt = { 0, }; rootloc.inode = inode_ref(this->itable->root); gf_uuid_copy(rootloc.gfid, rootloc.inode->gfid); ret = syncop_getxattr(subvol, &rootloc, &xattr, GF_XATTROP_ENTRY_CHANGES_GFID, NULL, NULL); if (ret || !xattr) { errno = -ret; goto out; } ret = dict_get_ptr(xattr, GF_XATTROP_ENTRY_CHANGES_GFID, &index_gfid); if (ret) { errno = EINVAL; goto out; } loc.inode = inode_new(this->itable); if (!loc.inode) { errno = ENOMEM; goto out; } gf_uuid_copy(loc.pargfid, index_gfid); loc.name = gf_strdup(uuid_utoa(pargfid)); ret = syncop_lookup(subvol, &loc, &iatt, NULL, NULL, NULL); if (ret < 0) { errno = -ret; goto out; } inode = inode_link(loc.inode, NULL, NULL, &iatt); out: if (xattr) dict_unref(xattr); loc_wipe(&rootloc); GF_FREE((char *)loc.name); loc_wipe(&loc); return inode; } static int afr_selfheal_entry_do_subvol(call_frame_t *frame, xlator_t *this, fd_t *fd, int child) { int ret = 0; gf_dirent_t entries; gf_dirent_t *entry = NULL; off_t offset = 0; call_frame_t *iter_frame = NULL; xlator_t *subvol = NULL; afr_private_t *priv = NULL; gf_boolean_t mismatch = _gf_false; afr_local_t *local = NULL; loc_t loc = { 0, }; priv = this->private; subvol = priv->children[child]; INIT_LIST_HEAD(&entries.list); local = frame->local; iter_frame = afr_copy_frame(frame); if (!iter_frame) return -ENOMEM; loc.inode = afr_shd_entry_changes_index_inode(this, subvol, fd->inode->gfid); while ((ret = syncop_readdir(subvol, fd, 131072, offset, &entries, NULL, NULL))) { if (ret > 0) ret = 0; list_for_each_entry(entry, &entries.list, list) { offset = entry->d_off; /* skip . and .. */ if (inode_dir_or_parentdir(entry)) continue; ret = afr_selfheal_entry_dirent(iter_frame, this, fd, entry->d_name, loc.inode, subvol, local->need_full_crawl); AFR_STACK_RESET(iter_frame); if (iter_frame->local == NULL) { ret = -ENOTCONN; break; } if (ret == -EIO) { /* gfid or type mismatch. */ mismatch = _gf_true; ret = 0; } if (ret) break; } gf_dirent_free(&entries); if (ret) break; } loc_wipe(&loc); AFR_STACK_DESTROY(iter_frame); if (mismatch == _gf_true) /* undo pending will be skipped */ ret = -1; return ret; } static int afr_selfheal_entry_granular_dirent(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { int ret = 0; afr_granular_esh_args_t *args = data; ret = afr_selfheal_entry_dirent(args->frame, args->xl, args->heal_fd, entry->d_name, parent->inode, subvol, _gf_false); AFR_STACK_RESET(args->frame); if (args->frame->local == NULL) ret = -ENOTCONN; if (ret == -1) args->mismatch = _gf_true; return ret; } static int afr_selfheal_entry_granular(call_frame_t *frame, xlator_t *this, fd_t *fd, int subvol_idx, gf_boolean_t is_src) { int ret = 0; loc_t loc = { 0, }; xlator_t *subvol = NULL; afr_private_t *priv = NULL; afr_granular_esh_args_t args = { 0, }; priv = this->private; subvol = priv->children[subvol_idx]; args.frame = afr_copy_frame(frame); if (!args.frame) goto out; args.xl = this; /* args.heal_fd represents the fd associated with the original directory * on which entry heal is being attempted. */ args.heal_fd = fd; /* @subvol here represents the subvolume of AFR where * indices/entry-changes/ will be processed */ loc.inode = afr_shd_entry_changes_index_inode(this, subvol, fd->inode->gfid); if (!loc.inode) { /* If granular heal failed on the sink (as it might sometimes * because it is the src that would mostly contain the granular * changelogs and the sink's entry-changes would be empty), * do not treat heal as failure. */ if (is_src) ret = -errno; else ret = 0; goto out; } ret = syncop_dir_scan(subvol, &loc, GF_CLIENT_PID_SELF_HEALD, &args, afr_selfheal_entry_granular_dirent); loc_wipe(&loc); if (args.mismatch == _gf_true) ret = -1; out: if (args.frame) AFR_STACK_DESTROY(args.frame); return ret; } static int afr_selfheal_entry_do(call_frame_t *frame, xlator_t *this, fd_t *fd, int source, unsigned char *sources, unsigned char *healed_sinks) { int i = 0; int ret = 0; gf_boolean_t mismatch = _gf_false; afr_local_t *local = NULL; afr_private_t *priv = NULL; priv = this->private; local = frame->local; gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_SELF_HEAL_INFO, "performing %s entry selfheal on %s", (local->need_full_crawl ? "full" : "granular"), uuid_utoa(fd->inode->gfid)); for (i = 0; i < priv->child_count; i++) { /* Expunge */ if (!healed_sinks[i]) continue; if (!local->need_full_crawl) /* Why call afr_selfheal_entry_granular() on a "healed sink", * given that it is the source that contains the granular * indices? * If the index for this directory is non-existent or empty on * this subvol (=> clear sink), then it will return early * without failure status. * If the index is non-empty and it is yet a 'healed sink', then * it is due to a split-brain in which case we anyway need to * crawl the indices/entry-changes/pargfid directory. */ ret = afr_selfheal_entry_granular(frame, this, fd, i, _gf_false); else ret = afr_selfheal_entry_do_subvol(frame, this, fd, i); if (ret == -EIO) { /* gfid or type mismatch. */ mismatch = _gf_true; ret = 0; } if (ret) break; } if (!ret && source != -1) { /* Impunge */ if (local->need_full_crawl) ret = afr_selfheal_entry_do_subvol(frame, this, fd, source); else ret = afr_selfheal_entry_granular(frame, this, fd, source, _gf_true); } if (mismatch == _gf_true) /* undo pending will be skipped */ ret = -1; return ret; } static int __afr_selfheal_entry(call_frame_t *frame, xlator_t *this, fd_t *fd, unsigned char *locked_on) { int ret = -1; int source = -1; unsigned char *sources = NULL; unsigned char *sinks = NULL; unsigned char *data_lock = NULL; unsigned char *postop_lock = NULL; unsigned char *healed_sinks = NULL; unsigned char *undid_pending = NULL; struct afr_reply *locked_replies = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; gf_boolean_t did_sh = _gf_true; char *heal_type = "granular entry"; priv = this->private; local = frame->local; sources = alloca0(priv->child_count); sinks = alloca0(priv->child_count); healed_sinks = alloca0(priv->child_count); undid_pending = alloca0(priv->child_count); data_lock = alloca0(priv->child_count); postop_lock = alloca0(priv->child_count); locked_replies = alloca0(sizeof(*locked_replies) * priv->child_count); ret = afr_selfheal_entrylk(frame, this, fd->inode, this->name, NULL, data_lock); { if (ret < priv->child_count) { gf_msg_debug(this->name, 0, "%s: Skipping " "entry self-heal as only %d sub-volumes could " "be locked in %s domain", uuid_utoa(fd->inode->gfid), ret, this->name); ret = -ENOTCONN; goto unlock; } ret = __afr_selfheal_entry_prepare(frame, this, fd->inode, data_lock, sources, sinks, healed_sinks, locked_replies, &source, NULL); if (AFR_COUNT(healed_sinks, priv->child_count) == 0) { did_sh = _gf_false; goto unlock; } local->need_full_crawl = afr_need_full_heal( this, locked_replies, source, healed_sinks, AFR_ENTRY_TRANSACTION); } unlock: afr_selfheal_unentrylk(frame, this, fd->inode, this->name, NULL, data_lock, NULL); if (ret < 0) goto out; if (!did_sh) goto out; ret = afr_selfheal_entry_do(frame, this, fd, source, sources, healed_sinks); if (ret) goto out; /* Take entrylks in xlator domain before doing post-op (undo-pending) in * entry self-heal. This is to prevent a parallel name self-heal on * an entry under @fd->inode from reading pending xattrs while it is * being modified by SHD after entry sh below, given that * name self-heal takes locks ONLY in xlator domain and is free to read * pending changelog in the absence of the following locking. */ ret = afr_selfheal_entrylk(frame, this, fd->inode, this->name, NULL, postop_lock); { if (AFR_CMP(data_lock, postop_lock, priv->child_count) != 0) { gf_msg_debug(this->name, 0, "%s: Skipping " "post-op after entry self-heal as %d " "sub-volumes, as opposed to %d, " "could be locked in %s domain", uuid_utoa(fd->inode->gfid), ret, AFR_COUNT(data_lock, priv->child_count), this->name); ret = -ENOTCONN; goto postop_unlock; } afr_selfheal_restore_time(frame, this, fd->inode, source, healed_sinks, locked_replies); ret = afr_selfheal_undo_pending( frame, this, fd->inode, sources, sinks, healed_sinks, undid_pending, AFR_ENTRY_TRANSACTION, locked_replies, postop_lock); } postop_unlock: afr_selfheal_unentrylk(frame, this, fd->inode, this->name, NULL, postop_lock, NULL); out: if (did_sh) { if (local->need_full_crawl) { heal_type = "full entry"; } afr_log_selfheal(fd->inode->gfid, this, ret, heal_type, source, sources, healed_sinks); } else { ret = 1; } if (locked_replies) afr_replies_wipe(locked_replies, priv->child_count); return ret; } static fd_t * afr_selfheal_data_opendir(xlator_t *this, inode_t *inode) { loc_t loc = { 0, }; int ret = 0; fd_t *fd = NULL; fd = fd_create(inode, 0); if (!fd) return NULL; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); ret = syncop_opendir(this, &loc, fd, NULL, NULL); if (ret) { fd_unref(fd); fd = NULL; } else { fd_bind(fd); } loc_wipe(&loc); return fd; } int afr_selfheal_entry(call_frame_t *frame, xlator_t *this, inode_t *inode) { afr_private_t *priv = NULL; unsigned char *locked_on = NULL; fd_t *fd = NULL; int ret = 0; priv = this->private; fd = afr_selfheal_data_opendir(this, inode); if (!fd) return -EIO; locked_on = alloca0(priv->child_count); ret = afr_selfheal_tie_breaker_entrylk(frame, this, inode, priv->sh_domain, NULL, locked_on); { if (ret < priv->child_count) { gf_msg_debug(this->name, 0, "%s: Skipping " "entry self-heal as only %d sub-volumes could " "be locked in %s domain", uuid_utoa(fd->inode->gfid), ret, priv->sh_domain); /* Either less than two subvols available, or another selfheal (from another server) is in progress. Skip for now in any case there isn't anything to do. */ ret = -ENOTCONN; goto unlock; } ret = __afr_selfheal_entry(frame, this, fd, locked_on); } unlock: afr_selfheal_unentrylk(frame, this, inode, priv->sh_domain, NULL, locked_on, NULL); if (fd) fd_unref(fd); return ret; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-self-heal.h0000644000000000000000000000013214522202451023653 xustar000000000000000030 mtime=1699284265.618027284 30 atime=1699284265.618027284 30 ctime=1699284301.100134156 glusterfs-11.1/xlators/cluster/afr/src/afr-self-heal.h0000664000175100017510000004363314522202451024143 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _AFR_SELFHEAL_H #define _AFR_SELFHEAL_H typedef struct afr_granular_esh_args { fd_t *heal_fd; xlator_t *xl; call_frame_t *frame; gf_boolean_t mismatch; /* flag to represent occurrence of type/gfid mismatch */ } afr_granular_esh_args_t; /* Perform fop on all UP subvolumes and wait for all callbacks to return */ #define AFR_ONALL(frame, rfn, fop, args...) \ do { \ afr_local_t *__local = frame->local; \ afr_private_t *__priv = frame->this->private; \ int __i = 0, __count = 0; \ unsigned char *__child_up = alloca(__priv->child_count); \ \ memcpy(__child_up, __priv->child_up, \ sizeof(*__child_up) * __priv->child_count); \ __count = AFR_COUNT(__child_up, __priv->child_count); \ \ __local->barrier.waitfor = __count; \ afr_local_replies_wipe(__local, __priv); \ \ for (__i = 0; __i < __priv->child_count; __i++) { \ if (!__child_up[__i]) \ continue; \ STACK_WIND_COOKIE(frame, rfn, (void *)(long)__i, \ __priv->children[__i], \ __priv->children[__i]->fops->fop, args); \ } \ syncbarrier_wait(&__local->barrier, __count); \ } while (0) /* Perform fop on all subvolumes represented by list[] array and wait for all callbacks to return */ #define AFR_ONLIST(list, frame, rfn, fop, args...) \ do { \ afr_local_t *__local = frame->local; \ afr_private_t *__priv = frame->this->private; \ int __i = 0; \ int __count = 0; \ unsigned char *__list = alloca(__priv->child_count); \ \ memcpy(__list, list, sizeof(*__list) * __priv->child_count); \ __count = AFR_COUNT(__list, __priv->child_count); \ __local->barrier.waitfor = __count; \ afr_local_replies_wipe(__local, __priv); \ \ for (__i = 0; __i < __priv->child_count; __i++) { \ if (!__list[__i]) \ continue; \ STACK_WIND_COOKIE(frame, rfn, (void *)(long)__i, \ __priv->children[__i], \ __priv->children[__i]->fops->fop, args); \ } \ syncbarrier_wait(&__local->barrier, __count); \ } while (0) #define AFR_SEQ(frame, rfn, fop, args...) \ do { \ afr_local_t *__local = frame->local; \ afr_private_t *__priv = frame->this->private; \ int __i = 0; \ \ afr_local_replies_wipe(__local, __priv); \ \ for (__i = 0; __i < __priv->child_count; __i++) { \ if (!__priv->child_up[__i]) \ continue; \ STACK_WIND_COOKIE(frame, rfn, (void *)(long)__i, \ __priv->children[__i], \ __priv->children[__i]->fops->fop, args); \ syncbarrier_wait(&__local->barrier, 1); \ } \ } while (0) #define ALLOC_MATRIX(n, type) \ ({ \ int __i; \ type **__ptr = alloca(n * sizeof(type *)); \ \ for (__i = 0; __i < n; __i++) \ __ptr[__i] = alloca0(n * sizeof(type)); \ __ptr; \ }) #define IA_EQUAL(f, s, field) \ (memcmp(&(f.ia_##field), &(s.ia_##field), sizeof(s.ia_##field)) == 0) #define SBRAIN_HEAL_NO_GO_MSG \ "Failed to obtain replies from all bricks of " \ "the replica (are they up?). Cannot resolve split-brain." #define SFILE_NOT_IN_SPLIT_BRAIN "File not in split-brain" #define SNO_BIGGER_FILE "No bigger file" #define SNO_DIFF_IN_MTIME "No difference in mtime" #define SUSE_SOURCE_BRICK_TO_HEAL \ "Use source-brick option to heal metadata" \ " split-brain" #define SINVALID_BRICK_NAME "Invalid brick name" #define SBRICK_IS_NOT_UP "Brick is not up" #define SBRICK_NOT_CONNECTED "Brick is not connected" #define SLESS_THAN2_BRICKS_in_REP "< 2 bricks in replica are up" #define SBRICK_IS_REMOTE "Brick is remote" #define SSTARTED_SELF_HEAL "Started self-heal" #define SOP_NOT_SUPPORTED "Operation Not Supported" #define SFILE_NOT_UNDER_DATA \ "The file is not under data or metadata " \ "split-brain" #define SFILE_NOT_IN_SPLIT_BRAIN "File not in split-brain" #define SALL_BRICKS_UP_TO_RESOLVE \ "All the bricks should be up to resolve the" \ " gfid split brain" #define SERROR_GETTING_SRC_BRICK "Error getting the source brick" int afr_selfheal(xlator_t *this, uuid_t gfid); gf_boolean_t afr_throttled_selfheal(call_frame_t *frame, xlator_t *this); int afr_selfheal_name(xlator_t *this, uuid_t gfid, const char *name, void *gfid_req, dict_t *req, dict_t *rsp); int afr_selfheal_data(call_frame_t *frame, xlator_t *this, fd_t *fd); int afr_selfheal_metadata(call_frame_t *frame, xlator_t *this, inode_t *inode); int afr_selfheal_entry(call_frame_t *frame, xlator_t *this, inode_t *inode); int afr_lookup_and_heal_gfid(xlator_t *this, inode_t *parent, const char *name, inode_t *inode, struct afr_reply *replies, int source, unsigned char *sources, void *gfid, int *gfid_idx); int afr_selfheal_inodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, unsigned char *locked_on); int afr_selfheal_tie_breaker_inodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, unsigned char *locked_on); int afr_selfheal_uninodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, const unsigned char *locked_on); int afr_selfheal_entrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on); int afr_selfheal_tryentrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on); int afr_selfheal_tie_breaker_entrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on); int afr_selfheal_unentrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on, dict_t *xdata); int afr_selfheal_unlocked_discover(call_frame_t *frame, inode_t *inode, uuid_t gfid, struct afr_reply *replies); int afr_selfheal_unlocked_discover_on(call_frame_t *frame, inode_t *inode, uuid_t gfid, struct afr_reply *replies, unsigned char *discover_on, dict_t *dict); inode_t * afr_selfheal_unlocked_lookup_on(call_frame_t *frame, inode_t *parent, const char *name, struct afr_reply *replies, unsigned char *lookup_on, dict_t *xattr); int afr_selfheal_find_direction(call_frame_t *frame, xlator_t *this, struct afr_reply *replies, afr_transaction_type type, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, uint64_t *witness, unsigned char *flag); int afr_selfheal_fill_matrix(xlator_t *this, int **matrix, int subvol, int idx, dict_t *xdata); int afr_selfheal_extract_xattr(xlator_t *this, struct afr_reply *replies, afr_transaction_type type, int *dirty, int **matrix); int afr_sh_generic_fop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata); int afr_selfheal_restore_time(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, unsigned char *healed_sinks, struct afr_reply *replies); int afr_selfheal_undo_pending(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, afr_transaction_type type, struct afr_reply *replies, unsigned char *locked_on); int afr_selfheal_recreate_entry(call_frame_t *frame, int dst, int source, unsigned char *sources, inode_t *dir, const char *name, inode_t *inode, struct afr_reply *replies); int afr_selfheal_post_op(call_frame_t *frame, xlator_t *this, inode_t *inode, int subvol, dict_t *xattr, dict_t *xdata); call_frame_t * afr_frame_create(xlator_t *this, int32_t *op_errno); inode_t * afr_inode_find(xlator_t *this, uuid_t gfid); int afr_selfheal_discover_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *parbuf); void afr_reply_copy(struct afr_reply *dst, struct afr_reply *src); void afr_replies_copy(struct afr_reply *dst, struct afr_reply *src, int count); int afr_selfheal_newentry_mark(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, struct afr_reply *replies, unsigned char *sources, unsigned char *newentry); unsigned int afr_success_count(struct afr_reply *replies, unsigned int count); void afr_log_selfheal(uuid_t gfid, xlator_t *this, int ret, char *type, int source, unsigned char *sources, unsigned char *healed_sinks); void afr_mark_largest_file_as_source(xlator_t *this, unsigned char *sources, struct afr_reply *replies); void afr_mark_active_sinks(xlator_t *this, unsigned char *sources, unsigned char *locked_on, unsigned char *sinks); gf_boolean_t afr_dict_contains_heal_op(call_frame_t *frame); gf_boolean_t afr_can_decide_split_brain_source_sinks(struct afr_reply *replies, int child_count); int afr_mark_split_brain_source_sinks( call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies, afr_transaction_type type); int afr_sh_get_fav_by_policy(xlator_t *this, struct afr_reply *replies, inode_t *inode, char **policy_str); int _afr_fav_child_reset_sink_xattrs(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, unsigned char *healed_sinks, unsigned char *undid_pending, afr_transaction_type type, unsigned char *locked_on, struct afr_reply *replies); int afr_get_child_index_from_name(xlator_t *this, char *name); gf_boolean_t afr_does_witness_exist(xlator_t *this, uint64_t *witness); int __afr_selfheal_data_prepare(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, struct afr_reply *replies, unsigned char *flag); int __afr_selfheal_metadata_prepare(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, struct afr_reply *replies, unsigned char *flag); int __afr_selfheal_entry_prepare(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, struct afr_reply *replies, int *source_p, unsigned char *flag); int afr_selfheal_unlocked_inspect(call_frame_t *frame, xlator_t *this, uuid_t gfid, inode_t **link_inode, gf_boolean_t *data_selfheal, gf_boolean_t *metadata_selfheal, gf_boolean_t *entry_selfheal, struct afr_reply *replies); int afr_selfheal_do(call_frame_t *frame, xlator_t *this, uuid_t gfid); int afr_selfheal_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata); int afr_locked_fill(call_frame_t *frame, xlator_t *this, unsigned char *locked_on); int afr_choose_source_by_policy(afr_private_t *priv, unsigned char *sources, afr_transaction_type type); int afr_selfheal_metadata_by_stbuf(xlator_t *this, struct iatt *stbuf); int afr_sh_fav_by_size(xlator_t *this, struct afr_reply *replies, inode_t *inode); int afr_sh_fav_by_mtime(xlator_t *this, struct afr_reply *replies, inode_t *inode); int afr_sh_fav_by_ctime(xlator_t *this, struct afr_reply *replies, inode_t *inode); int afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies, inode_t *inode, uuid_t pargfid, const char *bname, int src_idx, int child_idx, unsigned char *locked_on, int *src, dict_t *req, dict_t *rsp); int afr_mark_source_sinks_if_file_empty(xlator_t *this, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies, afr_transaction_type type); gf_boolean_t afr_is_file_empty_on_all_children(afr_private_t *priv, struct afr_reply *replies); int afr_selfheal_entry_delete(xlator_t *this, inode_t *dir, const char *name, inode_t *inode, int child, struct afr_reply *replies); int afr_anon_inode_create(xlator_t *this, int child, inode_t **linked_inode); void afr_selfheal_fill_cell(afr_private_t *priv, dict_t *src_xdata, int *cell, int sink, int idx); #endif /* !_AFR_SELFHEAL_H */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-dir-write.c0000644000000000000000000000013214522202451023714 xustar000000000000000030 mtime=1699284265.613027269 30 atime=1699284265.613027269 30 ctime=1699284301.110134186 glusterfs-11.1/xlators/cluster/afr/src/afr-dir-write.c0000664000175100017510000010522014522202451024173 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include "afr.h" #include #include #include #include #include #include "afr-transaction.h" static void afr_mark_entry_pending_changelog(call_frame_t *frame, xlator_t *this); static int afr_build_parent_loc(loc_t *parent, loc_t *child, int32_t *op_errno) { int ret = -1; char *child_path = NULL; if (!child->parent) { if (op_errno) *op_errno = EINVAL; goto out; } child_path = gf_strdup(child->path); if (!child_path) { if (op_errno) *op_errno = ENOMEM; goto out; } parent->path = gf_strdup(dirname(child_path)); if (!parent->path) { if (op_errno) *op_errno = ENOMEM; goto out; } parent->inode = inode_ref(child->parent); gf_uuid_copy(parent->gfid, child->pargfid); ret = 0; out: GF_FREE(child_path); return ret; } static void __afr_dir_write_finalize(afr_local_t *local, xlator_t *this) { afr_private_t *priv = NULL; int inode_read_subvol = -1; int parent_read_subvol = -1; int parent2_read_subvol = -1; int i = 0; afr_read_subvol_args_t args = { 0, }; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret == -1) continue; gf_uuid_copy(args.gfid, local->replies[i].poststat.ia_gfid); args.ia_type = local->replies[i].poststat.ia_type; break; } if (local->inode) { if (local->op != GF_FOP_RENAME && local->op != GF_FOP_LINK) afr_replies_interpret(local, this, local->inode, NULL); inode_read_subvol = afr_data_subvol_get(local->inode, this, NULL, NULL, NULL, &args); } if (local->parent) parent_read_subvol = afr_data_subvol_get(local->parent, this, NULL, local->readable, NULL, NULL); if (local->parent2) parent2_read_subvol = afr_data_subvol_get(local->parent2, this, NULL, local->readable2, NULL, NULL); local->op_ret = -1; local->op_errno = afr_final_errno(local, priv); afr_pick_error_xdata(local, priv->child_count, local->parent, local->readable, local->parent2, local->readable2); for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret < 0) { if (local->inode) afr_inode_need_refresh_set(local->inode, this); if (local->parent) afr_inode_need_refresh_set(local->parent, this); if (local->parent2) afr_inode_need_refresh_set(local->parent2, this); continue; } if (local->op_ret == -1) { local->op_ret = local->replies[i].op_ret; local->op_errno = local->replies[i].op_errno; local->cont.dir_fop.buf = local->replies[i].poststat; local->cont.dir_fop.preparent = local->replies[i].preparent; local->cont.dir_fop.postparent = local->replies[i].postparent; local->cont.dir_fop.prenewparent = local->replies[i].preparent2; local->cont.dir_fop.postnewparent = local->replies[i].postparent2; if (local->xdata_rsp) { dict_unref(local->xdata_rsp); local->xdata_rsp = NULL; } if (local->replies[i].xdata) local->xdata_rsp = dict_ref(local->replies[i].xdata); continue; } if (i == inode_read_subvol) { local->cont.dir_fop.buf = local->replies[i].poststat; if (local->replies[i].xdata) { if (local->xdata_rsp) dict_unref(local->xdata_rsp); local->xdata_rsp = dict_ref(local->replies[i].xdata); } } if (i == parent_read_subvol) { local->cont.dir_fop.preparent = local->replies[i].preparent; local->cont.dir_fop.postparent = local->replies[i].postparent; } if (i == parent2_read_subvol) { local->cont.dir_fop.prenewparent = local->replies[i].preparent2; local->cont.dir_fop.postnewparent = local->replies[i].postparent2; } } } static void __afr_dir_write_fill(afr_local_t *local, xlator_t *this, int child_index, int op_ret, int op_errno, struct iatt *poststat, struct iatt *preparent, struct iatt *postparent, struct iatt *preparent2, struct iatt *postparent2, dict_t *xdata) { afr_fd_ctx_t *fd_ctx = NULL; fd_ctx = local->fd_ctx; local->replies[child_index].valid = 1; local->replies[child_index].op_ret = op_ret; local->replies[child_index].op_errno = op_errno; if (xdata) local->replies[child_index].xdata = dict_ref(xdata); if (op_ret >= 0) { if (poststat) local->replies[child_index].poststat = *poststat; if (preparent) local->replies[child_index].preparent = *preparent; if (postparent) local->replies[child_index].postparent = *postparent; if (preparent2) local->replies[child_index].preparent2 = *preparent2; if (postparent2) local->replies[child_index].postparent2 = *postparent2; if (fd_ctx) fd_ctx->opened_on[child_index] = AFR_FD_OPENED; } else { if (op_errno != ENOTEMPTY) afr_transaction_fop_failed(local, child_index); if (fd_ctx) fd_ctx->opened_on[child_index] = AFR_FD_NOT_OPENED; } return; } static int __afr_dir_write_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, struct iatt *preparent2, struct iatt *postparent2, dict_t *xdata) { afr_local_t *local = NULL; int child_index = (long)cookie; int call_count = -1; afr_private_t *priv = NULL; priv = this->private; local = frame->local; LOCK(&frame->lock); { __afr_dir_write_fill(local, this, child_index, op_ret, op_errno, buf, preparent, postparent, preparent2, postparent2, xdata); call_count = --local->call_count; } UNLOCK(&frame->lock); if (call_count == 0) { __afr_dir_write_finalize(local, this); if (afr_txn_nothing_failed(frame, this)) { /*if it did pre-op, it will do post-op changing ctime*/ if (priv->consistent_metadata && afr_needs_changelog_update(local)) afr_zero_fill_stat(local); local->transaction.unwind(frame, this); } afr_mark_entry_pending_changelog(frame, this); afr_transaction_resume(frame, this); } return 0; } static int afr_mark_new_entry_changelog_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { int call_count = 0; call_count = afr_frame_return(frame); if (call_count == 0) AFR_STACK_DESTROY(frame); return 0; } void afr_mark_new_entry_changelog(call_frame_t *frame, xlator_t *this) { call_frame_t *new_frame = NULL; afr_local_t *local = NULL; afr_local_t *new_local = NULL; afr_private_t *priv = NULL; dict_t *xattr = NULL; int32_t **changelog = NULL; int i = 0; int op_errno = ENOMEM; unsigned char *pending = NULL; int call_count = 0; local = frame->local; priv = this->private; new_frame = copy_frame(frame); if (!new_frame) goto out; new_local = AFR_FRAME_INIT(new_frame, op_errno); if (!new_local) goto out; xattr = dict_new(); if (!xattr) goto out; pending = alloca0(priv->child_count); for (i = 0; i < priv->child_count; i++) { if (local->transaction.pre_op[i] && !local->transaction.failed_subvols[i]) { call_count++; continue; } pending[i] = 1; } changelog = afr_mark_pending_changelog(priv, pending, xattr, local->cont.dir_fop.buf.ia_type); if (!changelog) goto out; new_local->pending = changelog; gf_uuid_copy(new_local->loc.gfid, local->cont.dir_fop.buf.ia_gfid); new_local->loc.inode = inode_ref(local->inode); new_local->call_count = call_count; for (i = 0; i < priv->child_count; i++) { if (pending[i]) continue; STACK_WIND_COOKIE(new_frame, afr_mark_new_entry_changelog_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->xattrop, &new_local->loc, GF_XATTROP_ADD_ARRAY, xattr, NULL); if (!--call_count) break; } new_frame = NULL; out: if (new_frame) AFR_STACK_DESTROY(new_frame); if (xattr) dict_unref(xattr); return; } static void afr_mark_entry_pending_changelog(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int pre_op_count = 0; int failed_count = 0; unsigned char *success_replies = NULL; local = frame->local; priv = this->private; if (local->op_ret < 0) return; if (local->op != GF_FOP_CREATE && local->op != GF_FOP_MKNOD && local->op != GF_FOP_MKDIR) return; pre_op_count = AFR_COUNT(local->transaction.pre_op, priv->child_count); failed_count = AFR_COUNT(local->transaction.failed_subvols, priv->child_count); /* FOP succeeded on all bricks. */ if (pre_op_count == priv->child_count && !failed_count) return; /* FOP did not suceed on quorum no. of bricks. */ success_replies = alloca0(priv->child_count); afr_fill_success_replies(local, priv, success_replies); if (!afr_has_quorum(success_replies, priv, NULL)) return; if (priv->thin_arbiter_count) { /*Mark new entry using ta file*/ local->is_new_entry = _gf_true; return; } afr_mark_new_entry_changelog(frame, this); return; } /* {{{ create */ static int afr_create_unwind(call_frame_t *frame, xlator_t *this) { call_frame_t *main_frame = NULL; afr_local_t *local = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(create, main_frame, local->op_ret, local->op_errno, local->cont.create.fd, local->inode, &local->cont.dir_fop.buf, &local->cont.dir_fop.preparent, &local->cont.dir_fop.postparent, local->xdata_rsp); return 0; } static int afr_create_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return __afr_dir_write_cbk(frame, cookie, this, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } static int afr_create_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_create_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->create, &local->loc, local->cont.create.flags, local->cont.create.mode, local->umask, local->cont.create.fd, local->xdata_req); return 0; } int afr_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; loc_copy(&local->loc, loc); local->fd_ctx = afr_fd_ctx_get(fd, this); if (!local->fd_ctx) goto out; local->inode = inode_ref(loc->inode); local->parent = inode_ref(loc->parent); local->op = GF_FOP_CREATE; local->cont.create.flags = flags; local->fd_ctx->flags = flags; local->cont.create.mode = mode; local->cont.create.fd = fd_ref(fd); local->umask = umask; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->transaction.wind = afr_create_wind; local->transaction.unwind = afr_create_unwind; ret = afr_build_parent_loc(&local->transaction.parent_loc, loc, &op_errno); if (ret) goto out; local->transaction.main_frame = frame; local->transaction.basename = AFR_BASENAME(loc->path); ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ mknod */ static int afr_mknod_unwind(call_frame_t *frame, xlator_t *this) { call_frame_t *main_frame = NULL; afr_local_t *local = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(mknod, main_frame, local->op_ret, local->op_errno, local->inode, &local->cont.dir_fop.buf, &local->cont.dir_fop.preparent, &local->cont.dir_fop.postparent, local->xdata_rsp); return 0; } static int afr_mknod_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return __afr_dir_write_cbk(frame, cookie, this, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } static int afr_mknod_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_mknod_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->mknod, &local->loc, local->cont.mknod.mode, local->cont.mknod.dev, local->umask, local->xdata_req); return 0; } int afr_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; loc_copy(&local->loc, loc); local->inode = inode_ref(loc->inode); local->parent = inode_ref(loc->parent); local->op = GF_FOP_MKNOD; local->cont.mknod.mode = mode; local->cont.mknod.dev = dev; local->umask = umask; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->transaction.wind = afr_mknod_wind; local->transaction.unwind = afr_mknod_unwind; ret = afr_build_parent_loc(&local->transaction.parent_loc, loc, &op_errno); if (ret) goto out; local->transaction.main_frame = frame; local->transaction.basename = AFR_BASENAME(loc->path); ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ mkdir */ static int afr_mkdir_unwind(call_frame_t *frame, xlator_t *this) { call_frame_t *main_frame = NULL; afr_local_t *local = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(mkdir, main_frame, local->op_ret, local->op_errno, local->inode, &local->cont.dir_fop.buf, &local->cont.dir_fop.preparent, &local->cont.dir_fop.postparent, local->xdata_rsp); return 0; } static int afr_mkdir_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return __afr_dir_write_cbk(frame, cookie, this, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } static int afr_mkdir_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_mkdir_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->mkdir, &local->loc, local->cont.mkdir.mode, local->umask, local->xdata_req); return 0; } int afr_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; loc_copy(&local->loc, loc); local->inode = inode_ref(loc->inode); local->parent = inode_ref(loc->parent); local->cont.mkdir.mode = mode; local->umask = umask; if (!xdata || !dict_get_sizen(xdata, "gfid-req")) { op_errno = EPERM; gf_msg_callingfn(this->name, GF_LOG_WARNING, op_errno, AFR_MSG_GFID_NULL, "mkdir: %s is received " "without gfid-req %p", loc->path, xdata); goto out; } local->xdata_req = dict_copy_with_ref(xdata, NULL); if (!local->xdata_req) { op_errno = ENOMEM; goto out; } local->op = GF_FOP_MKDIR; local->transaction.wind = afr_mkdir_wind; local->transaction.unwind = afr_mkdir_unwind; ret = afr_build_parent_loc(&local->transaction.parent_loc, loc, &op_errno); if (ret) goto out; local->transaction.main_frame = frame; local->transaction.basename = AFR_BASENAME(loc->path); ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ link */ static int afr_link_unwind(call_frame_t *frame, xlator_t *this) { call_frame_t *main_frame = NULL; afr_local_t *local = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(link, main_frame, local->op_ret, local->op_errno, local->inode, &local->cont.dir_fop.buf, &local->cont.dir_fop.preparent, &local->cont.dir_fop.postparent, local->xdata_rsp); return 0; } static int afr_link_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return __afr_dir_write_cbk(frame, cookie, this, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } static int afr_link_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_link_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->link, &local->loc, &local->newloc, local->xdata_req); return 0; } int afr_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; loc_copy(&local->loc, oldloc); loc_copy(&local->newloc, newloc); local->inode = inode_ref(oldloc->inode); local->parent = inode_ref(newloc->parent); if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->op = GF_FOP_LINK; local->transaction.wind = afr_link_wind; local->transaction.unwind = afr_link_unwind; ret = afr_build_parent_loc(&local->transaction.parent_loc, newloc, &op_errno); if (ret) goto out; local->transaction.main_frame = frame; local->transaction.basename = AFR_BASENAME(newloc->path); ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ symlink */ static int afr_symlink_unwind(call_frame_t *frame, xlator_t *this) { call_frame_t *main_frame = NULL; afr_local_t *local = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(symlink, main_frame, local->op_ret, local->op_errno, local->inode, &local->cont.dir_fop.buf, &local->cont.dir_fop.preparent, &local->cont.dir_fop.postparent, local->xdata_rsp); return 0; } static int afr_symlink_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return __afr_dir_write_cbk(frame, cookie, this, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } static int afr_symlink_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_symlink_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->symlink, local->cont.symlink.linkpath, &local->loc, local->umask, local->xdata_req); return 0; } int afr_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; loc_copy(&local->loc, loc); local->inode = inode_ref(loc->inode); local->parent = inode_ref(loc->parent); local->cont.symlink.linkpath = gf_strdup(linkpath); local->umask = umask; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->op = GF_FOP_SYMLINK; local->transaction.wind = afr_symlink_wind; local->transaction.unwind = afr_symlink_unwind; ret = afr_build_parent_loc(&local->transaction.parent_loc, loc, &op_errno); if (ret) goto out; local->transaction.main_frame = frame; local->transaction.basename = AFR_BASENAME(loc->path); ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ rename */ static int afr_rename_unwind(call_frame_t *frame, xlator_t *this) { call_frame_t *main_frame = NULL; afr_local_t *local = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(rename, main_frame, local->op_ret, local->op_errno, &local->cont.dir_fop.buf, &local->cont.dir_fop.preparent, &local->cont.dir_fop.postparent, &local->cont.dir_fop.prenewparent, &local->cont.dir_fop.postnewparent, local->xdata_rsp); return 0; } static int afr_rename_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { return __afr_dir_write_cbk(frame, cookie, this, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); } static int afr_rename_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_rename_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->rename, &local->loc, &local->newloc, local->xdata_req); return 0; } int afr_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) { op_errno = ENOMEM; goto out; } local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; loc_copy(&local->loc, oldloc); loc_copy(&local->newloc, newloc); local->inode = inode_ref(oldloc->inode); local->parent = inode_ref(oldloc->parent); local->parent2 = inode_ref(newloc->parent); if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->op = GF_FOP_RENAME; local->transaction.wind = afr_rename_wind; local->transaction.unwind = afr_rename_unwind; ret = afr_build_parent_loc(&local->transaction.parent_loc, oldloc, &op_errno); if (ret) goto out; ret = afr_build_parent_loc(&local->transaction.new_parent_loc, newloc, &op_errno); if (ret) goto out; local->transaction.main_frame = frame; local->transaction.basename = AFR_BASENAME(oldloc->path); local->transaction.new_basename = AFR_BASENAME(newloc->path); ret = afr_transaction(transaction_frame, this, AFR_ENTRY_RENAME_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ unlink */ static int afr_unlink_unwind(call_frame_t *frame, xlator_t *this) { call_frame_t *main_frame = NULL; afr_local_t *local = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(unlink, main_frame, local->op_ret, local->op_errno, &local->cont.dir_fop.preparent, &local->cont.dir_fop.postparent, local->xdata_rsp); return 0; } static int afr_unlink_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return __afr_dir_write_cbk(frame, cookie, this, op_ret, op_errno, NULL, preparent, postparent, NULL, NULL, xdata); } static int afr_unlink_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_unlink_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->unlink, &local->loc, local->xflag, local->xdata_req); return 0; } int afr_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; loc_copy(&local->loc, loc); local->xflag = xflag; local->inode = inode_ref(loc->inode); local->parent = inode_ref(loc->parent); if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->op = GF_FOP_UNLINK; local->transaction.wind = afr_unlink_wind; local->transaction.unwind = afr_unlink_unwind; ret = afr_build_parent_loc(&local->transaction.parent_loc, loc, &op_errno); if (ret) goto out; local->transaction.main_frame = frame; local->transaction.basename = AFR_BASENAME(loc->path); ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ rmdir */ int afr_rmdir_unwind(call_frame_t *frame, xlator_t *this) { call_frame_t *main_frame = NULL; afr_local_t *local = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(rmdir, main_frame, local->op_ret, local->op_errno, &local->cont.dir_fop.preparent, &local->cont.dir_fop.postparent, local->xdata_rsp); return 0; } static int afr_rmdir_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return __afr_dir_write_cbk(frame, cookie, this, op_ret, op_errno, NULL, preparent, postparent, NULL, NULL, xdata); } static int afr_rmdir_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_rmdir_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->rmdir, &local->loc, local->cont.rmdir.flags, local->xdata_req); return 0; } int afr_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; loc_copy(&local->loc, loc); local->inode = inode_ref(loc->inode); local->parent = inode_ref(loc->parent); local->cont.rmdir.flags = flags; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->op = GF_FOP_RMDIR; local->transaction.wind = afr_rmdir_wind; local->transaction.unwind = afr_rmdir_unwind; ret = afr_build_parent_loc(&local->transaction.parent_loc, loc, &op_errno); if (ret) goto out; local->transaction.main_frame = frame; local->transaction.basename = AFR_BASENAME(loc->path); ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(rmdir, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* }}} */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-common.c0000644000000000000000000000013214522202451023276 xustar000000000000000030 mtime=1699284265.612027266 30 atime=1699284265.611027263 30 ctime=1699284301.103134165 glusterfs-11.1/xlators/cluster/afr/src/afr-common.c0000664000175100017510000066755514522202451023605 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include "afr.h" #include #include #include #include #include #include #include #include #include "afr-inode-read.h" #include "afr-inode-write.h" #include "afr-dir-read.h" #include "afr-dir-write.h" #include "afr-transaction.h" #include "afr-self-heal.h" #include "afr-self-heald.h" #include "afr-messages.h" static afr_fd_ctx_t * __afr_fd_ctx_get(fd_t *fd, xlator_t *this); static void afr_set_need_heal(xlator_t *this, afr_local_t *local); static int __afr_inode_need_refresh_set(inode_t *inode, xlator_t *this); int32_t afr_quorum_errno(afr_private_t *priv) { return ENOTCONN; } gf_boolean_t afr_is_private_directory(afr_private_t *priv, const char *name, pid_t pid) { if (strcmp(name, GF_REPLICATE_TRASH_DIR) == 0) { /*For backward compatibility /.landfill is private*/ return _gf_true; } if (pid == GF_CLIENT_PID_GSYNCD) { /*geo-rep needs to create/sync private directory on secondary because * it appears in changelog*/ return _gf_false; } if (pid == GF_CLIENT_PID_GLFS_HEAL || pid == GF_CLIENT_PID_SELF_HEALD) { if (strcmp(name, priv->anon_inode_name) == 0) { /* anonymous-inode dir is private*/ return _gf_true; } } else { if (strncmp(name, AFR_ANON_DIR_PREFIX, strlen(AFR_ANON_DIR_PREFIX)) == 0) { /* anonymous-inode dir prefix is private for geo-rep to work*/ return _gf_true; } } return _gf_false; } void afr_fill_success_replies(afr_local_t *local, afr_private_t *priv, unsigned char *replies) { int i = 0; for (i = 0; i < priv->child_count; i++) { if (local->replies[i].valid && local->replies[i].op_ret == 0) { replies[i] = 1; } else { replies[i] = 0; } } } int afr_fav_child_reset_sink_xattrs(void *opaque); static int afr_fav_child_reset_sink_xattrs_cbk(int ret, call_frame_t *frame, void *opaque); static void afr_discover_done(call_frame_t *frame, xlator_t *this); static int afr_dom_lock_acquire_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { afr_local_t *local = frame->local; afr_private_t *priv = this->private; int i = (long)cookie; local->cont.lk.dom_lock_op_ret[i] = op_ret; local->cont.lk.dom_lock_op_errno[i] = op_errno; if (op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, AFR_MSG_LK_HEAL_DOM, "%s: Failed to acquire %s on %s", uuid_utoa(local->fd->inode->gfid), AFR_LK_HEAL_DOM, priv->children[i]->name); } else { local->cont.lk.dom_locked_nodes[i] = 1; } syncbarrier_wake(&local->barrier); return 0; } static int afr_dom_lock_acquire(call_frame_t *frame) { afr_local_t *local = NULL; afr_private_t *priv = NULL; struct gf_flock flock = { 0, }; int i = 0; priv = frame->this->private; local = frame->local; local->cont.lk.dom_locked_nodes = GF_CALLOC( priv->child_count, sizeof(*local->cont.lk.locked_nodes), gf_afr_mt_char); if (!local->cont.lk.dom_locked_nodes) { return -ENOMEM; } local->cont.lk.dom_lock_op_ret = GF_CALLOC( priv->child_count, sizeof(*local->cont.lk.dom_lock_op_ret), gf_afr_mt_int32_t); if (!local->cont.lk.dom_lock_op_ret) { return -ENOMEM; /* CALLOC'd members are freed in afr_local_cleanup. */ } local->cont.lk.dom_lock_op_errno = GF_CALLOC( priv->child_count, sizeof(*local->cont.lk.dom_lock_op_errno), gf_afr_mt_int32_t); if (!local->cont.lk.dom_lock_op_errno) { return -ENOMEM; /* CALLOC'd members are freed in afr_local_cleanup. */ } flock.l_type = F_WRLCK; AFR_ONALL(frame, afr_dom_lock_acquire_cbk, finodelk, AFR_LK_HEAL_DOM, local->fd, F_SETLK, &flock, NULL); if (!afr_has_quorum(local->cont.lk.dom_locked_nodes, priv, NULL)) goto blocking_lock; /*If any of the bricks returned EAGAIN, we still need blocking locks.*/ if (AFR_COUNT(local->cont.lk.dom_locked_nodes, priv->child_count) != priv->child_count) { for (i = 0; i < priv->child_count; i++) { if (local->cont.lk.dom_lock_op_ret[i] == -1 && local->cont.lk.dom_lock_op_errno[i] == EAGAIN) goto blocking_lock; } } return 0; blocking_lock: afr_dom_lock_release(frame); AFR_ONALL(frame, afr_dom_lock_acquire_cbk, finodelk, AFR_LK_HEAL_DOM, local->fd, F_SETLKW, &flock, NULL); if (!afr_has_quorum(local->cont.lk.dom_locked_nodes, priv, NULL)) { afr_dom_lock_release(frame); return -afr_quorum_errno(priv); } return 0; } static int afr_dom_lock_release_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { afr_local_t *local = frame->local; afr_private_t *priv = this->private; int i = (long)cookie; if (op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, AFR_MSG_LK_HEAL_DOM, "%s: Failed to release %s on %s", local->loc.path, AFR_LK_HEAL_DOM, priv->children[i]->name); } local->cont.lk.dom_locked_nodes[i] = 0; syncbarrier_wake(&local->barrier); return 0; } void afr_dom_lock_release(call_frame_t *frame) { afr_local_t *local = NULL; afr_private_t *priv = NULL; unsigned char *locked_on = NULL; struct gf_flock flock = { 0, }; local = frame->local; priv = frame->this->private; locked_on = local->cont.lk.dom_locked_nodes; if (AFR_COUNT(locked_on, priv->child_count) == 0) return; flock.l_type = F_UNLCK; AFR_ONLIST(locked_on, frame, afr_dom_lock_release_cbk, finodelk, AFR_LK_HEAL_DOM, local->fd, F_SETLK, &flock, NULL); return; } static void afr_lk_heal_info_cleanup(afr_lk_heal_info_t *info) { if (!info) return; if (info->xdata_req) dict_unref(info->xdata_req); if (info->fd) fd_unref(info->fd); GF_FREE(info->locked_nodes); GF_FREE(info->child_up_event_gen); GF_FREE(info->child_down_event_gen); GF_FREE(info); } static int afr_add_lock_to_saved_locks(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = this->private; afr_local_t *local = frame->local; afr_lk_heal_info_t *info = NULL; afr_fd_ctx_t *fd_ctx = NULL; int ret = -ENOMEM; info = GF_CALLOC(sizeof(*info), 1, gf_afr_mt_lk_heal_info_t); if (!info) { goto cleanup; } INIT_LIST_HEAD(&info->pos); info->fd = fd_ref(local->fd); info->cmd = local->cont.lk.cmd; info->pid = frame->root->pid; gf_flock_copy(&info->flock, &local->cont.lk.user_flock); info->xdata_req = dict_copy_with_ref(local->xdata_req, NULL); if (!info->xdata_req) { goto cleanup; } lk_owner_copy(&info->lk_owner, &frame->root->lk_owner); info->locked_nodes = GF_MALLOC( sizeof(*info->locked_nodes) * priv->child_count, gf_afr_mt_char); if (!info->locked_nodes) { goto cleanup; } memcpy(info->locked_nodes, local->cont.lk.locked_nodes, sizeof(*info->locked_nodes) * priv->child_count); info->child_up_event_gen = GF_CALLOC(sizeof(*info->child_up_event_gen), priv->child_count, gf_afr_mt_int32_t); if (!info->child_up_event_gen) { goto cleanup; } info->child_down_event_gen = GF_CALLOC(sizeof(*info->child_down_event_gen), priv->child_count, gf_afr_mt_int32_t); if (!info->child_down_event_gen) { goto cleanup; } LOCK(&local->fd->lock); { fd_ctx = __afr_fd_ctx_get(local->fd, this); if (fd_ctx) fd_ctx->lk_heal_info = info; } UNLOCK(&local->fd->lock); if (!fd_ctx) { goto cleanup; } LOCK(&priv->lock); { list_add_tail(&info->pos, &priv->saved_locks); } UNLOCK(&priv->lock); return 0; cleanup: gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_LK_HEAL_DOM, "%s: Failed to add lock to healq", uuid_utoa(local->fd->inode->gfid)); if (info) { afr_lk_heal_info_cleanup(info); if (fd_ctx) { LOCK(&local->fd->lock); { fd_ctx->lk_heal_info = NULL; } UNLOCK(&local->fd->lock); } } return ret; } static int afr_remove_lock_from_saved_locks(afr_local_t *local, xlator_t *this) { afr_private_t *priv = this->private; struct gf_flock *user_flock; afr_lk_heal_info_t *info = NULL; afr_fd_ctx_t *fd_ctx = NULL; int ret = -EINVAL; fd_ctx = afr_fd_ctx_get(local->fd, this); if (!fd_ctx || !fd_ctx->lk_heal_info) { goto out; } user_flock = &local->cont.lk.user_flock; info = fd_ctx->lk_heal_info; if ((info->flock.l_start != user_flock->l_start) || (info->flock.l_whence != user_flock->l_whence) || (info->flock.l_len != user_flock->l_len)) { /*TODO: Compare lkowners too.*/ goto out; } LOCK(&priv->lock); { list_del(&fd_ctx->lk_heal_info->pos); } UNLOCK(&priv->lock); afr_lk_heal_info_cleanup(info); fd_ctx->lk_heal_info = NULL; return 0; out: if (ret) gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_LK_HEAL_DOM, "%s: Failed to remove lock from healq", uuid_utoa(local->fd->inode->gfid)); return ret; } static int afr_lock_heal_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { afr_local_t *local = frame->local; int i = (long)cookie; local->replies[i].valid = 1; local->replies[i].op_ret = op_ret; local->replies[i].op_errno = op_errno; if (op_ret != 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, AFR_MSG_LK_HEAL_DOM, "Failed to heal lock on child %d for %s", i, uuid_utoa(local->fd->inode->gfid)); } syncbarrier_wake(&local->barrier); return 0; } static int afr_getlk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { afr_local_t *local = frame->local; int i = (long)cookie; local->replies[i].valid = 1; local->replies[i].op_ret = op_ret; local->replies[i].op_errno = op_errno; if (op_ret != 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, AFR_MSG_LK_HEAL_DOM, "Failed getlk for %s", uuid_utoa(local->fd->inode->gfid)); } else { gf_flock_copy(&local->cont.lk.getlk_rsp[i], lock); } syncbarrier_wake(&local->barrier); return 0; } static gf_boolean_t afr_does_lk_owner_match(call_frame_t *frame, afr_private_t *priv, afr_lk_heal_info_t *info) { int i = 0; afr_local_t *local = frame->local; struct gf_flock flock; gf_boolean_t ret = _gf_true; char *wind_on = alloca0(priv->child_count); unsigned char *success_replies = alloca0(priv->child_count); local->cont.lk.getlk_rsp = GF_CALLOC(sizeof(*local->cont.lk.getlk_rsp), priv->child_count, gf_afr_mt_gf_lock); gf_flock_copy(&flock, &info->flock); for (i = 0; i < priv->child_count; i++) { if (info->locked_nodes[i]) wind_on[i] = 1; } AFR_ONLIST(wind_on, frame, afr_getlk_cbk, lk, info->fd, F_GETLK, &flock, info->xdata_req); afr_fill_success_replies(local, priv, success_replies); if (AFR_COUNT(success_replies, priv->child_count) == 0) { ret = _gf_false; goto out; } for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid || local->replies[i].op_ret != 0) continue; if (local->cont.lk.getlk_rsp[i].l_type == F_UNLCK) continue; /*TODO: Do we really need to compare lkowner if F_UNLCK is true?*/ if (!is_same_lkowner(&local->cont.lk.getlk_rsp[i].l_owner, &info->lk_owner)) { ret = _gf_false; break; } } out: afr_local_replies_wipe(local, priv); GF_FREE(local->cont.lk.getlk_rsp); local->cont.lk.getlk_rsp = NULL; return ret; } static void afr_mark_fd_bad(fd_t *fd, xlator_t *this) { afr_fd_ctx_t *fd_ctx = NULL; if (!fd) return; LOCK(&fd->lock); { fd_ctx = __afr_fd_ctx_get(fd, this); if (fd_ctx) { fd_ctx->is_fd_bad = _gf_true; fd_ctx->lk_heal_info = NULL; } } UNLOCK(&fd->lock); } static void afr_add_lock_to_lkhealq(afr_private_t *priv, afr_lk_heal_info_t *info) { LOCK(&priv->lock); { list_del(&info->pos); list_add_tail(&info->pos, &priv->lk_healq); } UNLOCK(&priv->lock); } static void afr_lock_heal_do(call_frame_t *frame, afr_private_t *priv, afr_lk_heal_info_t *info) { int i = 0; int op_errno = 0; int32_t *current_event_gen = NULL; afr_local_t *local = frame->local; xlator_t *this = frame->this; char *wind_on = alloca0(priv->child_count); gf_boolean_t retry = _gf_true; frame->root->pid = info->pid; lk_owner_copy(&frame->root->lk_owner, &info->lk_owner); op_errno = -afr_dom_lock_acquire(frame); if ((op_errno != 0)) { goto release; } if (!afr_does_lk_owner_match(frame, priv, info)) { gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_LK_HEAL_DOM, "Ignoring lock heal for %s since lk-onwers mismatch. " "Lock possibly pre-empted by another client.", uuid_utoa(info->fd->inode->gfid)); goto release; } for (i = 0; i < priv->child_count; i++) { if (info->locked_nodes[i]) continue; wind_on[i] = 1; } current_event_gen = alloca(priv->child_count * sizeof(*current_event_gen)); memcpy(current_event_gen, info->child_up_event_gen, priv->child_count * sizeof *current_event_gen); AFR_ONLIST(wind_on, frame, afr_lock_heal_cbk, lk, info->fd, info->cmd, &info->flock, info->xdata_req); LOCK(&priv->lock); { for (i = 0; i < priv->child_count; i++) { if (!wind_on[i]) continue; if ((!local->replies[i].valid) || (local->replies[i].op_ret != 0)) { continue; } if ((current_event_gen[i] == info->child_up_event_gen[i]) && (current_event_gen[i] > info->child_down_event_gen[i])) { info->locked_nodes[i] = 1; retry = _gf_false; list_del_init(&info->pos); list_add_tail(&info->pos, &priv->saved_locks); } else { /*We received subsequent child up/down events while heal was in * progress; don't mark child as healed. Attempt again on the * new child up*/ gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_LK_HEAL_DOM, "Event gen mismatch: skipped healing lock on child %d " "for %s.", i, uuid_utoa(info->fd->inode->gfid)); } } } UNLOCK(&priv->lock); release: afr_dom_lock_release(frame); if (retry) afr_add_lock_to_lkhealq(priv, info); return; } static int afr_lock_heal_done(int ret, call_frame_t *frame, void *opaque) { STACK_DESTROY(frame->root); return 0; } static int afr_lock_heal(void *opaque) { call_frame_t *frame = (call_frame_t *)opaque; call_frame_t *iter_frame = NULL; xlator_t *this = frame->this; afr_private_t *priv = this->private; afr_lk_heal_info_t *info = NULL; afr_lk_heal_info_t *tmp = NULL; struct list_head healq = { 0, }; int ret = 0; iter_frame = afr_copy_frame(frame); if (!iter_frame) { return ENOMEM; } INIT_LIST_HEAD(&healq); LOCK(&priv->lock); { list_splice_init(&priv->lk_healq, &healq); } UNLOCK(&priv->lock); list_for_each_entry_safe(info, tmp, &healq, pos) { GF_ASSERT((AFR_COUNT(info->locked_nodes, priv->child_count) < priv->child_count)); ((afr_local_t *)(iter_frame->local))->fd = fd_ref(info->fd); afr_lock_heal_do(iter_frame, priv, info); AFR_STACK_RESET(iter_frame); if (iter_frame->local == NULL) { ret = ENOTCONN; gf_msg(frame->this->name, GF_LOG_ERROR, ENOTCONN, AFR_MSG_LK_HEAL_DOM, "Aborting processing of lk_healq." "Healing will be reattempted on next child up for locks " "that are still in quorum."); LOCK(&priv->lock); { list_add_tail(&healq, &priv->lk_healq); } UNLOCK(&priv->lock); break; } } AFR_STACK_DESTROY(iter_frame); return ret; } static int __afr_lock_heal_synctask(xlator_t *this, afr_private_t *priv, int child) { int ret = 0; call_frame_t *frame = NULL; afr_lk_heal_info_t *info = NULL; afr_lk_heal_info_t *tmp = NULL; if (priv->shd.iamshd) return 0; list_for_each_entry_safe(info, tmp, &priv->saved_locks, pos) { info->child_up_event_gen[child] = priv->event_generation; list_del_init(&info->pos); list_add_tail(&info->pos, &priv->lk_healq); } frame = create_frame(this, this->ctx->pool); if (!frame) return -1; ret = synctask_new(this->ctx->env, afr_lock_heal, afr_lock_heal_done, frame, frame); if (ret) gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_LK_HEAL_DOM, "Failed to launch lock heal synctask"); return ret; } static int __afr_mark_pending_lk_heal(xlator_t *this, afr_private_t *priv, int child) { afr_lk_heal_info_t *info = NULL; afr_lk_heal_info_t *tmp = NULL; if (priv->shd.iamshd) return 0; list_for_each_entry_safe(info, tmp, &priv->saved_locks, pos) { info->child_down_event_gen[child] = priv->event_generation; if (info->locked_nodes[child] == 1) info->locked_nodes[child] = 0; if (!afr_has_quorum(info->locked_nodes, priv, NULL)) { /* Since the lock was lost on quorum no. of nodes, we should * not attempt to heal it anymore. Some other client could have * acquired the lock, modified data and released it and this * client wouldn't know about it if we heal it.*/ afr_mark_fd_bad(info->fd, this); list_del(&info->pos); afr_lk_heal_info_cleanup(info); /* We're not winding an unlock on the node where the lock is still * present because when fencing logic switches over to the new * client (since we marked the fd bad), it should preempt any * existing lock. */ } } return 0; } gf_boolean_t afr_is_consistent_io_possible(afr_local_t *local, afr_private_t *priv, int32_t *op_errno) { if (priv->consistent_io && local->call_count != priv->child_count) { gf_msg(THIS->name, GF_LOG_INFO, 0, AFR_MSG_SUBVOLS_DOWN, "All subvolumes are not up"); if (op_errno) *op_errno = ENOTCONN; return _gf_false; } return _gf_true; } gf_boolean_t afr_is_lock_mode_mandatory(dict_t *xdata) { int ret = 0; uint32_t lk_mode = GF_LK_ADVISORY; ret = dict_get_uint32(xdata, GF_LOCK_MODE, &lk_mode); if (!ret && lk_mode == GF_LK_MANDATORY) return _gf_true; return _gf_false; } call_frame_t * afr_copy_frame(call_frame_t *base) { afr_local_t *local = NULL; call_frame_t *frame = NULL; int op_errno = 0; frame = copy_frame(base); if (!frame) return NULL; local = AFR_FRAME_INIT(frame, op_errno); if (!local) { AFR_STACK_DESTROY(frame); return NULL; } return frame; } /* Check if an entry or inode could be undergoing a transaction. */ static gf_boolean_t afr_is_possibly_under_txn(afr_transaction_type type, afr_local_t *local, const unsigned int child_count) { int i = 0; int tmp = 0; GF_UNUSED char *key = NULL; int keylen = 0; if (type == AFR_ENTRY_TRANSACTION) { key = GLUSTERFS_PARENT_ENTRYLK; keylen = SLEN(GLUSTERFS_PARENT_ENTRYLK); } else if (type == AFR_DATA_TRANSACTION) { /*FIXME: Use GLUSTERFS_INODELK_DOM_COUNT etc. once * pl_inodelk_xattr_fill supports separate keys for different * domains.*/ key = GLUSTERFS_INODELK_COUNT; keylen = SLEN(GLUSTERFS_INODELK_COUNT); } for (i = 0; i < child_count; i++) { if (!local->replies[i].xdata) continue; if (dict_get_int32n(local->replies[i].xdata, key, keylen, &tmp) == 0) if (tmp) return _gf_true; } return _gf_false; } static void afr_inode_ctx_destroy(afr_inode_ctx_t *ctx) { int i = 0; if (!ctx) return; for (i = 0; i < AFR_NUM_CHANGE_LOGS; i++) { GF_FREE(ctx->pre_op_done[i]); } GF_FREE(ctx); } afr_inode_ctx_t * __afr_inode_ctx_get(xlator_t *this, inode_t *inode) { uint64_t ctx_int = 0; int ret; int i; int num_locks; afr_inode_ctx_t *ictx = NULL; afr_lock_t *lock = NULL; afr_private_t *priv = NULL; ret = __inode_ctx_get(inode, this, &ctx_int); if (ret == 0) { ictx = (afr_inode_ctx_t *)(uintptr_t)ctx_int; goto out; } ictx = GF_CALLOC(1, sizeof(afr_inode_ctx_t), gf_afr_mt_inode_ctx_t); if (!ictx) goto err; priv = this->private; for (i = 0; i < AFR_NUM_CHANGE_LOGS; i++) { ictx->pre_op_done[i] = GF_CALLOC(sizeof *ictx->pre_op_done[i], priv->child_count, gf_afr_mt_int32_t); if (!ictx->pre_op_done[i]) { goto err; } } num_locks = sizeof(ictx->lock) / sizeof(afr_lock_t); for (i = 0; i < num_locks; i++) { lock = &ictx->lock[i]; INIT_LIST_HEAD(&lock->post_op); INIT_LIST_HEAD(&lock->frozen); INIT_LIST_HEAD(&lock->waiting); INIT_LIST_HEAD(&lock->owners); } ctx_int = (uint64_t)(uintptr_t)ictx; ret = __inode_ctx_set(inode, this, &ctx_int); if (ret) { goto err; } ictx->spb_choice = -1; ictx->read_subvol = 0; ictx->write_subvol = 0; ictx->lock_count = 0; out: return ictx; err: if (ictx) { afr_inode_ctx_destroy(ictx); } return NULL; } /* * INODE CTX 64-bit VALUE FORMAT FOR SMALL (<= 16) SUBVOL COUNTS: * * |<---------- 64bit ------------>| * 63 32 31 16 15 0 * | EVENT_GEN | DATA | METADATA | * * * METADATA (bit-0 .. bit-15): bitmap representing subvolumes from which * metadata can be attempted to be read. * * bit-0 => priv->subvolumes[0] * bit-1 => priv->subvolumes[1] * ... etc. till bit-15 * * DATA (bit-16 .. bit-31): bitmap representing subvolumes from which data * can be attempted to be read. * * bit-16 => priv->subvolumes[0] * bit-17 => priv->subvolumes[1] * ... etc. till bit-31 * * EVENT_GEN (bit-32 .. bit-63): event generation (i.e priv->event_generation) * when DATA and METADATA was last updated. * * If EVENT_GEN is < priv->event_generation, * or is 0, it means afr_inode_refresh() needs * to be called to recalculate the bitmaps. */ static int __afr_set_in_flight_sb_status(xlator_t *this, afr_local_t *local, inode_t *inode) { int i = 0; int txn_type = 0; int count = 0; int index = -1; uint16_t datamap_old = 0; uint16_t metadatamap_old = 0; uint16_t datamap = 0; uint16_t metadatamap = 0; uint16_t tmp_map = 0; uint16_t mask = 0; uint32_t event = 0; uint64_t val = 0; afr_private_t *priv = NULL; priv = this->private; txn_type = local->transaction.type; if (txn_type == AFR_DATA_TRANSACTION) val = local->inode_ctx->write_subvol; else val = local->inode_ctx->read_subvol; metadatamap_old = metadatamap = (val & 0x000000000000ffff); datamap_old = datamap = (val & 0x00000000ffff0000) >> 16; event = (val & 0xffffffff00000000) >> 32; if (txn_type == AFR_DATA_TRANSACTION) tmp_map = datamap; else if (txn_type == AFR_METADATA_TRANSACTION) tmp_map = metadatamap; count = gf_bits_count(tmp_map); for (i = 0; i < priv->child_count; i++) { if (!local->transaction.failed_subvols[i]) continue; mask = 1 << i; if (txn_type == AFR_METADATA_TRANSACTION) metadatamap &= ~mask; else if (txn_type == AFR_DATA_TRANSACTION) datamap &= ~mask; } switch (txn_type) { case AFR_METADATA_TRANSACTION: if ((metadatamap_old != 0) && (metadatamap == 0) && (count == 1)) { index = gf_bits_index(tmp_map); local->transaction.in_flight_sb_errno = local->replies[index] .op_errno; local->transaction.in_flight_sb = _gf_true; metadatamap |= (1 << index); } if (metadatamap_old != metadatamap) { __afr_inode_need_refresh_set(inode, this); } break; case AFR_DATA_TRANSACTION: if ((datamap_old != 0) && (datamap == 0) && (count == 1)) { index = gf_bits_index(tmp_map); local->transaction.in_flight_sb_errno = local->replies[index] .op_errno; local->transaction.in_flight_sb = _gf_true; datamap |= (1 << index); } if (datamap_old != datamap) __afr_inode_need_refresh_set(inode, this); break; default: break; } val = ((uint64_t)metadatamap) | (((uint64_t)datamap) << 16) | (((uint64_t)event) << 32); if (txn_type == AFR_DATA_TRANSACTION) local->inode_ctx->write_subvol = val; local->inode_ctx->read_subvol = val; return 0; } gf_boolean_t afr_is_symmetric_error(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int op_errno = 0; int i_errno = 0; gf_boolean_t matching_errors = _gf_true; int i = 0; priv = this->private; local = frame->local; for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret != -1) { /* Operation succeeded on at least one subvol, so it is not a failed-everywhere situation. */ matching_errors = _gf_false; break; } i_errno = local->replies[i].op_errno; if (i_errno == ENOTCONN) { /* ENOTCONN is not a symmetric error. We do not know if the operation was performed on the backend or not. */ matching_errors = _gf_false; break; } if (!op_errno) { op_errno = i_errno; } else if (op_errno != i_errno) { /* Mismatching op_errno's */ matching_errors = _gf_false; break; } } return matching_errors; } int afr_set_in_flight_sb_status(xlator_t *this, call_frame_t *frame, inode_t *inode) { int ret = -1; afr_private_t *priv = NULL; afr_local_t *local = NULL; priv = this->private; local = frame->local; /* If this transaction saw no failures, then exit. */ if (AFR_COUNT(local->transaction.failed_subvols, priv->child_count) == 0) return 0; if (afr_is_symmetric_error(frame, this)) return 0; LOCK(&inode->lock); { ret = __afr_set_in_flight_sb_status(this, local, inode); } UNLOCK(&inode->lock); return ret; } static int __afr_inode_read_subvol_get_small(inode_t *inode, xlator_t *this, unsigned char *data, unsigned char *metadata, int *event_p) { afr_private_t *priv = NULL; uint16_t datamap = 0; uint16_t metadatamap = 0; uint32_t event = 0; uint64_t val = 0; int i = 0; afr_inode_ctx_t *ctx = NULL; priv = this->private; ctx = __afr_inode_ctx_get(this, inode); if (ctx == NULL) return -1; val = ctx->read_subvol; metadatamap = (val & 0x000000000000ffff); datamap = (val & 0x00000000ffff0000) >> 16; event = (val & 0xffffffff00000000) >> 32; for (i = 0; i < priv->child_count; i++) { if (metadata) metadata[i] = (metadatamap >> i) & 1; if (data) data[i] = (datamap >> i) & 1; } if (event_p) *event_p = event; return 0; } static int __afr_inode_read_subvol_set_small(inode_t *inode, xlator_t *this, unsigned char *data, unsigned char *metadata, int event) { afr_private_t *priv = NULL; uint16_t datamap = 0; uint16_t metadatamap = 0; uint64_t val = 0; int i = 0; afr_inode_ctx_t *ctx = NULL; priv = this->private; ctx = __afr_inode_ctx_get(this, inode); if (ctx == NULL) return -1; for (i = 0; i < priv->child_count; i++) { if (data[i]) datamap |= (1 << i); if (metadata[i]) metadatamap |= (1 << i); } val = ((uint64_t)metadatamap) | (((uint64_t)datamap) << 16) | (((uint64_t)event) << 32); ctx->read_subvol = val; return 0; } static int __afr_inode_read_subvol_get(inode_t *inode, xlator_t *this, unsigned char *data, unsigned char *metadata, int *event_p) { afr_private_t *priv = NULL; int ret = -1; priv = this->private; if (priv->child_count <= 16) ret = __afr_inode_read_subvol_get_small(inode, this, data, metadata, event_p); else /* TBD: allocate structure with array and read from it */ ret = -1; return ret; } static int __afr_inode_read_subvol_set(inode_t *inode, xlator_t *this, unsigned char *data, unsigned char *metadata, int event) { afr_private_t *priv = NULL; int ret = -1; priv = this->private; if (priv->child_count <= 16) ret = __afr_inode_read_subvol_set_small(inode, this, data, metadata, event); else ret = -1; return ret; } static int __afr_inode_split_brain_choice_set(inode_t *inode, xlator_t *this, int spb_choice) { afr_inode_ctx_t *ctx = NULL; ctx = __afr_inode_ctx_get(this, inode); if (ctx == NULL) return -1; ctx->spb_choice = spb_choice; return 0; } int afr_inode_read_subvol_get(inode_t *inode, xlator_t *this, unsigned char *data, unsigned char *metadata, int *event_p) { int ret = -1; GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { ret = __afr_inode_read_subvol_get(inode, this, data, metadata, event_p); } UNLOCK(&inode->lock); out: return ret; } int afr_inode_get_readable(call_frame_t *frame, inode_t *inode, xlator_t *this, unsigned char *readable, int *event_p, int type) { afr_private_t *priv = this->private; afr_local_t *local = frame->local; unsigned char *data = alloca0(priv->child_count); unsigned char *metadata = alloca0(priv->child_count); int data_count = 0; int metadata_count = 0; int event_generation = 0; int ret = 0; ret = afr_inode_read_subvol_get(inode, this, data, metadata, &event_generation); if (ret == -1) return -EIO; data_count = AFR_COUNT(data, priv->child_count); metadata_count = AFR_COUNT(metadata, priv->child_count); if (inode->ia_type == IA_IFDIR) { /* For directories, allow even if it is in data split-brain. */ if (type == AFR_METADATA_TRANSACTION || local->op == GF_FOP_STAT || local->op == GF_FOP_FSTAT) { if (!metadata_count) return -EIO; } } else { /* For files, abort in case of data/metadata split-brain. */ if (!data_count || !metadata_count) { return -EIO; } } if (type == AFR_METADATA_TRANSACTION && readable) memcpy(readable, metadata, priv->child_count * sizeof *metadata); if (type == AFR_DATA_TRANSACTION && readable) { if (!data_count) memcpy(readable, local->child_up, priv->child_count * sizeof *readable); else memcpy(readable, data, priv->child_count * sizeof *data); } if (event_p) *event_p = event_generation; return 0; } static int afr_inode_split_brain_choice_get(inode_t *inode, xlator_t *this, int *spb_choice) { int ret = 0; afr_inode_ctx_t *ctx = NULL; LOCK(&inode->lock); { ctx = __afr_inode_ctx_get(this, inode); if (ctx) { *spb_choice = ctx->spb_choice; } else { ret = -1; } } UNLOCK(&inode->lock); return ret; } /* * frame is used to get the favourite policy. Since * afr_inode_split_brain_choice_get was called with afr_open, it is possible to * have a frame with out local->replies. So in that case, frame is passed as * null, hence this function will handle the frame NULL case. */ int afr_split_brain_read_subvol_get(inode_t *inode, xlator_t *this, call_frame_t *frame, int *spb_subvol) { int ret = -1; afr_local_t *local = NULL; afr_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("afr", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); GF_VALIDATE_OR_GOTO(this->name, spb_subvol, out); priv = this->private; ret = afr_inode_split_brain_choice_get(inode, this, spb_subvol); if (*spb_subvol < 0 && priv->fav_child_policy && frame && frame->local) { local = frame->local; *spb_subvol = afr_sh_get_fav_by_policy(this, local->replies, inode, NULL); if (*spb_subvol >= 0) { ret = 0; } } out: return ret; } static int afr_inode_read_subvol_set(inode_t *inode, xlator_t *this, unsigned char *data, unsigned char *metadata, int event) { int ret = -1; GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { ret = __afr_inode_read_subvol_set(inode, this, data, metadata, event); } UNLOCK(&inode->lock); out: return ret; } int afr_inode_split_brain_choice_set(inode_t *inode, xlator_t *this, int spb_choice) { int ret = -1; GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { ret = __afr_inode_split_brain_choice_set(inode, this, spb_choice); } UNLOCK(&inode->lock); out: return ret; } /* The caller of this should perform afr_inode_refresh, if this function * returns _gf_true */ gf_boolean_t afr_is_inode_refresh_reqd(inode_t *inode, xlator_t *this, int event_gen1, int event_gen2) { gf_boolean_t need_refresh = _gf_false; afr_inode_ctx_t *ctx = NULL; GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { ctx = __afr_inode_ctx_get(this, inode); if (ctx == NULL) goto unlock; need_refresh = ctx->need_refresh; /* Hoping that the caller will do inode_refresh followed by * this, hence setting the need_refresh to false */ ctx->need_refresh = _gf_false; } unlock: UNLOCK(&inode->lock); if (event_gen1 != event_gen2) need_refresh = _gf_true; out: return need_refresh; } static int __afr_inode_need_refresh_set(inode_t *inode, xlator_t *this) { afr_inode_ctx_t *ctx = NULL; ctx = __afr_inode_ctx_get(this, inode); if (ctx) { ctx->need_refresh = _gf_true; return 0; } return -1; } int afr_inode_need_refresh_set(inode_t *inode, xlator_t *this) { int ret = -1; GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { ret = __afr_inode_need_refresh_set(inode, this); } UNLOCK(&inode->lock); out: return ret; } static void afr_spb_choice_timeout_cancel(xlator_t *this, inode_t *inode) { afr_inode_ctx_t *ctx = NULL; if (!inode) return; LOCK(&inode->lock); { ctx = __afr_inode_ctx_get(this, inode); if (ctx == NULL) { UNLOCK(&inode->lock); gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_SPLIT_BRAIN_CHOICE_ERROR, "Failed to cancel split-brain choice timer."); return; } ctx->spb_choice = -1; if (ctx->timer) { gf_timer_call_cancel(this->ctx, ctx->timer); ctx->timer = NULL; } } UNLOCK(&inode->lock); } static void afr_set_split_brain_choice_cbk(void *data) { inode_t *inode = data; xlator_t *this = THIS; afr_spb_choice_timeout_cancel(this, inode); inode_invalidate(inode); inode_unref(inode); return; } int afr_set_split_brain_choice(int ret, call_frame_t *frame, void *opaque) { int op_errno = ENOMEM; afr_private_t *priv = NULL; afr_inode_ctx_t *ctx = NULL; inode_t *inode = NULL; loc_t *loc = NULL; xlator_t *this = NULL; afr_spbc_timeout_t *data = opaque; struct timespec delta = { 0, }; gf_boolean_t timer_set = _gf_false; gf_boolean_t timer_cancelled = _gf_false; gf_boolean_t timer_reset = _gf_false; int old_spb_choice = -1; frame = data->frame; loc = data->loc; this = frame->this; priv = this->private; if (ret) { op_errno = -ret; ret = -1; goto out; } delta.tv_sec = priv->spb_choice_timeout; delta.tv_nsec = 0; if (!loc->inode) { ret = -1; op_errno = EINVAL; goto out; } if (!(data->d_spb || data->m_spb)) { gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_SPLIT_BRAIN_CHOICE_ERROR, "Cannot set " "replica.split-brain-choice on %s. File is" " not in data/metadata split-brain.", uuid_utoa(loc->gfid)); ret = -1; op_errno = EINVAL; goto out; } /* * we're ref'ing the inode before LOCK like it is done elsewhere in the * code. If we ref after LOCK, coverity complains of possible deadlocks. */ inode = inode_ref(loc->inode); LOCK(&inode->lock); { ctx = __afr_inode_ctx_get(this, inode); if (ctx == NULL) { UNLOCK(&inode->lock); ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN_CHOICE_ERROR, "Failed to get inode_ctx for %s", loc->name); goto post_unlock; } else { ret = 0; } old_spb_choice = ctx->spb_choice; ctx->spb_choice = data->spb_child_index; /* Possible changes in spb-choice : * valid to -1 : cancel timer and unref * valid to valid : cancel timer and inject new one * -1 to -1 : unref and do not do anything * -1 to valid : inject timer */ /* ctx->timer is NULL iff previous value of * ctx->spb_choice is -1 */ if (ctx->timer) { if (ctx->spb_choice == -1) { if (!gf_timer_call_cancel(this->ctx, ctx->timer)) { ctx->timer = NULL; timer_cancelled = _gf_true; } /* If timer cancel failed here it means that the * previous cbk will be executed which will set * spb_choice to -1. So we can consider the * 'valid to -1' case to be a success * (i.e. ret = 0) and goto unlock. */ goto unlock; } goto reset_timer; } else { if (ctx->spb_choice == -1) goto unlock; goto set_timer; } reset_timer: ret = gf_timer_call_cancel(this->ctx, ctx->timer); if (ret != 0) { /* We need to bail out now instead of launching a new * timer. Otherwise the cbk of the previous timer event * will cancel the new ctx->timer. */ ctx->spb_choice = old_spb_choice; ret = -1; op_errno = EAGAIN; goto unlock; } ctx->timer = NULL; timer_reset = _gf_true; set_timer: ctx->timer = gf_timer_call_after(this->ctx, delta, afr_set_split_brain_choice_cbk, inode); if (!ctx->timer) { ctx->spb_choice = old_spb_choice; ret = -1; op_errno = ENOMEM; } if (!timer_reset && ctx->timer) timer_set = _gf_true; if (timer_reset && !ctx->timer) timer_cancelled = _gf_true; } unlock: UNLOCK(&inode->lock); post_unlock: if (!timer_set) inode_unref(inode); if (timer_cancelled) inode_unref(inode); /* * We need to invalidate the inode to prevent the kernel from serving * reads from an older cached value despite a change in spb_choice to * a new value. */ inode_invalidate(inode); out: GF_FREE(data); AFR_STACK_UNWIND(setxattr, frame, ret, op_errno, NULL); return 0; } static int afr_accused_fill(afr_private_t *priv, dict_t *xdata, unsigned char *accused, afr_transaction_type type) { int i = 0; int idx = afr_index_for_transaction_type(type); void *pending_raw = NULL; int ret = 0; for (i = 0; i < priv->child_count; i++) { ret = dict_get_ptr(xdata, priv->pending_key[i], &pending_raw); if (ret) /* no pending flags */ continue; if (*((int *)pending_raw + idx)) accused[i] = 1; } return 0; } static int afr_accuse_smallfiles(afr_private_t *priv, struct afr_reply *replies, unsigned char *data_accused) { int i = 0; uint64_t maxsize = 0; for (i = 0; i < priv->child_count; i++) { if (replies[i].valid && replies[i].xdata && dict_get_sizen(replies[i].xdata, GLUSTERFS_BAD_INODE)) continue; if (data_accused[i]) continue; if (replies[i].poststat.ia_size > maxsize) maxsize = replies[i].poststat.ia_size; } for (i = 0; i < priv->child_count; i++) { if (data_accused[i]) continue; if (AFR_IS_ARBITER_BRICK(priv, i)) continue; if (replies[i].poststat.ia_size < maxsize) data_accused[i] = 1; } return 0; } static int afr_readables_fill(afr_local_t *local, xlator_t *this, inode_t *inode, unsigned char *data_accused, unsigned char *metadata_accused, unsigned char *data_readable, unsigned char *metadata_readable, struct afr_reply *replies) { afr_private_t *priv = NULL; dict_t *xdata = NULL; int i = 0; int ret = 0; ia_type_t ia_type = IA_INVAL; priv = this->private; for (i = 0; i < priv->child_count; i++) { data_readable[i] = 1; metadata_readable[i] = 1; } if (AFR_IS_ARBITER_BRICK(priv, ARBITER_BRICK_INDEX)) { data_readable[ARBITER_BRICK_INDEX] = 0; metadata_readable[ARBITER_BRICK_INDEX] = 0; } for (i = 0; i < priv->child_count; i++) { if (replies) { /* Lookup */ if (!replies[i].valid || replies[i].op_ret == -1 || (replies[i].xdata && dict_get_sizen(replies[i].xdata, GLUSTERFS_BAD_INODE))) { data_readable[i] = 0; metadata_readable[i] = 0; continue; } xdata = replies[i].xdata; ia_type = replies[i].poststat.ia_type; } else { /* pre-op xattrop */ xdata = local->transaction.changelog_xdata[i]; ia_type = inode->ia_type; } if (!xdata) continue; /* mkdir_cbk sends NULL xdata_rsp. */ afr_accused_fill(priv, xdata, data_accused, (ia_type == IA_IFDIR) ? AFR_ENTRY_TRANSACTION : AFR_DATA_TRANSACTION); afr_accused_fill(priv, xdata, metadata_accused, AFR_METADATA_TRANSACTION); } if (replies && ia_type != IA_INVAL && ia_type != IA_IFDIR && /* We want to accuse small files only when we know for * sure that there is no IO happening. Otherwise, the * ia_sizes obtained in post-refresh replies may * mismatch due to a race between inode-refresh and * ongoing writes, causing spurious heal launches*/ !afr_is_possibly_under_txn(AFR_DATA_TRANSACTION, local, priv->child_count)) { afr_accuse_smallfiles(priv, replies, data_accused); } for (i = 0; i < priv->child_count; i++) { if (data_accused[i]) { data_readable[i] = 0; ret = 1; } if (metadata_accused[i]) { metadata_readable[i] = 0; ret = 1; } } return ret; } int afr_replies_interpret(afr_local_t *local, xlator_t *this, inode_t *inode, gf_boolean_t *start_heal) { afr_private_t *priv = NULL; struct afr_reply *replies = NULL; int event_generation = 0; int i = 0; unsigned char *data_accused = NULL; unsigned char *metadata_accused = NULL; unsigned char *data_readable = NULL; unsigned char *metadata_readable = NULL; int ret = 0; priv = this->private; replies = local->replies; event_generation = local->event_generation; data_accused = alloca0(priv->child_count); data_readable = alloca0(priv->child_count); metadata_accused = alloca0(priv->child_count); metadata_readable = alloca0(priv->child_count); ret = afr_readables_fill(local, this, inode, data_accused, metadata_accused, data_readable, metadata_readable, replies); for (i = 0; i < priv->child_count; i++) { if (start_heal && priv->child_up[i] && (data_accused[i] || metadata_accused[i])) { *start_heal = _gf_true; break; } } afr_inode_read_subvol_set(inode, this, data_readable, metadata_readable, event_generation); return ret; } static int afr_refresh_selfheal_done(int ret, call_frame_t *heal, void *opaque) { if (heal) AFR_STACK_DESTROY(heal); return 0; } static int afr_inode_refresh_err(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; int err = 0; local = frame->local; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (local->replies[i].valid && !local->replies[i].op_ret) { err = 0; goto ret; } } err = afr_final_errno(local, priv); ret: return err; } static gf_boolean_t afr_selfheal_enabled(const xlator_t *this) { const afr_private_t *priv = this->private; return priv->data_self_heal || priv->metadata_self_heal || priv->entry_self_heal; } static int afr_txn_refresh_done(call_frame_t *frame, xlator_t *this, int err) { call_frame_t *heal_frame = NULL; afr_local_t *heal_local = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; inode_t *inode = NULL; int event_generation = 0; int read_subvol = -1; int ret = 0; local = frame->local; inode = local->inode; priv = this->private; if (err) goto refresh_done; if (local->op == GF_FOP_LOOKUP) goto refresh_done; ret = afr_inode_get_readable(frame, inode, this, local->readable, &event_generation, local->transaction.type); if (ret == -EIO) { /* No readable subvolume even after refresh ==> splitbrain.*/ if (!priv->fav_child_policy) { err = EIO; goto refresh_done; } read_subvol = afr_sh_get_fav_by_policy(this, local->replies, inode, NULL); if (read_subvol == -1) { err = EIO; goto refresh_done; } heal_frame = afr_frame_create(this, NULL); if (!heal_frame) { err = EIO; goto refresh_done; } heal_local = heal_frame->local; heal_local->xdata_req = dict_new(); if (!heal_local->xdata_req) { err = EIO; AFR_STACK_DESTROY(heal_frame); goto refresh_done; } heal_local->heal_frame = frame; ret = synctask_new(this->ctx->env, afr_fav_child_reset_sink_xattrs, afr_fav_child_reset_sink_xattrs_cbk, heal_frame, heal_frame); return 0; } refresh_done: afr_local_replies_wipe(local, this->private); local->refreshfn(frame, this, err); return 0; } static int afr_inode_refresh_done(call_frame_t *frame, xlator_t *this, int error) { call_frame_t *heal_frame = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; gf_boolean_t start_heal = _gf_false; afr_local_t *heal_local = NULL; unsigned char *success_replies = NULL; int ret = 0; if (error != 0) { goto refresh_done; } local = frame->local; priv = this->private; success_replies = alloca0(priv->child_count); afr_fill_success_replies(local, priv, success_replies); if (priv->thin_arbiter_count && local->is_read_txn && AFR_COUNT(success_replies, priv->child_count) != priv->child_count) { /* We need to query the good bricks and/or thin-arbiter.*/ if (success_replies[0]) { local->read_txn_query_child = AFR_CHILD_ZERO; } else if (success_replies[1]) { local->read_txn_query_child = AFR_CHILD_ONE; } error = EINVAL; goto refresh_done; } if (!afr_has_quorum(success_replies, priv, frame)) { error = afr_final_errno(frame->local, this->private); if (!error) error = afr_quorum_errno(priv); goto refresh_done; } ret = afr_replies_interpret(local, this, local->refreshinode, &start_heal); if (ret && afr_selfheal_enabled(this) && start_heal) { heal_frame = afr_frame_create(this, NULL); if (!heal_frame) goto refresh_done; heal_local = heal_frame->local; heal_local->refreshinode = inode_ref(local->refreshinode); heal_local->heal_frame = heal_frame; if (!afr_throttled_selfheal(heal_frame, this)) { AFR_STACK_DESTROY(heal_frame); goto refresh_done; } } refresh_done: afr_txn_refresh_done(frame, this, error); return 0; } static void afr_inode_refresh_subvol_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *buf, dict_t *xdata, struct iatt *par) { afr_local_t *local = NULL; int call_child = (long)cookie; int8_t need_heal = 1; int call_count = 0; int ret = 0; local = frame->local; local->replies[call_child].valid = 1; local->replies[call_child].op_ret = op_ret; local->replies[call_child].op_errno = op_errno; if (op_ret != -1) { local->replies[call_child].poststat = *buf; if (par) local->replies[call_child].postparent = *par; if (xdata) local->replies[call_child].xdata = dict_ref(xdata); } if (xdata) { ret = dict_get_int8(xdata, "link-count", &need_heal); if (ret) { gf_msg_debug(this->name, -ret, "Unable to get link count"); } } local->replies[call_child].need_heal = need_heal; call_count = afr_frame_return(frame); if (call_count == 0) { afr_set_need_heal(this, local); ret = afr_inode_refresh_err(frame, this); if (ret) { gf_msg_debug(this->name, ret, "afr_inode_refresh_err failed"); } afr_inode_refresh_done(frame, this, ret); } } static int afr_inode_refresh_subvol_with_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *par) { afr_inode_refresh_subvol_cbk(frame, cookie, this, op_ret, op_errno, buf, xdata, par); return 0; } static int afr_inode_refresh_subvol_with_lookup(call_frame_t *frame, xlator_t *this, int i, inode_t *inode, uuid_t gfid, dict_t *xdata) { loc_t loc = { 0, }; afr_private_t *priv = NULL; priv = this->private; loc.inode = inode; if (gf_uuid_is_null(inode->gfid) && gfid) { /* To handle setattr/setxattr on yet to be linked inode from * dht */ gf_uuid_copy(loc.gfid, gfid); } else { gf_uuid_copy(loc.gfid, inode->gfid); } STACK_WIND_COOKIE(frame, afr_inode_refresh_subvol_with_lookup_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->lookup, &loc, xdata); return 0; } int afr_inode_refresh_subvol_with_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { afr_inode_refresh_subvol_cbk(frame, cookie, this, op_ret, op_errno, buf, xdata, NULL); return 0; } static int afr_inode_refresh_subvol_with_fstat(call_frame_t *frame, xlator_t *this, int i, dict_t *xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; priv = this->private; local = frame->local; STACK_WIND_COOKIE(frame, afr_inode_refresh_subvol_with_fstat_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->fstat, local->fd, xdata); return 0; } static int afr_inode_refresh_do(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int call_count = 0; int i = 0; int ret = 0; dict_t *xdata = NULL; afr_fd_ctx_t *fd_ctx = NULL; unsigned char *wind_subvols = NULL; priv = this->private; local = frame->local; wind_subvols = alloca0(priv->child_count); afr_local_replies_wipe(local, priv); if (local->fd) { fd_ctx = afr_fd_ctx_get(local->fd, this); if (!fd_ctx) { afr_inode_refresh_done(frame, this, EINVAL); return 0; } } xdata = dict_new(); if (!xdata) { afr_inode_refresh_done(frame, this, ENOMEM); return 0; } ret = afr_xattr_req_prepare(this, xdata); if (ret != 0) { dict_unref(xdata); afr_inode_refresh_done(frame, this, -ret); return 0; } ret = dict_set_sizen_str_sizen(xdata, "link-count", GF_XATTROP_INDEX_COUNT); if (ret) { gf_msg_debug(this->name, -ret, "Unable to set link-count in dict "); } ret = dict_set_str_sizen(xdata, GLUSTERFS_INODELK_DOM_COUNT, this->name); if (ret) { gf_msg_debug(this->name, -ret, "Unable to set inodelk-dom-count in dict "); } if (local->fd) { for (i = 0; i < priv->child_count; i++) { if (local->child_up[i] && fd_ctx->opened_on[i] == AFR_FD_OPENED) wind_subvols[i] = 1; } } else { memcpy(wind_subvols, local->child_up, sizeof(*local->child_up) * priv->child_count); } local->call_count = AFR_COUNT(wind_subvols, priv->child_count); call_count = local->call_count; if (!call_count) { dict_unref(xdata); if (local->fd && AFR_COUNT(local->child_up, priv->child_count)) afr_inode_refresh_done(frame, this, EBADFD); else afr_inode_refresh_done(frame, this, ENOTCONN); return 0; } for (i = 0; i < priv->child_count; i++) { if (!wind_subvols[i]) continue; if (local->fd) afr_inode_refresh_subvol_with_fstat(frame, this, i, xdata); else afr_inode_refresh_subvol_with_lookup( frame, this, i, local->refreshinode, local->refreshgfid, xdata); if (!--call_count) break; } dict_unref(xdata); return 0; } int afr_inode_refresh(call_frame_t *frame, xlator_t *this, inode_t *inode, uuid_t gfid, afr_inode_refresh_cbk_t refreshfn) { afr_local_t *local = NULL; local = frame->local; local->refreshfn = refreshfn; if (local->refreshinode) { inode_unref(local->refreshinode); local->refreshinode = NULL; } local->refreshinode = inode_ref(inode); if (gfid) gf_uuid_copy(local->refreshgfid, gfid); else gf_uuid_clear(local->refreshgfid); afr_inode_refresh_do(frame, this); return 0; } int afr_xattr_req_prepare(xlator_t *this, dict_t *xattr_req) { int i = 0; afr_private_t *priv = NULL; int ret = 0; priv = this->private; for (i = 0; i < priv->child_count; i++) { ret = dict_set_uint64(xattr_req, priv->pending_key[i], AFR_NUM_CHANGE_LOGS * sizeof(int)); if (ret < 0) gf_msg(this->name, GF_LOG_WARNING, -ret, AFR_MSG_DICT_SET_FAILED, "Unable to set dict value for %s", priv->pending_key[i]); /* 3 = data+metadata+entry */ } ret = dict_set_uint64(xattr_req, AFR_DIRTY, AFR_NUM_CHANGE_LOGS * sizeof(int)); if (ret) { gf_msg_debug(this->name, -ret, "failed to set dirty " "query flag"); } ret = dict_set_int32_sizen(xattr_req, "list-xattr", 1); if (ret) { gf_msg_debug(this->name, -ret, "Unable to set list-xattr in dict "); } return ret; } static int afr_lookup_xattr_req_prepare(afr_local_t *local, xlator_t *this, dict_t *xattr_req, loc_t *loc) { int ret = -ENOMEM; if (!local->xattr_req) local->xattr_req = dict_new(); if (!local->xattr_req) goto out; if (xattr_req && (xattr_req != local->xattr_req)) dict_copy(xattr_req, local->xattr_req); ret = afr_xattr_req_prepare(this, local->xattr_req); ret = dict_set_uint64(local->xattr_req, GLUSTERFS_INODELK_COUNT, 0); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -ret, AFR_MSG_DICT_SET_FAILED, "%s: Unable to set dict value for %s", loc->path, GLUSTERFS_INODELK_COUNT); } ret = dict_set_uint64(local->xattr_req, GLUSTERFS_ENTRYLK_COUNT, 0); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -ret, AFR_MSG_DICT_SET_FAILED, "%s: Unable to set dict value for %s", loc->path, GLUSTERFS_ENTRYLK_COUNT); } ret = dict_set_uint32(local->xattr_req, GLUSTERFS_PARENT_ENTRYLK, 0); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -ret, AFR_MSG_DICT_SET_FAILED, "%s: Unable to set dict value for %s", loc->path, GLUSTERFS_PARENT_ENTRYLK); } ret = dict_set_sizen_str_sizen(local->xattr_req, "link-count", GF_XATTROP_INDEX_COUNT); if (ret) { gf_msg_debug(this->name, -ret, "Unable to set link-count in dict "); } ret = 0; out: return ret; } static int afr_least_pending_reads_child(afr_private_t *priv, unsigned char *readable) { int i = 0; int child = -1; int64_t read_iter = -1; int64_t pending_read = -1; for (i = 0; i < priv->child_count; i++) { if (AFR_IS_ARBITER_BRICK(priv, i) || !readable[i]) continue; read_iter = GF_ATOMIC_GET(priv->pending_reads[i]); if (child == -1 || read_iter < pending_read) { pending_read = read_iter; child = i; } } return child; } static int32_t afr_least_latency_child(afr_private_t *priv, unsigned char *readable) { int32_t i = 0; int child = -1; for (i = 0; i < priv->child_count; i++) { if (AFR_IS_ARBITER_BRICK(priv, i) || !readable[i] || priv->child_latency[i] < 0) continue; if (child == -1 || priv->child_latency[i] < priv->child_latency[child]) { child = i; } } return child; } static int32_t afr_least_latency_times_pending_reads_child(afr_private_t *priv, unsigned char *readable) { int32_t i = 0; int child = -1; int64_t pending_read = 0; int64_t latency = -1; int64_t least_latency = -1; for (i = 0; i < priv->child_count; i++) { if (AFR_IS_ARBITER_BRICK(priv, i) || !readable[i] || priv->child_latency[i] < 0) continue; pending_read = GF_ATOMIC_GET(priv->pending_reads[i]); latency = (pending_read + 1) * priv->child_latency[i]; if (child == -1 || latency < least_latency) { least_latency = latency; child = i; } } return child; } static int afr_hash_child(afr_read_subvol_args_t *args, afr_private_t *priv, unsigned char *readable) { uuid_t gfid_copy = { 0, }; pid_t pid; int child = -1; switch (priv->hash_mode) { case AFR_READ_POLICY_FIRST_UP: break; case AFR_READ_POLICY_GFID_HASH: gf_uuid_copy(gfid_copy, args->gfid); child = SuperFastHash((char *)gfid_copy, sizeof(gfid_copy)) % priv->child_count; break; case AFR_READ_POLICY_GFID_PID_HASH: if (args->ia_type != IA_IFDIR) { /* * Why getpid? Because it's one of the cheapest calls * available - faster than gethostname etc. - and * returns a constant-length value that's sure to be * shorter than a UUID. It's still very unlikely to be * the same across clients, so it still provides good * mixing. We're not trying for perfection here. All we * need is a low probability that multiple clients * won't converge on the same subvolume. */ gf_uuid_copy(gfid_copy, args->gfid); pid = getpid(); *(pid_t *)gfid_copy ^= pid; } child = SuperFastHash((char *)gfid_copy, sizeof(gfid_copy)) % priv->child_count; break; case AFR_READ_POLICY_LESS_LOAD: child = afr_least_pending_reads_child(priv, readable); break; case AFR_READ_POLICY_LEAST_LATENCY: child = afr_least_latency_child(priv, readable); break; case AFR_READ_POLICY_LOAD_LATENCY_HYBRID: child = afr_least_latency_times_pending_reads_child(priv, readable); break; } return child; } int afr_read_subvol_select_by_policy(inode_t *inode, xlator_t *this, unsigned char *readable, afr_read_subvol_args_t *args) { int i = 0; int read_subvol = -1; afr_private_t *priv = NULL; afr_read_subvol_args_t local_args = { 0, }; priv = this->private; /* first preference - explicitly specified or local subvolume */ if (priv->read_child >= 0 && readable[priv->read_child]) return priv->read_child; if (inode_is_linked(inode)) { gf_uuid_copy(local_args.gfid, inode->gfid); local_args.ia_type = inode->ia_type; } else if (args) { local_args = *args; } /* second preference - use hashed mode */ read_subvol = afr_hash_child(&local_args, priv, readable); if (read_subvol >= 0 && readable[read_subvol]) return read_subvol; for (i = 0; i < priv->child_count; i++) { if (readable[i]) return i; } /* no readable subvolumes, either split brain or all subvols down */ return -1; } static int afr_inode_read_subvol_type_get(inode_t *inode, xlator_t *this, unsigned char *readable, int *event_p, int type) { if (type == AFR_METADATA_TRANSACTION) return afr_inode_read_subvol_get(inode, this, 0, readable, event_p); else return afr_inode_read_subvol_get(inode, this, readable, 0, event_p); } static void afr_readables_intersect_get(inode_t *inode, xlator_t *this, int *event, unsigned char *intersection) { afr_private_t *priv = NULL; unsigned char *data_readable = NULL; unsigned char *metadata_readable = NULL; unsigned char *intersect = NULL; priv = this->private; data_readable = alloca0(priv->child_count); metadata_readable = alloca0(priv->child_count); intersect = alloca0(priv->child_count); afr_inode_read_subvol_get(inode, this, data_readable, metadata_readable, event); AFR_INTERSECT(intersect, data_readable, metadata_readable, priv->child_count); if (intersection) memcpy(intersection, intersect, sizeof(*intersection) * priv->child_count); } int afr_read_subvol_get(inode_t *inode, xlator_t *this, int *subvol_p, unsigned char *readables, int *event_p, afr_transaction_type type, afr_read_subvol_args_t *args) { afr_private_t *priv = NULL; unsigned char *readable = NULL; unsigned char *intersection = NULL; int subvol = -1; int event = 0; priv = this->private; readable = alloca0(priv->child_count); intersection = alloca0(priv->child_count); afr_inode_read_subvol_type_get(inode, this, readable, &event, type); afr_readables_intersect_get(inode, this, &event, intersection); if (AFR_COUNT(intersection, priv->child_count) > 0) subvol = afr_read_subvol_select_by_policy(inode, this, intersection, args); else subvol = afr_read_subvol_select_by_policy(inode, this, readable, args); if (subvol_p) *subvol_p = subvol; if (event_p) *event_p = event; if (readables) memcpy(readables, readable, sizeof(*readables) * priv->child_count); return subvol; } static void afr_local_transaction_cleanup(afr_local_t *local, unsigned int child_count) { int i = 0; afr_matrix_cleanup(local->pending, child_count); afr_lockees_cleanup(&local->internal_lock); GF_FREE(local->transaction.pre_op); GF_FREE(local->transaction.pre_op_sources); if (local->transaction.changelog_xdata) { for (i = 0; i < child_count; i++) { if (!local->transaction.changelog_xdata[i]) continue; dict_unref(local->transaction.changelog_xdata[i]); } GF_FREE(local->transaction.changelog_xdata); } GF_FREE(local->transaction.failed_subvols); GF_FREE(local->transaction.basename); GF_FREE(local->transaction.new_basename); loc_wipe(&local->transaction.parent_loc); loc_wipe(&local->transaction.new_parent_loc); } void afr_reply_wipe(struct afr_reply *reply) { if (reply->xdata) { dict_unref(reply->xdata); reply->xdata = NULL; } if (reply->xattr) { dict_unref(reply->xattr); reply->xattr = NULL; } } void afr_replies_wipe(struct afr_reply *replies, int count) { int i = 0; for (i = 0; i < count; i++) { afr_reply_wipe(&replies[i]); } } void afr_local_replies_wipe(afr_local_t *local, afr_private_t *priv) { if (!local->replies) return; afr_replies_wipe(local->replies, priv->child_count); memset(local->replies, 0, sizeof(*local->replies) * priv->child_count); } static gf_boolean_t afr_fop_lock_is_unlock(call_frame_t *frame) { afr_local_t *local = frame->local; switch (local->op) { case GF_FOP_INODELK: case GF_FOP_FINODELK: if ((F_UNLCK == local->cont.inodelk.in_flock.l_type) && (local->cont.inodelk.in_cmd == F_SETLKW || local->cont.inodelk.in_cmd == F_SETLK)) return _gf_true; break; case GF_FOP_ENTRYLK: case GF_FOP_FENTRYLK: if (ENTRYLK_UNLOCK == local->cont.entrylk.in_cmd) return _gf_true; break; default: return _gf_false; } return _gf_false; } static gf_boolean_t afr_lk_is_unlock(int32_t cmd, struct gf_flock *flock) { switch (cmd) { case F_RESLK_UNLCK: return _gf_true; break; #if F_SETLKW != F_SETLKW64 case F_SETLKW64: #endif case F_SETLKW: #if F_SETLK != F_SETLK64 case F_SETLK64: #endif case F_SETLK: if (F_UNLCK == flock->l_type) return _gf_true; break; default: return _gf_false; } return _gf_false; } void afr_handle_inconsistent_fop(call_frame_t *frame, int32_t *op_ret, int32_t *op_errno) { afr_private_t *priv = NULL; afr_local_t *local = NULL; if (!frame || !frame->this || !frame->local || !frame->this->private) return; if (*op_ret < 0) return; /* Failing inodelk/entrylk/lk here is not a good idea because we * need to cleanup the locks on the other bricks if we choose to fail * the fop here. The brick may go down just after unwind happens as well * so anyways the fop will fail when the next fop is sent so leaving * it like this for now.*/ local = frame->local; switch (local->op) { case GF_FOP_LOOKUP: case GF_FOP_INODELK: case GF_FOP_FINODELK: case GF_FOP_ENTRYLK: case GF_FOP_FENTRYLK: case GF_FOP_LK: return; default: break; } priv = frame->this->private; if (!priv->consistent_io) return; if (local->event_generation && (local->event_generation != priv->event_generation)) goto inconsistent; return; inconsistent: *op_ret = -1; *op_errno = ENOTCONN; } void afr_local_cleanup(afr_local_t *local, xlator_t *this) { afr_private_t *priv = NULL; if (!local) return; priv = this->private; syncbarrier_destroy(&local->barrier); afr_local_transaction_cleanup(local, priv->child_count); loc_wipe(&local->loc); loc_wipe(&local->newloc); if (local->fd) fd_unref(local->fd); if (local->xattr_req) dict_unref(local->xattr_req); if (local->xattr_rsp) dict_unref(local->xattr_rsp); if (local->dict) dict_unref(local->dict); afr_local_replies_wipe(local, priv); GF_FREE(local->replies); GF_FREE(local->child_up); GF_FREE(local->read_attempted); GF_FREE(local->readable); GF_FREE(local->readable2); if (local->inode) inode_unref(local->inode); if (local->parent) inode_unref(local->parent); if (local->parent2) inode_unref(local->parent2); if (local->refreshinode) inode_unref(local->refreshinode); { /* getxattr */ GF_FREE(local->cont.getxattr.name); } { /* lk */ GF_FREE(local->cont.lk.locked_nodes); GF_FREE(local->cont.lk.dom_locked_nodes); GF_FREE(local->cont.lk.dom_lock_op_ret); GF_FREE(local->cont.lk.dom_lock_op_errno); } { /* create */ if (local->cont.create.fd) fd_unref(local->cont.create.fd); if (local->cont.create.params) dict_unref(local->cont.create.params); } { /* mknod */ if (local->cont.mknod.params) dict_unref(local->cont.mknod.params); } { /* mkdir */ if (local->cont.mkdir.params) dict_unref(local->cont.mkdir.params); } { /* symlink */ if (local->cont.symlink.params) dict_unref(local->cont.symlink.params); } { /* writev */ GF_FREE(local->cont.writev.vector); if (local->cont.writev.iobref) iobref_unref(local->cont.writev.iobref); } { /* setxattr */ if (local->cont.setxattr.dict) dict_unref(local->cont.setxattr.dict); } { /* fsetxattr */ if (local->cont.fsetxattr.dict) dict_unref(local->cont.fsetxattr.dict); } { /* removexattr */ GF_FREE(local->cont.removexattr.name); } { /* xattrop */ if (local->cont.xattrop.xattr) dict_unref(local->cont.xattrop.xattr); } { /* symlink */ GF_FREE(local->cont.symlink.linkpath); } { /* opendir */ GF_FREE(local->cont.opendir.checksum); } { /* open */ if (local->cont.open.fd) fd_unref(local->cont.open.fd); } { /* readdirp */ if (local->cont.readdir.dict) dict_unref(local->cont.readdir.dict); } { /* inodelk */ GF_FREE(local->cont.inodelk.volume); if (local->cont.inodelk.xdata) dict_unref(local->cont.inodelk.xdata); } { /* entrylk */ GF_FREE(local->cont.entrylk.volume); GF_FREE(local->cont.entrylk.basename); if (local->cont.entrylk.xdata) dict_unref(local->cont.entrylk.xdata); } GF_FREE(local->need_open); if (local->xdata_req) dict_unref(local->xdata_req); if (local->xdata_rsp) dict_unref(local->xdata_rsp); } int afr_frame_return(call_frame_t *frame) { afr_local_t *local = NULL; int call_count = 0; local = frame->local; LOCK(&frame->lock); { call_count = --local->call_count; } UNLOCK(&frame->lock); return call_count; } static char *afr_ignore_xattrs[] = {GF_SELINUX_XATTR_KEY, QUOTA_SIZE_KEY, SQUOTA_SIZE_KEY, SQUOTA_LIMIT_KEY, NULL}; gf_boolean_t afr_is_xattr_ignorable(char *key) { int i = 0; if (!strncmp(key, AFR_XATTR_PREFIX, SLEN(AFR_XATTR_PREFIX))) return _gf_true; for (i = 0; afr_ignore_xattrs[i]; i++) { if (!strcmp(key, afr_ignore_xattrs[i])) return _gf_true; } return _gf_false; } static gf_boolean_t afr_xattr_match_needed(dict_t *this, char *key1, data_t *value1, void *data) { gf_boolean_t *is_arbiter = NULL; is_arbiter = data; /* Ignore all non-disk (i.e. virtual) xattrs right away. */ if (!gf_is_valid_xattr_namespace(key1)) return _gf_false; if (is_arbiter && *is_arbiter && !strcmp(key1, GF_XATTR_MDATA_KEY)) { return _gf_false; } /* Ignore on-disk xattrs that AFR doesn't need to heal. */ if (!afr_is_xattr_ignorable(key1)) return _gf_true; return _gf_false; } gf_boolean_t afr_xattrs_are_equal(dict_t *dict1, dict_t *dict2, gf_boolean_t is_arbiter) { return are_dicts_equal(dict1, dict2, afr_xattr_match_needed, &is_arbiter, NULL); } static int afr_get_parent_read_subvol(xlator_t *this, inode_t *parent, struct afr_reply *replies, unsigned char *readable) { int i = 0; int par_read_subvol = -1; int par_read_subvol_iter = -1; afr_private_t *priv = NULL; priv = this->private; if (parent) par_read_subvol = afr_data_subvol_get(parent, this, NULL, NULL, NULL, NULL); for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret < 0) continue; if (par_read_subvol_iter == -1) { par_read_subvol_iter = i; continue; } if ((par_read_subvol_iter != par_read_subvol) && readable[i]) par_read_subvol_iter = i; if (i == par_read_subvol) par_read_subvol_iter = i; } /* At the end of the for-loop, the only reason why @par_read_subvol_iter * could be -1 is when this LOOKUP has failed on all sub-volumes. * So it is okay to send an arbitrary subvolume (0 in this case) * as parent read subvol. */ if (par_read_subvol_iter == -1) par_read_subvol_iter = 0; return par_read_subvol_iter; } static int afr_read_subvol_decide(inode_t *inode, xlator_t *this, afr_read_subvol_args_t *args, unsigned char *readable) { int event = 0; afr_private_t *priv = NULL; unsigned char *intersection = NULL; priv = this->private; intersection = alloca0(priv->child_count); afr_readables_intersect_get(inode, this, &event, intersection); if (AFR_COUNT(intersection, priv->child_count) <= 0) { /* TODO: If we have one brick with valid data_readable and * another with metadata_readable, try to send an iatt with * valid bits from both.*/ return -1; } memcpy(readable, intersection, sizeof(*readable) * priv->child_count); return afr_read_subvol_select_by_policy(inode, this, intersection, args); } static inline int afr_first_up_child(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int i = 0; local = frame->local; priv = this->private; for (i = 0; i < priv->child_count; i++) if (local->replies[i].valid && local->replies[i].op_ret == 0) return i; return -1; } static void afr_attempt_readsubvol_set(call_frame_t *frame, xlator_t *this, unsigned char *success_replies, unsigned char *data_readable, int *read_subvol) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int spb_subvol = -1; int child_count = -1; if (*read_subvol != -1) return; priv = this->private; local = frame->local; child_count = priv->child_count; afr_split_brain_read_subvol_get(local->inode, this, frame, &spb_subvol); if ((spb_subvol >= 0) && (AFR_COUNT(success_replies, child_count) == child_count)) { *read_subvol = spb_subvol; } else if (!priv->quorum_count || frame->root->pid == GF_CLIENT_PID_GLFS_HEAL) { *read_subvol = afr_first_up_child(frame, this); } else if (priv->quorum_count && afr_has_quorum(data_readable, priv, NULL)) { /* read_subvol is guaranteed to be valid if we hit this path. */ *read_subvol = afr_first_up_child(frame, this); } else { /* If quorum is enabled and we do not have a readable yet, it means all good copies are down. */ local->op_ret = -1; local->op_errno = ENOTCONN; gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_READ_SUBVOL_ERROR, "no read " "subvols for %s", local->loc.path); } if (*read_subvol >= 0) dict_del_sizen(local->replies[*read_subvol].xdata, GF_CONTENT_KEY); } static void afr_lookup_done(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int i = -1; int op_errno = 0; int read_subvol = 0; int par_read_subvol = 0; int ret = -1; unsigned char *readable = NULL; unsigned char *success_replies = NULL; int event = 0; struct afr_reply *replies = NULL; uuid_t read_gfid = { 0, }; gf_boolean_t locked_entry = _gf_false; gf_boolean_t in_flight_create = _gf_false; gf_boolean_t can_interpret = _gf_true; inode_t *parent = NULL; ia_type_t ia_type = IA_INVAL; afr_read_subvol_args_t args = { 0, }; char *gfid_heal_msg = NULL; priv = this->private; local = frame->local; replies = local->replies; parent = local->loc.parent; locked_entry = afr_is_possibly_under_txn(AFR_ENTRY_TRANSACTION, local, priv->child_count); readable = alloca0(priv->child_count); success_replies = alloca0(priv->child_count); afr_inode_read_subvol_get(parent, this, readable, NULL, &event); par_read_subvol = afr_get_parent_read_subvol(this, parent, replies, readable); /* First, check if we have a gfid-change from somewhere, If so, propagate that so that a fresh lookup can be issued */ if (local->cont.lookup.needs_fresh_lookup) { local->op_ret = -1; local->op_errno = ESTALE; goto error; } op_errno = afr_final_errno(frame->local, this->private); local->op_errno = op_errno; read_subvol = -1; afr_fill_success_replies(local, priv, success_replies); for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret == -1) { if (locked_entry && replies[i].op_errno == ENOENT) { in_flight_create = _gf_true; } continue; } if (read_subvol == -1 || !readable[read_subvol]) { read_subvol = i; gf_uuid_copy(read_gfid, replies[i].poststat.ia_gfid); ia_type = replies[i].poststat.ia_type; local->op_ret = 0; } } if (in_flight_create && !afr_has_quorum(success_replies, priv, NULL)) { local->op_ret = -1; local->op_errno = ENOENT; goto error; } if (read_subvol == -1) goto error; /* We now have a read_subvol, which is readable[] (if there were any). Next we look for GFID mismatches. We don't consider a GFID mismatch as an error if read_subvol is readable[] but the mismatching GFID subvol is not. */ for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret == -1) { continue; } if (!gf_uuid_compare(replies[i].poststat.ia_gfid, read_gfid)) continue; can_interpret = _gf_false; if (locked_entry) continue; /* Now GFIDs mismatch. It's OK as long as this subvol is not readable[] but read_subvol is */ if (readable[read_subvol] && !readable[i]) continue; /* If we were called from glfsheal and there is still a gfid * mismatch, succeed the lookup and let glfsheal print the * response via gfid-heal-msg.*/ if (!dict_get_str_sizen(local->xattr_rsp, "gfid-heal-msg", &gfid_heal_msg)) goto cant_interpret; /* LOG ERROR */ local->op_ret = -1; local->op_errno = EIO; goto error; } /* Forth, for the finalized GFID, pick the best subvolume to return stats from. */ read_subvol = -1; memset(readable, 0, sizeof(*readable) * priv->child_count); if (can_interpret) { if (!afr_has_quorum(success_replies, priv, NULL)) goto cant_interpret; /* It is safe to call afr_replies_interpret() because we have a response from all the UP subvolumes and all of them resolved to the same GFID */ gf_uuid_copy(args.gfid, read_gfid); args.ia_type = ia_type; ret = afr_replies_interpret(local, this, local->inode, NULL); read_subvol = afr_read_subvol_decide(local->inode, this, &args, readable); if (read_subvol == -1) goto cant_interpret; if (ret) { afr_inode_need_refresh_set(local->inode, this); dict_del_sizen(local->replies[read_subvol].xdata, GF_CONTENT_KEY); } } else { cant_interpret: afr_attempt_readsubvol_set(frame, this, success_replies, readable, &read_subvol); if (read_subvol == -1) { goto error; } } afr_handle_quota_size(local, this); afr_set_need_heal(this, local); if (AFR_IS_ARBITER_BRICK(priv, read_subvol) && local->op_ret == 0) { local->op_ret = -1; local->op_errno = ENOTCONN; gf_msg_debug(this->name, 0, "Arbiter cannot be a read subvol " "for %s", local->loc.path); goto error; } ret = dict_get_str_sizen(local->xattr_rsp, "gfid-heal-msg", &gfid_heal_msg); if (!ret) { ret = dict_set_str_sizen(local->replies[read_subvol].xdata, "gfid-heal-msg", gfid_heal_msg); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_SET_FAILED, "Error setting gfid-heal-msg dict"); local->op_ret = -1; local->op_errno = ENOMEM; } } AFR_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, local->inode, &local->replies[read_subvol].poststat, local->replies[read_subvol].xdata, &local->replies[par_read_subvol].postparent); return; error: AFR_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, NULL, NULL, NULL, NULL); } /* * During a lookup, some errors are more "important" than * others in that they must be given higher priority while * returning to the user. * * The hierarchy is ENODATA > ENOENT > ESTALE > ENOSPC others */ int afr_higher_errno(int32_t old_errno, int32_t new_errno) { if (old_errno == ENODATA || new_errno == ENODATA) return ENODATA; if (old_errno == ENOENT || new_errno == ENOENT) return ENOENT; if (old_errno == ESTALE || new_errno == ESTALE) return ESTALE; if (old_errno == ENOSPC || new_errno == ENOSPC) return ENOSPC; return new_errno; } int afr_final_errno(afr_local_t *local, afr_private_t *priv) { int i = 0; int op_errno = 0; int tmp_errno = 0; for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret >= 0) continue; tmp_errno = local->replies[i].op_errno; op_errno = afr_higher_errno(op_errno, tmp_errno); } return op_errno; } static int32_t afr_local_discovery_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { int ret = 0; char *pathinfo = NULL; gf_boolean_t is_local = _gf_false; afr_private_t *priv = NULL; int32_t child_index = -1; if (op_ret != 0) { goto out; } priv = this->private; child_index = (int32_t)(long)cookie; ret = dict_get_str_sizen(dict, GF_XATTR_PATHINFO_KEY, &pathinfo); if (ret != 0) { goto out; } ret = glusterfs_is_local_pathinfo(pathinfo, &is_local); if (ret) { goto out; } /* * Note that one local subvolume will override another here. The only * way to avoid that would be to retain extra information about whether * the previous read_child is local, and it's just not worth it. Even * the slowest local subvolume is far preferable to a remote one. */ if (is_local) { priv->local[child_index] = 1; /* Don't set arbiter as read child. */ if (AFR_IS_ARBITER_BRICK(priv, child_index)) goto out; gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_LOCAL_CHILD, "selecting local read_child %s", priv->children[child_index]->name); priv->read_child = child_index; } out: STACK_DESTROY(frame->root); return 0; } static void afr_attempt_local_discovery(xlator_t *this, int32_t child_index) { call_frame_t *newframe = NULL; loc_t tmploc = { 0, }; afr_private_t *priv = this->private; newframe = create_frame(this, this->ctx->pool); if (!newframe) { return; } tmploc.gfid[sizeof(tmploc.gfid) - 1] = 1; STACK_WIND_COOKIE(newframe, afr_local_discovery_cbk, (void *)(long)child_index, priv->children[child_index], priv->children[child_index]->fops->getxattr, &tmploc, GF_XATTR_PATHINFO_KEY, NULL); } static int afr_lookup_sh_metadata_wrap(void *opaque) { call_frame_t *frame = opaque; afr_local_t *local = NULL; xlator_t *this = NULL; inode_t *inode = NULL; afr_private_t *priv = NULL; struct afr_reply *replies = NULL; int i = 0, first = -1; int ret = -1; dict_t *dict = NULL; local = frame->local; this = frame->this; priv = this->private; replies = local->replies; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret == -1) continue; first = i; break; } if (first == -1) goto out; if (afr_selfheal_metadata_by_stbuf(this, &replies[first].poststat)) goto out; afr_local_replies_wipe(local, this->private); dict = dict_new(); if (!dict) goto out; if (local->xattr_req) { dict_copy(local->xattr_req, dict); } ret = dict_set_sizen_str_sizen(dict, "link-count", GF_XATTROP_INDEX_COUNT); if (ret) { gf_msg_debug(this->name, -ret, "Unable to set link-count in dict "); } if (loc_is_nameless(&local->loc)) { ret = afr_selfheal_unlocked_discover_on(frame, local->inode, local->loc.gfid, local->replies, local->child_up, dict); } else { inode = afr_selfheal_unlocked_lookup_on(frame, local->loc.parent, local->loc.name, local->replies, local->child_up, dict); } if (inode) inode_unref(inode); out: if (loc_is_nameless(&local->loc)) afr_discover_done(frame, this); else afr_lookup_done(frame, this); if (dict) dict_unref(dict); return 0; } gf_boolean_t afr_is_pending_set(xlator_t *this, dict_t *xdata, int type) { int idx = -1; afr_private_t *priv = NULL; void *pending_raw = NULL; int i = 0; priv = this->private; idx = afr_index_for_transaction_type(type); if (dict_get_ptr(xdata, AFR_DIRTY, &pending_raw) == 0) { if (pending_raw) { if (*((int *)pending_raw + idx)) return _gf_true; } } for (i = 0; i < priv->child_count; i++) { if (dict_get_ptr(xdata, priv->pending_key[i], &pending_raw)) continue; if (!pending_raw) continue; if (*((int *)pending_raw + idx)) return _gf_true; } return _gf_false; } static gf_boolean_t afr_can_start_metadata_self_heal(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; struct afr_reply *replies = NULL; int i = 0, first = -1; gf_boolean_t start = _gf_false; struct iatt stbuf = { 0, }; local = frame->local; replies = local->replies; priv = this->private; if (!priv->metadata_self_heal) return _gf_false; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret == -1) continue; if (first == -1) { first = i; stbuf = replies[i].poststat; continue; } if (afr_is_pending_set(this, replies[i].xdata, AFR_METADATA_TRANSACTION)) { /* Let shd do the heal so that lookup is not blocked * on getting metadata lock/doing the heal */ start = _gf_false; break; } if (gf_uuid_compare(stbuf.ia_gfid, replies[i].poststat.ia_gfid)) { start = _gf_false; break; } if (!IA_EQUAL(stbuf, replies[i].poststat, type)) { start = _gf_false; break; } /*Check if iattrs need heal*/ if ((!IA_EQUAL(stbuf, replies[i].poststat, uid)) || (!IA_EQUAL(stbuf, replies[i].poststat, gid)) || (!IA_EQUAL(stbuf, replies[i].poststat, prot))) { start = _gf_true; continue; } /*Check if xattrs need heal*/ if (!afr_xattrs_are_equal( replies[first].xdata, replies[i].xdata, AFR_IS_ARBITER_BRICK(priv, i) ? _gf_true : _gf_false)) start = _gf_true; } return start; } int afr_lookup_metadata_heal_check(call_frame_t *frame, xlator_t *this) { call_frame_t *heal = NULL; afr_local_t *local = NULL; int ret = 0; local = frame->local; if (!afr_can_start_metadata_self_heal(frame, this)) goto out; heal = afr_frame_create(this, &ret); if (!heal) { ret = -ret; goto out; } ret = synctask_new(this->ctx->env, afr_lookup_sh_metadata_wrap, afr_refresh_selfheal_done, heal, frame); if (ret) goto out; return ret; out: if (loc_is_nameless(&local->loc)) afr_discover_done(frame, this); else afr_lookup_done(frame, this); if (heal) AFR_STACK_DESTROY(heal); return ret; } int afr_lookup_selfheal_wrap(void *opaque) { int ret = 0; call_frame_t *frame = opaque; afr_local_t *local = NULL; xlator_t *this = NULL; inode_t *inode = NULL; uuid_t pargfid = { 0, }; local = frame->local; this = frame->this; loc_pargfid(&local->loc, pargfid); if (!local->xattr_rsp) local->xattr_rsp = dict_new(); ret = afr_selfheal_name(frame->this, pargfid, local->loc.name, &local->cont.lookup.gfid_req, local->xattr_req, local->xattr_rsp); if (ret == -EIO) goto unwind; afr_local_replies_wipe(local, this->private); inode = afr_selfheal_unlocked_lookup_on(frame, local->loc.parent, local->loc.name, local->replies, local->child_up, local->xattr_req); if (inode) inode_unref(inode); afr_lookup_metadata_heal_check(frame, this); return 0; unwind: AFR_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, local->xattr_rsp, NULL); return 0; } static int afr_lookup_entry_heal(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; call_frame_t *heal = NULL; int i = 0, first = -1; gf_boolean_t name_state_mismatch = _gf_false; struct afr_reply *replies = NULL; int ret = 0; unsigned char *par_readables = NULL; unsigned char *success = NULL; int32_t op_errno = 0; uuid_t gfid = {0}; local = frame->local; replies = local->replies; priv = this->private; par_readables = alloca0(priv->child_count); success = alloca0(priv->child_count); ret = afr_inode_read_subvol_get(local->loc.parent, this, par_readables, NULL, NULL); if (ret < 0 || AFR_COUNT(par_readables, priv->child_count) == 0) { /* In this case set par_readables to all 1 so that name_heal * need checks at the end of this function will flag missing * entry when name state mismatches*/ memset(par_readables, 1, priv->child_count); } for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret == 0) { if (gf_uuid_is_null(gfid)) { gf_uuid_copy(gfid, replies[i].poststat.ia_gfid); } success[i] = 1; } else { if ((replies[i].op_errno != ENOTCONN) && (replies[i].op_errno != ENOENT) && (replies[i].op_errno != ESTALE)) { op_errno = replies[i].op_errno; } } /*gfid is missing, needs heal*/ if ((replies[i].op_ret == -1) && (replies[i].op_errno == ENODATA)) { goto name_heal; } if (first == -1) { first = i; continue; } if (replies[i].op_ret != replies[first].op_ret) { name_state_mismatch = _gf_true; } if (replies[i].op_ret == 0) { /* Rename after this lookup may succeed if we don't do * a name-heal and the destination may not have pending xattrs * to indicate which name is good and which is bad so always do * this heal*/ if (gf_uuid_compare(replies[i].poststat.ia_gfid, gfid)) { goto name_heal; } } } if (name_state_mismatch) { if (!priv->quorum_count) goto name_heal; if (!afr_has_quorum(success, priv, NULL)) goto name_heal; if (op_errno) goto name_heal; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if (par_readables[i] && replies[i].op_ret < 0 && replies[i].op_errno != ENOTCONN) { goto name_heal; } } } goto metadata_heal; name_heal: heal = afr_frame_create(this, NULL); if (!heal) goto metadata_heal; ret = synctask_new(this->ctx->env, afr_lookup_selfheal_wrap, afr_refresh_selfheal_done, heal, frame); if (ret) { AFR_STACK_DESTROY(heal); goto metadata_heal; } return ret; metadata_heal: ret = afr_lookup_metadata_heal_check(frame, this); return ret; } int afr_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { afr_local_t *local = NULL; int call_count = -1; int child_index = -1; GF_UNUSED int ret = 0; int8_t need_heal = 1; child_index = (long)cookie; local = frame->local; local->replies[child_index].valid = 1; local->replies[child_index].op_ret = op_ret; local->replies[child_index].op_errno = op_errno; /* * On revalidate lookup if the gfid-changed, afr should unwind the fop * with ESTALE so that a fresh lookup will be sent by the top xlator. * So remember it. */ if (xdata && dict_get_sizen(xdata, "gfid-changed")) local->cont.lookup.needs_fresh_lookup = _gf_true; if (xdata) { ret = dict_get_int8(xdata, "link-count", &need_heal); local->replies[child_index].need_heal = need_heal; } else { local->replies[child_index].need_heal = need_heal; } if (op_ret != -1) { local->replies[child_index].poststat = *buf; local->replies[child_index].postparent = *postparent; if (xdata) local->replies[child_index].xdata = dict_ref(xdata); } call_count = afr_frame_return(frame); if (call_count == 0) { afr_set_need_heal(this, local); afr_lookup_entry_heal(frame, this); } return 0; } static void afr_discover_unwind(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int read_subvol = -1; int ret = 0; unsigned char *data_readable = NULL; unsigned char *success_replies = NULL; priv = this->private; local = frame->local; data_readable = alloca0(priv->child_count); success_replies = alloca0(priv->child_count); afr_fill_success_replies(local, priv, success_replies); if (AFR_COUNT(success_replies, priv->child_count) > 0) local->op_ret = 0; if (local->op_ret < 0) { local->op_ret = -1; local->op_errno = afr_final_errno(frame->local, this->private); goto error; } if (!afr_has_quorum(success_replies, priv, frame)) goto unwind; ret = afr_replies_interpret(local, this, local->inode, NULL); if (ret) { afr_inode_need_refresh_set(local->inode, this); } read_subvol = afr_read_subvol_decide(local->inode, this, NULL, data_readable); unwind: afr_attempt_readsubvol_set(frame, this, success_replies, data_readable, &read_subvol); if (read_subvol == -1) goto error; if (AFR_IS_ARBITER_BRICK(priv, read_subvol) && local->op_ret == 0) { local->op_ret = -1; local->op_errno = ENOTCONN; gf_msg_debug(this->name, 0, "Arbiter cannot be a read subvol " "for %s", local->loc.path); } AFR_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, local->inode, &local->replies[read_subvol].poststat, local->replies[read_subvol].xdata, &local->replies[read_subvol].postparent); return; error: AFR_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, NULL, NULL, NULL, NULL); } static int afr_ta_id_file_check(void *opaque) { afr_private_t *priv = NULL; xlator_t *this = NULL; loc_t loc = { 0, }; struct iatt stbuf = { 0, }; dict_t *dict = NULL; uuid_t gfid = { 0, }; fd_t *fd = NULL; int ret = 0; this = opaque; priv = this->private; ret = afr_fill_ta_loc(this, &loc, _gf_false); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to populate thin-arbiter loc for: %s.", loc.name); goto out; } ret = syncop_lookup(priv->children[THIN_ARBITER_BRICK_INDEX], &loc, &stbuf, 0, 0, 0); if (ret == 0) { goto out; } else if (ret == -ENOENT) { fd = fd_create(loc.inode, getpid()); if (!fd) goto out; dict = dict_new(); if (!dict) goto out; gf_uuid_generate(gfid); ret = dict_set_gfuuid(dict, "gfid-req", gfid, true); ret = syncop_create(priv->children[THIN_ARBITER_BRICK_INDEX], &loc, O_RDWR, 0664, fd, &stbuf, dict, NULL); } out: if (ret == 0) { gf_uuid_copy(priv->ta_gfid, stbuf.ia_gfid); } else { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to lookup/create thin-arbiter id file."); } if (dict) dict_unref(dict); if (fd) fd_unref(fd); loc_wipe(&loc); return 0; } static int afr_ta_id_file_check_cbk(int ret, call_frame_t *ta_frame, void *opaque) { return 0; } static void afr_discover_done(call_frame_t *frame, xlator_t *this) { int ret = 0; afr_private_t *priv = NULL; priv = this->private; if (!priv->thin_arbiter_count) goto unwind; if (!gf_uuid_is_null(priv->ta_gfid)) goto unwind; ret = synctask_new(this->ctx->env, afr_ta_id_file_check, afr_ta_id_file_check_cbk, NULL, this); if (ret) goto unwind; unwind: afr_discover_unwind(frame, this); } int afr_discover_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { afr_local_t *local = NULL; int call_count = -1; int child_index = -1; GF_UNUSED int ret = 0; int8_t need_heal = 1; child_index = (long)cookie; local = frame->local; local->replies[child_index].valid = 1; local->replies[child_index].op_ret = op_ret; local->replies[child_index].op_errno = op_errno; if (op_ret != -1) { local->replies[child_index].poststat = *buf; local->replies[child_index].postparent = *postparent; if (xdata) local->replies[child_index].xdata = dict_ref(xdata); } if (local->do_discovery && (op_ret == 0)) afr_attempt_local_discovery(this, child_index); if (xdata) { ret = dict_get_int8(xdata, "link-count", &need_heal); local->replies[child_index].need_heal = need_heal; } else { local->replies[child_index].need_heal = need_heal; } call_count = afr_frame_return(frame); if (call_count == 0) { afr_set_need_heal(this, local); afr_lookup_metadata_heal_check(frame, this); } return 0; } int afr_discover_do(call_frame_t *frame, xlator_t *this, int err) { int ret = 0; int i = 0; afr_local_t *local = NULL; afr_private_t *priv = NULL; int call_count = 0; local = frame->local; priv = this->private; if (err) { local->op_errno = err; goto out; } call_count = local->call_count = AFR_COUNT(local->child_up, priv->child_count); ret = afr_lookup_xattr_req_prepare(local, this, local->xattr_req, &local->loc); if (ret) { local->op_errno = -ret; goto out; } for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { STACK_WIND_COOKIE( frame, afr_discover_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->lookup, &local->loc, local->xattr_req); if (!--call_count) break; } } return 0; out: AFR_STACK_UNWIND(lookup, frame, -1, local->op_errno, 0, 0, 0, 0); return 0; } int afr_discover(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { int op_errno = ENOMEM; afr_private_t *priv = NULL; afr_local_t *local = NULL; int event = 0; priv = this->private; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; if (!local->call_count) { op_errno = ENOTCONN; goto out; } if (__is_root_gfid(loc->inode->gfid)) { if (priv->choose_local && !priv->did_discovery) { /* Logic to detect which subvolumes of AFR are local, in order to prefer them for reads */ local->do_discovery = _gf_true; priv->did_discovery = _gf_true; } } local->op = GF_FOP_LOOKUP; loc_copy(&local->loc, loc); local->inode = inode_ref(loc->inode); if (xattr_req) { /* If xattr_req was null, afr_lookup_xattr_req_prepare() will allocate one for us */ local->xattr_req = dict_copy_with_ref(xattr_req, NULL); if (!local->xattr_req) { op_errno = ENOMEM; goto out; } } if (gf_uuid_is_null(loc->inode->gfid)) { afr_discover_do(frame, this, 0); return 0; } afr_read_subvol_get(loc->inode, this, NULL, NULL, &event, AFR_DATA_TRANSACTION, NULL); afr_discover_do(frame, this, 0); return 0; out: AFR_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } static int afr_lookup_do(call_frame_t *frame, xlator_t *this, int err) { int ret = 0; int i = 0; afr_local_t *local = NULL; afr_private_t *priv = NULL; int call_count = 0; local = frame->local; priv = this->private; if (err < 0) { local->op_errno = err; goto out; } call_count = local->call_count = AFR_COUNT(local->child_up, priv->child_count); ret = afr_lookup_xattr_req_prepare(local, this, local->xattr_req, &local->loc); if (ret) { local->op_errno = -ret; goto out; } for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { STACK_WIND_COOKIE( frame, afr_lookup_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->lookup, &local->loc, local->xattr_req); if (!--call_count) break; } } return 0; out: AFR_STACK_UNWIND(lookup, frame, -1, local->op_errno, 0, 0, 0, 0); return 0; } /* * afr_lookup() * * The goal here is to figure out what the element getting looked up is. * i.e what is the GFID, inode type and a conservative estimate of the * inode attributes are. * * As we lookup, operations may be underway on the entry name and the * inode. In lookup() we are primarily concerned only with the entry * operations. If the entry is getting unlinked or renamed, we detect * what operation is underway by querying for on-going transactions and * pending self-healing on the entry through xdata. * * If the entry is a file/dir, it may need self-heal and/or in a * split-brain condition. Lookup is not the place to worry about these * conditions. Outcast marking will naturally handle them in the read * paths. * * Here is a brief goal of what we are trying to achieve: * * - LOOKUP on all subvolumes concurrently, querying on-going transaction * and pending self-heal info from the servers. * * - If all servers reply the same inode type and GFID, the overall call * MUST be a success. * * - If inode types or GFIDs mismatch, and there IS either an on-going * transaction or pending self-heal, inspect what the nature of the * transaction or pending heal is, and select the appropriate subvolume's * reply as the winner. * * - If inode types or GFIDs mismatch, and there are no on-going transactions * or pending self-heal on the entry name on any of the servers, fail the * lookup with EIO. Something has gone wrong beyond reasonable action. */ int afr_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { afr_local_t *local = NULL; int32_t op_errno = 0; int event = 0; int ret = 0; if (loc_is_nameless(loc)) { if (xattr_req) dict_del_sizen(xattr_req, "gfid-req"); afr_discover(frame, this, loc, xattr_req); return 0; } if (__is_root_gfid(loc->parent->gfid) && afr_is_private_directory(this->private, loc->name, frame->root->pid)) { op_errno = EPERM; goto out; } local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; if (!local->call_count) { op_errno = ENOTCONN; goto out; } local->op = GF_FOP_LOOKUP; loc_copy(&local->loc, loc); local->inode = inode_ref(loc->inode); if (xattr_req) { /* If xattr_req was null, afr_lookup_xattr_req_prepare() will allocate one for us */ local->xattr_req = dict_copy_with_ref(xattr_req, NULL); if (!local->xattr_req) { op_errno = ENOMEM; goto out; } ret = dict_get_gfuuid(local->xattr_req, "gfid-req", &local->cont.lookup.gfid_req); if (ret == 0) { dict_del_sizen(local->xattr_req, "gfid-req"); } } afr_read_subvol_get(loc->parent, this, NULL, NULL, &event, AFR_DATA_TRANSACTION, NULL); afr_lookup_do(frame, this, 0); return 0; out: AFR_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } static void _afr_cleanup_fd_ctx(xlator_t *this, afr_fd_ctx_t *fd_ctx) { afr_private_t *priv = this->private; if (fd_ctx->lk_heal_info) { LOCK(&priv->lock); { list_del(&fd_ctx->lk_heal_info->pos); } UNLOCK(&priv->lock); afr_lk_heal_info_cleanup(fd_ctx->lk_heal_info); fd_ctx->lk_heal_info = NULL; } GF_FREE(fd_ctx->opened_on); GF_FREE(fd_ctx); return; } void afr_cleanup_fd_ctx(xlator_t *this, fd_t *fd) { afr_fd_ctx_t *fd_ctx = NULL; fd_ctx = fd_ctx_get_ptr(fd, this); if (fd_ctx) _afr_cleanup_fd_ctx(this, fd_ctx); } int afr_release(xlator_t *this, fd_t *fd) { afr_cleanup_fd_ctx(this, fd); return 0; } static afr_fd_ctx_t * __afr_fd_ctx_set(xlator_t *this, fd_t *fd) { afr_private_t *priv = NULL; int ret = -1; afr_fd_ctx_t *fd_ctx = NULL; int i = 0; VALIDATE_OR_GOTO(this->private, out); priv = this->private; fd_ctx = GF_CALLOC(1, sizeof(afr_fd_ctx_t), gf_afr_mt_afr_fd_ctx_t); if (!fd_ctx) { ret = -ENOMEM; goto out; } fd_ctx->opened_on = GF_CALLOC(sizeof(*fd_ctx->opened_on), priv->child_count, gf_afr_mt_int32_t); if (!fd_ctx->opened_on) { ret = -ENOMEM; goto out; } for (i = 0; i < priv->child_count; i++) { if (fd_is_anonymous(fd)) fd_ctx->opened_on[i] = AFR_FD_OPENED; else fd_ctx->opened_on[i] = AFR_FD_NOT_OPENED; } fd_ctx->readdir_subvol = -1; fd_ctx->lk_heal_info = NULL; ret = __fd_ctx_set(fd, this, (uint64_t)(long)fd_ctx); if (ret) gf_msg_debug(this->name, 0, "failed to set fd ctx (%p)", fd); out: if (ret && fd_ctx) { _afr_cleanup_fd_ctx(this, fd_ctx); fd_ctx = NULL; } return fd_ctx; } static afr_fd_ctx_t * __afr_fd_ctx_get(fd_t *fd, xlator_t *this) { afr_fd_ctx_t *fd_ctx = NULL; fd_ctx = __fd_ctx_get_ptr(fd, this); if (!fd_ctx) { fd_ctx = __afr_fd_ctx_set(this, fd); } return fd_ctx; } afr_fd_ctx_t * afr_fd_ctx_get(fd_t *fd, xlator_t *this) { afr_fd_ctx_t *fd_ctx = NULL; LOCK(&fd->lock); { fd_ctx = __afr_fd_ctx_get(fd, this); } UNLOCK(&fd->lock); return fd_ctx; } /* {{{ flush */ int afr_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { afr_local_t *local = NULL; int call_count = -1; local = frame->local; LOCK(&frame->lock); { if (op_ret != -1) { local->op_ret = op_ret; if (!local->xdata_rsp && xdata) local->xdata_rsp = dict_ref(xdata); } else { local->op_errno = op_errno; } call_count = --local->call_count; } UNLOCK(&frame->lock); if (call_count == 0) AFR_STACK_UNWIND(flush, frame, local->op_ret, local->op_errno, local->xdata_rsp); return 0; } static int afr_flush_wrapper(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int i = 0; afr_local_t *local = NULL; afr_private_t *priv = NULL; int call_count = -1; priv = this->private; local = frame->local; call_count = local->call_count; for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { STACK_WIND_COOKIE(frame, afr_flush_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->flush, local->fd, xdata); if (!--call_count) break; } } return 0; } static afr_local_t * afr_wakeup_same_fd_delayed_op(xlator_t *this, afr_lock_t *lock, fd_t *fd) { afr_local_t *local = NULL; if (lock->delay_timer) { local = list_entry(lock->post_op.next, afr_local_t, transaction.owner_list); if (fd == local->fd) { if (gf_timer_call_cancel(this->ctx, lock->delay_timer)) { local = NULL; } else { lock->delay_timer = NULL; } } else { local = NULL; } } return local; } static void afr_delayed_changelog_wake_resume(xlator_t *this, inode_t *inode, call_stub_t *stub) { afr_inode_ctx_t *ctx = NULL; afr_lock_t *lock = NULL; afr_local_t *metadata_local = NULL; afr_local_t *data_local = NULL; LOCK(&inode->lock); { ctx = __afr_inode_ctx_get(this, inode); if (ctx == NULL) goto unlock; lock = &ctx->lock[AFR_DATA_TRANSACTION]; data_local = afr_wakeup_same_fd_delayed_op(this, lock, stub->args.fd); lock = &ctx->lock[AFR_METADATA_TRANSACTION]; metadata_local = afr_wakeup_same_fd_delayed_op(this, lock, stub->args.fd); } unlock: UNLOCK(&inode->lock); if (data_local) { data_local->transaction.resume_stub = stub; } else if (metadata_local) { metadata_local->transaction.resume_stub = stub; } else { call_resume(stub); } if (data_local) { afr_delayed_changelog_wake_up_cbk(data_local); } if (metadata_local) { afr_delayed_changelog_wake_up_cbk(metadata_local); } } int afr_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { afr_local_t *local = NULL; call_stub_t *stub = NULL; int op_errno = ENOMEM; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_FLUSH; if (!afr_is_consistent_io_possible(local, this->private, &op_errno)) goto out; local->fd = fd_ref(fd); stub = fop_flush_stub(frame, afr_flush_wrapper, fd, xdata); if (!stub) goto out; afr_delayed_changelog_wake_resume(this, fd->inode, stub); return 0; out: AFR_STACK_UNWIND(flush, frame, -1, op_errno, NULL); return 0; } int afr_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { afr_local_t *local = NULL; int call_count = -1; local = frame->local; LOCK(&frame->lock); { if (op_ret == 0) { local->op_ret = 0; if (!local->xdata_rsp && xdata) local->xdata_rsp = dict_ref(xdata); } else { local->op_errno = op_errno; } call_count = --local->call_count; } UNLOCK(&frame->lock); if (call_count == 0) AFR_STACK_UNWIND(fsyncdir, frame, local->op_ret, local->op_errno, local->xdata_rsp); return 0; } int afr_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int i = 0; int32_t call_count = 0; int32_t op_errno = ENOMEM; priv = this->private; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_FSYNCDIR; if (!afr_is_consistent_io_possible(local, priv, &op_errno)) goto out; call_count = local->call_count; for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { STACK_WIND(frame, afr_fsyncdir_cbk, priv->children[i], priv->children[i]->fops->fsyncdir, fd, datasync, xdata); if (!--call_count) break; } } return 0; out: AFR_STACK_UNWIND(fsyncdir, frame, -1, op_errno, NULL); return 0; } /* }}} */ static int afr_serialized_lock_wind(call_frame_t *frame, xlator_t *this); static gf_boolean_t afr_is_conflicting_lock_present(int32_t op_ret, int32_t op_errno) { if (op_ret == -1 && op_errno == EAGAIN) return _gf_true; return _gf_false; } static void afr_fop_lock_unwind(call_frame_t *frame, glusterfs_fop_t op, int32_t op_ret, int32_t op_errno, dict_t *xdata) { switch (op) { case GF_FOP_INODELK: AFR_STACK_UNWIND(inodelk, frame, op_ret, op_errno, xdata); break; case GF_FOP_FINODELK: AFR_STACK_UNWIND(finodelk, frame, op_ret, op_errno, xdata); break; case GF_FOP_ENTRYLK: AFR_STACK_UNWIND(entrylk, frame, op_ret, op_errno, xdata); break; case GF_FOP_FENTRYLK: AFR_STACK_UNWIND(fentrylk, frame, op_ret, op_errno, xdata); break; default: break; } } static void afr_fop_lock_wind(call_frame_t *frame, xlator_t *this, int child_index, int32_t (*lock_cbk)(call_frame_t *, void *, xlator_t *, int32_t, int32_t, dict_t *)) { afr_local_t *local = frame->local; afr_private_t *priv = this->private; int i = child_index; switch (local->op) { case GF_FOP_INODELK: STACK_WIND_COOKIE( frame, lock_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->inodelk, (const char *)local->cont.inodelk.volume, &local->loc, local->cont.inodelk.cmd, &local->cont.inodelk.flock, local->cont.inodelk.xdata); break; case GF_FOP_FINODELK: STACK_WIND_COOKIE( frame, lock_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->finodelk, (const char *)local->cont.inodelk.volume, local->fd, local->cont.inodelk.cmd, &local->cont.inodelk.flock, local->cont.inodelk.xdata); break; case GF_FOP_ENTRYLK: STACK_WIND_COOKIE( frame, lock_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->entrylk, local->cont.entrylk.volume, &local->loc, local->cont.entrylk.basename, local->cont.entrylk.cmd, local->cont.entrylk.type, local->cont.entrylk.xdata); break; case GF_FOP_FENTRYLK: STACK_WIND_COOKIE( frame, lock_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->fentrylk, local->cont.entrylk.volume, local->fd, local->cont.entrylk.basename, local->cont.entrylk.cmd, local->cont.entrylk.type, local->cont.entrylk.xdata); break; default: break; } } static void afr_fop_lock_proceed(call_frame_t *frame) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = frame->this->private; if (local->fop_lock_state != AFR_FOP_LOCK_PARALLEL) { afr_fop_lock_unwind(frame, local->op, local->op_ret, local->op_errno, local->xdata_rsp); return; } /* At least one child is up */ /* * Non-blocking locks also need to be serialized. Otherwise there is * a chance that both the mounts which issued same non-blocking inodelk * may endup not acquiring the lock on any-brick. * Ex: Mount1 and Mount2 * request for full length lock on file f1. Mount1 afr may acquire the * partial lock on brick-1 and may not acquire the lock on brick-2 * because Mount2 already got the lock on brick-2, vice versa. Since * both the mounts only got partial locks, afr treats them as failure in * gaining the locks and unwinds with EAGAIN errno. */ local->op_ret = -1; local->op_errno = EUCLEAN; local->fop_lock_state = AFR_FOP_LOCK_SERIAL; afr_local_replies_wipe(local, priv); if (local->xdata_rsp) dict_unref(local->xdata_rsp); local->xdata_rsp = NULL; switch (local->op) { case GF_FOP_INODELK: case GF_FOP_FINODELK: local->cont.inodelk.cmd = local->cont.inodelk.in_cmd; gf_flock_copy(&local->cont.inodelk.flock, &local->cont.inodelk.in_flock); if (local->cont.inodelk.xdata) dict_unref(local->cont.inodelk.xdata); local->cont.inodelk.xdata = NULL; if (local->xdata_req) local->cont.inodelk.xdata = dict_ref(local->xdata_req); break; case GF_FOP_ENTRYLK: case GF_FOP_FENTRYLK: local->cont.entrylk.cmd = local->cont.entrylk.in_cmd; if (local->cont.entrylk.xdata) dict_unref(local->cont.entrylk.xdata); local->cont.entrylk.xdata = NULL; if (local->xdata_req) local->cont.entrylk.xdata = dict_ref(local->xdata_req); break; default: break; } afr_serialized_lock_wind(frame, frame->this); } static int32_t afr_unlock_partial_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int call_count = -1; int child_index = (long)cookie; uuid_t gfid = {0}; local = frame->local; priv = this->private; if (op_ret < 0 && op_errno != ENOTCONN) { if (local->fd) gf_uuid_copy(gfid, local->fd->inode->gfid); else loc_gfid(&local->loc, gfid); gf_msg(this->name, GF_LOG_ERROR, op_errno, AFR_MSG_UNLOCK_FAIL, "%s: Failed to unlock %s on %s " "with lk_owner: %s", uuid_utoa(gfid), gf_fop_list[local->op], priv->children[child_index]->name, lkowner_utoa(&frame->root->lk_owner)); } call_count = afr_frame_return(frame); if (call_count == 0) afr_fop_lock_proceed(frame); return 0; } static int32_t afr_unlock_locks_and_proceed(call_frame_t *frame, xlator_t *this, int call_count) { int i = 0; afr_private_t *priv = NULL; afr_local_t *local = NULL; if (call_count == 0) { afr_fop_lock_proceed(frame); goto out; } local = frame->local; priv = this->private; local->call_count = call_count; switch (local->op) { case GF_FOP_INODELK: case GF_FOP_FINODELK: local->cont.inodelk.flock.l_type = F_UNLCK; local->cont.inodelk.cmd = F_SETLK; if (local->cont.inodelk.xdata) dict_unref(local->cont.inodelk.xdata); local->cont.inodelk.xdata = NULL; break; case GF_FOP_ENTRYLK: case GF_FOP_FENTRYLK: local->cont.entrylk.cmd = ENTRYLK_UNLOCK; if (local->cont.entrylk.xdata) dict_unref(local->cont.entrylk.xdata); local->cont.entrylk.xdata = NULL; break; default: break; } for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret == -1) continue; afr_fop_lock_wind(frame, this, i, afr_unlock_partial_lock_cbk); if (!--call_count) break; } out: return 0; } static int32_t afr_fop_lock_done(call_frame_t *frame, xlator_t *this) { int i = 0; int lock_count = 0; unsigned char *success = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; success = alloca0(priv->child_count); for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret == 0) { lock_count++; success[i] = 1; } if (local->op_ret == -1 && local->op_errno == EAGAIN) continue; if ((local->replies[i].op_ret == -1) && (local->replies[i].op_errno == EAGAIN)) { local->op_ret = -1; local->op_errno = EAGAIN; continue; } if (local->replies[i].op_ret == 0) local->op_ret = 0; local->op_errno = local->replies[i].op_errno; } if (afr_fop_lock_is_unlock(frame)) goto unwind; if (afr_is_conflicting_lock_present(local->op_ret, local->op_errno)) { afr_unlock_locks_and_proceed(frame, this, lock_count); } else if (priv->quorum_count && !afr_has_quorum(success, priv, NULL)) { local->fop_lock_state = AFR_FOP_LOCK_QUORUM_FAILED; local->op_ret = -1; local->op_errno = afr_final_errno(local, priv); if (local->op_errno == 0) local->op_errno = afr_quorum_errno(priv); afr_unlock_locks_and_proceed(frame, this, lock_count); } else { goto unwind; } return 0; unwind: afr_fop_lock_unwind(frame, local->op, local->op_ret, local->op_errno, local->xdata_rsp); return 0; } static int afr_common_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { afr_local_t *local = NULL; int child_index = (long)cookie; local = frame->local; local->replies[child_index].valid = 1; local->replies[child_index].op_ret = op_ret; local->replies[child_index].op_errno = op_errno; if (op_ret == 0 && xdata) { local->replies[child_index].xdata = dict_ref(xdata); LOCK(&frame->lock); { if (!local->xdata_rsp) local->xdata_rsp = dict_ref(xdata); } UNLOCK(&frame->lock); } return 0; } static int32_t afr_serialized_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int child_index = (long)cookie; int next_child = 0; local = frame->local; priv = this->private; afr_common_lock_cbk(frame, cookie, this, op_ret, op_errno, xdata); for (next_child = child_index + 1; next_child < priv->child_count; next_child++) { if (local->child_up[next_child]) break; } if (afr_is_conflicting_lock_present(op_ret, op_errno) || (next_child == priv->child_count)) { afr_fop_lock_done(frame, this); } else { afr_fop_lock_wind(frame, this, next_child, afr_serialized_lock_cbk); } return 0; } static int afr_serialized_lock_wind(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int i = 0; priv = this->private; local = frame->local; for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { afr_fop_lock_wind(frame, this, i, afr_serialized_lock_cbk); break; } } return 0; } static int32_t afr_parallel_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { int call_count = 0; afr_common_lock_cbk(frame, cookie, this, op_ret, op_errno, xdata); call_count = afr_frame_return(frame); if (call_count == 0) afr_fop_lock_done(frame, this); return 0; } static int afr_parallel_lock_wind(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int call_count = 0; int i = 0; priv = this->private; local = frame->local; call_count = local->call_count; for (i = 0; i < priv->child_count; i++) { if (!local->child_up[i]) continue; afr_fop_lock_wind(frame, this, i, afr_parallel_lock_cbk); if (!--call_count) break; } return 0; } static int afr_fop_handle_lock(call_frame_t *frame, xlator_t *this) { afr_local_t *local = frame->local; int op_errno = 0; if (!afr_fop_lock_is_unlock(frame)) { if (!afr_is_consistent_io_possible(local, this->private, &op_errno)) goto out; switch (local->op) { case GF_FOP_INODELK: case GF_FOP_FINODELK: local->cont.inodelk.cmd = F_SETLK; break; case GF_FOP_ENTRYLK: case GF_FOP_FENTRYLK: local->cont.entrylk.cmd = ENTRYLK_LOCK_NB; break; default: break; } } if (local->xdata_req) { switch (local->op) { case GF_FOP_INODELK: case GF_FOP_FINODELK: local->cont.inodelk.xdata = dict_ref(local->xdata_req); break; case GF_FOP_ENTRYLK: case GF_FOP_FENTRYLK: local->cont.entrylk.xdata = dict_ref(local->xdata_req); break; default: break; } } local->fop_lock_state = AFR_FOP_LOCK_PARALLEL; afr_parallel_lock_wind(frame, this); out: return -op_errno; } static int32_t afr_handle_inodelk(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop, const char *volume, loc_t *loc, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { afr_local_t *local = NULL; int32_t op_errno = ENOMEM; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = fop; if (loc) loc_copy(&local->loc, loc); if (fd && (flock->l_type != F_UNLCK)) { AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); local->fd = fd_ref(fd); } local->cont.inodelk.volume = gf_strdup(volume); if (!local->cont.inodelk.volume) { op_errno = ENOMEM; goto out; } local->cont.inodelk.in_cmd = cmd; local->cont.inodelk.cmd = cmd; gf_flock_copy(&local->cont.inodelk.in_flock, flock); gf_flock_copy(&local->cont.inodelk.flock, flock); if (xdata) local->xdata_req = dict_ref(xdata); op_errno = -afr_fop_handle_lock(frame, frame->this); if (op_errno) goto out; return 0; out: afr_fop_lock_unwind(frame, fop, -1, op_errno, NULL); return 0; } int32_t afr_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { afr_handle_inodelk(frame, this, GF_FOP_INODELK, volume, loc, NULL, cmd, flock, xdata); return 0; } int32_t afr_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { afr_handle_inodelk(frame, this, GF_FOP_FINODELK, volume, NULL, fd, cmd, flock, xdata); return 0; } static int afr_handle_entrylk(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop, const char *volume, loc_t *loc, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { afr_local_t *local = NULL; int32_t op_errno = ENOMEM; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = fop; if (loc) loc_copy(&local->loc, loc); if (fd && (cmd != ENTRYLK_UNLOCK)) { AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); local->fd = fd_ref(fd); } local->cont.entrylk.cmd = cmd; local->cont.entrylk.in_cmd = cmd; local->cont.entrylk.type = type; local->cont.entrylk.volume = gf_strdup(volume); local->cont.entrylk.basename = gf_strdup(basename); if (!local->cont.entrylk.volume || !local->cont.entrylk.basename) { op_errno = ENOMEM; goto out; } if (xdata) local->xdata_req = dict_ref(xdata); op_errno = -afr_fop_handle_lock(frame, frame->this); if (op_errno) goto out; return 0; out: afr_fop_lock_unwind(frame, fop, -1, op_errno, NULL); return 0; } int afr_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { afr_handle_entrylk(frame, this, GF_FOP_ENTRYLK, volume, loc, NULL, basename, cmd, type, xdata); return 0; } int afr_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { afr_handle_entrylk(frame, this, GF_FOP_FENTRYLK, volume, NULL, fd, basename, cmd, type, xdata); return 0; } int afr_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct statvfs *statvfs, dict_t *xdata) { afr_local_t *local = NULL; int call_count = 0; struct statvfs *buf = NULL; local = frame->local; LOCK(&frame->lock); { if (op_ret != 0) { local->op_errno = op_errno; goto unlock; } local->op_ret = op_ret; buf = &local->cont.statfs.buf; if (local->cont.statfs.buf_set) { if (statvfs->f_bavail < buf->f_bavail) { *buf = *statvfs; if (xdata) { if (local->xdata_rsp) dict_unref(local->xdata_rsp); local->xdata_rsp = dict_ref(xdata); } } } else { *buf = *statvfs; local->cont.statfs.buf_set = 1; if (xdata) local->xdata_rsp = dict_ref(xdata); } } unlock: call_count = --local->call_count; UNLOCK(&frame->lock); if (call_count == 0) AFR_STACK_UNWIND(statfs, frame, local->op_ret, local->op_errno, &local->cont.statfs.buf, local->xdata_rsp); return 0; } int afr_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; int call_count = 0; int32_t op_errno = ENOMEM; priv = this->private; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_STATFS; if (!afr_is_consistent_io_possible(local, priv, &op_errno)) goto out; if (priv->arbiter_count == 1 && local->child_up[ARBITER_BRICK_INDEX]) local->call_count--; call_count = local->call_count; if (!call_count) { op_errno = ENOTCONN; goto out; } for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { if (AFR_IS_ARBITER_BRICK(priv, i)) continue; STACK_WIND(frame, afr_statfs_cbk, priv->children[i], priv->children[i]->fops->statfs, loc, xdata); if (!--call_count) break; } } return 0; out: AFR_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); return 0; } int32_t afr_lk_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = this->private; int call_count = -1; int child_index = (long)cookie; local = frame->local; if (op_ret < 0 && op_errno != ENOTCONN && op_errno != EBADFD) { gf_msg(this->name, GF_LOG_ERROR, op_errno, AFR_MSG_UNLOCK_FAIL, "gfid=%s: unlock failed on subvolume %s " "with lock owner %s", uuid_utoa(local->fd->inode->gfid), priv->children[child_index]->name, lkowner_utoa(&frame->root->lk_owner)); } call_count = afr_frame_return(frame); if (call_count == 0) { AFR_STACK_UNWIND(lk, frame, local->op_ret, local->op_errno, NULL, local->xdata_rsp); } return 0; } int32_t afr_lk_unlock(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; int call_count = 0; local = frame->local; priv = this->private; call_count = afr_locked_nodes_count(local->cont.lk.locked_nodes, priv->child_count); if (call_count == 0) { AFR_STACK_UNWIND(lk, frame, local->op_ret, local->op_errno, NULL, local->xdata_rsp); return 0; } local->call_count = call_count; local->cont.lk.user_flock.l_type = F_UNLCK; for (i = 0; i < priv->child_count; i++) { if (local->cont.lk.locked_nodes[i]) { STACK_WIND_COOKIE(frame, afr_lk_unlock_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->lk, local->fd, F_SETLK, &local->cont.lk.user_flock, NULL); if (!--call_count) break; } } return 0; } int32_t afr_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int child_index = -1; local = frame->local; priv = this->private; child_index = (long)cookie; afr_common_lock_cbk(frame, cookie, this, op_ret, op_errno, xdata); /* We have two options here to handle EINTR 1) Either Ignore EINTR and wind a call on other subvolume 2) or Unlock the already granted lock in the previous children and return the error. For EINTR we can't chose first option because EINTR is not a regular error. The user expecation is whole lock should be clear after receive an interrupt. However there is an issue if we do unlock already granted locks. Locks xlator implements posix locks as they are defined by the posix standard. This means that granted locks are "combined" with other existing granted locks. Unfortunately, in some cases this makes it impossible to revoke an already granted lock without unwanted side effects. For example consider a process that takes two read locks on the same file, but their ranges overlap a bit. Once both of them are granted in one brick, revoking any of them because of an interrupt will cause the overlapped range to be unlocked, even if one of the locks is still granted (from the point of view of the user, one of the locks has never been granted because it returned EINTR, so the user still expects that the other lock still covers the overlapping region). For the time being we have decided consider EINTR as same EAGAIN. */ if (op_ret < 0 && ((op_errno == EAGAIN) || (op_errno == EINTR))) { local->op_ret = -1; local->op_errno = op_errno; afr_lk_unlock(frame, this); return 0; } if (op_ret == 0) { local->op_ret = 0; local->op_errno = 0; local->cont.lk.locked_nodes[child_index] = 1; gf_flock_copy(&local->cont.lk.ret_flock, lock); } child_index++; if (child_index < priv->child_count) { STACK_WIND_COOKIE(frame, afr_lk_cbk, (void *)(long)child_index, priv->children[child_index], priv->children[child_index]->fops->lk, local->fd, local->cont.lk.cmd, &local->cont.lk.user_flock, local->xdata_req); } else if (priv->quorum_count && !afr_has_quorum(local->cont.lk.locked_nodes, priv, NULL)) { local->op_ret = -1; local->op_errno = afr_final_errno(local, priv); afr_lk_unlock(frame, this); } else { if (local->op_ret < 0) local->op_errno = afr_final_errno(local, priv); AFR_STACK_UNWIND(lk, frame, local->op_ret, local->op_errno, &local->cont.lk.ret_flock, local->xdata_rsp); } return 0; } int afr_lk_transaction_cbk(int ret, call_frame_t *frame, void *opaque) { return 0; } int afr_lk_txn_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { afr_local_t *local = NULL; int child_index = -1; local = frame->local; child_index = (long)cookie; afr_common_lock_cbk(frame, cookie, this, op_ret, op_errno, xdata); if (op_ret == 0) { local->op_ret = 0; local->op_errno = 0; local->cont.lk.locked_nodes[child_index] = 1; gf_flock_copy(&local->cont.lk.ret_flock, lock); } syncbarrier_wake(&local->barrier); return 0; } int afr_lk_txn_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { afr_local_t *local = frame->local; afr_private_t *priv = this->private; int child_index = (long)cookie; if (op_ret < 0 && op_errno != ENOTCONN && op_errno != EBADFD) { gf_msg(this->name, GF_LOG_ERROR, op_errno, AFR_MSG_UNLOCK_FAIL, "gfid=%s: unlock failed on subvolume %s " "with lock owner %s", uuid_utoa(local->fd->inode->gfid), priv->children[child_index]->name, lkowner_utoa(&frame->root->lk_owner)); } return 0; } int afr_lk_transaction(void *opaque) { call_frame_t *frame = NULL; xlator_t *this = NULL; afr_private_t *priv = NULL; afr_local_t *local = NULL; char *wind_on = NULL; int op_errno = 0; int i = 0; int ret = 0; frame = (call_frame_t *)opaque; local = frame->local; this = frame->this; priv = this->private; wind_on = alloca0(priv->child_count); if (priv->arbiter_count || priv->child_count != 3) { op_errno = ENOTSUP; gf_msg(frame->this->name, GF_LOG_ERROR, op_errno, AFR_MSG_LK_HEAL_DOM, "%s: Lock healing supported only for replica 3 volumes.", uuid_utoa(local->fd->inode->gfid)); goto err; } op_errno = -afr_dom_lock_acquire(frame); // Released during // AFR_STACK_UNWIND if (op_errno != 0) { goto err; } if (priv->quorum_count && !afr_has_quorum(local->cont.lk.dom_locked_nodes, priv, NULL)) { op_errno = afr_final_errno(local, priv); goto err; } for (i = 0; i < priv->child_count; i++) { if (priv->child_up[i] && local->cont.lk.dom_locked_nodes[i]) wind_on[i] = 1; } AFR_ONLIST(wind_on, frame, afr_lk_txn_wind_cbk, lk, local->fd, local->cont.lk.cmd, &local->cont.lk.user_flock, local->xdata_req); if (priv->quorum_count && !afr_has_quorum(local->cont.lk.locked_nodes, priv, NULL)) { local->op_ret = -1; local->op_errno = afr_final_errno(local, priv); goto unlock; } else { if (local->cont.lk.user_flock.l_type == F_UNLCK) ret = afr_remove_lock_from_saved_locks(local, this); else ret = afr_add_lock_to_saved_locks(frame, this); if (ret) { local->op_ret = -1; local->op_errno = -ret; goto unlock; } AFR_STACK_UNWIND(lk, frame, local->op_ret, local->op_errno, &local->cont.lk.ret_flock, local->xdata_rsp); } return 0; unlock: local->cont.lk.user_flock.l_type = F_UNLCK; AFR_ONLIST(local->cont.lk.locked_nodes, frame, afr_lk_txn_unlock_cbk, lk, local->fd, F_SETLK, &local->cont.lk.user_flock, NULL); err: AFR_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL); return -1; } int afr_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int ret = 0; int i = 0; int32_t op_errno = ENOMEM; priv = this->private; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_LK; if (!afr_lk_is_unlock(cmd, flock)) { AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); if (!afr_is_consistent_io_possible(local, priv, &op_errno)) goto out; } local->cont.lk.locked_nodes = GF_CALLOC( priv->child_count, sizeof(*local->cont.lk.locked_nodes), gf_afr_mt_char); if (!local->cont.lk.locked_nodes) { op_errno = ENOMEM; goto out; } local->fd = fd_ref(fd); local->cont.lk.cmd = cmd; gf_flock_copy(&local->cont.lk.user_flock, flock); gf_flock_copy(&local->cont.lk.ret_flock, flock); if (xdata) { local->xdata_req = dict_ref(xdata); if (afr_is_lock_mode_mandatory(xdata)) { ret = synctask_new(this->ctx->env, afr_lk_transaction, afr_lk_transaction_cbk, frame, frame); if (ret) { op_errno = ENOMEM; goto out; } return 0; } } STACK_WIND_COOKIE(frame, afr_lk_cbk, (void *)(long)0, priv->children[i], priv->children[i]->fops->lk, fd, cmd, flock, local->xdata_req); return 0; out: AFR_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t afr_lease_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_lease *lease, dict_t *xdata) { afr_local_t *local = NULL; int call_count = -1; local = frame->local; call_count = afr_frame_return(frame); if (call_count == 0) AFR_STACK_UNWIND(lease, frame, local->op_ret, local->op_errno, lease, xdata); return 0; } int32_t afr_lease_unlock(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; int call_count = 0; local = frame->local; priv = this->private; call_count = afr_locked_nodes_count(local->cont.lease.locked_nodes, priv->child_count); if (call_count == 0) { AFR_STACK_UNWIND(lease, frame, local->op_ret, local->op_errno, &local->cont.lease.ret_lease, NULL); return 0; } local->call_count = call_count; local->cont.lease.user_lease.cmd = GF_UNLK_LEASE; for (i = 0; i < priv->child_count; i++) { if (local->cont.lease.locked_nodes[i]) { STACK_WIND(frame, afr_lease_unlock_cbk, priv->children[i], priv->children[i]->fops->lease, &local->loc, &local->cont.lease.user_lease, NULL); if (!--call_count) break; } } return 0; } int32_t afr_lease_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_lease *lease, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int child_index = -1; local = frame->local; priv = this->private; child_index = (long)cookie; afr_common_lock_cbk(frame, cookie, this, op_ret, op_errno, xdata); if (op_ret < 0 && op_errno == EAGAIN) { local->op_ret = -1; local->op_errno = EAGAIN; afr_lease_unlock(frame, this); return 0; } if (op_ret == 0) { local->op_ret = 0; local->op_errno = 0; local->cont.lease.locked_nodes[child_index] = 1; local->cont.lease.ret_lease = *lease; } child_index++; if (child_index < priv->child_count) { STACK_WIND_COOKIE(frame, afr_lease_cbk, (void *)(long)child_index, priv->children[child_index], priv->children[child_index]->fops->lease, &local->loc, &local->cont.lease.user_lease, xdata); } else if (priv->quorum_count && !afr_has_quorum(local->cont.lease.locked_nodes, priv, NULL)) { local->op_ret = -1; local->op_errno = afr_final_errno(local, priv); afr_lease_unlock(frame, this); } else { if (local->op_ret < 0) local->op_errno = afr_final_errno(local, priv); AFR_STACK_UNWIND(lease, frame, local->op_ret, local->op_errno, &local->cont.lease.ret_lease, NULL); } return 0; } int afr_lease(call_frame_t *frame, xlator_t *this, loc_t *loc, struct gf_lease *lease, dict_t *xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int32_t op_errno = ENOMEM; priv = this->private; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_LEASE; local->cont.lease.locked_nodes = GF_CALLOC( priv->child_count, sizeof(*local->cont.lease.locked_nodes), gf_afr_mt_char); if (!local->cont.lease.locked_nodes) { op_errno = ENOMEM; goto out; } loc_copy(&local->loc, loc); local->cont.lease.user_lease = *lease; local->cont.lease.ret_lease = *lease; STACK_WIND_COOKIE(frame, afr_lease_cbk, (void *)(long)0, priv->children[0], priv->children[0]->fops->lease, loc, lease, xdata); return 0; out: AFR_STACK_UNWIND(lease, frame, -1, op_errno, NULL, NULL); return 0; } int afr_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { afr_local_t *local = NULL; int child_index = (long)cookie; int call_count = 0; gf_boolean_t failed = _gf_false; gf_boolean_t succeeded = _gf_false; int i = 0; afr_private_t *priv = NULL; local = frame->local; priv = this->private; local->replies[child_index].valid = 1; local->replies[child_index].op_ret = op_ret; local->replies[child_index].op_errno = op_errno; if (xdata) local->replies[child_index].xdata = dict_ref(xdata); call_count = afr_frame_return(frame); if (call_count) goto out; /* If any of the subvolumes failed with other than ENOTCONN * return error else return success unless all the subvolumes * failed. * TODO: In case of failure, we need to unregister the xattrs * from the other subvolumes where it succeeded (once upcall * fixes the Bz-1371622)*/ for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret < 0 && local->replies[i].op_errno != ENOTCONN) { local->op_ret = local->replies[i].op_ret; local->op_errno = local->replies[i].op_errno; if (local->xdata_rsp) dict_unref(local->xdata_rsp); local->xdata_rsp = NULL; if (local->replies[i].xdata) { local->xdata_rsp = dict_ref(local->replies[i].xdata); } failed = _gf_true; break; } if (local->replies[i].op_ret == 0) { succeeded = _gf_true; local->op_ret = 0; local->op_errno = 0; if (!local->xdata_rsp && local->replies[i].xdata) { local->xdata_rsp = dict_ref(local->replies[i].xdata); } } } if (!succeeded && !failed) { local->op_ret = -1; local->op_errno = ENOTCONN; } AFR_STACK_UNWIND(ipc, frame, local->op_ret, local->op_errno, local->xdata_rsp); out: return 0; } int afr_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) { afr_local_t *local = NULL; int32_t op_errno = -1; afr_private_t *priv = NULL; int i = 0; int call_cnt = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); if (op != GF_IPC_TARGET_UPCALL) goto wind_default; VALIDATE_OR_GOTO(this->private, err); priv = this->private; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto err; call_cnt = local->call_count; if (xdata) { for (i = 0; i < priv->child_count; i++) { if (dict_set_int8(xdata, priv->pending_key[i], 0) < 0) goto err; } } for (i = 0; i < priv->child_count; i++) { if (!local->child_up[i]) continue; STACK_WIND_COOKIE(frame, afr_ipc_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->ipc, op, xdata); if (!--call_cnt) break; } return 0; err: if (op_errno == -1) op_errno = errno; AFR_STACK_UNWIND(ipc, frame, -1, op_errno, NULL); return 0; wind_default: STACK_WIND(frame, default_ipc_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc, op, xdata); return 0; } int afr_forget(xlator_t *this, inode_t *inode) { uint64_t ctx_int = 0; afr_inode_ctx_t *ctx = NULL; afr_spb_choice_timeout_cancel(this, inode); inode_ctx_del(inode, this, &ctx_int); if (!ctx_int) return 0; ctx = (afr_inode_ctx_t *)(uintptr_t)ctx_int; afr_inode_ctx_destroy(ctx); return 0; } int afr_priv_dump(xlator_t *this) { afr_private_t *priv = NULL; char key_prefix[GF_DUMP_MAX_BUF_LEN]; char key[GF_DUMP_MAX_BUF_LEN]; int i = 0; GF_ASSERT(this); priv = this->private; GF_ASSERT(priv); snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type, this->name); gf_proc_dump_add_section("%s", key_prefix); gf_proc_dump_write("child_count", "%u", priv->child_count); for (i = 0; i < priv->child_count; i++) { sprintf(key, "child_up[%d]", i); gf_proc_dump_write(key, "%d", priv->child_up[i]); sprintf(key, "pending_key[%d]", i); gf_proc_dump_write(key, "%s", priv->pending_key[i]); sprintf(key, "pending_reads[%d]", i); gf_proc_dump_write(key, "%" PRId64, GF_ATOMIC_GET(priv->pending_reads[i])); sprintf(key, "child_latency[%d]", i); gf_proc_dump_write(key, "%" PRId64, priv->child_latency[i]); sprintf(key, "halo_child_up[%d]", i); gf_proc_dump_write(key, "%d", priv->halo_child_up[i]); } gf_proc_dump_write("data_self_heal", "%d", priv->data_self_heal); gf_proc_dump_write("metadata_self_heal", "%d", priv->metadata_self_heal); gf_proc_dump_write("entry_self_heal", "%d", priv->entry_self_heal); gf_proc_dump_write("read_child", "%d", priv->read_child); gf_proc_dump_write("wait_count", "%u", priv->wait_count); gf_proc_dump_write("heal-wait-queue-length", "%d", priv->heal_wait_qlen); gf_proc_dump_write("heal-waiters", "%d", priv->heal_waiters); gf_proc_dump_write("background-self-heal-count", "%d", priv->background_self_heal_count); gf_proc_dump_write("healers", "%d", priv->healers); gf_proc_dump_write("read-hash-mode", "%d", priv->hash_mode); gf_proc_dump_write("use-anonymous-inode", "%d", priv->use_anon_inode); if (priv->quorum_count == AFR_QUORUM_AUTO) { gf_proc_dump_write("quorum-type", "auto"); } else if (priv->quorum_count == 0) { gf_proc_dump_write("quorum-type", "none"); } else { gf_proc_dump_write("quorum-type", "fixed"); gf_proc_dump_write("quorum-count", "%d", priv->quorum_count); } gf_proc_dump_write("up", "%u", afr_has_quorum(priv->child_up, priv, NULL)); if (priv->thin_arbiter_count) { gf_proc_dump_write("ta_child_up", "%d", priv->ta_child_up); gf_proc_dump_write("ta_bad_child_index", "%d", priv->ta_bad_child_index); gf_proc_dump_write("ta_notify_dom_lock_offset", "%" PRId64, priv->ta_notify_dom_lock_offset); } return 0; } /** * find_child_index - find the child's index in the array of subvolumes * @this: AFR * @child: child */ static int afr_find_child_index(xlator_t *this, xlator_t *child) { afr_private_t *priv = NULL; int child_count = -1; int i = -1; priv = this->private; child_count = priv->child_count; if (priv->thin_arbiter_count) { child_count++; } for (i = 0; i < child_count; i++) { if ((xlator_t *)child == priv->children[i]) break; } return i; } int __afr_get_up_children_count(afr_private_t *priv) { int up_children = 0; int i = 0; for (i = 0; i < priv->child_count; i++) if (priv->child_up[i] == 1) up_children++; return up_children; } static int __get_heard_from_all_status(afr_private_t *priv) { int i; for (i = 0; i < priv->child_count; i++) { if (!priv->last_event[i]) { return 0; } } if (priv->thin_arbiter_count && !priv->ta_child_up) { return 0; } return 1; } static glusterfs_event_t __afr_transform_event_from_state(afr_private_t *priv) { int i = 0; int up_children = 0; if (__get_heard_from_all_status(priv)) /* have_heard_from_all. Let afr_notify() do the propagation. */ return GF_EVENT_MAXVAL; up_children = __afr_get_up_children_count(priv); /* Treat the children with pending notification, as having sent a * GF_EVENT_CHILD_DOWN. i.e. set the event as GF_EVENT_SOME_DESCENDENT_DOWN, * as done in afr_notify() */ for (i = 0; i < priv->child_count; i++) { if (priv->last_event[i]) continue; priv->last_event[i] = GF_EVENT_SOME_DESCENDENT_DOWN; priv->child_up[i] = 0; } if (up_children) /* We received at least one child up */ return GF_EVENT_CHILD_UP; else return GF_EVENT_CHILD_DOWN; return GF_EVENT_MAXVAL; } static void afr_notify_cbk(void *data) { xlator_t *this = data; afr_private_t *priv = this->private; glusterfs_event_t event = GF_EVENT_MAXVAL; gf_boolean_t propagate = _gf_false; LOCK(&priv->lock); { if (!priv->timer) { /* * Either child_up/child_down is already sent to parent. * This is a spurious wake up. */ goto unlock; } priv->timer = NULL; event = __afr_transform_event_from_state(priv); if (event != GF_EVENT_MAXVAL) propagate = _gf_true; } unlock: UNLOCK(&priv->lock); if (propagate) default_notify(this, event, NULL); } static void __afr_launch_notify_timer(xlator_t *this, afr_private_t *priv) { struct timespec delay = { 0, }; gf_msg_debug(this->name, 0, "Initiating child-down timer"); delay.tv_sec = 10; delay.tv_nsec = 0; priv->timer = gf_timer_call_after(this->ctx, delay, afr_notify_cbk, this); if (priv->timer == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_TIMER_CREATE_FAIL, "Cannot create timer for delayed initialization"); } } static int find_best_down_child(xlator_t *this) { afr_private_t *priv = NULL; int i = -1; int32_t best_child = -1; int64_t best_latency = INT64_MAX; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!priv->child_up[i] && priv->child_latency[i] >= 0 && priv->child_latency[i] < best_latency) { best_child = i; best_latency = priv->child_latency[i]; } } if (best_child >= 0) { gf_msg_debug(this->name, 0, "Found best down child (%d) @ %" PRId64 " ms latency", best_child, best_latency); } return best_child; } static int find_worst_up_child(xlator_t *this) { afr_private_t *priv = NULL; int i = -1; int32_t worst_child = -1; int64_t worst_latency = INT64_MIN; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (priv->child_up[i] && priv->child_latency[i] >= 0 && priv->child_latency[i] > worst_latency) { worst_child = i; worst_latency = priv->child_latency[i]; } } if (worst_child >= 0) { gf_msg_debug(this->name, 0, "Found worst up child (%d) @ %" PRId64 " ms latency", worst_child, worst_latency); } return worst_child; } static void __afr_handle_ping_event(xlator_t *this, xlator_t *child_xlator, const int idx, int64_t halo_max_latency_msec, int32_t *event, int64_t child_latency_msec) { afr_private_t *priv = NULL; int up_children = 0; priv = this->private; priv->child_latency[idx] = child_latency_msec; gf_msg_debug(child_xlator->name, 0, "Client ping @ %" PRId64 " ms", child_latency_msec); if (priv->shd.iamshd) return; up_children = __afr_get_up_children_count(priv); if (child_latency_msec > halo_max_latency_msec && priv->child_up[idx] == 1 && up_children > priv->halo_min_replicas) { if ((up_children - 1) < priv->halo_min_replicas) { gf_log(child_xlator->name, GF_LOG_INFO, "Overriding halo threshold, " "min replicas: %d", priv->halo_min_replicas); } else { gf_log(child_xlator->name, GF_LOG_INFO, "Child latency (%" PRId64 " ms) " "exceeds halo threshold (%" PRId64 "), " "marking child down.", child_latency_msec, halo_max_latency_msec); if (priv->halo_child_up[idx]) { *event = GF_EVENT_CHILD_DOWN; } } } else if (child_latency_msec < halo_max_latency_msec && priv->child_up[idx] == 0) { if (up_children < priv->halo_max_replicas) { gf_log(child_xlator->name, GF_LOG_INFO, "Child latency (%" PRId64 " ms) " "below halo threshold (%" PRId64 "), " "marking child up.", child_latency_msec, halo_max_latency_msec); if (priv->halo_child_up[idx]) { *event = GF_EVENT_CHILD_UP; } } else { gf_log(child_xlator->name, GF_LOG_INFO, "Not marking child %d up, " "max replicas (%d) reached.", idx, priv->halo_max_replicas); } } } static int64_t afr_get_halo_latency(xlator_t *this) { afr_private_t *priv = NULL; int64_t halo_max_latency_msec = 0; priv = this->private; if (priv->shd.iamshd) { halo_max_latency_msec = priv->shd.halo_max_latency_msec; } else if (priv->nfsd.iamnfsd) { halo_max_latency_msec = priv->nfsd.halo_max_latency_msec; } else { halo_max_latency_msec = priv->halo_max_latency_msec; } gf_msg_debug(this->name, 0, "Using halo latency %" PRId64, halo_max_latency_msec); return halo_max_latency_msec; } static void __afr_handle_child_up_event(xlator_t *this, xlator_t *child_xlator, const int idx, int64_t child_latency_msec, int32_t *event, int32_t *call_psh, int32_t *up_child) { afr_private_t *priv = NULL; int up_children = 0; int worst_up_child = -1; int64_t halo_max_latency_msec = afr_get_halo_latency(this); priv = this->private; /* * This only really counts if the child was never up * (value = -1) or had been down (value = 0). See * comment at GF_EVENT_CHILD_DOWN for a more detailed * explanation. */ if (priv->child_up[idx] != 1) { priv->event_generation++; } priv->child_up[idx] = 1; *call_psh = 1; *up_child = idx; up_children = __afr_get_up_children_count(priv); /* * If this is an _actual_ CHILD_UP event, we * want to set the child_latency to MAX to indicate * the child needs ping data to be available before doing child-up */ if (!priv->halo_enabled) goto out; if (child_latency_msec < 0) { /*set to INT64_MAX-1 so that it is found for best_down_child*/ priv->halo_child_up[idx] = 1; if (priv->child_latency[idx] < 0) { priv->child_latency[idx] = AFR_HALO_MAX_LATENCY; } } /* * Handle the edge case where we exceed * halo_min_replicas and we've got a child which is * marked up as it was helping to satisfy the * halo_min_replicas even though it's latency exceeds * halo_max_latency_msec. */ if (up_children > priv->halo_min_replicas) { worst_up_child = find_worst_up_child(this); if (worst_up_child >= 0 && priv->child_latency[worst_up_child] > halo_max_latency_msec) { gf_msg_debug(this->name, 0, "Marking child %d down, " "doesn't meet halo threshold (%" PRId64 "), and > " "halo_min_replicas (%d)", worst_up_child, halo_max_latency_msec, priv->halo_min_replicas); priv->child_up[worst_up_child] = 0; up_children--; } } if (up_children > priv->halo_max_replicas && !priv->shd.iamshd) { worst_up_child = find_worst_up_child(this); if (worst_up_child < 0) { worst_up_child = idx; } priv->child_up[worst_up_child] = 0; up_children--; gf_msg_debug(this->name, 0, "Marking child %d down, " "up_children (%d) > halo_max_replicas (%d)", worst_up_child, up_children, priv->halo_max_replicas); } out: if (up_children == 1) { gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_SUBVOL_UP, "Subvolume '%s' came back up; " "going online.", child_xlator->name); gf_event(EVENT_AFR_SUBVOL_UP, "client-pid=%d; subvol=%s", this->ctx->cmd_args.client_pid, this->name); } else { *event = GF_EVENT_SOME_DESCENDENT_UP; } priv->last_event[idx] = *event; } void __afr_handle_child_down_event(xlator_t *this, xlator_t *child_xlator, int idx, int64_t child_latency_msec, int32_t *event, int32_t *call_psh, int32_t *up_child) { afr_private_t *priv = NULL; int i = 0; int up_children = 0; int down_children = 0; int best_down_child = -1; priv = this->private; /* * If a brick is down when we start, we'll get a * CHILD_DOWN to indicate its initial state. There * was never a CHILD_UP in this case, so if we * increment "down_count" the difference between than * and "up_count" will no longer be the number of * children that are currently up. This has serious * implications e.g. for quorum enforcement, so we * don't increment these values unless the event * represents an actual state transition between "up" * (value = 1) and anything else. */ if (priv->child_up[idx] == 1) { priv->event_generation++; } /* * If this is an _actual_ CHILD_DOWN event, we * want to set the child_latency to < 0 to indicate * the child is really disconnected. */ if (child_latency_msec < 0) { priv->child_latency[idx] = child_latency_msec; priv->halo_child_up[idx] = 0; } priv->child_up[idx] = 0; up_children = __afr_get_up_children_count(priv); /* * Handle the edge case where we need to find the * next best child (to mark up) as marking this child * down would cause us to fall below halo_min_replicas. * We will also force the SHD to heal this child _now_ * as we want it to be up to date if we are going to * begin using it synchronously. */ if (priv->halo_enabled && up_children < priv->halo_min_replicas) { best_down_child = find_best_down_child(this); if (best_down_child >= 0) { gf_msg_debug(this->name, 0, "Swapping out child %d for " "child %d to satisfy halo_min_replicas (%d).", idx, best_down_child, priv->halo_min_replicas); priv->child_up[best_down_child] = 1; *call_psh = 1; *up_child = best_down_child; } } for (i = 0; i < priv->child_count; i++) if (priv->child_up[i] == 0) down_children++; if (down_children == priv->child_count) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SUBVOLS_DOWN, "All subvolumes are down. Going " "offline until at least one of them " "comes back up."); gf_event(EVENT_AFR_SUBVOLS_DOWN, "client-pid=%d; subvol=%s", this->ctx->cmd_args.client_pid, this->name); } else { *event = GF_EVENT_SOME_DESCENDENT_DOWN; } priv->last_event[idx] = *event; } void afr_ta_lock_release_synctask(xlator_t *this) { call_frame_t *ta_frame = NULL; int ret = 0; ta_frame = afr_ta_frame_create(this); if (!ta_frame) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_THIN_ARB, "Failed to create ta_frame"); return; } ret = synctask_new(this->ctx->env, afr_release_notify_lock_for_ta, afr_ta_lock_release_done, ta_frame, this); if (ret) { STACK_DESTROY(ta_frame->root); gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_THIN_ARB, "Failed to release " "AFR_TA_DOM_NOTIFY lock."); } } static void afr_handle_inodelk_contention(xlator_t *this, struct gf_upcall *upcall) { struct gf_upcall_inodelk_contention *lc = NULL; unsigned int inmem_count = 0; unsigned int onwire_count = 0; afr_private_t *priv = this->private; lc = upcall->data; if (strcmp(lc->domain, AFR_TA_DOM_NOTIFY) != 0) return; if (priv->shd.iamshd) { /* shd should ignore AFR_TA_DOM_NOTIFY release requests. */ return; } LOCK(&priv->lock); { if (priv->release_ta_notify_dom_lock == _gf_true) { /* Ignore multiple release requests from shds.*/ UNLOCK(&priv->lock); return; } priv->release_ta_notify_dom_lock = _gf_true; inmem_count = priv->ta_in_mem_txn_count; onwire_count = priv->ta_on_wire_txn_count; } UNLOCK(&priv->lock); if (inmem_count || onwire_count) /* lock release will happen in txn code path after * in-memory or on-wire txns are over.*/ return; afr_ta_lock_release_synctask(this); } static void afr_handle_upcall_event(xlator_t *this, struct gf_upcall *upcall, const int idx) { struct gf_upcall_cache_invalidation *up_ci = NULL; afr_private_t *priv = this->private; inode_t *inode = NULL; inode_table_t *itable = NULL; int i = 0; switch (upcall->event_type) { case GF_UPCALL_INODELK_CONTENTION: afr_handle_inodelk_contention(this, upcall); break; case GF_UPCALL_CACHE_INVALIDATION: up_ci = (struct gf_upcall_cache_invalidation *)upcall->data; if (AFR_IS_ARBITER_BRICK(priv, idx)) { /* Skip all update involving iatt from arbiter * node, since the size contains invalid info */ up_ci->flags &= ~UP_ATTR_FLAGS; up_ci->flags &= ~UP_PARENT_DENTRY_FLAGS; } /* Since md-cache will be aggressively filtering * lookups, the stale read issue will be more * pronounced. Hence when a pending xattr is set notify * all the md-cache clients to invalidate the existing * stat cache and send the lookup next time */ if (!up_ci->dict) break; for (i = 0; i < priv->child_count; i++) { if (!dict_get(up_ci->dict, priv->pending_key[i])) continue; up_ci->flags |= UP_INVAL_ATTR; itable = ((xlator_t *)this->graph->top)->itable; /*Internal processes may not have itable for *top xlator*/ if (itable) inode = inode_find(itable, upcall->gfid); if (inode) afr_inode_need_refresh_set(inode, this); break; } break; default: break; } } int32_t afr_notify(xlator_t *this, int32_t event, void *data, void *data2) { afr_private_t *priv = NULL; xlator_t *child_xlator = NULL; int i = -1; int propagate = 0; int had_heard_from_all = 0; int have_heard_from_all = 0; int idx = -1; int ret = -1; int call_psh = 0; int up_child = -1; dict_t *input = NULL; dict_t *output = NULL; gf_boolean_t had_quorum = _gf_false; gf_boolean_t has_quorum = _gf_false; int64_t halo_max_latency_msec = 0; int64_t child_latency_msec = -1; child_xlator = (xlator_t *)data; priv = this->private; if (!priv) return 0; /* * We need to reset this in case children come up in "staggered" * fashion, so that we discover a late-arriving local subvolume. Note * that we could end up issuing N lookups to the first subvolume, and * O(N^2) overall, but N is small for AFR so it shouldn't be an issue. */ priv->did_discovery = _gf_false; /* parent xlators don't need to know about every child_up, child_down * because of afr ha. If all subvolumes go down, child_down has * to be triggered. In that state when 1 subvolume comes up child_up * needs to be triggered. dht optimizes revalidate lookup by sending * it only to one of its subvolumes. When child up/down happens * for afr's subvolumes dht should be notified by child_modified. The * subsequent revalidate lookup happens on all the dht's subvolumes * which triggers afr self-heals if any. */ idx = afr_find_child_index(this, child_xlator); if (idx < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_INVALID_CHILD_UP, "Received child_up from invalid subvolume"); goto out; } had_quorum = priv->quorum_count && afr_has_quorum(priv->child_up, priv, NULL); if (event == GF_EVENT_CHILD_PING) { child_latency_msec = (int64_t)(uintptr_t)data2; if (priv->halo_enabled) { halo_max_latency_msec = afr_get_halo_latency(this); /* Calculates the child latency and sets event */ LOCK(&priv->lock); { __afr_handle_ping_event(this, child_xlator, idx, halo_max_latency_msec, &event, child_latency_msec); } UNLOCK(&priv->lock); } else { LOCK(&priv->lock); { priv->child_latency[idx] = child_latency_msec; } UNLOCK(&priv->lock); } } if (event == GF_EVENT_CHILD_PING) { /* This is the only xlator that handles PING, no reason to * propagate. */ goto out; } if (event == GF_EVENT_TRANSLATOR_OP) { LOCK(&priv->lock); { had_heard_from_all = __get_heard_from_all_status(priv); } UNLOCK(&priv->lock); if (!had_heard_from_all) { ret = -1; } else { input = data; output = data2; ret = afr_xl_op(this, input, output); } goto out; } if (event == GF_EVENT_UPCALL) { afr_handle_upcall_event(this, data, idx); } LOCK(&priv->lock); { had_heard_from_all = __get_heard_from_all_status(priv); switch (event) { case GF_EVENT_PARENT_UP: __afr_launch_notify_timer(this, priv); propagate = 1; break; case GF_EVENT_CHILD_UP: if (priv->thin_arbiter_count && (idx == AFR_CHILD_THIN_ARBITER)) { priv->ta_child_up = 1; priv->ta_event_gen++; break; } __afr_handle_child_up_event(this, child_xlator, idx, child_latency_msec, &event, &call_psh, &up_child); __afr_lock_heal_synctask(this, priv, idx); break; case GF_EVENT_CHILD_DOWN: if (priv->thin_arbiter_count && (idx == AFR_CHILD_THIN_ARBITER)) { priv->ta_child_up = 0; priv->ta_event_gen++; afr_ta_locked_priv_invalidate(priv); break; } __afr_handle_child_down_event(this, child_xlator, idx, child_latency_msec, &event, &call_psh, &up_child); __afr_mark_pending_lk_heal(this, priv, idx); break; case GF_EVENT_CHILD_CONNECTING: priv->last_event[idx] = event; break; case GF_EVENT_SOME_DESCENDENT_DOWN: priv->last_event[idx] = event; break; default: propagate = 1; break; } have_heard_from_all = __get_heard_from_all_status(priv); if (!had_heard_from_all && have_heard_from_all) { if (priv->timer) { gf_timer_call_cancel(this->ctx, priv->timer); priv->timer = NULL; } /* This is the first event which completes aggregation of events from all subvolumes. If at least one subvol had come up, propagate CHILD_UP, but only this time */ event = GF_EVENT_CHILD_DOWN; for (i = 0; i < priv->child_count; i++) { if (priv->last_event[i] == GF_EVENT_CHILD_UP) { event = GF_EVENT_CHILD_UP; break; } if (priv->last_event[i] == GF_EVENT_CHILD_CONNECTING) { event = GF_EVENT_CHILD_CONNECTING; /* continue to check other events for CHILD_UP */ } } } } UNLOCK(&priv->lock); if (priv->quorum_count) { has_quorum = afr_has_quorum(priv->child_up, priv, NULL); if (!had_quorum && has_quorum) { gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_QUORUM_MET, "Client-quorum is met"); gf_event(EVENT_AFR_QUORUM_MET, "client-pid=%d; subvol=%s", this->ctx->cmd_args.client_pid, this->name); } if (had_quorum && !has_quorum) { gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_QUORUM_FAIL, "Client-quorum is not met"); gf_event(EVENT_AFR_QUORUM_FAIL, "client-pid=%d; subvol=%s", this->ctx->cmd_args.client_pid, this->name); } } /* if all subvols have reported status, no need to hide anything or wait for anything else. Just propagate blindly */ if (have_heard_from_all) propagate = 1; ret = 0; if (propagate) ret = default_notify(this, event, data); if ((!had_heard_from_all) || call_psh) { /* Launch self-heal on all local subvolumes if: * a) We have_heard_from_all for the first time * b) Already heard from everyone, but we now got a child-up * event. */ if (have_heard_from_all) { afr_selfheal_childup(this, priv); } } out: return ret; } int afr_local_init(afr_local_t *local, afr_private_t *priv, int32_t *op_errno) { int __ret; local->op_ret = -1; local->op_errno = EUCLEAN; __ret = syncbarrier_init(&local->barrier); if (__ret) { if (op_errno) *op_errno = __ret; goto out; } local->child_up = GF_MALLOC(priv->child_count * sizeof(*local->child_up), gf_afr_mt_char); if (!local->child_up) { if (op_errno) *op_errno = ENOMEM; goto out; } memcpy(local->child_up, priv->child_up, sizeof(*local->child_up) * priv->child_count); local->call_count = AFR_COUNT(local->child_up, priv->child_count); if (local->call_count == 0) { gf_msg(THIS->name, GF_LOG_INFO, 0, AFR_MSG_SUBVOLS_DOWN, "no subvolumes up"); if (op_errno) *op_errno = ENOTCONN; goto out; } local->event_generation = priv->event_generation; local->read_attempted = GF_CALLOC(priv->child_count, sizeof(char), gf_afr_mt_char); if (!local->read_attempted) { if (op_errno) *op_errno = ENOMEM; goto out; } local->readable = GF_CALLOC(priv->child_count, sizeof(char), gf_afr_mt_char); if (!local->readable) { if (op_errno) *op_errno = ENOMEM; goto out; } local->readable2 = GF_CALLOC(priv->child_count, sizeof(char), gf_afr_mt_char); if (!local->readable2) { if (op_errno) *op_errno = ENOMEM; goto out; } local->read_subvol = -1; local->replies = GF_CALLOC(priv->child_count, sizeof(*local->replies), gf_afr_mt_reply_t); if (!local->replies) { if (op_errno) *op_errno = ENOMEM; goto out; } local->need_full_crawl = _gf_false; if (priv->thin_arbiter_count) { local->ta_child_up = priv->ta_child_up; local->ta_failed_subvol = AFR_CHILD_UNKNOWN; local->read_txn_query_child = AFR_CHILD_UNKNOWN; local->ta_event_gen = priv->ta_event_gen; local->fop_state = TA_SUCCESS; } local->is_new_entry = _gf_false; local->need_open = GF_CALLOC(priv->child_count, sizeof(*local->need_open), gf_afr_mt_char); if (!local->need_open) { if (op_errno) *op_errno = ENOMEM; goto out; } INIT_LIST_HEAD(&local->healer); return 0; out: return -1; } static inline void afr_internal_lock_init(afr_internal_lock_t *lk, size_t child_count) { lk->lock_op_ret = -1; lk->lock_op_errno = EUCLEAN; } void afr_matrix_cleanup(int32_t **matrix, unsigned int m) { int i = 0; if (!matrix) goto out; for (i = 0; i < m; i++) { GF_FREE(matrix[i]); } GF_FREE(matrix); out: return; } int32_t ** afr_matrix_create(unsigned int m, unsigned int n) { int32_t **matrix = NULL; int i = 0; matrix = GF_CALLOC(sizeof(*matrix), m, gf_afr_mt_int32_t); if (!matrix) goto out; for (i = 0; i < m; i++) { matrix[i] = GF_CALLOC(sizeof(*matrix[i]), n, gf_afr_mt_int32_t); if (!matrix[i]) goto out; } return matrix; out: afr_matrix_cleanup(matrix, m); return NULL; } int afr_transaction_local_init(afr_local_t *local, xlator_t *this) { int ret = -ENOMEM; afr_private_t *priv = NULL; priv = this->private; INIT_LIST_HEAD(&local->transaction.wait_list); INIT_LIST_HEAD(&local->transaction.owner_list); INIT_LIST_HEAD(&local->ta_waitq); INIT_LIST_HEAD(&local->ta_onwireq); afr_internal_lock_init(&local->internal_lock, priv->child_count); ret = -ENOMEM; local->pre_op_compat = priv->pre_op_compat; local->transaction.pre_op = GF_CALLOC(sizeof(*local->transaction.pre_op), priv->child_count, gf_afr_mt_char); if (!local->transaction.pre_op) goto out; local->transaction.changelog_xdata = GF_CALLOC( sizeof(*local->transaction.changelog_xdata), priv->child_count, gf_afr_mt_dict_t); if (!local->transaction.changelog_xdata) goto out; if (priv->arbiter_count == 1) { local->transaction.pre_op_sources = GF_CALLOC( sizeof(*local->transaction.pre_op_sources), priv->child_count, gf_afr_mt_char); if (!local->transaction.pre_op_sources) goto out; } local->transaction.failed_subvols = GF_CALLOC( sizeof(*local->transaction.failed_subvols), priv->child_count, gf_afr_mt_char); if (!local->transaction.failed_subvols) goto out; local->pending = afr_matrix_create(priv->child_count, AFR_NUM_CHANGE_LOGS); if (!local->pending) goto out; ret = 0; out: return ret; } void afr_priv_destroy(afr_private_t *priv) { int i = 0; int child_count = -1; if (!priv) goto out; GF_FREE(priv->sh_domain); GF_FREE(priv->last_event); child_count = priv->child_count; if (priv->thin_arbiter_count) { child_count++; } if (priv->pending_key) { for (i = 0; i < child_count; i++) GF_FREE(priv->pending_key[i]); } GF_FREE(priv->pending_reads); GF_FREE(priv->local); GF_FREE(priv->pending_key); GF_FREE(priv->children); GF_FREE(priv->anon_inode); GF_FREE(priv->child_up); GF_FREE(priv->halo_child_up); GF_FREE(priv->child_latency); LOCK_DESTROY(&priv->lock); GF_FREE(priv); out: return; } int ** afr_mark_pending_changelog(afr_private_t *priv, unsigned char *pending, dict_t *xattr, ia_type_t iat) { int i = 0; int **changelog = NULL; int idx = -1; int m_idx = 0; int d_idx = 0; int ret = 0; uint32_t hton32_1; m_idx = afr_index_for_transaction_type(AFR_METADATA_TRANSACTION); d_idx = afr_index_for_transaction_type(AFR_DATA_TRANSACTION); idx = afr_index_from_ia_type(iat); changelog = afr_matrix_create(priv->child_count, AFR_NUM_CHANGE_LOGS); if (!changelog) goto out; hton32_1 = htobe32(1); for (i = 0; i < priv->child_count; i++) { if (!pending[i]) continue; changelog[i][m_idx] = hton32_1; if (idx != -1) changelog[i][idx] = hton32_1; /* If the newentry marking is on a newly created directory, * then mark it with the full-heal indicator. */ if ((IA_ISDIR(iat)) && (priv->esh_granular)) changelog[i][d_idx] = hton32_1; } ret = afr_set_pending_dict(priv, xattr, changelog); if (ret < 0) { afr_matrix_cleanup(changelog, priv->child_count); return NULL; } out: return changelog; } static dict_t * afr_set_heal_info(char *status) { dict_t *dict = NULL; int ret = -1; dict = dict_new(); if (!dict) { ret = -ENOMEM; goto out; } ret = dict_set_dynstr_sizen(dict, "heal-info", status); if (ret) gf_msg("", GF_LOG_WARNING, -ret, AFR_MSG_DICT_SET_FAILED, "Failed to set heal-info key to " "%s", status); out: /* Any error other than EINVAL, dict_set_dynstr frees status */ if (ret == -ENOMEM || ret == -EINVAL) { GF_FREE(status); } if (ret && dict) { dict_unref(dict); dict = NULL; } return dict; } static gf_boolean_t afr_is_dirty_count_non_unary_for_txn(xlator_t *this, struct afr_reply *replies, afr_transaction_type type) { afr_private_t *priv = this->private; int *dirty = alloca0(priv->child_count * sizeof(int)); int i = 0; afr_selfheal_extract_xattr(this, replies, type, dirty, NULL); for (i = 0; i < priv->child_count; i++) { if (dirty[i] > 1) return _gf_true; } return _gf_false; } static gf_boolean_t afr_is_dirty_count_non_unary(xlator_t *this, struct afr_reply *replies, ia_type_t ia_type) { gf_boolean_t data_chk = _gf_false; gf_boolean_t mdata_chk = _gf_false; gf_boolean_t entry_chk = _gf_false; switch (ia_type) { case IA_IFDIR: mdata_chk = _gf_true; entry_chk = _gf_true; break; case IA_IFREG: mdata_chk = _gf_true; data_chk = _gf_true; break; default: /*IA_IFBLK, IA_IFCHR, IA_IFLNK, IA_IFIFO, IA_IFSOCK*/ mdata_chk = _gf_true; break; } if (data_chk && afr_is_dirty_count_non_unary_for_txn( this, replies, AFR_DATA_TRANSACTION)) { return _gf_true; } else if (mdata_chk && afr_is_dirty_count_non_unary_for_txn( this, replies, AFR_METADATA_TRANSACTION)) { return _gf_true; } else if (entry_chk && afr_is_dirty_count_non_unary_for_txn( this, replies, AFR_ENTRY_TRANSACTION)) { return _gf_true; } return _gf_false; } static int afr_update_heal_status(xlator_t *this, struct afr_reply *replies, ia_type_t ia_type, gf_boolean_t *esh, gf_boolean_t *dsh, gf_boolean_t *msh, unsigned char pending) { int ret = -1; GF_UNUSED int ret1 = 0; int i = 0; int io_domain_lk_count = 0; int shd_domain_lk_count = 0; afr_private_t *priv = NULL; char *key1 = NULL; char *key2 = NULL; priv = this->private; key1 = alloca0(strlen(GLUSTERFS_INODELK_DOM_PREFIX) + 2 + strlen(this->name)); key2 = alloca0(strlen(GLUSTERFS_INODELK_DOM_PREFIX) + 2 + strlen(priv->sh_domain)); sprintf(key1, "%s:%s", GLUSTERFS_INODELK_DOM_PREFIX, this->name); sprintf(key2, "%s:%s", GLUSTERFS_INODELK_DOM_PREFIX, priv->sh_domain); for (i = 0; i < priv->child_count; i++) { if ((replies[i].valid != 1) || (replies[i].op_ret != 0)) continue; if (!io_domain_lk_count) { ret1 = dict_get_int32(replies[i].xdata, key1, &io_domain_lk_count); } if (!shd_domain_lk_count) { ret1 = dict_get_int32(replies[i].xdata, key2, &shd_domain_lk_count); } } if (!pending) { if ((afr_is_dirty_count_non_unary(this, replies, ia_type)) || (!io_domain_lk_count)) { /* Needs heal. */ ret = 0; } else { /* No heal needed. */ *dsh = *esh = *msh = 0; } } else { if (shd_domain_lk_count) { ret = -EAGAIN; /*For 'possibly-healing'. */ } else { ret = 0; /*needs heal. Just set a non -ve value so that it is assumed as the source index.*/ } } return ret; } /*return EIO, EAGAIN or pending*/ static int afr_lockless_inspect(call_frame_t *frame, xlator_t *this, uuid_t gfid, inode_t **inode, gf_boolean_t *entry_selfheal, gf_boolean_t *data_selfheal, gf_boolean_t *metadata_selfheal, unsigned char *pending) { int ret = -1; int i = 0; afr_private_t *priv = NULL; struct afr_reply *replies = NULL; gf_boolean_t dsh = _gf_false; gf_boolean_t msh = _gf_false; gf_boolean_t esh = _gf_false; unsigned char *sources = NULL; unsigned char *sinks = NULL; unsigned char *valid_on = NULL; uint64_t *witness = NULL; priv = this->private; replies = alloca0(sizeof(*replies) * priv->child_count); sources = alloca0(sizeof(*sources) * priv->child_count); sinks = alloca0(sizeof(*sinks) * priv->child_count); witness = alloca0(sizeof(*witness) * priv->child_count); valid_on = alloca0(sizeof(*valid_on) * priv->child_count); ret = afr_selfheal_unlocked_inspect(frame, this, gfid, inode, &dsh, &msh, &esh, replies); if (ret) goto out; for (i = 0; i < priv->child_count; i++) { if (replies[i].valid && replies[i].op_ret == 0) { valid_on[i] = 1; } } if (msh) { ret = afr_selfheal_find_direction(frame, this, replies, AFR_METADATA_TRANSACTION, valid_on, sources, sinks, witness, pending); if (*pending & PFLAG_SBRAIN) ret = -EIO; if (ret) goto out; } if (dsh) { ret = afr_selfheal_find_direction(frame, this, replies, AFR_DATA_TRANSACTION, valid_on, sources, sinks, witness, pending); if (*pending & PFLAG_SBRAIN) ret = -EIO; if (ret) goto out; } if (esh) { ret = afr_selfheal_find_direction(frame, this, replies, AFR_ENTRY_TRANSACTION, valid_on, sources, sinks, witness, pending); if (*pending & PFLAG_SBRAIN) ret = -EIO; if (ret) goto out; } ret = afr_update_heal_status(this, replies, (*inode)->ia_type, &esh, &dsh, &msh, *pending); out: *data_selfheal = dsh; *entry_selfheal = esh; *metadata_selfheal = msh; if (replies) afr_replies_wipe(replies, priv->child_count); return ret; } int afr_get_heal_info(call_frame_t *frame, xlator_t *this, loc_t *loc) { gf_boolean_t data_selfheal = _gf_false; gf_boolean_t metadata_selfheal = _gf_false; gf_boolean_t entry_selfheal = _gf_false; unsigned char pending = 0; dict_t *dict = NULL; int ret = -1; int op_errno = ENOMEM; inode_t *inode = NULL; char *substr = NULL; char *status = NULL; call_frame_t *heal_frame = NULL; afr_local_t *heal_local = NULL; /*Use frame with lk-owner set*/ heal_frame = afr_frame_create(frame->this, &op_errno); if (!heal_frame) { ret = -1; goto out; } heal_local = heal_frame->local; heal_frame->local = frame->local; ret = afr_lockless_inspect(heal_frame, this, loc->gfid, &inode, &entry_selfheal, &data_selfheal, &metadata_selfheal, &pending); if (ret == -ENOMEM) { ret = -1; goto out; } if (pending & PFLAG_PENDING) { gf_asprintf(&substr, "-pending"); if (!substr) goto out; } if (ret == -EIO) { ret = gf_asprintf(&status, "split-brain%s", substr ? substr : ""); if (ret < 0) { goto out; } dict = afr_set_heal_info(status); if (!dict) { ret = -1; goto out; } } else if (ret == -EAGAIN) { ret = gf_asprintf(&status, "possibly-healing%s", substr ? substr : ""); if (ret < 0) { goto out; } dict = afr_set_heal_info(status); if (!dict) { ret = -1; goto out; } } else if (ret >= 0) { /* value of ret = source index * so ret >= 0 and at least one of the 3 booleans set to * true means a source is identified; heal is required. */ if (!data_selfheal && !entry_selfheal && !metadata_selfheal) { status = gf_strdup("no-heal"); if (!status) { ret = -1; goto out; } dict = afr_set_heal_info(status); if (!dict) { ret = -1; goto out; } } else { ret = gf_asprintf(&status, "heal%s", substr ? substr : ""); if (ret < 0) { goto out; } dict = afr_set_heal_info(status); if (!dict) { ret = -1; goto out; } } } else if (ret < 0) { /* Apart from above checked -ve ret values, there are * other possible ret values like ENOTCONN * (returned when number of valid replies received are * less than 2) * in which case heal is required when one of the * selfheal booleans is set. */ if (data_selfheal || entry_selfheal || metadata_selfheal) { ret = gf_asprintf(&status, "heal%s", substr ? substr : ""); if (ret < 0) { goto out; } dict = afr_set_heal_info(status); if (!dict) { ret = -1; goto out; } } } ret = 0; op_errno = 0; out: if (heal_frame) { heal_frame->local = heal_local; AFR_STACK_DESTROY(heal_frame); } AFR_STACK_UNWIND(getxattr, frame, ret, op_errno, dict, NULL); if (dict) dict_unref(dict); if (inode) inode_unref(inode); GF_FREE(substr); return ret; } int _afr_is_split_brain(call_frame_t *frame, xlator_t *this, struct afr_reply *replies, afr_transaction_type type, gf_boolean_t *spb) { afr_private_t *priv = NULL; uint64_t *witness = NULL; unsigned char *sources = NULL; unsigned char *sinks = NULL; int sources_count = 0; int ret = 0; priv = this->private; sources = alloca0(priv->child_count); sinks = alloca0(priv->child_count); witness = alloca0(priv->child_count * sizeof(*witness)); ret = afr_selfheal_find_direction(frame, this, replies, type, priv->child_up, sources, sinks, witness, NULL); if (ret) return ret; sources_count = AFR_COUNT(sources, priv->child_count); if (!sources_count) *spb = _gf_true; return ret; } int afr_is_split_brain(call_frame_t *frame, xlator_t *this, inode_t *inode, uuid_t gfid, gf_boolean_t *d_spb, gf_boolean_t *m_spb) { int ret = -1; afr_private_t *priv = NULL; struct afr_reply *replies = NULL; priv = this->private; replies = alloca0(sizeof(*replies) * priv->child_count); ret = afr_selfheal_unlocked_discover(frame, inode, gfid, replies); if (ret) goto out; if (!afr_can_decide_split_brain_source_sinks(replies, priv->child_count)) { ret = -EAGAIN; goto out; } ret = _afr_is_split_brain(frame, this, replies, AFR_DATA_TRANSACTION, d_spb); if (ret) goto out; ret = _afr_is_split_brain(frame, this, replies, AFR_METADATA_TRANSACTION, m_spb); out: if (replies) { afr_replies_wipe(replies, priv->child_count); replies = NULL; } return ret; } int afr_get_split_brain_status_cbk(int ret, call_frame_t *frame, void *opaque) { GF_FREE(opaque); return 0; } int afr_get_split_brain_status(void *opaque) { gf_boolean_t d_spb = _gf_false; gf_boolean_t m_spb = _gf_false; int ret = -1; int op_errno = 0; int i = 0; char *choices = NULL; char *status = NULL; dict_t *dict = NULL; inode_t *inode = NULL; afr_private_t *priv = NULL; xlator_t **children = NULL; call_frame_t *frame = NULL; xlator_t *this = NULL; loc_t *loc = NULL; afr_spb_status_t *data = NULL; data = opaque; frame = data->frame; this = frame->this; loc = data->loc; priv = this->private; children = priv->children; inode = afr_inode_find(this, loc->gfid); if (!inode) goto out; dict = dict_new(); if (!dict) { op_errno = ENOMEM; ret = -1; goto out; } /* Calculation for string length : * (child_count X length of child-name) + SLEN(" Choices :") * child-name consists of : * a) 251 = max characters for volname according to GD_VOLUME_NAME_MAX * b) strlen("-client-00,") assuming 16 replicas */ choices = alloca0(priv->child_count * (256 + SLEN("-client-00,")) + SLEN(" Choices:")); ret = afr_is_split_brain(frame, this, inode, loc->gfid, &d_spb, &m_spb); if (ret) { op_errno = -ret; if (ret == -EAGAIN) { ret = dict_set_sizen_str_sizen(dict, GF_AFR_SBRAIN_STATUS, SBRAIN_HEAL_NO_GO_MSG); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, AFR_MSG_DICT_SET_FAILED, "Failed to set GF_AFR_SBRAIN_STATUS in dict"); } } ret = -1; goto out; } if (d_spb || m_spb) { sprintf(choices, " Choices:"); for (i = 0; i < priv->child_count; i++) { strcat(choices, children[i]->name); strcat(choices, ","); } choices[strlen(choices) - 1] = '\0'; ret = gf_asprintf(&status, "data-split-brain:%s " "metadata-split-brain:%s%s", (d_spb) ? "yes" : "no", (m_spb) ? "yes" : "no", choices); if (-1 == ret) { op_errno = ENOMEM; goto out; } ret = dict_set_dynstr_sizen(dict, GF_AFR_SBRAIN_STATUS, status); if (ret) { op_errno = -ret; ret = -1; goto out; } } else { ret = dict_set_sizen_str_sizen(dict, GF_AFR_SBRAIN_STATUS, SFILE_NOT_UNDER_DATA); if (ret) { op_errno = -ret; ret = -1; goto out; } } ret = 0; out: AFR_STACK_UNWIND(getxattr, frame, ret, op_errno, dict, NULL); if (dict) dict_unref(dict); if (inode) inode_unref(inode); return ret; } int32_t afr_heal_splitbrain_file(call_frame_t *frame, xlator_t *this, loc_t *loc) { int ret = 0; int op_errno = 0; dict_t *dict = NULL; afr_local_t *local = NULL; afr_local_t *heal_local = NULL; call_frame_t *heal_frame = NULL; local = frame->local; dict = dict_new(); if (!dict) { op_errno = ENOMEM; ret = -1; goto out; } heal_frame = afr_frame_create(this, &op_errno); if (!heal_frame) { ret = -1; goto out; } heal_local = heal_frame->local; heal_frame->local = frame->local; /*Initiate heal with heal_frame with lk-owner set so that inodelk/entrylk * work correctly*/ ret = afr_selfheal_do(heal_frame, this, loc->gfid); if (ret == 1 || ret == 2) { ret = dict_set_sizen_str_sizen(dict, "sh-fail-msg", SFILE_NOT_IN_SPLIT_BRAIN); if (ret) gf_msg(this->name, GF_LOG_WARNING, -ret, AFR_MSG_DICT_SET_FAILED, "Failed to set sh-fail-msg in dict"); ret = 0; goto out; } else { if (local->xdata_rsp) { /* 'sh-fail-msg' has been set in the dict during self-heal.*/ dict_copy(local->xdata_rsp, dict); ret = 0; } else if (ret < 0) { op_errno = -ret; ret = -1; } } out: if (heal_frame) { heal_frame->local = heal_local; AFR_STACK_DESTROY(heal_frame); } if (local->op == GF_FOP_GETXATTR) AFR_STACK_UNWIND(getxattr, frame, ret, op_errno, dict, NULL); else if (local->op == GF_FOP_SETXATTR) AFR_STACK_UNWIND(setxattr, frame, ret, op_errno, NULL); if (dict) dict_unref(dict); return ret; } int afr_get_child_index_from_name(xlator_t *this, char *name) { afr_private_t *priv = this->private; int index = -1; for (index = 0; index < priv->child_count; index++) { if (!strcmp(priv->children[index]->name, name)) goto out; } index = -1; out: return index; } void afr_priv_need_heal_set(afr_private_t *priv, gf_boolean_t need_heal) { LOCK(&priv->lock); { priv->need_heal = need_heal; } UNLOCK(&priv->lock); } static void afr_set_need_heal(xlator_t *this, afr_local_t *local) { int i = 0; afr_private_t *priv = this->private; gf_boolean_t need_heal = _gf_false; for (i = 0; i < priv->child_count; i++) { if (local->replies[i].valid && local->replies[i].need_heal) { need_heal = _gf_true; break; } } afr_priv_need_heal_set(priv, need_heal); return; } gf_boolean_t afr_get_need_heal(afr_private_t *priv) { gf_boolean_t need_heal = _gf_true; LOCK(&priv->lock); { need_heal = priv->need_heal; } UNLOCK(&priv->lock); return need_heal; } static int afr_fav_child_reset_sink_xattrs_cbk(int ret, call_frame_t *heal_frame, void *opaque) { call_frame_t *txn_frame = NULL; afr_local_t *local = NULL; afr_local_t *heal_local = NULL; xlator_t *this = NULL; heal_local = heal_frame->local; txn_frame = heal_local->heal_frame; local = txn_frame->local; this = txn_frame->this; /* Refresh the inode agan and proceed with the transaction.*/ afr_inode_refresh(txn_frame, this, local->inode, NULL, local->refreshfn); AFR_STACK_DESTROY(heal_frame); return 0; } int afr_fav_child_reset_sink_xattrs(void *opaque) { call_frame_t *heal_frame = NULL; call_frame_t *txn_frame = NULL; xlator_t *this = NULL; gf_boolean_t d_spb = _gf_false; gf_boolean_t m_spb = _gf_false; afr_local_t *heal_local = NULL; afr_local_t *txn_local = NULL; afr_private_t *priv = NULL; inode_t *inode = NULL; unsigned char *locked_on = NULL; unsigned char *sources = NULL; unsigned char *sinks = NULL; unsigned char *healed_sinks = NULL; unsigned char *undid_pending = NULL; struct afr_reply *locked_replies = NULL; int ret = 0; heal_frame = (call_frame_t *)opaque; heal_local = heal_frame->local; txn_frame = heal_local->heal_frame; txn_local = txn_frame->local; this = txn_frame->this; inode = txn_local->inode; priv = this->private; locked_on = alloca0(priv->child_count); sources = alloca0(priv->child_count); sinks = alloca0(priv->child_count); healed_sinks = alloca0(priv->child_count); undid_pending = alloca0(priv->child_count); locked_replies = alloca0(sizeof(*locked_replies) * priv->child_count); ret = _afr_is_split_brain(txn_frame, this, txn_local->replies, AFR_DATA_TRANSACTION, &d_spb); ret = _afr_is_split_brain(txn_frame, this, txn_local->replies, AFR_METADATA_TRANSACTION, &m_spb); /* Take appropriate locks and reset sink xattrs. */ if (d_spb) { ret = afr_selfheal_inodelk(heal_frame, this, inode, this->name, 0, 0, locked_on); { if (ret < priv->child_count) goto data_unlock; ret = __afr_selfheal_data_prepare( heal_frame, this, inode, locked_on, sources, sinks, healed_sinks, undid_pending, locked_replies, NULL); } data_unlock: afr_selfheal_uninodelk(heal_frame, this, inode, this->name, 0, 0, locked_on); } if (m_spb) { memset(locked_on, 0, sizeof(*locked_on) * priv->child_count); memset(undid_pending, 0, sizeof(*undid_pending) * priv->child_count); ret = afr_selfheal_inodelk(heal_frame, this, inode, this->name, LLONG_MAX - 1, 0, locked_on); { if (ret < priv->child_count) goto mdata_unlock; ret = __afr_selfheal_metadata_prepare( heal_frame, this, inode, locked_on, sources, sinks, healed_sinks, undid_pending, locked_replies, NULL); } mdata_unlock: afr_selfheal_uninodelk(heal_frame, this, inode, this->name, LLONG_MAX - 1, 0, locked_on); } return ret; } /* * Concatenates the xattrs in local->replies separated by a delimiter. */ int afr_serialize_xattrs_with_delimiter(call_frame_t *frame, xlator_t *this, char *buf, size_t size, const char *default_str, int32_t *serz_len, char delimiter) { afr_private_t *priv = NULL; afr_local_t *local = NULL; char *xattr = NULL; int i = 0; size_t len = 0; int keylen = 0; int ret = -1; priv = this->private; local = frame->local; keylen = strlen(local->cont.getxattr.name); for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid || local->replies[i].op_ret) { len += snprintf(buf + len, size - len, "%s%c", default_str, delimiter); } else { ret = dict_get_strn(local->replies[i].xattr, local->cont.getxattr.name, keylen, &xattr); if (ret) { gf_msg("TEST", GF_LOG_ERROR, -ret, AFR_MSG_DICT_GET_FAILED, "Failed to get the node_uuid of brick " "%d", i); goto out; } len += snprintf(buf + len, size - len, "%s%c", xattr, delimiter); } /* No overflow but buffer size is not enough. */ GF_ASSERT(len <= size); } buf[--len] = '\0'; /*remove the last delimiter*/ if (serz_len) *serz_len = ++len; ret = 0; out: return ret; } uint64_t afr_write_subvol_get(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; uint64_t write_subvol = 0; local = frame->local; LOCK(&local->inode->lock); write_subvol = local->inode_ctx->write_subvol; UNLOCK(&local->inode->lock); return write_subvol; } int afr_write_subvol_set(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; unsigned char *data_accused = NULL; unsigned char *metadata_accused = NULL; unsigned char *data_readable = NULL; unsigned char *metadata_readable = NULL; uint16_t datamap = 0; uint16_t metadatamap = 0; uint64_t val = 0; int event = 0; int i = 0; local = frame->local; priv = this->private; data_accused = alloca0(priv->child_count); metadata_accused = alloca0(priv->child_count); data_readable = alloca0(priv->child_count); metadata_readable = alloca0(priv->child_count); event = local->event_generation; afr_readables_fill(local, this, local->inode, data_accused, metadata_accused, data_readable, metadata_readable, NULL); for (i = 0; i < priv->child_count; i++) { if (data_readable[i]) datamap |= (1 << i); if (metadata_readable[i]) metadatamap |= (1 << i); } val = ((uint64_t)metadatamap) | (((uint64_t)datamap) << 16) | (((uint64_t)event) << 32); LOCK(&local->inode->lock); { if (local->inode_ctx->write_subvol == 0 && local->transaction.type == AFR_DATA_TRANSACTION) { local->inode_ctx->write_subvol = val; } } UNLOCK(&local->inode->lock); return 0; } int afr_write_subvol_reset(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; local = frame->local; LOCK(&local->inode->lock); { GF_ASSERT(local->inode_ctx->lock_count > 0); local->inode_ctx->lock_count--; if (!local->inode_ctx->lock_count) local->inode_ctx->write_subvol = 0; } UNLOCK(&local->inode->lock); return 0; } int afr_set_inode_local(xlator_t *this, afr_local_t *local, inode_t *inode) { afr_inode_ctx_t *inode_ctx = NULL; local->inode = inode_ref(inode); LOCK(&local->inode->lock); { inode_ctx = __afr_inode_ctx_get(this, local->inode); if (inode_ctx) { local->inode_ctx = inode_ctx; } } UNLOCK(&local->inode->lock); if (inode_ctx == NULL) { gf_msg_callingfn( this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_INODE_CTX_GET_FAILED, "Error getting inode ctx %s", uuid_utoa(local->inode->gfid)); return -1; } return 0; } gf_boolean_t afr_ta_is_fop_called_from_synctask(xlator_t *this) { struct synctask *task = NULL; gf_lkowner_t tmp_owner; task = synctask_get(); if (!task) return _gf_false; set_lk_owner_from_ptr(&tmp_owner, (void *)this); if (!is_same_lkowner(&tmp_owner, &task->frame->root->lk_owner)) return _gf_false; return _gf_true; } int afr_ta_post_op_lock(xlator_t *this, loc_t *loc) { int ret = 0; uuid_t gfid = { 0, }; afr_private_t *priv = this->private; gf_boolean_t locked = _gf_false; struct gf_flock flock1 = { 0, }; struct gf_flock flock2 = { 0, }; int32_t cmd = 0; /* Clients must take AFR_TA_DOM_NOTIFY lock only when the previous lock * has been released in afr_notify due to upcall notification from shd. */ GF_ASSERT(priv->ta_notify_dom_lock_offset == 0); if (!priv->shd.iamshd) GF_ASSERT(afr_ta_is_fop_called_from_synctask(this)); flock1.l_type = F_WRLCK; while (!locked) { if (priv->shd.iamshd) { cmd = F_SETLKW; flock1.l_start = 0; flock1.l_len = 0; } else { cmd = F_SETLK; gf_uuid_generate(gfid); flock1.l_start = gfid_to_ino(gfid); if (flock1.l_start < 0) flock1.l_start = -flock1.l_start; flock1.l_len = 1; } ret = syncop_inodelk(priv->children[THIN_ARBITER_BRICK_INDEX], AFR_TA_DOM_NOTIFY, loc, cmd, &flock1, NULL, NULL); if (!ret) { locked = _gf_true; priv->ta_notify_dom_lock_offset = flock1.l_start; } else if (ret == -EAGAIN) { continue; } else { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to get " "AFR_TA_DOM_NOTIFY lock on %s.", loc->name); goto out; } } flock2.l_type = F_WRLCK; flock2.l_start = 0; flock2.l_len = 0; ret = syncop_inodelk(priv->children[THIN_ARBITER_BRICK_INDEX], AFR_TA_DOM_MODIFY, loc, F_SETLKW, &flock2, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to get AFR_TA_DOM_MODIFY lock on %s.", loc->name); flock1.l_type = F_UNLCK; ret = syncop_inodelk(priv->children[THIN_ARBITER_BRICK_INDEX], AFR_TA_DOM_NOTIFY, loc, F_SETLK, &flock1, NULL, NULL); } out: return ret; } int afr_ta_post_op_unlock(xlator_t *this, loc_t *loc) { afr_private_t *priv = this->private; struct gf_flock flock = { 0, }; int ret = 0; if (!priv->shd.iamshd) GF_ASSERT(afr_ta_is_fop_called_from_synctask(this)); flock.l_type = F_UNLCK; flock.l_start = 0; flock.l_len = 0; ret = syncop_inodelk(priv->children[THIN_ARBITER_BRICK_INDEX], AFR_TA_DOM_MODIFY, loc, F_SETLK, &flock, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to unlock AFR_TA_DOM_MODIFY lock."); goto out; } if (!priv->shd.iamshd) /* Mounts (clients) will not release the AFR_TA_DOM_NOTIFY lock * in post-op as they use it as a notification mechanism. When * shd sends a lock request on TA during heal, the clients will * receive a lock-contention upcall notification upon which they * will release the AFR_TA_DOM_NOTIFY lock after completing the * in flight I/O.*/ goto out; ret = syncop_inodelk(priv->children[THIN_ARBITER_BRICK_INDEX], AFR_TA_DOM_NOTIFY, loc, F_SETLK, &flock, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to unlock AFR_TA_DOM_NOTIFY lock."); } out: return ret; } call_frame_t * afr_ta_frame_create(xlator_t *this) { call_frame_t *frame = NULL; void *lk_owner = NULL; frame = create_frame(this, this->ctx->pool); if (!frame) return NULL; lk_owner = (void *)this; afr_set_lk_owner(frame, this, lk_owner); return frame; } gf_boolean_t afr_ta_has_quorum(afr_private_t *priv, afr_local_t *local) { int data_count = 0; data_count = AFR_COUNT(local->child_up, priv->child_count); if (data_count == 2) { return _gf_true; } else if (data_count == 1 && local->ta_child_up) { return _gf_true; } return _gf_false; } static gf_boolean_t afr_is_add_replica_mount_lookup_on_root(call_frame_t *frame) { afr_local_t *local = NULL; if (frame->root->pid != GF_CLIENT_PID_ADD_REPLICA_MOUNT) return _gf_false; local = frame->local; if (local->op != GF_FOP_LOOKUP) /* TODO:If the replica count is being increased on a plain distribute * volume that was never mounted, we need to allow setxattr on '/' with * GF_CLIENT_PID_NO_ROOT_SQUASH to accomodate for DHT layout setting */ return _gf_false; if (local->inode == NULL) return _gf_false; if (!__is_root_gfid(local->inode->gfid)) return _gf_false; return _gf_true; } gf_boolean_t afr_lookup_has_quorum(call_frame_t *frame, const unsigned int up_children_count) { if (frame && (up_children_count > 0) && afr_is_add_replica_mount_lookup_on_root(frame)) return _gf_true; return _gf_false; } void afr_handle_replies_quorum(call_frame_t *frame, xlator_t *this) { afr_local_t *local = frame->local; afr_private_t *priv = this->private; unsigned char *success_replies = NULL; success_replies = alloca0(priv->child_count); afr_fill_success_replies(local, priv, success_replies); if (priv->quorum_count && !afr_has_quorum(success_replies, priv, NULL)) { local->op_errno = afr_final_errno(local, priv); if (!local->op_errno) local->op_errno = afr_quorum_errno(priv); local->op_ret = -1; } } gf_boolean_t afr_ta_dict_contains_pending_xattr(dict_t *dict, afr_private_t *priv, int child) { int *pending = NULL; int ret = 0; int i = 0; ret = dict_get_ptr(dict, priv->pending_key[child], (void *)&pending); if (ret == 0) { for (i = 0; i < AFR_NUM_CHANGE_LOGS; i++) { if (pending[i]) { return _gf_true; } } } return _gf_false; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-self-heal-common.c0000644000000000000000000000013214522202451025134 xustar000000000000000030 mtime=1699284265.617027281 30 atime=1699284265.616027278 30 ctime=1699284301.124134228 glusterfs-11.1/xlators/cluster/afr/src/afr-self-heal-common.c0000664000175100017510000025016614522202451025425 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "afr.h" #include "afr-self-heal.h" #include "protocol-common.h" #include "afr-messages.h" #include #include void afr_heal_synctask(xlator_t *this, afr_local_t *local); int afr_lookup_and_heal_gfid(xlator_t *this, inode_t *parent, const char *name, inode_t *inode, struct afr_reply *replies, int source, unsigned char *sources, void *gfid, int *gfid_idx) { afr_private_t *priv = NULL; call_frame_t *frame = NULL; afr_local_t *local = NULL; unsigned char *wind_on = NULL; ia_type_t ia_type = IA_INVAL; dict_t *xdata = NULL; loc_t loc = { 0, }; int ret = 0; int i = 0; priv = this->private; wind_on = alloca0(priv->child_count); if (source >= 0 && replies[source].valid && replies[source].op_ret == 0) ia_type = replies[source].poststat.ia_type; if (ia_type != IA_INVAL) goto heal; /* If ia_type is still invalid, it means either * (a)'source' was -1, i.e. parent dir pending xattrs are in split-brain * (or) (b) The parent dir pending xattrs are all zeroes (i.e. all bricks * are sources) and the 'source' we selected earlier might be the one where * the file is not actually present. * * In both cases, let us pick a brick with a successful reply and use its * ia_type. * */ for (i = 0; i < priv->child_count; i++) { if (source == -1) { /* case (a) above. */ if (replies[i].valid && replies[i].op_ret == 0 && replies[i].poststat.ia_type != IA_INVAL) { ia_type = replies[i].poststat.ia_type; break; } } else { /* case (b) above. */ if (i == source) continue; if (sources[i] && replies[i].valid && replies[i].op_ret == 0 && replies[i].poststat.ia_type != IA_INVAL) { ia_type = replies[i].poststat.ia_type; break; } } } heal: /* gfid heal on those subvolumes that do not have gfid associated * with the inode and update those replies. */ for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret != 0) continue; if (gf_uuid_is_null(gfid) && !gf_uuid_is_null(replies[i].poststat.ia_gfid) && replies[i].poststat.ia_type == ia_type) gfid = replies[i].poststat.ia_gfid; if (!gf_uuid_is_null(replies[i].poststat.ia_gfid) || replies[i].poststat.ia_type != ia_type) continue; wind_on[i] = 1; } if (AFR_COUNT(wind_on, priv->child_count) == 0) return 0; xdata = dict_new(); if (!xdata) { ret = -ENOMEM; goto out; } ret = dict_set_gfuuid(xdata, "gfid-req", gfid, true); if (ret) { ret = -ENOMEM; goto out; } frame = afr_frame_create(this, &ret); if (!frame) { ret = -ret; goto out; } local = frame->local; loc.parent = inode_ref(parent); gf_uuid_copy(loc.pargfid, parent->gfid); loc.name = name; loc.inode = inode_ref(inode); AFR_ONLIST(wind_on, frame, afr_selfheal_discover_cbk, lookup, &loc, xdata); for (i = 0; i < priv->child_count; i++) { if (!wind_on[i]) continue; afr_reply_wipe(&replies[i]); afr_reply_copy(&replies[i], &local->replies[i]); } if (gfid_idx && (*gfid_idx == -1)) { /*Pick a brick where the gifd heal was successful.*/ for (i = 0; i < priv->child_count; i++) { if (!wind_on[i]) continue; if (replies[i].valid && replies[i].op_ret == 0 && !gf_uuid_is_null(replies[i].poststat.ia_gfid)) { *gfid_idx = i; break; } } } out: if (gfid_idx && (*gfid_idx == -1) && (ret == 0) && local) { ret = -afr_final_errno(local, priv); } loc_wipe(&loc); if (frame) AFR_STACK_DESTROY(frame); if (xdata) dict_unref(xdata); return ret; } static int afr_gfid_sbrain_source_from_src_brick(xlator_t *this, struct afr_reply *replies, char *src_brick) { int i = 0; afr_private_t *priv = NULL; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret == -1) continue; if (strcmp(priv->children[i]->name, src_brick) == 0) return i; } return -1; } static int afr_selfheal_gfid_mismatch_by_majority(struct afr_reply *replies, int child_count) { int j = 0; int i = 0; int votes; for (i = 0; i < child_count; i++) { if (!replies[i].valid || replies[i].op_ret == -1) continue; votes = 1; for (j = i + 1; j < child_count; j++) { if ((!gf_uuid_compare(replies[i].poststat.ia_gfid, replies[j].poststat.ia_gfid))) votes++; if (votes > child_count / 2) return i; } } return -1; } static int afr_gfid_sbrain_source_from_bigger_file(struct afr_reply *replies, int child_count) { int i = 0; int src = -1; uint64_t size = 0; for (i = 0; i < child_count; i++) { if (!replies[i].valid || replies[i].op_ret == -1) continue; if (size < replies[i].poststat.ia_size) { src = i; size = replies[i].poststat.ia_size; } else if (replies[i].poststat.ia_size == size) { src = -1; } } return src; } static int afr_gfid_sbrain_source_from_latest_mtime(struct afr_reply *replies, int child_count) { int i = 0; int src = -1; uint64_t mtime = 0; uint32_t mtime_nsec = 0; for (i = 0; i < child_count; i++) { if (!replies[i].valid || replies[i].op_ret != 0) continue; if ((mtime < replies[i].poststat.ia_mtime) || ((mtime == replies[i].poststat.ia_mtime) && (mtime_nsec < replies[i].poststat.ia_mtime_nsec))) { src = i; mtime = replies[i].poststat.ia_mtime; mtime_nsec = replies[i].poststat.ia_mtime_nsec; } else if ((mtime == replies[i].poststat.ia_mtime) && (mtime_nsec == replies[i].poststat.ia_mtime_nsec)) { src = -1; } } return src; } int afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies, inode_t *inode, uuid_t pargfid, const char *bname, int src_idx, int child_idx, unsigned char *locked_on, int *src, dict_t *req, dict_t *rsp) { afr_private_t *priv = NULL; char g1[64] = { 0, }; char g2[64] = { 0, }; int up_count = 0; int heal_op = -1; int ret = -1; char *src_brick = NULL; *src = -1; priv = this->private; up_count = AFR_COUNT(locked_on, priv->child_count); if (up_count != priv->child_count) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, "All the bricks should be up to resolve the gfid split " "barin"); if (rsp) { ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg", SALL_BRICKS_UP_TO_RESOLVE); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_SET_FAILED, "Error setting" " gfid-heal-msg dict"); } goto out; } if (req) { ret = dict_get_int32_sizen(req, "heal-op", &heal_op); if (ret) goto fav_child; } else { goto fav_child; } switch (heal_op) { case GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE: *src = afr_gfid_sbrain_source_from_bigger_file(replies, priv->child_count); if (*src == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, SNO_BIGGER_FILE); if (rsp) { ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg", SNO_BIGGER_FILE); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_SET_FAILED, "Error" " setting gfid-heal-msg dict"); } } break; case GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME: *src = afr_gfid_sbrain_source_from_latest_mtime(replies, priv->child_count); if (*src == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, SNO_DIFF_IN_MTIME); if (rsp) { ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg", SNO_DIFF_IN_MTIME); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_SET_FAILED, "Error" "setting gfid-heal-msg dict"); } } break; case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK: ret = dict_get_str_sizen(req, "child-name", &src_brick); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, "Error getting the source " "brick"); break; } *src = afr_gfid_sbrain_source_from_src_brick(this, replies, src_brick); if (*src == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, SERROR_GETTING_SRC_BRICK); if (rsp) { ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg", SERROR_GETTING_SRC_BRICK); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_SET_FAILED, "Error" " setting gfid-heal-msg dict"); } } break; default: break; } goto out; fav_child: switch (priv->fav_child_policy) { case AFR_FAV_CHILD_BY_SIZE: *src = afr_sh_fav_by_size(this, replies, inode); break; case AFR_FAV_CHILD_BY_MTIME: *src = afr_sh_fav_by_mtime(this, replies, inode); break; case AFR_FAV_CHILD_BY_CTIME: *src = afr_sh_fav_by_ctime(this, replies, inode); break; case AFR_FAV_CHILD_BY_MAJORITY: if (priv->child_count != 2) *src = afr_selfheal_gfid_mismatch_by_majority( replies, priv->child_count); else *src = -1; if (*src == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, "No majority to resolve " "gfid split brain"); } break; default: break; } /* At this point we have a source selected by favourite child policy, * If this is for a directory it might not be a good idea to automatically * resolve the GFID. Because the ultimate view of a dir is owned by DHT. * But if it is not a distributed volume, then it might be fine to do * the automatic gfid fix. * So here we skip the automatic split brain resolution */ if (*src != -1 && IA_ISDIR(replies[*src].poststat.ia_type)) { gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_SPLIT_BRAIN, "Automatic Gfid mismatch resolution for directories will be " "skipped. Please manually resolve the splitbrain using cli"); *src = -1; } out: if (*src == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, "Gfid mismatch detected for /%s>, %s on %s and" " %s on %s.", uuid_utoa(pargfid), bname, uuid_utoa_r(replies[child_idx].poststat.ia_gfid, g1), priv->children[child_idx]->name, uuid_utoa_r(replies[src_idx].poststat.ia_gfid, g2), priv->children[src_idx]->name); gf_event(EVENT_AFR_SPLIT_BRAIN, "client-pid=%d;" "subvol=%s;type=gfid;file=" "/%s>;count=2;child-%d=%s;gfid-%d=%s;" "child-%d=%s;gfid-%d=%s", this->ctx->cmd_args.client_pid, this->name, uuid_utoa(pargfid), bname, child_idx, priv->children[child_idx]->name, child_idx, uuid_utoa_r(replies[child_idx].poststat.ia_gfid, g1), src_idx, priv->children[src_idx]->name, src_idx, uuid_utoa_r(replies[src_idx].poststat.ia_gfid, g2)); return -EIO; } return 0; } static int afr_selfheal_post_op_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; local->op_ret = op_ret; local->op_errno = op_errno; syncbarrier_wake(&local->barrier); return 0; } int afr_selfheal_post_op(call_frame_t *frame, xlator_t *this, inode_t *inode, int subvol, dict_t *xattr, dict_t *xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; loc_t loc = { 0, }; int ret = 0; priv = this->private; local = frame->local; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); local->op_ret = 0; STACK_WIND(frame, afr_selfheal_post_op_cbk, priv->children[subvol], priv->children[subvol]->fops->xattrop, &loc, GF_XATTROP_ADD_ARRAY, xattr, xdata); syncbarrier_wait(&local->barrier, 1); if (local->op_ret < 0) ret = -local->op_errno; loc_wipe(&loc); local->op_ret = 0; return ret; } static int afr_check_stale_error(struct afr_reply *replies, afr_private_t *priv) { int i = 0; int op_errno = 0; int tmp_errno = 0; int stale_count = 0; for (i = 0; i < priv->child_count; i++) { tmp_errno = replies[i].op_errno; if (tmp_errno == ENOENT || tmp_errno == ESTALE) { op_errno = afr_higher_errno(op_errno, tmp_errno); stale_count++; } } if (stale_count != priv->child_count) return -ENOTCONN; else return -op_errno; } int afr_sh_generic_fop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { int i = (long)cookie; afr_local_t *local = NULL; local = frame->local; local->replies[i].valid = 1; local->replies[i].op_ret = op_ret; local->replies[i].op_errno = op_errno; if (pre) local->replies[i].prestat = *pre; if (post) local->replies[i].poststat = *post; if (xdata) local->replies[i].xdata = dict_ref(xdata); syncbarrier_wake(&local->barrier); return 0; } int afr_selfheal_restore_time(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, unsigned char *healed_sinks, struct afr_reply *replies) { loc_t loc = { 0, }; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); AFR_ONLIST(healed_sinks, frame, afr_sh_generic_fop_cbk, setattr, &loc, &replies[source].poststat, (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME | GF_SET_ATTR_CTIME), NULL); loc_wipe(&loc); return 0; } static dict_t * afr_selfheal_output_xattr(xlator_t *this, gf_boolean_t is_full_crawl, afr_transaction_type type, int *output_dirty, int **output_matrix, int subvol, int **full_heal_mtx_out) { int j = 0; int idx = 0; int d_idx = 0; int ret = 0; int *raw = 0; dict_t *xattr = NULL; afr_private_t *priv = NULL; priv = this->private; idx = afr_index_for_transaction_type(type); d_idx = afr_index_for_transaction_type(AFR_DATA_TRANSACTION); xattr = dict_new(); if (!xattr) return NULL; /* clear dirty */ raw = GF_CALLOC(sizeof(int), AFR_NUM_CHANGE_LOGS, gf_afr_mt_int32_t); if (!raw) goto err; raw[idx] = htobe32(output_dirty[subvol]); ret = dict_set_bin(xattr, AFR_DIRTY, raw, sizeof(int) * AFR_NUM_CHANGE_LOGS); if (ret) { GF_FREE(raw); goto err; } /* clear/set pending */ for (j = 0; j < priv->child_count; j++) { raw = GF_CALLOC(sizeof(int), AFR_NUM_CHANGE_LOGS, gf_afr_mt_int32_t); if (!raw) goto err; raw[idx] = htobe32(output_matrix[subvol][j]); if (is_full_crawl) raw[d_idx] = htobe32(full_heal_mtx_out[subvol][j]); ret = dict_set_bin(xattr, priv->pending_key[j], raw, sizeof(int) * AFR_NUM_CHANGE_LOGS); if (ret) { GF_FREE(raw); goto err; } } return xattr; err: if (xattr) dict_unref(xattr); return NULL; } int afr_selfheal_undo_pending(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, afr_transaction_type type, struct afr_reply *replies, unsigned char *locked_on) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int i = 0; int j = 0; unsigned char *pending = NULL; int *input_dirty = NULL; int **input_matrix = NULL; int **full_heal_mtx_in = NULL; int **full_heal_mtx_out = NULL; int *output_dirty = NULL; int **output_matrix = NULL; dict_t *xattr = NULL; dict_t *xdata = NULL; priv = this->private; local = frame->local; pending = alloca0(priv->child_count); input_dirty = alloca0(priv->child_count * sizeof(int)); input_matrix = ALLOC_MATRIX(priv->child_count, int); full_heal_mtx_in = ALLOC_MATRIX(priv->child_count, int); full_heal_mtx_out = ALLOC_MATRIX(priv->child_count, int); output_dirty = alloca0(priv->child_count * sizeof(int)); output_matrix = ALLOC_MATRIX(priv->child_count, int); xdata = dict_new(); if (!xdata) return -1; afr_selfheal_extract_xattr(this, replies, type, input_dirty, input_matrix); if (local->need_full_crawl) afr_selfheal_extract_xattr(this, replies, AFR_DATA_TRANSACTION, NULL, full_heal_mtx_in); for (i = 0; i < priv->child_count; i++) if (sinks[i] && !healed_sinks[i]) pending[i] = 1; for (i = 0; i < priv->child_count; i++) { for (j = 0; j < priv->child_count; j++) { if (pending[j]) { output_matrix[i][j] = 1; if (type == AFR_ENTRY_TRANSACTION) full_heal_mtx_out[i][j] = 1; } else if (locked_on[j]) { output_matrix[i][j] = -input_matrix[i][j]; if (type == AFR_ENTRY_TRANSACTION) full_heal_mtx_out[i][j] = -full_heal_mtx_in[i][j]; } } } for (i = 0; i < priv->child_count; i++) { if (!pending[i]) output_dirty[i] = -input_dirty[i]; } for (i = 0; i < priv->child_count; i++) { if (!locked_on[i]) /* perform post-op only on subvols we had locked and inspected on. */ continue; if (undid_pending[i]) /* We already unset the pending xattrs in * _afr_fav_child_reset_sink_xattrs(). */ continue; xattr = afr_selfheal_output_xattr(this, local->need_full_crawl, type, output_dirty, output_matrix, i, full_heal_mtx_out); if (!xattr) { continue; } if ((type == AFR_ENTRY_TRANSACTION) && (priv->esh_granular)) { if (xdata && dict_set_int8(xdata, GF_XATTROP_PURGE_INDEX, 1)) gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_DICT_SET_FAILED, "Failed to set" " dict value for %s", GF_XATTROP_PURGE_INDEX); } afr_selfheal_post_op(frame, this, inode, i, xattr, xdata); dict_unref(xattr); } if (xdata) dict_unref(xdata); return 0; } void afr_reply_copy(struct afr_reply *dst, struct afr_reply *src) { dict_t *xdata = NULL; dst->valid = src->valid; dst->op_ret = src->op_ret; dst->op_errno = src->op_errno; dst->prestat = src->prestat; dst->poststat = src->poststat; dst->preparent = src->preparent; dst->postparent = src->postparent; dst->preparent2 = src->preparent2; dst->postparent2 = src->postparent2; if (src->xdata) xdata = dict_ref(src->xdata); else xdata = NULL; if (dst->xdata) dict_unref(dst->xdata); dst->xdata = xdata; if (xdata && dict_get_str_boolean(xdata, "fips-mode-rchecksum", _gf_false) == _gf_true) { memcpy(dst->checksum, src->checksum, SHA256_DIGEST_LENGTH); } else { memcpy(dst->checksum, src->checksum, MD5_DIGEST_LENGTH); } dst->fips_mode_rchecksum = src->fips_mode_rchecksum; } void afr_replies_copy(struct afr_reply *dst, struct afr_reply *src, int count) { int i = 0; if (dst == src) return; for (i = 0; i < count; i++) { afr_reply_copy(&dst[i], &src[i]); } } static int afr_selfheal_fill_dirty(xlator_t *this, int *dirty, int subvol, int idx, dict_t *xdata) { void *pending_raw = NULL; if (!dirty) return 0; if (dict_get_ptr(xdata, AFR_DIRTY, &pending_raw)) return -1; if (!pending_raw) return -1; dirty[subvol] = be32toh(*((int *)pending_raw + idx)); return 0; } void afr_selfheal_fill_cell(afr_private_t *priv, dict_t *src_xdata, int *cell, int sink, int idx) { void *pending_raw = NULL; *cell = 0; if (dict_get_ptr(src_xdata, priv->pending_key[sink], &pending_raw)) goto out; if (!pending_raw) goto out; *cell = be32toh(*((int *)pending_raw + idx)); out: return; } int afr_selfheal_fill_matrix(xlator_t *this, int **matrix, int subvol, int idx, dict_t *xdata) { int i = 0; afr_private_t *priv = NULL; priv = this->private; if (!matrix) return 0; for (i = 0; i < priv->child_count; i++) { afr_selfheal_fill_cell(priv, xdata, &matrix[subvol][i], i, idx); } return 0; } int afr_selfheal_extract_xattr(xlator_t *this, struct afr_reply *replies, afr_transaction_type type, int *dirty, int **matrix) { afr_private_t *priv = NULL; int i = 0; dict_t *xdata = NULL; int idx = -1; idx = afr_index_for_transaction_type(type); priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret != 0) continue; if (!replies[i].xdata) continue; xdata = replies[i].xdata; afr_selfheal_fill_dirty(this, dirty, i, idx, xdata); afr_selfheal_fill_matrix(this, matrix, i, idx, xdata); } return 0; } /* * If by chance there are multiple sources with differing sizes, select * the largest file as the source. * * This can happen if data was directly modified in the backend or for snapshots */ void afr_mark_largest_file_as_source(xlator_t *this, unsigned char *sources, struct afr_reply *replies) { int i = 0; afr_private_t *priv = NULL; uint64_t size = 0; /* Find source with biggest file size */ priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; if (!replies[i].valid || replies[i].op_ret != 0) { sources[i] = 0; continue; } if (size <= replies[i].poststat.ia_size) { size = replies[i].poststat.ia_size; } } /* Mark sources with less size as not source */ for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; if (size > replies[i].poststat.ia_size) sources[i] = 0; } } void afr_mark_latest_mtime_file_as_source(xlator_t *this, unsigned char *sources, struct afr_reply *replies) { int i = 0; afr_private_t *priv = NULL; uint64_t mtime = 0; uint32_t mtime_nsec = 0; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; if (!replies[i].valid || replies[i].op_ret != 0) { sources[i] = 0; continue; } if ((mtime < replies[i].poststat.ia_mtime) || ((mtime == replies[i].poststat.ia_mtime) && (mtime_nsec < replies[i].poststat.ia_mtime_nsec))) { mtime = replies[i].poststat.ia_mtime; mtime_nsec = replies[i].poststat.ia_mtime_nsec; } } for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; if ((mtime > replies[i].poststat.ia_mtime) || ((mtime == replies[i].poststat.ia_mtime) && (mtime_nsec > replies[i].poststat.ia_mtime_nsec))) { sources[i] = 0; } } } void afr_mark_active_sinks(xlator_t *this, unsigned char *sources, unsigned char *locked_on, unsigned char *sinks) { int i = 0; afr_private_t *priv = NULL; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!sources[i] && locked_on[i]) sinks[i] = 1; else sinks[i] = 0; } } gf_boolean_t afr_dict_contains_heal_op(call_frame_t *frame) { afr_local_t *local = NULL; dict_t *xdata_req = NULL; int ret = 0; int heal_op = -1; local = frame->local; xdata_req = local->xdata_req; ret = dict_get_int32_sizen(xdata_req, "heal-op", &heal_op); if (ret) return _gf_false; if (local->xdata_rsp == NULL) { local->xdata_rsp = dict_new(); if (!local->xdata_rsp) return _gf_true; } ret = dict_set_sizen_str_sizen(local->xdata_rsp, "sh-fail-msg", SFILE_NOT_IN_SPLIT_BRAIN); return _gf_true; } gf_boolean_t afr_can_decide_split_brain_source_sinks(struct afr_reply *replies, int child_count) { int i = 0; for (i = 0; i < child_count; i++) if (replies[i].valid != 1 || replies[i].op_ret != 0) return _gf_false; return _gf_true; } int afr_mark_split_brain_source_sinks_by_heal_op( call_frame_t *frame, xlator_t *this, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies, afr_transaction_type type, int heal_op) { afr_local_t *local = NULL; afr_private_t *priv = NULL; dict_t *xdata_req = NULL; dict_t *xdata_rsp = NULL; int ret = 0; int i = 0; char *name = NULL; int source = -1; local = frame->local; priv = this->private; xdata_req = local->xdata_req; for (i = 0; i < priv->child_count; i++) { if (locked_on[i]) if (sources[i] || !sinks[i] || !healed_sinks[i]) { ret = -1; goto out; } } if (local->xdata_rsp == NULL) { local->xdata_rsp = dict_new(); if (!local->xdata_rsp) { ret = -1; goto out; } } xdata_rsp = local->xdata_rsp; if (!afr_can_decide_split_brain_source_sinks(replies, priv->child_count)) { ret = dict_set_sizen_str_sizen(xdata_rsp, "sh-fail-msg", SBRAIN_HEAL_NO_GO_MSG); ret = -1; goto out; } for (i = 0; i < priv->child_count; i++) if (locked_on[i]) sources[i] = 1; switch (heal_op) { case GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE: if (type == AFR_METADATA_TRANSACTION) { ret = dict_set_sizen_str_sizen(xdata_rsp, "sh-fail-msg", SUSE_SOURCE_BRICK_TO_HEAL); if (!ret) ret = -1; goto out; } afr_mark_largest_file_as_source(this, sources, replies); if (AFR_COUNT(sources, priv->child_count) != 1) { ret = dict_set_sizen_str_sizen(xdata_rsp, "sh-fail-msg", SNO_BIGGER_FILE); if (!ret) ret = -1; goto out; } break; case GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME: if (type == AFR_METADATA_TRANSACTION) { ret = dict_set_sizen_str_sizen(xdata_rsp, "sh-fail-msg", SUSE_SOURCE_BRICK_TO_HEAL); if (!ret) ret = -1; goto out; } afr_mark_latest_mtime_file_as_source(this, sources, replies); if (AFR_COUNT(sources, priv->child_count) != 1) { ret = dict_set_sizen_str_sizen(xdata_rsp, "sh-fail-msg", SNO_DIFF_IN_MTIME); if (!ret) ret = -1; goto out; } break; case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK: ret = dict_get_str_sizen(xdata_req, "child-name", &name); if (ret) goto out; source = afr_get_child_index_from_name(this, name); if (source < 0) { ret = dict_set_sizen_str_sizen(xdata_rsp, "sh-fail-msg", SINVALID_BRICK_NAME); if (!ret) ret = -1; goto out; } if (locked_on[source] != 1) { ret = dict_set_sizen_str_sizen(xdata_rsp, "sh-fail-msg", SBRICK_IS_NOT_UP); if (!ret) ret = -1; goto out; } memset(sources, 0, sizeof(*sources) * priv->child_count); sources[source] = 1; break; default: ret = -1; goto out; } for (i = 0; i < priv->child_count; i++) { if (sources[i]) { source = i; break; } } sinks[source] = 0; healed_sinks[source] = 0; ret = source; out: if (ret < 0) memset(sources, 0, sizeof(*sources) * priv->child_count); return ret; } static int afr_sh_fav_by_majority(xlator_t *this, struct afr_reply *replies, inode_t *inode) { afr_private_t *priv; int vote_count = -1; int fav_child = -1; int i = 0; int k = 0; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (replies[i].valid == 1) { gf_msg_debug(this->name, 0, "Child:%s mtime_sec = %" PRId64 ", size = %" PRIu64 " for gfid %s", priv->children[i]->name, replies[i].poststat.ia_mtime, replies[i].poststat.ia_size, uuid_utoa(inode->gfid)); vote_count = 0; for (k = 0; k < priv->child_count; k++) { if ((replies[k].poststat.ia_mtime == replies[i].poststat.ia_mtime) && (replies[k].poststat.ia_size == replies[i].poststat.ia_size)) { vote_count++; } } if (vote_count > priv->child_count / 2) { fav_child = i; break; } } } return fav_child; } /* * afr_sh_fav_by_mtime: Choose favorite child by mtime. */ int afr_sh_fav_by_mtime(xlator_t *this, struct afr_reply *replies, inode_t *inode) { afr_private_t *priv; int fav_child = -1; int i = 0; uint64_t cmp_mtime = 0; uint32_t cmp_mtime_nsec = 0; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (replies[i].valid == 1) { gf_msg_debug(this->name, 0, "Child:%s mtime = %" PRId64 ", mtime_nsec = %d for " "gfid %s", priv->children[i]->name, replies[i].poststat.ia_mtime, replies[i].poststat.ia_mtime_nsec, uuid_utoa(inode->gfid)); if (replies[i].poststat.ia_mtime > cmp_mtime) { cmp_mtime = replies[i].poststat.ia_mtime; cmp_mtime_nsec = replies[i].poststat.ia_mtime_nsec; fav_child = i; } else if ((replies[i].poststat.ia_mtime == cmp_mtime) && (replies[i].poststat.ia_mtime_nsec > cmp_mtime_nsec)) { cmp_mtime = replies[i].poststat.ia_mtime; cmp_mtime_nsec = replies[i].poststat.ia_mtime_nsec; fav_child = i; } } } return fav_child; } /* * afr_sh_fav_by_ctime: Choose favorite child by ctime. */ int afr_sh_fav_by_ctime(xlator_t *this, struct afr_reply *replies, inode_t *inode) { afr_private_t *priv; int fav_child = -1; int i = 0; uint64_t cmp_ctime = 0; uint32_t cmp_ctime_nsec = 0; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (replies[i].valid == 1) { gf_msg_debug(this->name, 0, "Child:%s ctime = %" PRId64 ", ctime_nsec = %d for " "gfid %s", priv->children[i]->name, replies[i].poststat.ia_ctime, replies[i].poststat.ia_ctime_nsec, uuid_utoa(inode->gfid)); if (replies[i].poststat.ia_ctime > cmp_ctime) { cmp_ctime = replies[i].poststat.ia_ctime; cmp_ctime_nsec = replies[i].poststat.ia_ctime_nsec; fav_child = i; } else if ((replies[i].poststat.ia_ctime == cmp_ctime) && (replies[i].poststat.ia_ctime_nsec > cmp_ctime_nsec)) { cmp_ctime = replies[i].poststat.ia_ctime; cmp_ctime_nsec = replies[i].poststat.ia_ctime_nsec; fav_child = i; } } } return fav_child; } /* * afr_sh_fav_by_size: Choose favorite child by size * when not all files are of zero size. */ int afr_sh_fav_by_size(xlator_t *this, struct afr_reply *replies, inode_t *inode) { afr_private_t *priv; int fav_child = -1; int i = 0; uint64_t cmp_sz = 0; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) { continue; } gf_msg_debug(this->name, 0, "Child:%s file size = %" PRIu64 " for gfid %s", priv->children[i]->name, replies[i].poststat.ia_size, uuid_utoa(inode->gfid)); if (replies[i].poststat.ia_type == IA_IFDIR) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SBRAIN_FAV_CHILD_POLICY, "Cannot perform selfheal on %s. " "Size policy is not applicable to directories.", uuid_utoa(inode->gfid)); break; } if (replies[i].poststat.ia_size > cmp_sz) { cmp_sz = replies[i].poststat.ia_size; fav_child = i; } else if (replies[i].poststat.ia_size == cmp_sz) { fav_child = -1; } } if (fav_child == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, "No bigger file"); } return fav_child; } int afr_sh_get_fav_by_policy(xlator_t *this, struct afr_reply *replies, inode_t *inode, char **policy_str) { afr_private_t *priv = NULL; int fav_child = -1; priv = this->private; if (!afr_can_decide_split_brain_source_sinks(replies, priv->child_count)) { return -1; } switch (priv->fav_child_policy) { case AFR_FAV_CHILD_BY_SIZE: fav_child = afr_sh_fav_by_size(this, replies, inode); if (policy_str && fav_child >= 0) { *policy_str = "SIZE"; } break; case AFR_FAV_CHILD_BY_CTIME: fav_child = afr_sh_fav_by_ctime(this, replies, inode); if (policy_str && fav_child >= 0) { *policy_str = "CTIME"; } break; case AFR_FAV_CHILD_BY_MTIME: fav_child = afr_sh_fav_by_mtime(this, replies, inode); if (policy_str && fav_child >= 0) { *policy_str = "MTIME"; } break; case AFR_FAV_CHILD_BY_MAJORITY: fav_child = afr_sh_fav_by_majority(this, replies, inode); if (policy_str && fav_child >= 0) { *policy_str = "MAJORITY"; } break; case AFR_FAV_CHILD_NONE: default: break; } return fav_child; } static int afr_mark_split_brain_source_sinks_by_policy( call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies, afr_transaction_type type) { afr_private_t *priv = NULL; int fav_child = -1; char mtime_str[256]; char ctime_str[256]; char *policy_str = NULL; struct tm *tm_ptr; time_t time; priv = this->private; fav_child = afr_sh_get_fav_by_policy(this, replies, inode, &policy_str); if (fav_child == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SBRAIN_FAV_CHILD_POLICY, "No child selected by favorite-child policy."); } else if (fav_child > priv->child_count - 1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SBRAIN_FAV_CHILD_POLICY, "Invalid child (%d) " "selected by policy %s.", fav_child, policy_str); } else if (fav_child >= 0) { time = replies[fav_child].poststat.ia_mtime; tm_ptr = localtime(&time); strftime(mtime_str, sizeof(mtime_str), "%Y-%m-%d %H:%M:%S", tm_ptr); time = replies[fav_child].poststat.ia_ctime; tm_ptr = localtime(&time); strftime(ctime_str, sizeof(ctime_str), "%Y-%m-%d %H:%M:%S", tm_ptr); gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_SBRAIN_FAV_CHILD_POLICY, "Source %s selected as authentic to resolve conflicting data " "in file (gfid:%s) by %s (%" PRIu64 " bytes @ %s mtime, %s " "ctime).", priv->children[fav_child]->name, uuid_utoa(inode->gfid), policy_str, replies[fav_child].poststat.ia_size, mtime_str, ctime_str); sources[fav_child] = 1; sinks[fav_child] = 0; healed_sinks[fav_child] = 0; } return fav_child; } gf_boolean_t afr_is_file_empty_on_all_children(afr_private_t *priv, struct afr_reply *replies) { int i = 0; for (i = 0; i < priv->child_count; i++) { if ((!replies[i].valid) || (replies[i].op_ret != 0) || (replies[i].poststat.ia_size != 0)) return _gf_false; } return _gf_true; } int afr_mark_source_sinks_if_file_empty(xlator_t *this, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies, afr_transaction_type type) { int source = -1; int i = 0; afr_private_t *priv = this->private; struct iatt stbuf = { 0, }; if ((AFR_COUNT(locked_on, priv->child_count) < priv->child_count) || (afr_success_count(replies, priv->child_count) < priv->child_count)) return -1; if (type == AFR_DATA_TRANSACTION) { if (!afr_is_file_empty_on_all_children(priv, replies)) return -1; goto mark; } /*For AFR_METADATA_TRANSACTION, metadata must be same on all bricks.*/ stbuf = replies[0].poststat; for (i = 1; i < priv->child_count; i++) { if ((!IA_EQUAL(stbuf, replies[i].poststat, type)) || (!IA_EQUAL(stbuf, replies[i].poststat, uid)) || (!IA_EQUAL(stbuf, replies[i].poststat, gid)) || (!IA_EQUAL(stbuf, replies[i].poststat, prot))) return -1; } for (i = 1; i < priv->child_count; i++) { if (!afr_xattrs_are_equal( replies[0].xdata, replies[i].xdata, AFR_IS_ARBITER_BRICK(priv, i) ? _gf_true : _gf_false)) return -1; } mark: /* data/metadata is same on all bricks. Pick one of them as source. Rest * are sinks.*/ for (i = 0; i < priv->child_count; i++) { if (source == -1) { source = i; sources[i] = 1; sinks[i] = 0; healed_sinks[i] = 0; continue; } sources[i] = 0; sinks[i] = 1; healed_sinks[i] = 1; } return source; } /* Return a source depending on the type of heal_op, and set sources[source], * sinks[source] and healed_sinks[source] to 1, 0 and 0 respectively. Do so * only if the following condition is met: * ∀i((i ∈ locked_on[] ∧ i=1)==>(sources[i]=0 ∧ sinks[i]=1 ∧ healed_sinks[i]=1)) * i.e. for each locked node, sources[node] is 0; healed_sinks[node] and * sinks[node] are 1. This should be the case if the file is in split-brain. */ int afr_mark_split_brain_source_sinks( call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies, afr_transaction_type type) { afr_local_t *local = NULL; afr_private_t *priv = NULL; dict_t *xdata_req = NULL; int heal_op = -1; int ret = -1; int source = -1; local = frame->local; priv = this->private; xdata_req = local->xdata_req; source = afr_mark_source_sinks_if_file_empty( this, sources, sinks, healed_sinks, locked_on, replies, type); if (source >= 0) return source; ret = dict_get_int32_sizen(xdata_req, "heal-op", &heal_op); if (ret) goto autoheal; source = afr_mark_split_brain_source_sinks_by_heal_op( frame, this, sources, sinks, healed_sinks, locked_on, replies, type, heal_op); return source; autoheal: /* Automatically heal if fav_child_policy is set. */ if (priv->fav_child_policy != AFR_FAV_CHILD_NONE) { source = afr_mark_split_brain_source_sinks_by_policy( frame, this, inode, sources, sinks, healed_sinks, locked_on, replies, type); if (source != -1) { ret = dict_set_int32_sizen(xdata_req, "fav-child-policy", 1); if (ret) return -1; } } return source; } int _afr_fav_child_reset_sink_xattrs(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, unsigned char *healed_sinks, unsigned char *undid_pending, afr_transaction_type type, unsigned char *locked_on, struct afr_reply *replies) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int *input_dirty = NULL; int **input_matrix = NULL; int *output_dirty = NULL; int **output_matrix = NULL; dict_t *xattr = NULL; dict_t *xdata = NULL; int i = 0; priv = this->private; local = frame->local; if (!dict_get_sizen(local->xdata_req, "fav-child-policy")) return 0; xdata = dict_new(); if (!xdata) return -1; input_dirty = alloca0(priv->child_count * sizeof(int)); input_matrix = ALLOC_MATRIX(priv->child_count, int); output_dirty = alloca0(priv->child_count * sizeof(int)); output_matrix = ALLOC_MATRIX(priv->child_count, int); afr_selfheal_extract_xattr(this, replies, type, input_dirty, input_matrix); for (i = 0; i < priv->child_count; i++) { if (i == source || !healed_sinks[i]) continue; output_dirty[i] = -input_dirty[i]; output_matrix[i][source] = -input_matrix[i][source]; } for (i = 0; i < priv->child_count; i++) { if (!healed_sinks[i] || !locked_on[i]) continue; xattr = afr_selfheal_output_xattr(this, _gf_false, type, output_dirty, output_matrix, i, NULL); afr_selfheal_post_op(frame, this, inode, i, xattr, xdata); undid_pending[i] = 1; dict_unref(xattr); } if (xdata) dict_unref(xdata); return 0; } gf_boolean_t afr_does_witness_exist(xlator_t *this, uint64_t *witness) { int i = 0; afr_private_t *priv = NULL; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (witness[i]) return _gf_true; } return _gf_false; } unsigned int afr_get_quorum_count(afr_private_t *priv) { if (priv->quorum_count == AFR_QUORUM_AUTO) { return priv->child_count / 2 + 1; } else { return priv->quorum_count; } } static void afr_selfheal_post_op_failure_accounting(afr_private_t *priv, char *accused, unsigned char *sources, unsigned char *locked_on) { int i = 0; unsigned int quorum_count = 0; if (AFR_COUNT(sources, priv->child_count) != 0) return; quorum_count = afr_get_quorum_count(priv); for (i = 0; i < priv->child_count; i++) { if ((accused[i] < quorum_count) && locked_on[i]) { sources[i] = 1; } } return; } /* * This function determines if a self-heal is required for a given inode, * and if needed, in what direction. * * locked_on[] is the array representing servers which have been locked and * from which xattrs have been fetched for analysis. * * The output of the function is by filling the arrays sources[] and sinks[]. * * sources[i] is set if i'th server is an eligible source for a selfheal. * * sinks[i] is set if i'th server needs to be healed. * * if sources[0..N] are all set, there is no need for a selfheal. * * if sinks[0..N] are all set, the inode is in split brain. * */ int afr_selfheal_find_direction(call_frame_t *frame, xlator_t *this, struct afr_reply *replies, afr_transaction_type type, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, uint64_t *witness, unsigned char *pflag) { afr_private_t *priv = NULL; int i = 0; int j = 0; int *dirty = NULL; /* Denotes if dirty xattr is set */ int **matrix = NULL; /* Changelog matrix */ char *accused = NULL; /* Accused others without any self-accusal */ char *pending = NULL; /* Have pending operations on others */ char *self_accused = NULL; /* Accused itself */ priv = this->private; dirty = alloca0(priv->child_count * sizeof(int)); accused = alloca0(priv->child_count); pending = alloca0(priv->child_count); self_accused = alloca0(priv->child_count); matrix = ALLOC_MATRIX(priv->child_count, int); memset(witness, 0, sizeof(*witness) * priv->child_count); /* First construct the pending matrix for further analysis */ afr_selfheal_extract_xattr(this, replies, type, dirty, matrix); if (pflag) { for (i = 0; i < priv->child_count; i++) { for (j = 0; j < priv->child_count; j++) if (matrix[i][j]) *pflag |= PFLAG_PENDING; if (*pflag) break; } } if (afr_success_count(replies, priv->child_count) < priv->child_count) { /* Treat this just like locks not being acquired */ return -ENOTCONN; } /* short list all self-accused */ for (i = 0; i < priv->child_count; i++) { if (matrix[i][i]) self_accused[i] = 1; } /* Next short list all accused to exclude them from being sources */ /* Self-accused can't accuse others as they are FOOLs */ for (i = 0; i < priv->child_count; i++) { for (j = 0; j < priv->child_count; j++) { if (matrix[i][j]) { if (!self_accused[i]) accused[j] += 1; if (i != j) pending[i] += 1; } } } /* Short list all non-accused as sources */ for (i = 0; i < priv->child_count; i++) { if (!accused[i] && locked_on[i]) sources[i] = 1; else sources[i] = 0; } /* Everyone accused by non-self-accused sources are sinks */ memset(sinks, 0, priv->child_count); for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; if (self_accused[i]) continue; for (j = 0; j < priv->child_count; j++) { if (matrix[i][j]) sinks[j] = 1; } } /* For breaking ties provide with number of fops they witnessed */ /* * count the pending fops witnessed from itself to others when it is * self-accused */ for (i = 0; i < priv->child_count; i++) { if (!self_accused[i]) continue; for (j = 0; j < priv->child_count; j++) { if (i == j) continue; witness[i] += matrix[i][j]; } } if (type == AFR_DATA_TRANSACTION || type == AFR_METADATA_TRANSACTION) afr_selfheal_post_op_failure_accounting(priv, accused, sources, locked_on); /* If no sources, all locked nodes are sinks - split brain */ if (AFR_COUNT(sources, priv->child_count) == 0) { for (i = 0; i < priv->child_count; i++) { if (locked_on[i]) sinks[i] = 1; } if (pflag) *pflag |= PFLAG_SBRAIN; } /* One more class of witness similar to dirty in v2 is where no pending * exists but we have self-accusing markers. This can happen in afr-v1 * if the brick crashes just after doing xattrop on self but * before xattrop on the other xattrs on the brick in pre-op. */ if (AFR_COUNT(pending, priv->child_count) == 0) { for (i = 0; i < priv->child_count; i++) { if (self_accused[i]) witness[i] += matrix[i][i]; } } else { /* In afr-v1 if a file is self-accused and has pending * operations on others then it is similar to 'dirty' in afr-v2. * Consider such cases as witness. */ for (i = 0; i < priv->child_count; i++) { if (self_accused[i] && pending[i]) witness[i] += matrix[i][i]; } } /* count the number of dirty fops witnessed */ for (i = 0; i < priv->child_count; i++) witness[i] += dirty[i]; return 0; } void afr_log_selfheal(uuid_t gfid, xlator_t *this, int ret, char *type, int source, unsigned char *sources, unsigned char *healed_sinks) { char *status = NULL; char *sinks_str = NULL; char *p = NULL; char *sources_str = NULL; char *q = NULL; afr_private_t *priv = NULL; gf_loglevel_t loglevel = GF_LOG_NONE; int i = 0; priv = this->private; sinks_str = alloca0(priv->child_count * 8); p = sinks_str; sources_str = alloca0(priv->child_count * 8); q = sources_str; for (i = 0; i < priv->child_count; i++) { if (healed_sinks[i]) p += sprintf(p, "%d ", i); if (sources[i]) { if (source == i) { q += sprintf(q, "[%d] ", i); } else { q += sprintf(q, "%d ", i); } } } if (ret < 0) { status = "Failed"; loglevel = GF_LOG_DEBUG; } else { status = "Completed"; loglevel = GF_LOG_INFO; } gf_msg(this->name, loglevel, 0, AFR_MSG_SELF_HEAL_INFO, "%s %s selfheal on %s. " "sources=%s sinks=%s", status, type, uuid_utoa(gfid), sources_str, sinks_str); } int afr_selfheal_discover_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *parbuf) { afr_local_t *local = NULL; int i = -1; GF_UNUSED int ret = -1; int8_t need_heal = 1; local = frame->local; i = (long)cookie; local->replies[i].valid = 1; local->replies[i].op_ret = op_ret; local->replies[i].op_errno = op_errno; if (buf) local->replies[i].poststat = *buf; if (parbuf) local->replies[i].postparent = *parbuf; if (xdata) { local->replies[i].xdata = dict_ref(xdata); ret = dict_get_int8(xdata, "link-count", &need_heal); } local->replies[i].need_heal = need_heal; syncbarrier_wake(&local->barrier); return 0; } inode_t * afr_selfheal_unlocked_lookup_on(call_frame_t *frame, inode_t *parent, const char *name, struct afr_reply *replies, unsigned char *lookup_on, dict_t *xattr) { loc_t loc = { 0, }; dict_t *xattr_req = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; inode_t *inode = NULL; local = frame->local; priv = frame->this->private; xattr_req = dict_new(); if (!xattr_req) return NULL; if (xattr) dict_copy(xattr, xattr_req); if (afr_xattr_req_prepare(frame->this, xattr_req) != 0) { dict_unref(xattr_req); return NULL; } inode = inode_new(parent->table); if (!inode) { dict_unref(xattr_req); return NULL; } loc.parent = inode_ref(parent); gf_uuid_copy(loc.pargfid, parent->gfid); loc.name = name; loc.inode = inode_ref(inode); AFR_ONLIST(lookup_on, frame, afr_selfheal_discover_cbk, lookup, &loc, xattr_req); afr_replies_copy(replies, local->replies, priv->child_count); loc_wipe(&loc); dict_unref(xattr_req); return inode; } static int afr_set_multi_dom_lock_count_request(xlator_t *this, dict_t *dict) { int ret = 0; afr_private_t *priv = NULL; char *key1 = NULL; char *key2 = NULL; priv = this->private; key1 = alloca0(strlen(GLUSTERFS_INODELK_DOM_PREFIX) + 2 + strlen(this->name)); key2 = alloca0(strlen(GLUSTERFS_INODELK_DOM_PREFIX) + 2 + strlen(priv->sh_domain)); ret = dict_set_uint32(dict, GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS, 1); if (ret) return ret; sprintf(key1, "%s:%s", GLUSTERFS_INODELK_DOM_PREFIX, this->name); ret = dict_set_uint32(dict, key1, 1); if (ret) return ret; sprintf(key2, "%s:%s", GLUSTERFS_INODELK_DOM_PREFIX, priv->sh_domain); ret = dict_set_uint32(dict, key2, 1); if (ret) return ret; return 0; } int afr_selfheal_unlocked_discover_on(call_frame_t *frame, inode_t *inode, uuid_t gfid, struct afr_reply *replies, unsigned char *discover_on, dict_t *dict) { loc_t loc = { 0, }; dict_t *xattr_req = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = frame->this->private; xattr_req = dict_new(); if (!xattr_req) return -ENOMEM; if (dict) dict_copy(dict, xattr_req); if (afr_xattr_req_prepare(frame->this, xattr_req) != 0) { dict_unref(xattr_req); return -ENOMEM; } if (afr_set_multi_dom_lock_count_request(frame->this, xattr_req)) { dict_unref(xattr_req); return -1; } loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, gfid); AFR_ONLIST(discover_on, frame, afr_selfheal_discover_cbk, lookup, &loc, xattr_req); afr_replies_copy(replies, local->replies, priv->child_count); loc_wipe(&loc); dict_unref(xattr_req); return 0; } int afr_selfheal_unlocked_discover(call_frame_t *frame, inode_t *inode, uuid_t gfid, struct afr_reply *replies) { afr_local_t *local = NULL; dict_t *dict = NULL; local = frame->local; if (local->xattr_req) dict = local->xattr_req; return afr_selfheal_unlocked_discover_on(frame, inode, gfid, replies, local->child_up, dict); } unsigned int afr_success_count(struct afr_reply *replies, unsigned int count) { int i = 0; unsigned int success = 0; for (i = 0; i < count; i++) if (replies[i].valid && replies[i].op_ret == 0) success++; return success; } int afr_selfheal_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { afr_local_t *local = NULL; int i = 0; local = frame->local; i = (long)cookie; local->replies[i].valid = 1; local->replies[i].op_ret = op_ret; local->replies[i].op_errno = op_errno; syncbarrier_wake(&local->barrier); return 0; } int afr_locked_fill(call_frame_t *frame, xlator_t *this, unsigned char *locked_on) { int i = 0; afr_private_t *priv = NULL; afr_local_t *local = NULL; int count = 0; local = frame->local; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (local->replies[i].valid && local->replies[i].op_ret == 0) { locked_on[i] = 1; count++; } else { locked_on[i] = 0; } } return count; } int afr_selfheal_inodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, unsigned char *locked_on) { loc_t loc = { 0, }; struct gf_flock flock = { 0, }; afr_local_t *local = NULL; int i = 0; afr_private_t *priv = NULL; priv = this->private; local = frame->local; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); flock.l_type = F_WRLCK; flock.l_start = off; flock.l_len = size; AFR_ONALL(frame, afr_selfheal_lock_cbk, inodelk, dom, &loc, F_SETLK, &flock, NULL); for (i = 0; i < priv->child_count; i++) { if (local->replies[i].op_ret == -1 && local->replies[i].op_errno == EAGAIN) { afr_locked_fill(frame, this, locked_on); afr_selfheal_uninodelk(frame, this, inode, dom, off, size, locked_on); AFR_SEQ(frame, afr_selfheal_lock_cbk, inodelk, dom, &loc, F_SETLKW, &flock, NULL); break; } } loc_wipe(&loc); return afr_locked_fill(frame, this, locked_on); } static void afr_get_lock_and_eagain_counts(afr_private_t *priv, struct afr_reply *replies, int *lock_count, int *eagain_count) { int i = 0; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret == 0) { (*lock_count)++; } else if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) { (*eagain_count)++; } } } /*Do blocking locks if number of locks acquired is majority and there were some * EAGAINs. Useful for odd-way replication*/ int afr_selfheal_tie_breaker_inodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, unsigned char *locked_on) { loc_t loc = { 0, }; struct gf_flock flock = { 0, }; afr_local_t *local = NULL; afr_private_t *priv = NULL; int lock_count = 0; int eagain_count = 0; priv = this->private; local = frame->local; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); flock.l_type = F_WRLCK; flock.l_start = off; flock.l_len = size; AFR_ONALL(frame, afr_selfheal_lock_cbk, inodelk, dom, &loc, F_SETLK, &flock, NULL); afr_get_lock_and_eagain_counts(priv, local->replies, &lock_count, &eagain_count); if (lock_count > priv->child_count / 2 && eagain_count) { afr_locked_fill(frame, this, locked_on); afr_selfheal_uninodelk(frame, this, inode, dom, off, size, locked_on); AFR_SEQ(frame, afr_selfheal_lock_cbk, inodelk, dom, &loc, F_SETLKW, &flock, NULL); } loc_wipe(&loc); return afr_locked_fill(frame, this, locked_on); } int afr_selfheal_uninodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, const unsigned char *locked_on) { loc_t loc = { 0, }; struct gf_flock flock = { 0, }; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); flock.l_type = F_UNLCK; flock.l_start = off; flock.l_len = size; AFR_ONLIST(locked_on, frame, afr_selfheal_lock_cbk, inodelk, dom, &loc, F_SETLK, &flock, NULL); loc_wipe(&loc); return 0; } int afr_selfheal_tryentrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on) { loc_t loc = { 0, }; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); AFR_ONALL(frame, afr_selfheal_lock_cbk, entrylk, dom, &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL); loc_wipe(&loc); return afr_locked_fill(frame, this, locked_on); } int afr_selfheal_entrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on) { loc_t loc = { 0, }; afr_local_t *local = NULL; int i = 0; afr_private_t *priv = NULL; priv = this->private; local = frame->local; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); AFR_ONALL(frame, afr_selfheal_lock_cbk, entrylk, dom, &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL); for (i = 0; i < priv->child_count; i++) { if (local->replies[i].op_ret == -1 && local->replies[i].op_errno == EAGAIN) { afr_locked_fill(frame, this, locked_on); afr_selfheal_unentrylk(frame, this, inode, dom, name, locked_on, NULL); AFR_SEQ(frame, afr_selfheal_lock_cbk, entrylk, dom, &loc, name, ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL); break; } } loc_wipe(&loc); return afr_locked_fill(frame, this, locked_on); } int afr_selfheal_tie_breaker_entrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on) { loc_t loc = { 0, }; afr_local_t *local = NULL; afr_private_t *priv = NULL; int lock_count = 0; int eagain_count = 0; priv = this->private; local = frame->local; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); AFR_ONALL(frame, afr_selfheal_lock_cbk, entrylk, dom, &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL); afr_get_lock_and_eagain_counts(priv, local->replies, &lock_count, &eagain_count); if (lock_count > priv->child_count / 2 && eagain_count) { afr_locked_fill(frame, this, locked_on); afr_selfheal_unentrylk(frame, this, inode, dom, name, locked_on, NULL); AFR_SEQ(frame, afr_selfheal_lock_cbk, entrylk, dom, &loc, name, ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL); } loc_wipe(&loc); return afr_locked_fill(frame, this, locked_on); } int afr_selfheal_unentrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on, dict_t *xdata) { loc_t loc = { 0, }; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); AFR_ONLIST(locked_on, frame, afr_selfheal_lock_cbk, entrylk, dom, &loc, name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); loc_wipe(&loc); return 0; } static gf_boolean_t afr_is_data_set(xlator_t *this, dict_t *xdata) { return afr_is_pending_set(this, xdata, AFR_DATA_TRANSACTION); } static gf_boolean_t afr_is_metadata_set(xlator_t *this, dict_t *xdata) { return afr_is_pending_set(this, xdata, AFR_METADATA_TRANSACTION); } static gf_boolean_t afr_is_entry_set(xlator_t *this, dict_t *xdata) { return afr_is_pending_set(this, xdata, AFR_ENTRY_TRANSACTION); } /* * This function inspects the looked up replies (in an unlocked manner) * and decides whether a locked verification and possible healing is * required or not. It updates the three booleans for each type * of healing. If the boolean flag gets set to FALSE, then we are sure * no healing is required. If the boolean flag gets set to TRUE then * we have to proceed with locked reinspection. */ int afr_selfheal_unlocked_inspect(call_frame_t *frame, xlator_t *this, uuid_t gfid, inode_t **link_inode, gf_boolean_t *data_selfheal, gf_boolean_t *metadata_selfheal, gf_boolean_t *entry_selfheal, struct afr_reply *replies_dst) { afr_private_t *priv = NULL; inode_t *inode = NULL; int i = 0; int valid_cnt = 0; struct iatt first = { 0, }; int first_idx = 0; struct afr_reply *replies = NULL; int ret = -1; priv = this->private; inode = afr_inode_find(this, gfid); if (!inode) goto out; replies = alloca0(sizeof(*replies) * priv->child_count); ret = afr_selfheal_unlocked_discover(frame, inode, gfid, replies); if (ret) goto out; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret == -1) continue; /* The data segment of the changelog can be non-zero to indicate * the directory needs a full heal. So the check below ensures * it's not a directory before setting the data_selfheal boolean. */ if (data_selfheal && !IA_ISDIR(replies[i].poststat.ia_type) && afr_is_data_set(this, replies[i].xdata)) *data_selfheal = _gf_true; if (metadata_selfheal && afr_is_metadata_set(this, replies[i].xdata)) *metadata_selfheal = _gf_true; if (entry_selfheal && afr_is_entry_set(this, replies[i].xdata)) *entry_selfheal = _gf_true; valid_cnt++; if (valid_cnt == 1) { first = replies[i].poststat; first_idx = i; continue; } if (!IA_EQUAL(first, replies[i].poststat, type)) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN, "TYPE mismatch %d vs %d on %s for gfid:%s", (int)first.ia_type, (int)replies[i].poststat.ia_type, priv->children[i]->name, uuid_utoa(replies[i].poststat.ia_gfid)); gf_event(EVENT_AFR_SPLIT_BRAIN, "client-pid=%d;" "subvol=%s;" "type=file;gfid=%s;" "ia_type-%d=%s;ia_type-%d=%s", this->ctx->cmd_args.client_pid, this->name, uuid_utoa(replies[i].poststat.ia_gfid), first_idx, gf_inode_type_to_str(first.ia_type), i, gf_inode_type_to_str(replies[i].poststat.ia_type)); ret = -EIO; goto out; } if (!IA_EQUAL(first, replies[i].poststat, uid)) { gf_msg_debug(this->name, 0, "UID mismatch " "%d vs %d on %s for gfid:%s", (int)first.ia_uid, (int)replies[i].poststat.ia_uid, priv->children[i]->name, uuid_utoa(replies[i].poststat.ia_gfid)); if (metadata_selfheal) *metadata_selfheal = _gf_true; } if (!IA_EQUAL(first, replies[i].poststat, gid)) { gf_msg_debug(this->name, 0, "GID mismatch " "%d vs %d on %s for gfid:%s", (int)first.ia_uid, (int)replies[i].poststat.ia_uid, priv->children[i]->name, uuid_utoa(replies[i].poststat.ia_gfid)); if (metadata_selfheal) *metadata_selfheal = _gf_true; } if (!IA_EQUAL(first, replies[i].poststat, prot)) { gf_msg_debug(this->name, 0, "MODE mismatch " "%d vs %d on %s for gfid:%s", (int)st_mode_from_ia(first.ia_prot, 0), (int)st_mode_from_ia(replies[i].poststat.ia_prot, 0), priv->children[i]->name, uuid_utoa(replies[i].poststat.ia_gfid)); if (metadata_selfheal) *metadata_selfheal = _gf_true; } if (IA_ISREG(first.ia_type) && !IA_EQUAL(first, replies[i].poststat, size)) { gf_msg_debug(this->name, 0, "SIZE mismatch " "%lld vs %lld on %s for gfid:%s", (long long)first.ia_size, (long long)replies[i].poststat.ia_size, priv->children[i]->name, uuid_utoa(replies[i].poststat.ia_gfid)); if (data_selfheal) *data_selfheal = _gf_true; } } if (valid_cnt > 0 && link_inode) { *link_inode = inode_link(inode, NULL, NULL, &first); if (!*link_inode) { ret = -EINVAL; goto out; } } else if (valid_cnt < 2) { ret = afr_check_stale_error(replies, priv); goto out; } ret = 0; out: if (replies && replies_dst) afr_replies_copy(replies_dst, replies, priv->child_count); if (inode) inode_unref(inode); if (replies) afr_replies_wipe(replies, priv->child_count); return ret; } inode_t * afr_inode_find(xlator_t *this, uuid_t gfid) { inode_table_t *table = NULL; inode_t *inode = NULL; table = this->itable; if (!table) return NULL; inode = inode_find(table, gfid); if (inode) return inode; inode = inode_new(table); if (!inode) return NULL; gf_uuid_copy(inode->gfid, gfid); return inode; } call_frame_t * afr_frame_create(xlator_t *this, int32_t *op_errno) { call_frame_t *frame = NULL; afr_local_t *local = NULL; pid_t pid = GF_CLIENT_PID_SELF_HEALD; frame = create_frame(this, this->ctx->pool); if (!frame) { if (op_errno) *op_errno = ENOMEM; return NULL; } local = AFR_FRAME_INIT(frame, (*op_errno)); if (!local) { STACK_DESTROY(frame->root); return NULL; } syncopctx_setfspid(&pid); frame->root->pid = pid; afr_set_lk_owner(frame, this, frame->root); return frame; } int afr_selfheal_newentry_mark(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, struct afr_reply *replies, unsigned char *sources, unsigned char *newentry) { int ret = 0; int i = 0; afr_private_t *priv = NULL; dict_t *xattr = NULL; int **changelog = NULL; priv = this->private; gf_uuid_copy(inode->gfid, replies[source].poststat.ia_gfid); xattr = dict_new(); if (!xattr) return -ENOMEM; changelog = afr_mark_pending_changelog(priv, newentry, xattr, replies[source].poststat.ia_type); if (!changelog) { ret = -ENOMEM; goto out; } for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; ret |= afr_selfheal_post_op(frame, this, inode, i, xattr, NULL); } out: if (changelog) afr_matrix_cleanup(changelog, priv->child_count); if (xattr) dict_unref(xattr); return ret; } int afr_selfheal_do(call_frame_t *frame, xlator_t *this, uuid_t gfid) { int ret = -1; int entry_ret = 1; int metadata_ret = 1; int data_ret = 1; int or_ret = 0; inode_t *inode = NULL; fd_t *fd = NULL; gf_boolean_t data_selfheal = _gf_false; gf_boolean_t metadata_selfheal = _gf_false; gf_boolean_t entry_selfheal = _gf_false; afr_private_t *priv = NULL; priv = this->private; ret = afr_selfheal_unlocked_inspect(frame, this, gfid, &inode, &data_selfheal, &metadata_selfheal, &entry_selfheal, NULL); if (ret) goto out; if (!(data_selfheal || metadata_selfheal || entry_selfheal)) { ret = 2; goto out; } if (inode->ia_type == IA_IFREG) { ret = afr_selfheal_data_open(this, inode, &fd); if (!fd) { ret = -EIO; goto out; } } gf_msg_debug( this->name, 0, "heals needed for %s: [entry-heal=%d, metadata-heal=%d, data-heal=%d]", uuid_utoa(gfid), entry_selfheal, metadata_selfheal, data_selfheal); if (data_selfheal && priv->data_self_heal) data_ret = afr_selfheal_data(frame, this, fd); if (metadata_selfheal && priv->metadata_self_heal) metadata_ret = afr_selfheal_metadata(frame, this, inode); if (entry_selfheal && priv->entry_self_heal) entry_ret = afr_selfheal_entry(frame, this, inode); or_ret = (data_ret | metadata_ret | entry_ret); if (data_ret == -EIO || metadata_ret == -EIO || entry_ret == -EIO) ret = -EIO; else if (data_ret == 1 && metadata_ret == 1 && entry_ret == 1) ret = 1; else if (or_ret < 0) ret = or_ret; else ret = 0; out: if (inode) inode_unref(inode); if (fd) fd_unref(fd); return ret; } /* * This is the entry point for healing a given GFID. The return values for this * function are as follows: * '0' if the self-heal is successful * '1' if the afr-xattrs are non-zero (due to on-going IO) and no heal is needed * '2' if the afr-xattrs are all-zero and no heal is needed * $errno if the heal on the gfid failed. */ int afr_selfheal(xlator_t *this, uuid_t gfid) { int ret = -1; call_frame_t *frame = NULL; afr_local_t *local = NULL; frame = afr_frame_create(this, NULL); if (!frame) return ret; local = frame->local; local->xdata_req = dict_new(); ret = afr_selfheal_do(frame, this, gfid); if (frame) AFR_STACK_DESTROY(frame); return ret; } afr_local_t * __afr_dequeue_heals(afr_private_t *priv) { afr_local_t *local = NULL; if (list_empty(&priv->heal_waiting)) goto none; if ((priv->background_self_heal_count > 0) && (priv->healers >= priv->background_self_heal_count)) goto none; local = list_entry(priv->heal_waiting.next, afr_local_t, healer); priv->heal_waiters--; GF_ASSERT(priv->heal_waiters >= 0); list_del_init(&local->healer); list_add(&local->healer, &priv->healing); priv->healers++; return local; none: gf_msg_debug(THIS->name, 0, "Nothing dequeued. " "Num healers: %d, Num Waiters: %d", priv->healers, priv->heal_waiters); return NULL; } static int afr_refresh_selfheal_wrap(void *opaque) { call_frame_t *heal_frame = opaque; afr_local_t *local = heal_frame->local; int ret = 0; ret = afr_selfheal(heal_frame->this, local->refreshinode->gfid); return ret; } static int afr_refresh_heal_done(int ret, call_frame_t *frame, void *opaque) { call_frame_t *heal_frame = opaque; xlator_t *this = heal_frame->this; afr_private_t *priv = this->private; afr_local_t *local = heal_frame->local; LOCK(&priv->lock); { list_del_init(&local->healer); priv->healers--; GF_ASSERT(priv->healers >= 0); local = __afr_dequeue_heals(priv); } UNLOCK(&priv->lock); AFR_STACK_DESTROY(heal_frame); if (local) afr_heal_synctask(this, local); return 0; } void afr_heal_synctask(xlator_t *this, afr_local_t *local) { int ret = 0; call_frame_t *heal_frame = NULL; heal_frame = local->heal_frame; ret = synctask_new(this->ctx->env, afr_refresh_selfheal_wrap, afr_refresh_heal_done, heal_frame, heal_frame); if (ret < 0) /* Heal not launched. Will be queued when the next inode * refresh happens and shd hasn't healed it yet. */ afr_refresh_heal_done(ret, heal_frame, heal_frame); } gf_boolean_t afr_throttled_selfheal(call_frame_t *frame, xlator_t *this) { gf_boolean_t can_heal = _gf_true; afr_private_t *priv = this->private; afr_local_t *local = frame->local; LOCK(&priv->lock); { if ((priv->background_self_heal_count > 0) && (priv->heal_wait_qlen + priv->background_self_heal_count) > (priv->heal_waiters + priv->healers)) { list_add_tail(&local->healer, &priv->heal_waiting); priv->heal_waiters++; local = __afr_dequeue_heals(priv); } else { can_heal = _gf_false; } } UNLOCK(&priv->lock); if (can_heal) { if (local) afr_heal_synctask(this, local); else gf_msg_debug(this->name, 0, "Max number of heals are " "pending, background self-heal rejected."); } return can_heal; } int afr_choose_source_by_policy(afr_private_t *priv, unsigned char *sources, afr_transaction_type type) { int source = -1; int i = 0; /* Give preference to local child to save on bandwidth */ for (i = 0; i < priv->child_count; i++) { if (priv->local[i] && sources[i]) { if ((type == AFR_DATA_TRANSACTION) && AFR_IS_ARBITER_BRICK(priv, i)) continue; source = i; goto out; } } for (i = 0; i < priv->child_count; i++) { if (sources[i]) { source = i; goto out; } } out: return source; } static int afr_anon_inode_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { afr_local_t *local = frame->local; int i = (long)cookie; local->replies[i].valid = 1; local->replies[i].op_ret = op_ret; local->replies[i].op_errno = op_errno; if (op_ret == 0) { local->op_ret = 0; local->replies[i].poststat = *buf; local->replies[i].preparent = *preparent; local->replies[i].postparent = *postparent; } if (xdata) { local->replies[i].xdata = dict_ref(xdata); } syncbarrier_wake(&local->barrier); return 0; } int afr_anon_inode_create(xlator_t *this, int child, inode_t **linked_inode) { call_frame_t *frame = NULL; afr_local_t *local = NULL; afr_private_t *priv = this->private; unsigned char *mkdir_on = alloca0(priv->child_count); unsigned char *lookup_on = alloca0(priv->child_count); loc_t loc = {0}; int32_t op_errno = 0; int32_t child_op_errno = 0; struct iatt iatt = {0}; dict_t *xdata = NULL; uuid_t anon_inode_gfid = {0}; int mkdir_count = 0; int i = 0; /*Try to mkdir everywhere and return success if the dir exists on 'child' */ if (!priv->use_anon_inode) { op_errno = EINVAL; goto out; } frame = afr_frame_create(this, &op_errno); if (!frame) { goto out; } local = frame->local; if (!local->child_up[child]) { /*Other bricks may need mkdir so don't error out yet*/ child_op_errno = ENOTCONN; } gf_uuid_parse(priv->anon_gfid_str, anon_inode_gfid); for (i = 0; i < priv->child_count; i++) { if (!local->child_up[i]) continue; if (priv->anon_inode[i]) { mkdir_on[i] = 0; } else { mkdir_on[i] = 1; mkdir_count++; } } if (mkdir_count == 0) { *linked_inode = inode_find(this->itable, anon_inode_gfid); if (*linked_inode) { op_errno = 0; goto out; } } loc.parent = inode_ref(this->itable->root); loc.name = priv->anon_inode_name; loc.inode = inode_new(this->itable); if (!loc.inode) { op_errno = ENOMEM; goto out; } xdata = dict_new(); if (!xdata) { op_errno = ENOMEM; goto out; } op_errno = -dict_set_gfuuid(xdata, "gfid-req", anon_inode_gfid, _gf_true); if (op_errno) { goto out; } if (mkdir_count == 0) { memcpy(lookup_on, local->child_up, priv->child_count); goto lookup; } AFR_ONLIST(mkdir_on, frame, afr_anon_inode_mkdir_cbk, mkdir, &loc, 0755, 0, xdata); for (i = 0; i < priv->child_count; i++) { if (!mkdir_on[i]) { continue; } if (local->replies[i].op_ret == 0) { priv->anon_inode[i] = 1; iatt = local->replies[i].poststat; } else if (local->replies[i].op_ret < 0 && local->replies[i].op_errno == EEXIST) { lookup_on[i] = 1; } else if (i == child) { child_op_errno = local->replies[i].op_errno; } } if (AFR_COUNT(lookup_on, priv->child_count) == 0) { goto link; } lookup: AFR_ONLIST(lookup_on, frame, afr_selfheal_discover_cbk, lookup, &loc, xdata); for (i = 0; i < priv->child_count; i++) { if (!lookup_on[i]) { continue; } if (local->replies[i].op_ret == 0) { if (gf_uuid_compare(anon_inode_gfid, local->replies[i].poststat.ia_gfid) == 0) { priv->anon_inode[i] = 1; iatt = local->replies[i].poststat; } else { if (i == child) child_op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_INVALID_DATA, "%s has gfid: %s", priv->anon_inode_name, uuid_utoa(local->replies[i].poststat.ia_gfid)); } } else if (i == child) { child_op_errno = local->replies[i].op_errno; } } link: if (!gf_uuid_is_null(iatt.ia_gfid)) { *linked_inode = inode_link(loc.inode, loc.parent, loc.name, &iatt); if (*linked_inode) { op_errno = 0; inode_lookup(*linked_inode); } else { op_errno = ENOMEM; } goto out; } out: if (xdata) dict_unref(xdata); loc_wipe(&loc); /*child_op_errno takes precedence*/ if (child_op_errno == 0) { child_op_errno = op_errno; } if (child_op_errno && *linked_inode) { inode_unref(*linked_inode); *linked_inode = NULL; } if (frame) AFR_STACK_DESTROY(frame); return -child_op_errno; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-inode-write.c0000644000000000000000000000013214522202451024234 xustar000000000000000030 mtime=1699284265.615027275 30 atime=1699284265.614027272 30 ctime=1699284301.113134195 glusterfs-11.1/xlators/cluster/afr/src/afr-inode-write.c0000664000175100017510000021335714522202451024526 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include "protocol-common.h" #include "afr-transaction.h" #include "afr-self-heal.h" #include "afr-messages.h" static void __afr_inode_write_finalize(call_frame_t *frame, xlator_t *this) { int i = 0; int ret = 0; int read_subvol = 0; struct iatt *stbuf = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; afr_lock_t *lock = NULL; afr_read_subvol_args_t args = { 0, }; local = frame->local; priv = this->private; GF_VALIDATE_OR_GOTO(this->name, local->inode, out); if (local->update_num_inodelks && local->transaction.type == AFR_DATA_TRANSACTION) { lock = &local->inode_ctx->lock[local->transaction.type]; lock->num_inodelks = local->num_inodelks; } /*This code needs to stay till DHT sends fops on linked * inodes*/ if (!inode_is_linked(local->inode)) { for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret == -1) continue; if (!gf_uuid_is_null(local->replies[i].poststat.ia_gfid)) { gf_uuid_copy(args.gfid, local->replies[i].poststat.ia_gfid); args.ia_type = local->replies[i].poststat.ia_type; break; } else { ret = dict_get_bin(local->replies[i].xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf); if (ret) continue; gf_uuid_copy(args.gfid, stbuf->ia_gfid); args.ia_type = stbuf->ia_type; break; } } } if (local->transaction.type == AFR_METADATA_TRANSACTION) { read_subvol = afr_metadata_subvol_get(local->inode, this, NULL, local->readable, NULL, &args); } else { read_subvol = afr_data_subvol_get(local->inode, this, NULL, local->readable, NULL, &args); } local->op_ret = -1; local->op_errno = afr_final_errno(local, priv); afr_pick_error_xdata(local, priv->child_count, local->inode, local->readable, NULL, NULL); for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret < 0) continue; /* Order of checks in the compound conditional below is important. - Highest precedence: largest op_ret - Next precedence: if all op_rets are equal, read subvol - Least precedence: any succeeded subvol */ if ((local->op_ret < local->replies[i].op_ret) || ((local->op_ret == local->replies[i].op_ret) && (i == read_subvol))) { local->op_ret = local->replies[i].op_ret; local->op_errno = local->replies[i].op_errno; local->cont.inode_wfop.prebuf = local->replies[i].prestat; local->cont.inode_wfop.postbuf = local->replies[i].poststat; if (local->replies[i].xdata) { if (local->xdata_rsp) dict_unref(local->xdata_rsp); local->xdata_rsp = dict_ref(local->replies[i].xdata); } if (local->replies[i].xattr) { if (local->xattr_rsp) dict_unref(local->xattr_rsp); local->xattr_rsp = dict_ref(local->replies[i].xattr); } } } afr_set_in_flight_sb_status(this, frame, local->inode); out: return; } static void __afr_inode_write_fill(afr_local_t *local, afr_private_t *priv, int child_index, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xattr, dict_t *xdata) { int num_inodelks = 0; local->replies[child_index].valid = 1; if (AFR_IS_ARBITER_BRICK(priv, child_index) && op_ret == 1) op_ret = iov_length(local->cont.writev.vector, local->cont.writev.count); local->replies[child_index].op_ret = op_ret; local->replies[child_index].op_errno = op_errno; if (xdata) { local->replies[child_index].xdata = dict_ref(xdata); if (dict_get_int32_sizen(xdata, GLUSTERFS_INODELK_COUNT, &num_inodelks) == 0) { if (num_inodelks > local->num_inodelks) { local->num_inodelks = num_inodelks; local->update_num_inodelks = _gf_true; } } } if (op_ret >= 0) { if (prebuf) local->replies[child_index].prestat = *prebuf; if (postbuf) local->replies[child_index].poststat = *postbuf; if (xattr) local->replies[child_index].xattr = dict_ref(xattr); } else { afr_transaction_fop_failed(local, child_index); } return; } static int __afr_inode_write_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xattr, dict_t *xdata) { afr_local_t *local = NULL; int child_index = (long)cookie; int call_count = -1; afr_private_t *priv = NULL; priv = this->private; local = frame->local; LOCK(&frame->lock); { __afr_inode_write_fill(local, priv, child_index, op_ret, op_errno, prebuf, postbuf, xattr, xdata); call_count = --local->call_count; } UNLOCK(&frame->lock); if (call_count == 0) { __afr_inode_write_finalize(frame, this); if (afr_txn_nothing_failed(frame, this)) { /*if it did pre-op, it will do post-op changing ctime*/ if (priv->consistent_metadata && afr_needs_changelog_update(local)) afr_zero_fill_stat(local); local->transaction.unwind(frame, this); } afr_transaction_resume(frame, this); } return 0; } /* {{{ writev */ static void afr_writev_copy_outvars(call_frame_t *src_frame, call_frame_t *dst_frame) { afr_local_t *src_local = NULL; afr_local_t *dst_local = NULL; src_local = src_frame->local; dst_local = dst_frame->local; dst_local->op_ret = src_local->op_ret; dst_local->op_errno = src_local->op_errno; dst_local->cont.inode_wfop.prebuf = src_local->cont.inode_wfop.prebuf; dst_local->cont.inode_wfop.postbuf = src_local->cont.inode_wfop.postbuf; if (src_local->xdata_rsp) dst_local->xdata_rsp = dict_ref(src_local->xdata_rsp); } static void afr_writev_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = this->private; local = frame->local; if (priv->consistent_metadata) afr_zero_fill_stat(local); AFR_STACK_UNWIND(writev, frame, local->op_ret, local->op_errno, &local->cont.inode_wfop.prebuf, &local->cont.inode_wfop.postbuf, local->xdata_rsp); } static int afr_transaction_writev_unwind(call_frame_t *frame, xlator_t *this) { call_frame_t *fop_frame = NULL; fop_frame = afr_transaction_detach_fop_frame(frame); if (fop_frame) { afr_writev_copy_outvars(frame, fop_frame); afr_writev_unwind(fop_frame, this); } return 0; } static void afr_writev_handle_short_writes(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; local = frame->local; priv = this->private; /* * We already have the best case result of the writev calls staged * as the return value. Any writev that returns some value less * than the best case is now out of sync, so mark the fop as * failed. Note that fops that have returned with errors have * already been marked as failed. */ for (i = 0; i < priv->child_count; i++) { if ((!local->replies[i].valid) || (local->replies[i].op_ret == -1)) continue; if (local->replies[i].op_ret < local->op_ret) afr_transaction_fop_failed(local, i); } } static int afr_inode_write_fill(call_frame_t *frame, xlator_t *this, int child_index, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { int ret = 0; afr_local_t *local = frame->local; uint32_t open_fd_count = 0; uint32_t write_is_append = 0; int call_count; LOCK(&frame->lock); { __afr_inode_write_fill(local, this->private, child_index, op_ret, op_errno, prebuf, postbuf, NULL, xdata); if (op_ret == -1 || !xdata) goto unlock; write_is_append = 0; ret = dict_get_uint32(xdata, GLUSTERFS_WRITE_IS_APPEND, &write_is_append); if (ret || !write_is_append) local->append_write = _gf_false; ret = dict_get_uint32(xdata, GLUSTERFS_ACTIVE_FD_COUNT, &open_fd_count); if (ret < 0) goto unlock; if (open_fd_count > local->open_fd_count) { local->open_fd_count = open_fd_count; local->update_open_fd_count = _gf_true; } } unlock: call_count = --local->call_count; UNLOCK(&frame->lock); return call_count; } static void afr_process_post_writev(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; local = frame->local; if (!local->stable_write && !local->append_write) /* An appended write removes the necessity to fsync() the file. This is because self-heal has the logic to check for larger file when the xattrs are not reliably pointing at a stale file. */ afr_fd_report_unstable_write(this, local); __afr_inode_write_finalize(frame, this); afr_writev_handle_short_writes(frame, this); if (local->update_open_fd_count) local->inode_ctx->open_fd_count = local->open_fd_count; } static int afr_writev_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { call_frame_t *fop_frame = NULL; int child_index = (long)cookie; int call_count; call_count = afr_inode_write_fill(frame, this, child_index, op_ret, op_errno, prebuf, postbuf, xdata); if (call_count == 0) { afr_process_post_writev(frame, this); if (!afr_txn_nothing_failed(frame, this)) { // Don't unwind until post-op is complete afr_transaction_resume(frame, this); } else { /* * Generally inode-write fops do transaction.unwind then * transaction.resume, but writev needs to make sure that * delayed post-op frame is placed in fdctx before unwind * happens. This prevents the race of flush doing the * changelog wakeup first in fuse thread and then this * writev placing its delayed post-op frame in fdctx. * This helps flush make sure all the delayed post-ops are * completed. */ fop_frame = afr_transaction_detach_fop_frame(frame); afr_writev_copy_outvars(frame, fop_frame); afr_transaction_resume(frame, this); afr_writev_unwind(fop_frame, this); } } return 0; } static int afr_arbiter_writev_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = frame->local; afr_private_t *priv = this->private; static char byte = 0xFF; static struct iovec vector = {&byte, 1}; int32_t count = 1; STACK_WIND_COOKIE( frame, afr_writev_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->writev, local->fd, &vector, count, local->cont.writev.offset, local->cont.writev.flags, local->cont.writev.iobref, local->xdata_req); return 0; } int afr_writev_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; if (AFR_IS_ARBITER_BRICK(priv, subvol)) { afr_arbiter_writev_wind(frame, this, subvol); return 0; } STACK_WIND_COOKIE(frame, afr_writev_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->writev, local->fd, local->cont.writev.vector, local->cont.writev.count, local->cont.writev.offset, local->cont.writev.flags, local->cont.writev.iobref, local->xdata_req); return 0; } static int afr_do_writev(call_frame_t *frame, xlator_t *this) { call_frame_t *transaction_frame = NULL; afr_local_t *local = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = frame->local; transaction_frame->local = local; frame->local = NULL; if (!AFR_FRAME_INIT(frame, op_errno)) goto out; local->op = GF_FOP_WRITE; local->transaction.wind = afr_writev_wind; local->transaction.unwind = afr_transaction_writev_unwind; local->transaction.main_frame = frame; if (local->fd->flags & O_APPEND) { /* * Backend vfs ignores the 'offset' for append mode fd so * locking just the region provided for the writev does not * give consistency guarantee. The actual write may happen at a * completely different range than the one provided by the * offset, len in the fop. So lock the entire file. */ local->transaction.start = 0; local->transaction.len = 0; } else { local->transaction.start = local->cont.writev.offset; local->transaction.len = iov_length(local->cont.writev.vector, local->cont.writev.count); } ret = afr_transaction(transaction_frame, this, AFR_DATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int afr_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { afr_local_t *local = NULL; int op_errno = ENOMEM; int ret = -1; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->cont.writev.vector = iov_dup(vector, count); if (!local->cont.writev.vector) goto out; local->cont.writev.count = count; local->cont.writev.offset = offset; local->cont.writev.flags = flags; local->cont.writev.iobref = iobref_ref(iobref); if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; if (dict_set_uint32(local->xdata_req, GLUSTERFS_ACTIVE_FD_COUNT, 4)) { op_errno = ENOMEM; goto out; } if (dict_set_str_sizen(local->xdata_req, GLUSTERFS_INODELK_DOM_COUNT, this->name)) { op_errno = ENOMEM; goto out; } if (dict_set_uint32(local->xdata_req, GLUSTERFS_WRITE_IS_APPEND, 4)) { op_errno = ENOMEM; goto out; } /* Set append_write to be true speculatively. If on any server it turns not be true, we unset it in the callback. */ local->append_write = _gf_true; /* detect here, but set it in writev_wind_cbk *after* the unstable write is performed */ local->stable_write = !!((fd->flags | flags) & (O_SYNC | O_DSYNC)); afr_fix_open(fd, this); afr_do_writev(frame, this); return 0; out: AFR_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ truncate */ static int afr_truncate_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(truncate, main_frame, local->op_ret, local->op_errno, &local->cont.inode_wfop.prebuf, &local->cont.inode_wfop.postbuf, local->xdata_rsp); return 0; } static int afr_truncate_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret == 0 && prebuf->ia_size != postbuf->ia_size) local->stable_write = _gf_false; return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, prebuf, postbuf, NULL, xdata); } static int afr_truncate_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_truncate_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->truncate, &local->loc, local->cont.truncate.offset, local->xdata_req); return 0; } int afr_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.truncate.offset = offset; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->transaction.wind = afr_truncate_wind; local->transaction.unwind = afr_truncate_unwind; loc_copy(&local->loc, loc); ret = afr_set_inode_local(this, local, loc->inode); if (ret) goto out; local->op = GF_FOP_TRUNCATE; local->transaction.main_frame = frame; local->transaction.start = offset; local->transaction.len = 0; /* Set it true speculatively, will get reset in afr_truncate_wind_cbk if truncate was not a NOP */ local->stable_write = _gf_true; ret = afr_transaction(transaction_frame, this, AFR_DATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ ftruncate */ static int afr_ftruncate_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(ftruncate, main_frame, local->op_ret, local->op_errno, &local->cont.inode_wfop.prebuf, &local->cont.inode_wfop.postbuf, local->xdata_rsp); return 0; } static int afr_ftruncate_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret == 0 && prebuf->ia_size != postbuf->ia_size) local->stable_write = _gf_false; return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, prebuf, postbuf, NULL, xdata); } static int afr_ftruncate_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_ftruncate_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->ftruncate, local->fd, local->cont.ftruncate.offset, local->xdata_req); return 0; } int afr_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.ftruncate.offset = offset; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; local->op = GF_FOP_FTRUNCATE; local->transaction.wind = afr_ftruncate_wind; local->transaction.unwind = afr_ftruncate_unwind; local->transaction.main_frame = frame; local->transaction.start = local->cont.ftruncate.offset; local->transaction.len = 0; afr_fix_open(fd, this); /* Set it true speculatively, will get reset in afr_ftruncate_wind_cbk if truncate was not a NOP */ local->stable_write = _gf_true; ret = afr_transaction(transaction_frame, this, AFR_DATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: AFR_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ setattr */ static int afr_setattr_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(setattr, main_frame, local->op_ret, local->op_errno, &local->cont.inode_wfop.prebuf, &local->cont.inode_wfop.postbuf, local->xdata_rsp); return 0; } static int afr_setattr_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preop, struct iatt *postop, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, preop, postop, NULL, xdata); } static int afr_setattr_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_setattr_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->setattr, &local->loc, &local->cont.setattr.in_buf, local->cont.setattr.valid, local->xdata_req); return 0; } int afr_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *buf, int32_t valid, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.setattr.in_buf = *buf; local->cont.setattr.valid = valid; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->transaction.wind = afr_setattr_wind; local->transaction.unwind = afr_setattr_unwind; loc_copy(&local->loc, loc); ret = afr_set_inode_local(this, local, loc->inode); if (ret) goto out; local->op = GF_FOP_SETATTR; local->transaction.main_frame = frame; local->transaction.start = LLONG_MAX - 1; local->transaction.len = 0; ret = afr_transaction(transaction_frame, this, AFR_METADATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(setattr, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* {{{ fsetattr */ static int afr_fsetattr_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(fsetattr, main_frame, local->op_ret, local->op_errno, &local->cont.inode_wfop.prebuf, &local->cont.inode_wfop.postbuf, local->xdata_rsp); return 0; } static int afr_fsetattr_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preop, struct iatt *postop, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, preop, postop, NULL, xdata); } static int afr_fsetattr_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_fsetattr_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->fsetattr, local->fd, &local->cont.fsetattr.in_buf, local->cont.fsetattr.valid, local->xdata_req); return 0; } int afr_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *buf, int32_t valid, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.fsetattr.in_buf = *buf; local->cont.fsetattr.valid = valid; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->transaction.wind = afr_fsetattr_wind; local->transaction.unwind = afr_fsetattr_unwind; local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; local->op = GF_FOP_FSETATTR; afr_fix_open(fd, this); local->transaction.main_frame = frame; local->transaction.start = LLONG_MAX - 1; local->transaction.len = 0; ret = afr_transaction(transaction_frame, this, AFR_METADATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(fsetattr, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* {{{ setxattr */ static int afr_setxattr_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(setxattr, main_frame, local->op_ret, local->op_errno, local->xdata_rsp); return 0; } static int afr_setxattr_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, NULL, NULL, NULL, xdata); } static int afr_setxattr_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_setxattr_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->setxattr, &local->loc, local->cont.setxattr.dict, local->cont.setxattr.flags, local->xdata_req); return 0; } static int afr_emptyb_set_pending_changelog_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i, ret = 0; char *op_type = NULL; local = frame->local; priv = this->private; i = (long)cookie; local->replies[i].valid = 1; local->replies[i].op_ret = op_ret; local->replies[i].op_errno = op_errno; ret = dict_get_str_sizen(local->xdata_req, "replicate-brick-op", &op_type); if (ret) goto out; gf_smsg(this->name, op_ret ? GF_LOG_ERROR : GF_LOG_INFO, op_ret ? op_errno : 0, AFR_MSG_SET_PEND_XATTR, "name=%s", priv->children[i]->name, "op_ret=%s", op_ret ? "failed" : "succeeded", NULL); out: syncbarrier_wake(&local->barrier); return 0; } static int afr_emptyb_set_pending_changelog(call_frame_t *frame, xlator_t *this, unsigned char *locked_nodes) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int ret = 0, i = 0; local = frame->local; priv = this->private; AFR_ONLIST(locked_nodes, frame, afr_emptyb_set_pending_changelog_cbk, xattrop, &local->loc, GF_XATTROP_ADD_ARRAY, local->xattr_req, NULL); /* It is sufficient if xattrop was successful on one child */ for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret == 0) { ret = 0; goto out; } else { ret = afr_higher_errno(ret, local->replies[i].op_errno); } } out: return -ret; } static int _afr_handle_empty_brick_type(xlator_t *this, call_frame_t *frame, loc_t *loc, int empty_index, afr_transaction_type type, char *op_type, const int op_type_len) { int count = 0; int ret = -ENOMEM; int idx = -1; int d_idx = -1; unsigned char *locked_nodes = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; priv = this->private; local = frame->local; uint32_t hton32_1; locked_nodes = alloca0(priv->child_count); idx = afr_index_for_transaction_type(type); d_idx = afr_index_for_transaction_type(AFR_DATA_TRANSACTION); local->pending = afr_matrix_create(priv->child_count, AFR_NUM_CHANGE_LOGS); if (!local->pending) goto out; hton32_1 = htobe32(1); local->pending[empty_index][idx] = hton32_1; if ((priv->esh_granular) && (type == AFR_ENTRY_TRANSACTION)) local->pending[empty_index][d_idx] = hton32_1; local->xdata_req = dict_new(); if (!local->xdata_req) goto out; ret = dict_set_nstrn(local->xdata_req, "replicate-brick-op", SLEN("replicate-brick-op"), op_type, op_type_len); if (ret) goto out; local->xattr_req = dict_new(); if (!local->xattr_req) goto out; ret = afr_set_pending_dict(priv, local->xattr_req, local->pending); if (ret < 0) goto out; if (AFR_ENTRY_TRANSACTION == type) { count = afr_selfheal_entrylk(frame, this, loc->inode, this->name, NULL, locked_nodes); } else { count = afr_selfheal_inodelk(frame, this, loc->inode, this->name, LLONG_MAX - 1, 0, locked_nodes); } if (!count) { gf_smsg(this->name, GF_LOG_ERROR, EAGAIN, AFR_MSG_REPLACE_BRICK_STATUS, NULL); ret = -EAGAIN; goto unlock; } ret = afr_emptyb_set_pending_changelog(frame, this, locked_nodes); if (ret) goto unlock; ret = 0; unlock: if (AFR_ENTRY_TRANSACTION == type) { afr_selfheal_unentrylk(frame, this, loc->inode, this->name, NULL, locked_nodes, NULL); } else { afr_selfheal_uninodelk(frame, this, loc->inode, this->name, LLONG_MAX - 1, 0, locked_nodes); } out: return ret; } static void afr_brick_args_cleanup(void *opaque) { afr_empty_brick_args_t *data = NULL; data = opaque; loc_wipe(&data->loc); GF_FREE(data); } static int _afr_handle_empty_brick_cbk(int ret, call_frame_t *frame, void *opaque) { afr_brick_args_cleanup(opaque); return 0; } static int _afr_handle_empty_brick(void *opaque) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int empty_index = -1; int ret = -1; int op_errno = ENOMEM; call_frame_t *frame = NULL; xlator_t *this = NULL; char *op_type = NULL; int op_type_len = 0; afr_empty_brick_args_t *data = NULL; call_frame_t *op_frame = NULL; data = opaque; frame = data->frame; empty_index = data->empty_index; if (!data->op_type) goto out; op_frame = copy_frame(frame); if (!op_frame) { ret = -1; op_errno = ENOMEM; goto out; } op_type = data->op_type; op_type_len = strlen(op_type); this = op_frame->this; priv = this->private; afr_set_lk_owner(op_frame, this, op_frame->root); local = AFR_FRAME_INIT(op_frame, op_errno); if (!local) goto out; loc_copy(&local->loc, &data->loc); gf_smsg(this->name, GF_LOG_INFO, 0, AFR_MSG_NEW_BRICK, "name=%s", priv->children[empty_index]->name, NULL); ret = _afr_handle_empty_brick_type(this, op_frame, &local->loc, empty_index, AFR_METADATA_TRANSACTION, op_type, op_type_len); if (ret) { op_errno = -ret; ret = -1; goto out; } dict_unref(local->xdata_req); dict_unref(local->xattr_req); afr_matrix_cleanup(local->pending, priv->child_count); local->pending = NULL; local->xattr_req = NULL; local->xdata_req = NULL; ret = _afr_handle_empty_brick_type(this, op_frame, &local->loc, empty_index, AFR_ENTRY_TRANSACTION, op_type, op_type_len); if (ret) { op_errno = -ret; ret = -1; goto out; } ret = 0; out: if (op_frame) { AFR_STACK_DESTROY(op_frame); } AFR_STACK_UNWIND(setxattr, frame, ret, op_errno, NULL); return 0; } static int afr_split_brain_resolve_do(call_frame_t *frame, xlator_t *this, loc_t *loc, char *data) { afr_local_t *local = NULL; int ret = -1; int op_errno = EINVAL; local = frame->local; local->xdata_req = dict_new(); if (!local->xdata_req) { op_errno = ENOMEM; goto out; } ret = dict_set_int32_sizen(local->xdata_req, "heal-op", GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK); if (ret) { op_errno = -ret; ret = -1; goto out; } ret = dict_set_str_sizen(local->xdata_req, "child-name", data); if (ret) { op_errno = -ret; ret = -1; goto out; } /* set spb choice to -1 whether heal succeeds or not: * If heal succeeds : spb-choice should be set to -1 as * it is no longer valid; file is not * in split-brain anymore. * If heal doesn't succeed: * spb-choice should be set to -1 * otherwise reads will be served * from spb-choice which is misleading. */ ret = afr_inode_split_brain_choice_set(loc->inode, this, -1); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, AFR_MSG_SPLIT_BRAIN_SET_FAILED, NULL); afr_heal_splitbrain_file(frame, this, loc); ret = 0; out: if (ret < 0) AFR_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); return 0; } static int afr_get_split_brain_child_index(xlator_t *this, void *value, size_t len) { int spb_child_index = -1; char *spb_child_str = NULL; spb_child_str = alloca0(len + 1); memcpy(spb_child_str, value, len); if (!strcmp(spb_child_str, "none")) return -2; spb_child_index = afr_get_child_index_from_name(this, spb_child_str); if (spb_child_index < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, AFR_MSG_INVALID_SUBVOL, "subvol=%s", spb_child_str, NULL); } return spb_child_index; } static int afr_can_set_split_brain_choice(void *opaque) { afr_spbc_timeout_t *data = opaque; call_frame_t *frame = NULL; xlator_t *this = NULL; loc_t *loc = NULL; int ret = -1; frame = data->frame; loc = data->loc; this = frame->this; ret = afr_is_split_brain(frame, this, loc->inode, loc->gfid, &data->d_spb, &data->m_spb); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN_DETERMINE_FAILED, "gfid=%s", uuid_utoa(loc->gfid), NULL); return ret; } static int afr_handle_split_brain_commands(xlator_t *this, call_frame_t *frame, loc_t *loc, dict_t *dict) { void *choice_value = NULL; void *resolve_value = NULL; afr_private_t *priv = NULL; afr_local_t *local = NULL; afr_spbc_timeout_t *data = NULL; int len = 0; int spb_child_index = -1; int ret = -1; int op_errno = EINVAL; priv = this->private; ret = dict_get_ptr_and_len(dict, GF_AFR_SBRAIN_CHOICE, &choice_value, &len); ret = dict_get_ptr_and_len(dict, GF_AFR_SBRAIN_RESOLVE, &resolve_value, &len); if (!choice_value && !resolve_value) { ret = -1; goto out; } local = AFR_FRAME_INIT(frame, op_errno); if (!local) { ret = 1; goto out; } local->op = GF_FOP_SETXATTR; if (choice_value) { spb_child_index = afr_get_split_brain_child_index(this, choice_value, len); if (spb_child_index < 0) { /* Case where value was "none" */ if (spb_child_index == -2) spb_child_index = -1; else { ret = 1; op_errno = EINVAL; goto out; } } data = GF_CALLOC(1, sizeof(*data), gf_afr_mt_spbc_timeout_t); if (!data) { ret = 1; goto out; } data->spb_child_index = spb_child_index; data->frame = frame; loc_copy(&local->loc, loc); data->loc = &local->loc; ret = synctask_new(this->ctx->env, afr_can_set_split_brain_choice, afr_set_split_brain_choice, NULL, data); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN_STATUS, "name=%s", loc->name, NULL); ret = 1; op_errno = ENOMEM; goto out; } ret = 0; goto out; } if (resolve_value) { spb_child_index = afr_get_split_brain_child_index(this, resolve_value, len); if (spb_child_index < 0) { ret = 1; goto out; } afr_split_brain_resolve_do(frame, this, loc, priv->children[spb_child_index]->name); ret = 0; } out: /* key was correct but value was invalid when ret == 1 */ if (ret == 1) { AFR_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); if (data) GF_FREE(data); ret = 0; } return ret; } static int afr_handle_spb_choice_timeout(xlator_t *this, call_frame_t *frame, dict_t *dict) { int ret = -1; int op_errno = 0; uint64_t timeout = 0; afr_private_t *priv = NULL; priv = this->private; ret = dict_get_uint64(dict, GF_AFR_SPB_CHOICE_TIMEOUT, &timeout); if (!ret) { priv->spb_choice_timeout = timeout * 60; AFR_STACK_UNWIND(setxattr, frame, ret, op_errno, NULL); } return ret; } static int afr_handle_empty_brick(xlator_t *this, call_frame_t *frame, loc_t *loc, dict_t *dict) { int ret = -1; int ab_ret = -1; int empty_index = -1; int op_errno = EPERM; char *empty_brick = NULL; char *op_type = NULL; afr_empty_brick_args_t *data = NULL; ret = dict_get_str_sizen(dict, GF_AFR_REPLACE_BRICK, &empty_brick); if (!ret) op_type = GF_AFR_REPLACE_BRICK; ab_ret = dict_get_str_sizen(dict, GF_AFR_ADD_BRICK, &empty_brick); if (!ab_ret) op_type = GF_AFR_ADD_BRICK; if (ret && ab_ret) goto out; if (frame->root->pid != GF_CLIENT_PID_ADD_REPLICA_MOUNT) { gf_smsg(this->name, GF_LOG_ERROR, EPERM, AFR_MSG_INTERNAL_ATTR, "op_type=%s", op_type, NULL); ret = 1; goto out; } empty_index = afr_get_child_index_from_name(this, empty_brick); if (empty_index < 0) { /* Didn't belong to this replica pair * Just do a no-op */ AFR_STACK_UNWIND(setxattr, frame, 0, 0, NULL); return 0; } else { data = GF_CALLOC(1, sizeof(*data), gf_afr_mt_empty_brick_t); if (!data) { ret = 1; op_errno = ENOMEM; goto out; } data->frame = frame; loc_copy(&data->loc, loc); data->empty_index = empty_index; data->op_type = op_type; ret = synctask_new(this->ctx->env, _afr_handle_empty_brick, _afr_handle_empty_brick_cbk, NULL, data); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN_STATUS, NULL); ret = 1; op_errno = ENOMEM; afr_brick_args_cleanup(data); goto out; } } ret = 0; out: if (ret == 1) { AFR_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); ret = 0; } return ret; } static int afr_handle_special_xattr(xlator_t *this, call_frame_t *frame, loc_t *loc, dict_t *dict) { int ret = -1; ret = afr_handle_split_brain_commands(this, frame, loc, dict); if (ret == 0) goto out; ret = afr_handle_spb_choice_timeout(this, frame, dict); if (ret == 0) goto out; /* Applicable for replace-brick and add-brick commands */ ret = afr_handle_empty_brick(this, frame, loc, dict); out: return ret; } int afr_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = EINVAL; GF_IF_INTERNAL_XATTR_GOTO("trusted.afr.*", dict, op_errno, out); GF_IF_INTERNAL_XATTR_GOTO("trusted.glusterfs.afr.*", dict, op_errno, out); ret = afr_handle_special_xattr(this, frame, loc, dict); if (ret == 0) return 0; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.setxattr.dict = dict_ref(dict); local->cont.setxattr.flags = flags; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->transaction.wind = afr_setxattr_wind; local->transaction.unwind = afr_setxattr_unwind; loc_copy(&local->loc, loc); ret = afr_set_inode_local(this, local, loc->inode); if (ret) goto out; local->transaction.main_frame = frame; local->transaction.start = LLONG_MAX - 1; local->transaction.len = 0; local->op = GF_FOP_SETXATTR; ret = afr_transaction(transaction_frame, this, AFR_METADATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); return 0; } /* {{{ fsetxattr */ static int afr_fsetxattr_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(fsetxattr, main_frame, local->op_ret, local->op_errno, local->xdata_rsp); return 0; } static int afr_fsetxattr_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, NULL, NULL, NULL, xdata); } static int afr_fsetxattr_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_fsetxattr_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->fsetxattr, local->fd, local->cont.fsetxattr.dict, local->cont.fsetxattr.flags, local->xdata_req); return 0; } int afr_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; GF_IF_INTERNAL_XATTR_GOTO("trusted.afr.*", dict, op_errno, out); GF_IF_INTERNAL_XATTR_GOTO("trusted.glusterfs.afr.*", dict, op_errno, out); AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.fsetxattr.dict = dict_ref(dict); local->cont.fsetxattr.flags = flags; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->transaction.wind = afr_fsetxattr_wind; local->transaction.unwind = afr_fsetxattr_unwind; local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; local->op = GF_FOP_FSETXATTR; local->transaction.main_frame = frame; local->transaction.start = LLONG_MAX - 1; local->transaction.len = 0; ret = afr_transaction(transaction_frame, this, AFR_METADATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); return 0; } /* }}} */ /* {{{ removexattr */ static int afr_removexattr_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(removexattr, main_frame, local->op_ret, local->op_errno, local->xdata_rsp); return 0; } int afr_removexattr_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, NULL, NULL, NULL, xdata); } static int afr_removexattr_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_removexattr_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->removexattr, &local->loc, local->cont.removexattr.name, local->xdata_req); return 0; } int afr_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; GF_IF_NATIVE_XATTR_GOTO("trusted.afr.*", name, op_errno, out); GF_IF_NATIVE_XATTR_GOTO("trusted.glusterfs.afr.*", name, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.removexattr.name = gf_strdup(name); if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->transaction.wind = afr_removexattr_wind; local->transaction.unwind = afr_removexattr_unwind; loc_copy(&local->loc, loc); ret = afr_set_inode_local(this, local, loc->inode); if (ret) goto out; local->op = GF_FOP_REMOVEXATTR; local->transaction.main_frame = frame; local->transaction.start = LLONG_MAX - 1; local->transaction.len = 0; ret = afr_transaction(transaction_frame, this, AFR_METADATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); return 0; } /* ffremovexattr */ static int afr_fremovexattr_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(fremovexattr, main_frame, local->op_ret, local->op_errno, local->xdata_rsp); return 0; } static int afr_fremovexattr_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, NULL, NULL, NULL, xdata); } static int afr_fremovexattr_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_fremovexattr_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->fremovexattr, local->fd, local->cont.removexattr.name, local->xdata_req); return 0; } int afr_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; GF_IF_NATIVE_XATTR_GOTO("trusted.afr.*", name, op_errno, out); GF_IF_NATIVE_XATTR_GOTO("trusted.glusterfs.afr.*", name, op_errno, out); AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.removexattr.name = gf_strdup(name); if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->transaction.wind = afr_fremovexattr_wind; local->transaction.unwind = afr_fremovexattr_unwind; local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; local->op = GF_FOP_FREMOVEXATTR; local->transaction.main_frame = frame; local->transaction.start = LLONG_MAX - 1; local->transaction.len = 0; ret = afr_transaction(transaction_frame, this, AFR_METADATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(fremovexattr, frame, -1, op_errno, NULL); return 0; } static int afr_fallocate_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(fallocate, main_frame, local->op_ret, local->op_errno, &local->cont.inode_wfop.prebuf, &local->cont.inode_wfop.postbuf, local->xdata_rsp); return 0; } static int afr_fallocate_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, prebuf, postbuf, NULL, xdata); } static int afr_fallocate_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_fallocate_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->fallocate, local->fd, local->cont.fallocate.mode, local->cont.fallocate.offset, local->cont.fallocate.len, local->xdata_req); return 0; } int afr_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { call_frame_t *transaction_frame = NULL; afr_local_t *local = NULL; int ret = -1; int op_errno = ENOMEM; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.fallocate.mode = mode; local->cont.fallocate.offset = offset; local->cont.fallocate.len = len; local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->op = GF_FOP_FALLOCATE; local->transaction.wind = afr_fallocate_wind; local->transaction.unwind = afr_fallocate_unwind; local->transaction.main_frame = frame; local->transaction.start = local->cont.fallocate.offset; local->transaction.len = 0; afr_fix_open(fd, this); ret = afr_transaction(transaction_frame, this, AFR_DATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* }}} */ /* {{{ discard */ static int afr_discard_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(discard, main_frame, local->op_ret, local->op_errno, &local->cont.inode_wfop.prebuf, &local->cont.inode_wfop.postbuf, local->xdata_rsp); return 0; } static int afr_discard_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, prebuf, postbuf, NULL, xdata); } static int afr_discard_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_discard_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->discard, local->fd, local->cont.discard.offset, local->cont.discard.len, local->xdata_req); return 0; } int afr_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.discard.offset = offset; local->cont.discard.len = len; local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->op = GF_FOP_DISCARD; local->transaction.wind = afr_discard_wind; local->transaction.unwind = afr_discard_unwind; local->transaction.main_frame = frame; local->transaction.start = local->cont.discard.offset; local->transaction.len = 0; afr_fix_open(fd, this); ret = afr_transaction(transaction_frame, this, AFR_DATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* {{{ zerofill */ static int afr_zerofill_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(discard, main_frame, local->op_ret, local->op_errno, &local->cont.inode_wfop.prebuf, &local->cont.inode_wfop.postbuf, local->xdata_rsp); return 0; } static int afr_zerofill_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, prebuf, postbuf, NULL, xdata); } static int afr_zerofill_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_zerofill_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->zerofill, local->fd, local->cont.zerofill.offset, local->cont.zerofill.len, local->xdata_req); return 0; } int afr_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.zerofill.offset = offset; local->cont.zerofill.len = len; local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; if (xdata) local->xdata_req = dict_copy_with_ref(xdata, NULL); else local->xdata_req = dict_new(); if (!local->xdata_req) goto out; local->op = GF_FOP_ZEROFILL; local->transaction.wind = afr_zerofill_wind; local->transaction.unwind = afr_zerofill_unwind; local->transaction.main_frame = frame; local->transaction.start = local->cont.zerofill.offset; local->transaction.len = len; afr_fix_open(fd, this); ret = afr_transaction(transaction_frame, this, AFR_DATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL); return 0; } /* }}} */ static int32_t afr_xattrop_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, NULL, NULL, xattr, xdata); } static int afr_xattrop_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_xattrop_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->xattrop, &local->loc, local->cont.xattrop.optype, local->cont.xattrop.xattr, local->xdata_req); return 0; } static int afr_xattrop_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(xattrop, main_frame, local->op_ret, local->op_errno, local->xattr_rsp, local->xdata_rsp); return 0; } int32_t afr_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.xattrop.xattr = dict_ref(xattr); local->cont.xattrop.optype = optype; if (xdata) local->xdata_req = dict_ref(xdata); local->transaction.wind = afr_xattrop_wind; local->transaction.unwind = afr_xattrop_unwind; loc_copy(&local->loc, loc); ret = afr_set_inode_local(this, local, loc->inode); if (ret) goto out; local->op = GF_FOP_XATTROP; local->transaction.main_frame = frame; local->transaction.start = LLONG_MAX - 1; local->transaction.len = 0; ret = afr_transaction(transaction_frame, this, AFR_METADATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL); return 0; } int32_t afr_fxattrop_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, NULL, NULL, xattr, xdata); } int afr_fxattrop_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_fxattrop_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->fxattrop, local->fd, local->cont.xattrop.optype, local->cont.xattrop.xattr, local->xdata_req); return 0; } int afr_fxattrop_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(fxattrop, main_frame, local->op_ret, local->op_errno, local->xattr_rsp, local->xdata_rsp); return 0; } int32_t afr_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int op_errno = ENOMEM; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; local->cont.xattrop.xattr = dict_ref(xattr); local->cont.xattrop.optype = optype; if (xdata) local->xdata_req = dict_ref(xdata); local->transaction.wind = afr_fxattrop_wind; local->transaction.unwind = afr_fxattrop_unwind; local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; local->op = GF_FOP_FXATTROP; local->transaction.main_frame = frame; local->transaction.start = LLONG_MAX - 1; local->transaction.len = 0; ret = afr_transaction(transaction_frame, this, AFR_METADATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(fxattrop, frame, -1, op_errno, NULL, NULL); return 0; } static int afr_fsync_unwind(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; call_frame_t *main_frame = NULL; local = frame->local; main_frame = afr_transaction_detach_fop_frame(frame); if (!main_frame) return 0; AFR_STACK_UNWIND(fsync, main_frame, local->op_ret, local->op_errno, &local->cont.inode_wfop.prebuf, &local->cont.inode_wfop.postbuf, local->xdata_rsp); return 0; } int afr_fsync_wind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { return __afr_inode_write_cbk(frame, cookie, this, op_ret, op_errno, prebuf, postbuf, NULL, xdata); } static int afr_fsync_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; STACK_WIND_COOKIE(frame, afr_fsync_wind_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->fsync, local->fd, local->cont.fsync.datasync, local->xdata_req); return 0; } int afr_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; int ret = -1; int32_t op_errno = ENOMEM; int8_t last_fsync = 0; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); transaction_frame = copy_frame(frame); if (!transaction_frame) goto out; local = AFR_FRAME_INIT(transaction_frame, op_errno); if (!local) goto out; if (xdata) { local->xdata_req = dict_copy_with_ref(xdata, NULL); if (dict_get_int8(xdata, "last-fsync", &last_fsync) == 0) { if (last_fsync) { local->transaction.disable_delayed_post_op = _gf_true; } } } else { local->xdata_req = dict_new(); } if (!local->xdata_req) goto out; if (dict_set_str_sizen(local->xdata_req, GLUSTERFS_INODELK_DOM_COUNT, this->name)) { op_errno = ENOMEM; goto out; } local->fd = fd_ref(fd); ret = afr_set_inode_local(this, local, fd->inode); if (ret) goto out; local->op = GF_FOP_FSYNC; local->cont.fsync.datasync = datasync; if (afr_fd_has_witnessed_unstable_write(this, fd->inode)) { /* don't care. we only wanted to CLEAR the bit */ } local->transaction.wind = afr_fsync_wind; local->transaction.unwind = afr_fsync_unwind; local->transaction.main_frame = frame; ret = afr_transaction(transaction_frame, this, AFR_DATA_TRANSACTION); if (ret < 0) { op_errno = -ret; goto out; } return 0; out: if (transaction_frame) AFR_STACK_DESTROY(transaction_frame); AFR_STACK_UNWIND(fsync, frame, -1, op_errno, NULL, NULL, NULL); return 0; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-transaction.c0000644000000000000000000000013114522202451024332 xustar000000000000000029 mtime=1699284265.62002729 30 atime=1699284265.619027287 30 ctime=1699284301.117134207 glusterfs-11.1/xlators/cluster/afr/src/afr-transaction.c0000664000175100017510000024452714522202451024630 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "afr-transaction.h" #include "afr-self-heal.h" #include "afr-messages.h" #include typedef enum { AFR_TRANSACTION_PRE_OP, AFR_TRANSACTION_POST_OP, } afr_xattrop_type_t; static void afr_lock_resume_shared(struct list_head *list); static void afr_post_op_handle_success(call_frame_t *frame, xlator_t *this); static void afr_post_op_handle_failure(call_frame_t *frame, xlator_t *this, int op_errno); static int afr_internal_lock_finish(call_frame_t *frame, xlator_t *this); static void __afr_transaction_wake_shared(afr_local_t *local, struct list_head *shared); static void afr_changelog_post_op_do(call_frame_t *frame, xlator_t *this); static int afr_changelog_post_op_safe(call_frame_t *frame, xlator_t *this); static gf_boolean_t afr_changelog_pre_op_uninherit(call_frame_t *frame, xlator_t *this); static gf_boolean_t afr_changelog_pre_op_update(call_frame_t *frame, xlator_t *this); static int afr_changelog_call_count(afr_transaction_type type, unsigned char *pre_op_subvols, unsigned char *failed_subvols, unsigned int child_count); static int afr_changelog_do(call_frame_t *frame, xlator_t *this, dict_t *xattr, afr_changelog_resume_t changelog_resume, afr_xattrop_type_t op); static void afr_ta_decide_post_op_state(call_frame_t *frame, xlator_t *this); static int afr_ta_post_op_do(void *opaque); static int afr_ta_post_op_synctask(xlator_t *this, afr_local_t *local); static int afr_changelog_post_op_done(call_frame_t *frame, xlator_t *this); static void afr_changelog_post_op_fail(call_frame_t *frame, xlator_t *this, int op_errno); void afr_ta_locked_priv_invalidate(afr_private_t *priv) { priv->ta_bad_child_index = AFR_CHILD_UNKNOWN; priv->release_ta_notify_dom_lock = _gf_false; priv->ta_notify_dom_lock_offset = 0; } static void afr_ta_process_waitq(xlator_t *this) { afr_local_t *entry = NULL; afr_private_t *priv = this->private; struct list_head waitq = { 0, }; INIT_LIST_HEAD(&waitq); LOCK(&priv->lock); list_splice_init(&priv->ta_waitq, &waitq); UNLOCK(&priv->lock); list_for_each_entry(entry, &waitq, ta_waitq) { afr_ta_decide_post_op_state(entry->transaction.frame, this); } } int afr_ta_lock_release_done(int ret, call_frame_t *ta_frame, void *opaque) { afr_ta_process_waitq(ta_frame->this); STACK_DESTROY(ta_frame->root); return 0; } int afr_release_notify_lock_for_ta(void *opaque) { xlator_t *this = NULL; afr_private_t *priv = NULL; loc_t loc = { 0, }; struct gf_flock flock = { 0, }; int ret = -1; this = (xlator_t *)opaque; priv = this->private; ret = afr_fill_ta_loc(this, &loc, _gf_true); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to populate loc for thin-arbiter."); goto out; } flock.l_type = F_UNLCK; flock.l_start = priv->ta_notify_dom_lock_offset; flock.l_len = 1; ret = syncop_inodelk(priv->children[THIN_ARBITER_BRICK_INDEX], AFR_TA_DOM_NOTIFY, &loc, F_SETLK, &flock, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to unlock AFR_TA_DOM_NOTIFY lock."); } LOCK(&priv->lock); { afr_ta_locked_priv_invalidate(priv); } UNLOCK(&priv->lock); out: loc_wipe(&loc); return ret; } static void gf_zero_fill_stat(struct iatt *buf) { buf->ia_nlink = 0; buf->ia_ctime = 0; } void afr_zero_fill_stat(afr_local_t *local) { if (!local) return; if (local->transaction.type == AFR_DATA_TRANSACTION || local->transaction.type == AFR_METADATA_TRANSACTION) { gf_zero_fill_stat(&local->cont.inode_wfop.prebuf); gf_zero_fill_stat(&local->cont.inode_wfop.postbuf); } else if (local->transaction.type == AFR_ENTRY_TRANSACTION || local->transaction.type == AFR_ENTRY_RENAME_TRANSACTION) { gf_zero_fill_stat(&local->cont.dir_fop.buf); gf_zero_fill_stat(&local->cont.dir_fop.preparent); gf_zero_fill_stat(&local->cont.dir_fop.postparent); if (local->transaction.type == AFR_ENTRY_TRANSACTION) return; gf_zero_fill_stat(&local->cont.dir_fop.prenewparent); gf_zero_fill_stat(&local->cont.dir_fop.postnewparent); } } /* In case of errors afr needs to choose which xdata from lower xlators it needs * to unwind with. The way it is done is by checking if there are * any good subvols which failed. Give preference to errnos other than * ENOTCONN even if the child is source */ void afr_pick_error_xdata(afr_local_t *local, unsigned int child_count, inode_t *inode1, unsigned char *readable1, inode_t *inode2, unsigned char *readable2) { int s = -1; /*selection*/ int i = 0; unsigned char *readable = NULL; if (local->xdata_rsp) { dict_unref(local->xdata_rsp); local->xdata_rsp = NULL; } readable = alloca0(child_count * sizeof(*readable)); if (inode2 && readable2) { /*rename fop*/ AFR_INTERSECT(readable, readable1, readable2, child_count); } else { memcpy(readable, readable1, sizeof(*readable) * child_count); } for (i = 0; i < child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret >= 0) continue; if (local->replies[i].op_errno == ENOTCONN) continue; /*Order is important in the following condition*/ if ((s < 0) || (!readable[s] && readable[i])) s = i; } if (s != -1 && local->replies[s].xdata) { local->xdata_rsp = dict_ref(local->replies[s].xdata); } else if (s == -1) { for (i = 0; i < child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret >= 0) continue; if (!local->replies[i].xdata) continue; local->xdata_rsp = dict_ref(local->replies[i].xdata); break; } } } gf_boolean_t afr_needs_changelog_update(afr_local_t *local) { if (local->transaction.type == AFR_DATA_TRANSACTION) return _gf_true; if (!local->optimistic_change_log) return _gf_true; return _gf_false; } static gf_boolean_t afr_changelog_has_quorum(afr_local_t *local, xlator_t *this) { afr_private_t *priv = NULL; int i = 0; unsigned char *success_children = NULL; priv = this->private; success_children = alloca0(priv->child_count); for (i = 0; i < priv->child_count; i++) { if (!local->transaction.failed_subvols[i]) { success_children[i] = 1; } } if (afr_has_quorum(success_children, priv, NULL)) { return _gf_true; } return _gf_false; } static gf_boolean_t afr_is_write_subvol_valid(call_frame_t *frame, xlator_t *this) { int i = 0; afr_local_t *local = NULL; afr_private_t *priv = NULL; uint64_t write_subvol = 0; unsigned char *writable = NULL; uint16_t datamap = 0; local = frame->local; priv = this->private; writable = alloca0(priv->child_count); write_subvol = afr_write_subvol_get(frame, this); datamap = (write_subvol & 0x00000000ffff0000) >> 16; for (i = 0; i < priv->child_count; i++) { if (datamap & (1 << i)) writable[i] = 1; if (writable[i] && !local->transaction.failed_subvols[i]) return _gf_true; } return _gf_false; } int afr_transaction_fop(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int call_count = -1; unsigned char *failed_subvols = NULL; int i = 0; local = frame->local; priv = this->private; failed_subvols = local->transaction.failed_subvols; call_count = priv->child_count - AFR_COUNT(failed_subvols, priv->child_count); /* Fail if pre-op did not succeed on quorum no. of bricks. */ if (!afr_changelog_has_quorum(local, this) || !call_count) { local->op_ret = -1; /* local->op_errno is already captured in changelog cbk. */ afr_transaction_resume(frame, this); return 0; } /* Fail if at least one writeable brick isn't up.*/ if (local->transaction.type == AFR_DATA_TRANSACTION && !afr_is_write_subvol_valid(frame, this)) { local->op_ret = -1; local->op_errno = EIO; afr_transaction_resume(frame, this); return 0; } local->call_count = call_count; for (i = 0; i < priv->child_count; i++) { if (local->transaction.pre_op[i] && !failed_subvols[i]) { local->transaction.wind(frame, this, i); if (!--call_count) break; } } return 0; } static int afr_transaction_done(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; gf_boolean_t unwind = _gf_false; afr_lock_t *lock = NULL; afr_local_t *lock_local = NULL; priv = this->private; local = frame->local; if (priv->consistent_metadata) { LOCK(&frame->lock); { unwind = (local->transaction.main_frame != NULL); } UNLOCK(&frame->lock); if (unwind) /*It definitely did post-op*/ afr_zero_fill_stat(local); } if (local->transaction.do_eager_unlock) { lock = &local->inode_ctx->lock[local->transaction.type]; LOCK(&local->inode->lock); { lock->acquired = _gf_false; lock->release = _gf_false; list_splice_init(&lock->frozen, &lock->waiting); if (list_empty(&lock->waiting)) goto unlock; lock_local = list_entry(lock->waiting.next, afr_local_t, transaction.wait_list); list_del_init(&lock_local->transaction.wait_list); list_add(&lock_local->transaction.owner_list, &lock->owners); } unlock: UNLOCK(&local->inode->lock); } if (lock_local) { afr_lock(lock_local->transaction.frame, lock_local->transaction.frame->this); } local->transaction.unwind(frame, this); GF_ASSERT(list_empty(&local->transaction.owner_list)); GF_ASSERT(list_empty(&local->transaction.wait_list)); AFR_STACK_DESTROY(frame); return 0; } static void afr_lock_fail_shared(afr_local_t *local, struct list_head *list) { afr_local_t *each = NULL; while (!list_empty(list)) { each = list_entry(list->next, afr_local_t, transaction.wait_list); list_del_init(&each->transaction.wait_list); each->op_ret = -1; each->op_errno = local->op_errno; afr_transaction_done(each->transaction.frame, each->transaction.frame->this); } } static void afr_handle_lock_acquire_failure(afr_local_t *local) { struct list_head shared; afr_lock_t *lock = NULL; if (!local->transaction.eager_lock_on) goto out; lock = &local->inode_ctx->lock[local->transaction.type]; INIT_LIST_HEAD(&shared); LOCK(&local->inode->lock); { lock->release = _gf_true; list_splice_init(&lock->waiting, &shared); } UNLOCK(&local->inode->lock); afr_lock_fail_shared(local, &shared); local->transaction.do_eager_unlock = _gf_true; out: local->internal_lock.lock_cbk = afr_transaction_done; afr_unlock(local->transaction.frame, local->transaction.frame->this); } call_frame_t * afr_transaction_detach_fop_frame(call_frame_t *frame) { afr_local_t *local = NULL; call_frame_t *fop_frame = NULL; local = frame->local; afr_handle_inconsistent_fop(frame, &local->op_ret, &local->op_errno); LOCK(&frame->lock); { fop_frame = local->transaction.main_frame; local->transaction.main_frame = NULL; } UNLOCK(&frame->lock); return fop_frame; } static void afr_save_lk_owner(call_frame_t *frame) { afr_local_t *local = NULL; local = frame->local; lk_owner_copy(&local->saved_lk_owner, &frame->root->lk_owner); } static void afr_restore_lk_owner(call_frame_t *frame) { afr_local_t *local = NULL; local = frame->local; lk_owner_copy(&frame->root->lk_owner, &local->saved_lk_owner); } void __mark_all_success(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int i; local = frame->local; priv = this->private; for (i = 0; i < priv->child_count; i++) { local->transaction.failed_subvols[i] = 0; } } static void afr_compute_pre_op_sources(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; afr_transaction_type type = -1; dict_t *xdata = NULL; int **matrix = NULL; int idx = -1; int i = 0; int j = 0; priv = this->private; local = frame->local; type = local->transaction.type; idx = afr_index_for_transaction_type(type); matrix = ALLOC_MATRIX(priv->child_count, int); for (i = 0; i < priv->child_count; i++) { if (!local->transaction.changelog_xdata[i]) continue; xdata = local->transaction.changelog_xdata[i]; afr_selfheal_fill_matrix(this, matrix, i, idx, xdata); } memset(local->transaction.pre_op_sources, 1, priv->child_count); /*If lock or pre-op failed on a brick, it is not a source. */ for (i = 0; i < priv->child_count; i++) { if (local->transaction.failed_subvols[i]) local->transaction.pre_op_sources[i] = 0; } /* If brick is blamed by others, it is not a source. */ for (i = 0; i < priv->child_count; i++) for (j = 0; j < priv->child_count; j++) if (matrix[i][j] != 0) local->transaction.pre_op_sources[j] = 0; } static void afr_txn_arbitrate_fop(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int pre_op_sources_count = 0; int i = 0; priv = this->private; local = frame->local; afr_compute_pre_op_sources(frame, this); pre_op_sources_count = AFR_COUNT(local->transaction.pre_op_sources, priv->child_count); /* If arbiter is the only source, do not proceed. */ if (pre_op_sources_count < 2 && local->transaction.pre_op_sources[ARBITER_BRICK_INDEX]) { local->op_ret = -1; local->op_errno = ENOTCONN; for (i = 0; i < priv->child_count; i++) local->transaction.failed_subvols[i] = 1; } afr_transaction_fop(frame, this); return; } static int afr_transaction_perform_fop(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; int ret = 0; int failure_count = 0; struct list_head shared; afr_lock_t *lock = NULL; local = frame->local; priv = this->private; INIT_LIST_HEAD(&shared); if (local->transaction.type == AFR_DATA_TRANSACTION && !local->transaction.inherited) { ret = afr_write_subvol_set(frame, this); if (ret) { /*act as if operation failed on all subvols*/ local->op_ret = -1; local->op_errno = -ret; for (i = 0; i < priv->child_count; i++) local->transaction.failed_subvols[i] = 1; } } if (local->pre_op_compat) /* old mode, pre-op was done as afr_changelog_do() just now, before OP */ afr_changelog_pre_op_update(frame, this); if (!local->transaction.eager_lock_on || local->transaction.inherited) goto fop; failure_count = AFR_COUNT(local->transaction.failed_subvols, priv->child_count); if (failure_count == priv->child_count) { afr_handle_lock_acquire_failure(local); return 0; } else { lock = &local->inode_ctx->lock[local->transaction.type]; LOCK(&local->inode->lock); { lock->acquired = _gf_true; __afr_transaction_wake_shared(local, &shared); } UNLOCK(&local->inode->lock); } fop: /* Perform fops with the lk-owner from top xlator. * Eg: lk-owner of posix-lk and flush should be same, * flush cant clear the posix-lks without that lk-owner. */ afr_save_lk_owner(frame); lk_owner_copy(&frame->root->lk_owner, &local->transaction.main_frame->root->lk_owner); if (priv->arbiter_count == 1) { afr_txn_arbitrate_fop(frame, this); } else { afr_transaction_fop(frame, this); } afr_lock_resume_shared(&shared); return 0; } int afr_set_pending_dict(afr_private_t *priv, dict_t *xattr, int **pending) { int i = 0; int ret = 0; for (i = 0; i < priv->child_count; i++) { ret = dict_set_static_bin(xattr, priv->pending_key[i], pending[i], AFR_NUM_CHANGE_LOGS * sizeof(int)); /* 3 = data+metadata+entry */ if (ret) break; } return ret; } static void afr_ta_dom_lock_check_and_release(afr_ta_fop_state_t fop_state, xlator_t *this) { afr_private_t *priv = this->private; unsigned int inmem_count = 0; unsigned int onwire_count = 0; gf_boolean_t release = _gf_false; LOCK(&priv->lock); { /*Once we get notify lock release upcall notification, if any of the fop state counters are non-zero, we will not release the lock. */ onwire_count = priv->ta_on_wire_txn_count; inmem_count = priv->ta_in_mem_txn_count; switch (fop_state) { case TA_GET_INFO_FROM_TA_FILE: onwire_count = --priv->ta_on_wire_txn_count; break; case TA_INFO_IN_MEMORY_SUCCESS: case TA_INFO_IN_MEMORY_FAILED: inmem_count = --priv->ta_in_mem_txn_count; break; case TA_WAIT_FOR_NOTIFY_LOCK_REL: GF_ASSERT(0); break; case TA_SUCCESS: break; } release = priv->release_ta_notify_dom_lock; } UNLOCK(&priv->lock); if (inmem_count != 0 || release == _gf_false || onwire_count != 0) return; afr_ta_lock_release_synctask(this); } static void afr_ta_process_onwireq(afr_ta_fop_state_t fop_state, xlator_t *this) { afr_private_t *priv = this->private; afr_local_t *entry = NULL; int bad_child = AFR_CHILD_UNKNOWN; struct list_head onwireq = { 0, }; INIT_LIST_HEAD(&onwireq); LOCK(&priv->lock); { bad_child = priv->ta_bad_child_index; if (bad_child == AFR_CHILD_UNKNOWN) { /*The previous on-wire ta_post_op was a failure. Just dequeue *one element to wind on-wire again. */ entry = list_entry(priv->ta_onwireq.next, afr_local_t, ta_onwireq); list_del_init(&entry->ta_onwireq); } else { /* Prepare to process all fops based on bad_child_index. */ list_splice_init(&priv->ta_onwireq, &onwireq); } } UNLOCK(&priv->lock); if (entry) { afr_ta_post_op_synctask(this, entry); return; } else { while (!list_empty(&onwireq)) { entry = list_entry(onwireq.next, afr_local_t, ta_onwireq); list_del_init(&entry->ta_onwireq); if (entry->ta_failed_subvol == bad_child) { afr_post_op_handle_success(entry->transaction.frame, this); } else { afr_post_op_handle_failure(entry->transaction.frame, this, EIO); } } } } static int afr_changelog_post_op_done(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_internal_lock_t *int_lock = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; int_lock = &local->internal_lock; if (priv->thin_arbiter_count) { /*fop should not come here with TA_WAIT_FOR_NOTIFY_LOCK_REL state */ afr_ta_dom_lock_check_and_release(local->fop_state, this); } /* Fail the FOP if post-op did not succeed on quorum no. of bricks. */ if (!afr_changelog_has_quorum(local, this)) { local->op_ret = -1; /*local->op_errno is already captured in changelog cbk*/ } if (local->transaction.resume_stub) { call_resume(local->transaction.resume_stub); local->transaction.resume_stub = NULL; } int_lock->lock_cbk = afr_transaction_done; afr_unlock(frame, this); return 0; } static void afr_changelog_post_op_fail(call_frame_t *frame, xlator_t *this, int op_errno) { afr_local_t *local = frame->local; local->op_ret = -1; local->op_errno = op_errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, AFR_MSG_THIN_ARB, "Failing %s for gfid %s. Fop state is:%d", gf_fop_list[local->op], uuid_utoa(local->inode->gfid), local->fop_state); afr_changelog_post_op_done(frame, this); } unsigned char * afr_locked_nodes_get(afr_transaction_type type, afr_internal_lock_t *int_lock) { /*Because same set of subvols participate in all lockee * entities*/ return int_lock->lockee[0].locked_nodes; } static int afr_changelog_call_count(afr_transaction_type type, unsigned char *pre_op_subvols, unsigned char *failed_subvols, unsigned int child_count) { int i = 0; int call_count = 0; for (i = 0; i < child_count; i++) { if (pre_op_subvols[i] && !failed_subvols[i]) { call_count++; } } if (type == AFR_ENTRY_RENAME_TRANSACTION) call_count *= 2; return call_count; } gf_boolean_t afr_txn_nothing_failed(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int i = 0; local = frame->local; priv = this->private; if (priv->thin_arbiter_count) { /* We need to perform post-op even if 1 data brick was down * before the txn started.*/ if (AFR_COUNT(local->transaction.failed_subvols, priv->child_count)) return _gf_false; } for (i = 0; i < priv->child_count; i++) { if (local->transaction.pre_op[i] && local->transaction.failed_subvols[i]) return _gf_false; } return _gf_true; } static void afr_handle_symmetric_errors(call_frame_t *frame, xlator_t *this) { if (afr_is_symmetric_error(frame, this)) __mark_all_success(frame, this); } gf_boolean_t afr_has_quorum(unsigned char *subvols, afr_private_t *priv, call_frame_t *frame) { unsigned int quorum_count = 0; unsigned int up_children_count = 0; up_children_count = AFR_COUNT(subvols, priv->child_count); if (afr_lookup_has_quorum(frame, up_children_count)) return _gf_true; if (priv->quorum_count == AFR_QUORUM_AUTO) { /* * Special case for auto-quorum with an even number of nodes. * * A replica set with even count N can only handle the same * number of failures as odd N-1 before losing "vanilla" * quorum, and the probability of more simultaneous failures is * actually higher. For example, with a 1% chance of failure * we'd have a 0.03% chance of two simultaneous failures with * N=3 but a 0.06% chance with N=4. However, the special case * is necessary for N=2 because there's no real quorum in that * case (i.e. can't normally survive *any* failures). In that * case, we treat the first node as a tie-breaker, allowing * quorum to be retained in some cases while still honoring the * all-important constraint that there can not simultaneously * be two partitioned sets of nodes each believing they have * quorum. Of two equally sized sets, the one without that * first node will lose. * * It turns out that the special case is beneficial for higher * values of N as well. Continuing the example above, the * probability of losing quorum with N=4 and this type of * quorum is (very) slightly lower than with N=3 and vanilla * quorum. The difference becomes even more pronounced with * higher N. Therefore, even though such replica counts are * unlikely to be seen in practice, we might as well use the * "special" quorum then as well. */ if ((up_children_count * 2) == priv->child_count) { return subvols[0]; } } if (priv->quorum_count == AFR_QUORUM_AUTO) { quorum_count = priv->child_count / 2 + 1; } else { quorum_count = priv->quorum_count; } if (up_children_count >= quorum_count) return _gf_true; return _gf_false; } static gf_boolean_t afr_has_fop_quorum(call_frame_t *frame) { xlator_t *this = frame->this; afr_local_t *local = frame->local; unsigned char *locked_nodes = NULL; locked_nodes = afr_locked_nodes_get(local->transaction.type, &local->internal_lock); return afr_has_quorum(locked_nodes, this->private, NULL); } static gf_boolean_t afr_has_fop_cbk_quorum(call_frame_t *frame) { afr_local_t *local = frame->local; xlator_t *this = frame->this; afr_private_t *priv = this->private; unsigned char *success = alloca0(priv->child_count); int i = 0; for (i = 0; i < priv->child_count; i++) { if (local->transaction.pre_op[i]) if (!local->transaction.failed_subvols[i]) success[i] = 1; } return afr_has_quorum(success, priv, NULL); } static gf_boolean_t afr_need_dirty_marking(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = this->private; afr_local_t *local = NULL; gf_boolean_t need_dirty = _gf_false; local = frame->local; if (!priv->quorum_count || !local->optimistic_change_log) return _gf_false; if (local->transaction.type == AFR_DATA_TRANSACTION || local->transaction.type == AFR_METADATA_TRANSACTION) return _gf_false; if (AFR_COUNT(local->transaction.failed_subvols, priv->child_count) == priv->child_count) return _gf_false; if (!afr_has_fop_cbk_quorum(frame)) need_dirty = _gf_true; return need_dirty; } static void afr_handle_quorum(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; const char *file = NULL; uuid_t gfid = {0}; local = frame->local; priv = frame->this->private; if (priv->quorum_count == 0) return; /* If the fop already failed return right away to preserve errno */ if (local->op_ret == -1) return; /* * Network split may happen just after the fops are unwound, so check * if the fop succeeded in a way it still follows quorum. If it doesn't, * mark the fop as failure, mark the changelogs so it reflects that * failure. * * Scenario: * There are 3 mounts on 3 machines(node1, node2, node3) all writing to * single file. Network split happened in a way that node1 can't see * node2, node3. Node2, node3 both of them can't see node1. Now at the * time of sending write all the bricks are up. Just after write fop is * wound on node1, network split happens. Node1 thinks write fop failed * on node2, node3 so marks pending changelog for those 2 extended * attributes on node1. Node2, node3 thinks writes failed on node1 so * they mark pending changelog for node1. When the network is stable * again the file already is in split-brain. These checks prevent * marking pending changelog on other subvolumes if the fop doesn't * succeed in a way it is still following quorum. So with this fix what * is happening is, node1 will have all pending changelog(FOOL) because * the write succeeded only on node1 but failed on node2, node3 so * instead of marking pending changelogs on node2, node3 it just treats * the fop as failure and goes into DIRTY state. Where as node2, node3 * say they are sources and have pending changelog to node1 so there is * no split-brain with the fix. The problem is eliminated completely. */ if (afr_has_fop_cbk_quorum(frame)) return; if (afr_need_dirty_marking(frame, this)) goto set_response; for (i = 0; i < priv->child_count; i++) { if (local->transaction.pre_op[i]) afr_transaction_fop_failed(local, i); } set_response: local->op_ret = -1; local->op_errno = afr_final_errno(local, priv); if (local->op_errno == 0) local->op_errno = afr_quorum_errno(priv); if (local->fd) { gf_uuid_copy(gfid, local->fd->inode->gfid); file = uuid_utoa(gfid); } else { loc_path(&local->loc, local->loc.name); file = local->loc.path; } gf_msg(frame->this->name, GF_LOG_WARNING, local->op_errno, AFR_MSG_QUORUM_FAIL, "%s: Failing %s as quorum is not met", file, gf_fop_list[local->op]); switch (local->transaction.type) { case AFR_ENTRY_TRANSACTION: case AFR_ENTRY_RENAME_TRANSACTION: afr_pick_error_xdata(local, priv->child_count, local->parent, local->readable, local->parent2, local->readable2); break; default: afr_pick_error_xdata(local, priv->child_count, local->inode, local->readable, NULL, NULL); break; } } int afr_fill_ta_loc(xlator_t *this, loc_t *loc, gf_boolean_t is_gfid_based_fop) { afr_private_t *priv = NULL; priv = this->private; loc->parent = inode_ref(this->itable->root); gf_uuid_copy(loc->pargfid, loc->parent->gfid); loc->name = priv->pending_key[THIN_ARBITER_BRICK_INDEX]; if (is_gfid_based_fop && gf_uuid_is_null(priv->ta_gfid)) { /* Except afr_ta_id_file_check() which is path based, all other gluster * FOPS need gfid.*/ return -EINVAL; } gf_uuid_copy(loc->gfid, priv->ta_gfid); loc->inode = inode_new(loc->parent->table); if (!loc->inode) { loc_wipe(loc); return -ENOMEM; } return 0; } static int afr_ta_post_op_done(int ret, call_frame_t *frame, void *opaque) { xlator_t *this = NULL; afr_local_t *local = NULL; call_frame_t *txn_frame = NULL; afr_ta_fop_state_t fop_state; local = (afr_local_t *)opaque; fop_state = local->fop_state; txn_frame = local->transaction.frame; this = frame->this; if (ret == 0) { /*Mark pending xattrs on the up data brick.*/ afr_post_op_handle_success(txn_frame, this); } else { afr_post_op_handle_failure(txn_frame, this, -ret); } STACK_DESTROY(frame->root); afr_ta_process_onwireq(fop_state, this); return 0; } static int ** afr_set_changelog_xattr(afr_private_t *priv, unsigned char *pending, dict_t *xattr, afr_local_t *local) { int **changelog = NULL; int idx = 0; int ret = 0; int i; uint32_t hton32_1; if (local->is_new_entry == _gf_true) { changelog = afr_mark_pending_changelog(priv, pending, xattr, local->cont.dir_fop.buf.ia_type); } else { idx = afr_index_for_transaction_type(local->transaction.type); changelog = afr_matrix_create(priv->child_count, AFR_NUM_CHANGE_LOGS); if (!changelog) { goto out; } hton32_1 = htobe32(1); for (i = 0; i < priv->child_count; i++) { if (local->transaction.failed_subvols[i]) changelog[i][idx] = hton32_1; } ret = afr_set_pending_dict(priv, xattr, changelog); if (ret < 0) { afr_matrix_cleanup(changelog, priv->child_count); return NULL; } } out: return changelog; } static void afr_ta_locked_xattrop_validate(afr_private_t *priv, afr_local_t *local, gf_boolean_t *valid) { if (priv->ta_event_gen > local->ta_event_gen) { /* We can't trust the ta's response anymore.*/ afr_ta_locked_priv_invalidate(priv); *valid = _gf_false; return; } return; } static int afr_ta_post_op_do(void *opaque) { afr_local_t *local = NULL; afr_private_t *priv = NULL; xlator_t *this = NULL; dict_t *xattr = NULL; unsigned char *pending = NULL; int **changelog = NULL; int failed_subvol = -1; int success_subvol = -1; loc_t loc = { 0, }; int i = 0; int ret = 0; gf_boolean_t valid = _gf_true; local = (afr_local_t *)opaque; this = local->transaction.frame->this; priv = this->private; ret = afr_fill_ta_loc(this, &loc, _gf_true); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Failed to populate loc for thin-arbiter."); goto out; } xattr = dict_new(); if (!xattr) { ret = -ENOMEM; goto out; } pending = alloca0(priv->child_count); for (i = 0; i < priv->child_count; i++) { if (local->transaction.failed_subvols[i]) { pending[i] = 1; failed_subvol = i; } else { success_subvol = i; } } changelog = afr_set_changelog_xattr(priv, pending, xattr, local); if (!changelog) { ret = -ENOMEM; goto out; } ret = afr_ta_post_op_lock(this, &loc); if (ret) goto out; ret = syncop_xattrop(priv->children[THIN_ARBITER_BRICK_INDEX], &loc, GF_XATTROP_ADD_ARRAY, xattr, NULL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, "Post-op on thin-arbiter id file %s failed for gfid %s.", priv->pending_key[THIN_ARBITER_BRICK_INDEX], uuid_utoa(local->inode->gfid)); } LOCK(&priv->lock); { if (ret == 0) { priv->ta_bad_child_index = failed_subvol; } else if (ret == -EINVAL) { priv->ta_bad_child_index = success_subvol; ret = -EIO; /* TA failed the fop. Return EIO to application. */ } afr_ta_locked_xattrop_validate(priv, local, &valid); } UNLOCK(&priv->lock); if (valid == _gf_false) { gf_msg(this->name, GF_LOG_ERROR, EIO, AFR_MSG_THIN_ARB, "Post-op on thin-arbiter id file %s for gfid %s invalidated due " "to event-gen mismatch.", priv->pending_key[THIN_ARBITER_BRICK_INDEX], uuid_utoa(local->inode->gfid)); ret = -EIO; } afr_ta_post_op_unlock(this, &loc); out: if (xattr) dict_unref(xattr); if (changelog) afr_matrix_cleanup(changelog, priv->child_count); loc_wipe(&loc); return ret; } static int afr_ta_post_op_synctask(xlator_t *this, afr_local_t *local) { call_frame_t *ta_frame = NULL; int ret = 0; ta_frame = afr_ta_frame_create(this); if (!ta_frame) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_THIN_ARB, "Failed to create ta_frame"); goto err; } ret = synctask_new(this->ctx->env, afr_ta_post_op_do, afr_ta_post_op_done, ta_frame, local); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_THIN_ARB, "Failed to launch post-op on thin arbiter for gfid %s", uuid_utoa(local->inode->gfid)); STACK_DESTROY(ta_frame->root); goto err; } return ret; err: afr_changelog_post_op_fail(local->transaction.frame, this, ENOMEM); return ret; } static void afr_ta_set_fop_state(afr_private_t *priv, afr_local_t *local, int *on_wire_count) { LOCK(&priv->lock); { if (priv->release_ta_notify_dom_lock == _gf_true) { /* Put the fop in waitq until notify dom lock is released.*/ local->fop_state = TA_WAIT_FOR_NOTIFY_LOCK_REL; list_add_tail(&local->ta_waitq, &priv->ta_waitq); } else if (priv->ta_bad_child_index == AFR_CHILD_UNKNOWN) { /* Post-op on thin-arbiter to decide success/failure. */ local->fop_state = TA_GET_INFO_FROM_TA_FILE; *on_wire_count = ++priv->ta_on_wire_txn_count; if (*on_wire_count > 1) { /*Avoid sending multiple on-wire post-ops on TA*/ list_add_tail(&local->ta_onwireq, &priv->ta_onwireq); } } else if (local->ta_failed_subvol == priv->ta_bad_child_index) { /* Post-op on TA not needed as the fop failed on the in-memory bad * brick. Just mark pending xattrs on the good data brick.*/ local->fop_state = TA_INFO_IN_MEMORY_SUCCESS; priv->ta_in_mem_txn_count++; } else { /* Post-op on TA not needed as the fop succeeded only on the * in-memory bad data brick and not the good one. Fail the fop.*/ local->fop_state = TA_INFO_IN_MEMORY_FAILED; priv->ta_in_mem_txn_count++; } } UNLOCK(&priv->lock); } static void afr_ta_fill_failed_subvol(afr_private_t *priv, afr_local_t *local) { int i = 0; for (i = 0; i < priv->child_count; i++) { if (local->transaction.failed_subvols[i]) { local->ta_failed_subvol = i; break; } } } static void afr_post_op_handle_success(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; local = frame->local; if (local->is_new_entry == _gf_true) { afr_mark_new_entry_changelog(frame, this); } afr_changelog_post_op_do(frame, this); return; } static void afr_post_op_handle_failure(call_frame_t *frame, xlator_t *this, int op_errno) { afr_changelog_post_op_fail(frame, this, op_errno); return; } static void afr_ta_decide_post_op_state(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int on_wire_count = 0; priv = this->private; local = frame->local; afr_ta_set_fop_state(priv, local, &on_wire_count); switch (local->fop_state) { case TA_GET_INFO_FROM_TA_FILE: if (on_wire_count == 1) afr_ta_post_op_synctask(this, local); /*else, fop is queued in ta_onwireq.*/ break; case TA_WAIT_FOR_NOTIFY_LOCK_REL: /*Post releasing the notify lock, we will act on this queue*/ break; case TA_INFO_IN_MEMORY_SUCCESS: afr_post_op_handle_success(frame, this); break; case TA_INFO_IN_MEMORY_FAILED: afr_post_op_handle_failure(frame, this, EIO); break; default: break; } return; } static void afr_handle_failure_using_thin_arbiter(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = this->private; afr_local_t *local = frame->local; afr_ta_fill_failed_subvol(priv, local); gf_msg_debug(this->name, 0, "Fop failed on data brick (%s) for gfid=%s. " "ta info needed to decide fop result.", priv->children[local->ta_failed_subvol]->name, uuid_utoa(local->inode->gfid)); afr_ta_decide_post_op_state(frame, this); } static void afr_changelog_post_op_do(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = this->private; afr_local_t *local = NULL; dict_t *xattr = NULL; int i = 0; int ret = 0; int idx = 0; int nothing_failed = 1; gf_boolean_t need_undirty = _gf_false; uint32_t hton32_1; afr_handle_quorum(frame, this); local = frame->local; idx = afr_index_for_transaction_type(local->transaction.type); xattr = dict_new(); if (!xattr) { afr_changelog_post_op_fail(frame, this, ENOMEM); goto out; } nothing_failed = afr_txn_nothing_failed(frame, this); if (afr_changelog_pre_op_uninherit(frame, this)) need_undirty = _gf_false; else need_undirty = _gf_true; hton32_1 = htobe32(1); if (local->op_ret < 0 && !nothing_failed) { if (afr_need_dirty_marking(frame, this)) { local->dirty[idx] = hton32_1; goto set_dirty; } afr_changelog_post_op_done(frame, this); goto out; } if (nothing_failed && !need_undirty) { afr_changelog_post_op_done(frame, this); goto out; } if (local->transaction.in_flight_sb) { afr_changelog_post_op_fail(frame, this, local->transaction.in_flight_sb_errno); goto out; } for (i = 0; i < priv->child_count; i++) { if (local->transaction.failed_subvols[i]) local->pending[i][idx] = hton32_1; } ret = afr_set_pending_dict(priv, xattr, local->pending); if (ret < 0) { afr_changelog_post_op_fail(frame, this, ENOMEM); goto out; } if (need_undirty) local->dirty[idx] = htobe32(-1); else local->dirty[idx] = 0; set_dirty: ret = dict_set_static_bin(xattr, AFR_DIRTY, local->dirty, sizeof(int) * AFR_NUM_CHANGE_LOGS); if (ret) { afr_changelog_post_op_fail(frame, this, ENOMEM); goto out; } afr_changelog_do(frame, this, xattr, afr_changelog_post_op_done, AFR_TRANSACTION_POST_OP); out: if (xattr) dict_unref(xattr); return; } static int afr_changelog_post_op_now(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int failed_count = 0; priv = this->private; local = frame->local; if (priv->thin_arbiter_count) { failed_count = AFR_COUNT(local->transaction.failed_subvols, priv->child_count); if (failed_count == 1) { afr_handle_failure_using_thin_arbiter(frame, this); return 0; } else { /* Txn either succeeded or failed on both data bricks. Let * post_op_do handle it as the case might be. */ } } afr_changelog_post_op_do(frame, this); return 0; } static gf_boolean_t afr_changelog_pre_op_uninherit(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; afr_inode_ctx_t *ctx = NULL; int i = 0; gf_boolean_t ret = _gf_false; int type = 0; local = frame->local; priv = this->private; ctx = local->inode_ctx; type = afr_index_for_transaction_type(local->transaction.type); if (type != AFR_DATA_TRANSACTION) return !local->transaction.dirtied; if (local->transaction.no_uninherit) return _gf_false; /* This function must be idempotent. So check if we were called before and return the same answer again. It is important to keep this function idempotent for the call in afr_changelog_post_op_safe() to not have side effects on the call from afr_changelog_post_op_now() */ if (local->transaction.uninherit_done) return local->transaction.uninherit_value; LOCK(&local->inode->lock); { for (i = 0; i < priv->child_count; i++) { if (local->transaction.pre_op[i] != ctx->pre_op_done[type][i]) { ret = !local->transaction.dirtied; goto unlock; } } if (ctx->inherited[type]) { ret = _gf_true; ctx->inherited[type]--; } else if (ctx->on_disk[type]) { ret = _gf_false; ctx->on_disk[type]--; } else { /* ASSERT */ ret = _gf_false; } if (!ctx->inherited[type] && !ctx->on_disk[type]) { for (i = 0; i < priv->child_count; i++) ctx->pre_op_done[type][i] = 0; } } unlock: UNLOCK(&local->inode->lock); local->transaction.uninherit_done = _gf_true; local->transaction.uninherit_value = ret; return ret; } static gf_boolean_t afr_changelog_pre_op_inherit(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; gf_boolean_t ret = _gf_false; int type = 0; local = frame->local; priv = this->private; if (local->transaction.type != AFR_DATA_TRANSACTION) return _gf_false; type = afr_index_for_transaction_type(local->transaction.type); LOCK(&local->inode->lock); { if (!local->inode_ctx->on_disk[type]) { /* nothing to inherit yet */ ret = _gf_false; goto unlock; } for (i = 0; i < priv->child_count; i++) { if (local->transaction.pre_op[i] != local->inode_ctx->pre_op_done[type][i]) { /* either inherit exactly, or don't */ ret = _gf_false; goto unlock; } } local->inode_ctx->inherited[type]++; ret = _gf_true; local->transaction.inherited = _gf_true; } unlock: UNLOCK(&local->inode->lock); return ret; } static gf_boolean_t afr_changelog_pre_op_update(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; gf_boolean_t ret = _gf_false; int type = 0; local = frame->local; priv = this->private; if (local->transaction.type == AFR_ENTRY_TRANSACTION || local->transaction.type == AFR_ENTRY_RENAME_TRANSACTION) return _gf_false; if (local->transaction.inherited) /* was already inherited in afr_changelog_pre_op */ return _gf_false; if (!local->transaction.dirtied) return _gf_false; if (!afr_txn_nothing_failed(frame, this)) return _gf_false; type = afr_index_for_transaction_type(local->transaction.type); ret = _gf_false; LOCK(&local->inode->lock); { if (!local->inode_ctx->on_disk[type]) { for (i = 0; i < priv->child_count; i++) local->inode_ctx->pre_op_done[type][i] = (!local->transaction.failed_subvols[i]); } else { for (i = 0; i < priv->child_count; i++) if (local->inode_ctx->pre_op_done[type][i] != (!local->transaction.failed_subvols[i])) { local->transaction.no_uninherit = 1; goto unlock; } } local->inode_ctx->on_disk[type]++; ret = _gf_true; } unlock: UNLOCK(&local->inode->lock); return ret; } static int afr_changelog_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { afr_local_t *local = NULL; int call_count = -1; int child_index = -1; local = frame->local; child_index = (long)cookie; if (op_ret == -1) { local->op_errno = op_errno; afr_transaction_fop_failed(local, child_index); } if (xattr) local->transaction.changelog_xdata[child_index] = dict_ref(xattr); call_count = afr_frame_return(frame); if (call_count == 0) { local->transaction.changelog_resume(frame, this); } return 0; } static void afr_changelog_populate_xdata(call_frame_t *frame, afr_xattrop_type_t op, dict_t **xdata, dict_t **newloc_xdata) { int i = 0; int ret = 0; char *key = NULL; int keylen = 0; const char *name = NULL; dict_t *xdata1 = NULL; dict_t *xdata2 = NULL; xlator_t *this = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; gf_boolean_t need_entry_key_set = _gf_true; local = frame->local; this = THIS; priv = this->private; if (local->transaction.type == AFR_DATA_TRANSACTION || local->transaction.type == AFR_METADATA_TRANSACTION) goto out; if (!priv->esh_granular) goto out; xdata1 = dict_new(); if (!xdata1) goto out; name = local->loc.name; if (local->op == GF_FOP_LINK) name = local->newloc.name; switch (op) { case AFR_TRANSACTION_PRE_OP: key = GF_XATTROP_ENTRY_IN_KEY; break; case AFR_TRANSACTION_POST_OP: if (afr_txn_nothing_failed(frame, this)) { key = GF_XATTROP_ENTRY_OUT_KEY; for (i = 0; i < priv->child_count; i++) { if (!local->transaction.failed_subvols[i]) continue; need_entry_key_set = _gf_false; break; } /* If the transaction itself did not fail and there * are no failed subvolumes, check whether the fop * failed due to a symmetric error. If it did, do * not set the ENTRY_OUT xattr which would end up * deleting a name index which was created possibly by * an earlier entry txn that may have failed on some * of the sub-volumes. */ if (local->op_ret) need_entry_key_set = _gf_false; } else { key = GF_XATTROP_ENTRY_IN_KEY; } break; } if (need_entry_key_set) { keylen = strlen(key); ret = dict_set_strn(xdata1, key, keylen, (char *)name); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_SET_FAILED, "%s/%s: Could not set %s key during xattrop", uuid_utoa(local->loc.pargfid), local->loc.name, key); if (local->transaction.type == AFR_ENTRY_RENAME_TRANSACTION) { xdata2 = dict_new(); if (!xdata2) goto out; ret = dict_set_strn(xdata2, key, keylen, (char *)local->newloc.name); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_SET_FAILED, "%s/%s: Could not set %s key during " "xattrop", uuid_utoa(local->newloc.pargfid), local->newloc.name, key); } } *xdata = xdata1; *newloc_xdata = xdata2; xdata1 = xdata2 = NULL; out: if (xdata1) dict_unref(xdata1); return; } static int afr_changelog_prepare(xlator_t *this, call_frame_t *frame, int *call_count, afr_changelog_resume_t changelog_resume, afr_xattrop_type_t op, dict_t **xdata, dict_t **newloc_xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; local = frame->local; priv = this->private; *call_count = afr_changelog_call_count( local->transaction.type, local->transaction.pre_op, local->transaction.failed_subvols, priv->child_count); if (*call_count == 0) { changelog_resume(frame, this); return -1; } afr_changelog_populate_xdata(frame, op, xdata, newloc_xdata); local->call_count = *call_count; local->transaction.changelog_resume = changelog_resume; return 0; } static int afr_changelog_do(call_frame_t *frame, xlator_t *this, dict_t *xattr, afr_changelog_resume_t changelog_resume, afr_xattrop_type_t op) { afr_local_t *local = NULL; afr_private_t *priv = NULL; dict_t *xdata = NULL; dict_t *newloc_xdata = NULL; int i = 0; int call_count = 0; int ret = 0; local = frame->local; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (local->transaction.changelog_xdata[i]) { dict_unref(local->transaction.changelog_xdata[i]); local->transaction.changelog_xdata[i] = NULL; } } ret = afr_changelog_prepare(this, frame, &call_count, changelog_resume, op, &xdata, &newloc_xdata); if (ret) return 0; for (i = 0; i < priv->child_count; i++) { if (!local->transaction.pre_op[i] || local->transaction.failed_subvols[i]) continue; switch (local->transaction.type) { case AFR_DATA_TRANSACTION: case AFR_METADATA_TRANSACTION: if (!local->fd) { STACK_WIND_COOKIE( frame, afr_changelog_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->xattrop, &local->loc, GF_XATTROP_ADD_ARRAY, xattr, xdata); } else { STACK_WIND_COOKIE( frame, afr_changelog_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->fxattrop, local->fd, GF_XATTROP_ADD_ARRAY, xattr, xdata); } break; case AFR_ENTRY_RENAME_TRANSACTION: STACK_WIND_COOKIE(frame, afr_changelog_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->xattrop, &local->transaction.new_parent_loc, GF_XATTROP_ADD_ARRAY, xattr, newloc_xdata); call_count--; /* fall through */ case AFR_ENTRY_TRANSACTION: if (local->fd) STACK_WIND_COOKIE( frame, afr_changelog_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->fxattrop, local->fd, GF_XATTROP_ADD_ARRAY, xattr, xdata); else STACK_WIND_COOKIE(frame, afr_changelog_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->xattrop, &local->transaction.parent_loc, GF_XATTROP_ADD_ARRAY, xattr, xdata); break; } if (!--call_count) break; } if (xdata) dict_unref(xdata); if (newloc_xdata) dict_unref(newloc_xdata); return 0; } static void afr_init_optimistic_changelog_for_txn(xlator_t *this, afr_local_t *local) { int locked_count = 0; afr_private_t *priv = NULL; priv = this->private; locked_count = AFR_COUNT(local->transaction.pre_op, priv->child_count); if (priv->optimistic_change_log && locked_count == priv->child_count) local->optimistic_change_log = 1; return; } int afr_changelog_pre_op(call_frame_t *frame, xlator_t *this) { afr_private_t *priv = this->private; int i = 0; int ret = 0; int call_count = 0; int op_errno = 0; afr_local_t *local = NULL; afr_internal_lock_t *int_lock = NULL; unsigned char *locked_nodes = NULL; int idx = -1; gf_boolean_t pre_nop = _gf_true; dict_t *xdata_req = NULL; local = frame->local; int_lock = &local->internal_lock; idx = afr_index_for_transaction_type(local->transaction.type); locked_nodes = afr_locked_nodes_get(local->transaction.type, int_lock); for (i = 0; i < priv->child_count; i++) { if (locked_nodes[i]) { local->transaction.pre_op[i] = 1; call_count++; } else { local->transaction.failed_subvols[i] = 1; } } afr_init_optimistic_changelog_for_txn(this, local); if (afr_changelog_pre_op_inherit(frame, this)) goto next; /* This condition should not be met with present code, as * transaction.done will be called if locks are not acquired on even a * single node. */ if (call_count == 0) { op_errno = ENOTCONN; goto err; } /* Check if the fop can be performed on at least * quorum number of nodes. */ if (priv->quorum_count && !afr_has_fop_quorum(frame)) { op_errno = int_lock->lock_op_errno; if (op_errno == 0) op_errno = afr_quorum_errno(priv); goto err; } xdata_req = dict_new(); if (!xdata_req) { op_errno = ENOMEM; goto err; } if (call_count < priv->child_count) pre_nop = _gf_false; /* Set an all-zero pending changelog so that in the cbk, we can get the * current on-disk values. In a replica 3 volume with arbiter enabled, * these values are needed to arrive at a go/ no-go of the fop phase to * avoid ending up in split-brain.*/ ret = afr_set_pending_dict(priv, xdata_req, local->pending); if (ret < 0) { op_errno = ENOMEM; goto err; } if (afr_needs_changelog_update(local)) { local->dirty[idx] = htobe32(1); ret = dict_set_static_bin(xdata_req, AFR_DIRTY, local->dirty, sizeof(int) * AFR_NUM_CHANGE_LOGS); if (ret) { op_errno = ENOMEM; goto err; } pre_nop = _gf_false; local->transaction.dirtied = 1; } if (pre_nop) goto next; if (!local->pre_op_compat) { dict_copy(xdata_req, local->xdata_req); goto next; } afr_changelog_do(frame, this, xdata_req, afr_transaction_perform_fop, AFR_TRANSACTION_PRE_OP); if (xdata_req) dict_unref(xdata_req); return 0; next: afr_transaction_perform_fop(frame, this); if (xdata_req) dict_unref(xdata_req); return 0; err: local->internal_lock.lock_cbk = afr_transaction_done; local->op_ret = -1; local->op_errno = op_errno; afr_handle_lock_acquire_failure(local); if (xdata_req) dict_unref(xdata_req); return 0; } static int afr_post_nonblocking_lock_cbk(call_frame_t *frame, xlator_t *this) { afr_internal_lock_t *int_lock = NULL; afr_local_t *local = NULL; local = frame->local; int_lock = &local->internal_lock; /* Initiate blocking locks if non-blocking has failed */ if (int_lock->lock_op_ret < 0) { gf_msg_debug(this->name, 0, "Non blocking locks failed. Proceeding to blocking"); int_lock->lock_cbk = afr_internal_lock_finish; afr_blocking_lock(frame, this); } else { gf_msg_debug(this->name, 0, "Non blocking locks done. Proceeding to FOP"); afr_internal_lock_finish(frame, this); } return 0; } static int afr_set_transaction_flock(xlator_t *this, afr_local_t *local, afr_lockee_t *lockee) { afr_private_t *priv = NULL; struct gf_flock *flock = NULL; priv = this->private; flock = &lockee->flock; if ((priv->arbiter_count || local->transaction.eager_lock_on || priv->full_lock) && local->transaction.type == AFR_DATA_TRANSACTION) { /*Lock entire file to avoid network split brains.*/ flock->l_len = 0; flock->l_start = 0; } else { flock->l_len = local->transaction.len; flock->l_start = local->transaction.start; } flock->l_type = F_WRLCK; return 0; } int afr_lock(call_frame_t *frame, xlator_t *this) { afr_internal_lock_t *int_lock = NULL; afr_local_t *local = NULL; int i = 0; local = frame->local; int_lock = &local->internal_lock; int_lock->lock_cbk = afr_post_nonblocking_lock_cbk; int_lock->domain = this->name; switch (local->transaction.type) { case AFR_DATA_TRANSACTION: case AFR_METADATA_TRANSACTION: for (i = 0; i < int_lock->lockee_count; i++) { afr_set_transaction_flock(this, local, &int_lock->lockee[i]); } break; case AFR_ENTRY_TRANSACTION: if (local->transaction.parent_loc.path) int_lock->lk_loc = &local->transaction.parent_loc; else GF_ASSERT(local->fd); break; case AFR_ENTRY_RENAME_TRANSACTION: break; } afr_lock_nonblocking(frame, this); return 0; } static gf_boolean_t afr_locals_overlap(afr_local_t *local1, afr_local_t *local2) { uint64_t start1 = local1->transaction.start; uint64_t start2 = local2->transaction.start; uint64_t end1 = 0; uint64_t end2 = 0; if (local1->transaction.len) end1 = start1 + local1->transaction.len - 1; else end1 = ULLONG_MAX; if (local2->transaction.len) end2 = start2 + local2->transaction.len - 1; else end2 = ULLONG_MAX; return ((end1 >= start2) && (end2 >= start1)); } gf_boolean_t afr_has_lock_conflict(afr_local_t *local, gf_boolean_t waitlist_check) { afr_local_t *each = NULL; afr_lock_t *lock = NULL; lock = &local->inode_ctx->lock[local->transaction.type]; /* * Once full file lock is acquired in eager-lock phase, overlapping * writes do not compete for inode-locks, instead are transferred to the * next writes. Because of this overlapping writes are not ordered. * This can cause inconsistencies in replication. * Example: * Two overlapping writes w1, w2 are sent in parallel on same fd * in two threads t1, t2. * Both threads can execute afr_writev_wind in the following manner. * t1 winds w1 on brick-0 * t2 winds w2 on brick-0 * t2 winds w2 on brick-1 * t1 winds w1 on brick-1 * * This check makes sure the locks are not transferred for * overlapping writes. */ list_for_each_entry(each, &lock->owners, transaction.owner_list) { if (afr_locals_overlap(each, local)) { return _gf_true; } } if (!waitlist_check) return _gf_false; list_for_each_entry(each, &lock->waiting, transaction.wait_list) { if (afr_locals_overlap(each, local)) { return _gf_true; } } return _gf_false; } /* }}} */ static void afr_copy_inodelk_vars(afr_internal_lock_t *dst, afr_internal_lock_t *src, xlator_t *this, int lockee_num) { afr_private_t *priv = this->private; afr_lockee_t *sl = &src->lockee[lockee_num]; afr_lockee_t *dl = &dst->lockee[lockee_num]; dst->domain = src->domain; dl->flock.l_len = sl->flock.l_len; dl->flock.l_start = sl->flock.l_start; dl->flock.l_type = sl->flock.l_type; dl->locked_count = sl->locked_count; memcpy(dl->locked_nodes, sl->locked_nodes, priv->child_count * sizeof(*dl->locked_nodes)); } static void __afr_transaction_wake_shared(afr_local_t *local, struct list_head *shared) { gf_boolean_t conflict = _gf_false; afr_local_t *each = NULL; afr_lock_t *lock = &local->inode_ctx->lock[local->transaction.type]; while (!conflict) { if (list_empty(&lock->waiting)) return; each = list_entry(lock->waiting.next, afr_local_t, transaction.wait_list); if (afr_has_lock_conflict(each, _gf_false)) { conflict = _gf_true; } if (conflict && !list_empty(&lock->owners)) return; afr_copy_inodelk_vars(&each->internal_lock, &local->internal_lock, each->transaction.frame->this, 0); list_move_tail(&each->transaction.wait_list, shared); list_add_tail(&each->transaction.owner_list, &lock->owners); } } static void afr_lock_resume_shared(struct list_head *list) { afr_local_t *each = NULL; while (!list_empty(list)) { each = list_entry(list->next, afr_local_t, transaction.wait_list); list_del_init(&each->transaction.wait_list); afr_changelog_pre_op(each->transaction.frame, each->transaction.frame->this); } } static int afr_internal_lock_finish(call_frame_t *frame, xlator_t *this) { afr_local_t *local = frame->local; afr_lock_t *lock = NULL; local->internal_lock.lock_cbk = NULL; if (!local->transaction.eager_lock_on) { if (local->internal_lock.lock_op_ret < 0) { afr_transaction_done(frame, this); return 0; } afr_changelog_pre_op(frame, this); } else { lock = &local->inode_ctx->lock[local->transaction.type]; if (local->internal_lock.lock_op_ret < 0) { afr_handle_lock_acquire_failure(local); } else { lock->event_generation = local->event_generation; afr_changelog_pre_op(frame, this); } } return 0; } static gf_boolean_t afr_are_conflicting_ops_waiting(afr_local_t *local, xlator_t *this) { afr_lock_t *lock = NULL; lock = &local->inode_ctx->lock[local->transaction.type]; /* Lets say mount1 has eager-lock(full-lock) and after the eager-lock * is taken mount2 opened the same file, it won't be able to * perform any {meta,}data operations until mount1 releases eager-lock. * To avoid such scenario do not enable eager-lock for this transaction * if open-fd-count is > 1 for metadata transactions and if num-inodelks > 1 * for data transactions */ if (local->transaction.type == AFR_METADATA_TRANSACTION) { if (local->inode_ctx->open_fd_count > 1) { return _gf_true; } } else if (local->transaction.type == AFR_DATA_TRANSACTION) { if (lock->num_inodelks > 1) { return _gf_true; } } return _gf_false; } static gf_boolean_t afr_is_delayed_changelog_post_op_needed(call_frame_t *frame, xlator_t *this, int delay) { afr_local_t *local = NULL; afr_lock_t *lock = NULL; gf_boolean_t res = _gf_false; local = frame->local; lock = &local->inode_ctx->lock[local->transaction.type]; if (!afr_txn_nothing_failed(frame, this)) { lock->release = _gf_true; goto out; } if (afr_are_conflicting_ops_waiting(local, this)) { lock->release = _gf_true; goto out; } if (!list_empty(&lock->owners)) goto out; else GF_ASSERT(list_empty(&lock->waiting)); if (lock->release) { goto out; } if (!delay) { goto out; } if (local->transaction.disable_delayed_post_op) { goto out; } if ((local->op != GF_FOP_WRITE) && (local->op != GF_FOP_FXATTROP) && (local->op != GF_FOP_FSYNC)) { /*Only allow writes/fsyncs but shard does [f]xattrops on writes, so * they are fine too*/ goto out; } res = _gf_true; out: return res; } void afr_delayed_changelog_wake_up_cbk(void *data) { afr_lock_t *lock = NULL; afr_local_t *local = data; afr_local_t *timer_local = NULL; struct list_head shared; INIT_LIST_HEAD(&shared); lock = &local->inode_ctx->lock[local->transaction.type]; LOCK(&local->inode->lock); { timer_local = list_entry(lock->post_op.next, afr_local_t, transaction.owner_list); if (list_empty(&lock->owners) && (local == timer_local)) { GF_ASSERT(list_empty(&lock->waiting)); /*Last owner*/ lock->release = _gf_true; lock->delay_timer = NULL; } } UNLOCK(&local->inode->lock); afr_changelog_post_op_now(local->transaction.frame, local->transaction.frame->this); } /* SET operation */ int afr_fd_report_unstable_write(xlator_t *this, afr_local_t *local) { LOCK(&local->inode->lock); { local->inode_ctx->witnessed_unstable_write = _gf_true; } UNLOCK(&local->inode->lock); return 0; } /* TEST and CLEAR operation */ gf_boolean_t afr_fd_has_witnessed_unstable_write(xlator_t *this, inode_t *inode) { afr_inode_ctx_t *ctx = NULL; gf_boolean_t witness = _gf_false; LOCK(&inode->lock); { ctx = __afr_inode_ctx_get(this, inode); if (ctx == NULL) goto unlock; if (ctx->witnessed_unstable_write) { witness = _gf_true; ctx->witnessed_unstable_write = _gf_false; } } unlock: UNLOCK(&inode->lock); return witness; } static int afr_changelog_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { afr_private_t *priv = NULL; int child_index = (long)cookie; int call_count = -1; afr_local_t *local = NULL; priv = this->private; local = frame->local; if (op_ret != 0) { /* Failure of fsync() is as good as failure of previous write(). So treat it like one. */ gf_msg(this->name, GF_LOG_WARNING, op_errno, AFR_MSG_FSYNC_FAILED, "fsync(%s) failed on subvolume %s. Transaction was %s", uuid_utoa(local->fd->inode->gfid), priv->children[child_index]->name, gf_fop_list[local->op]); afr_transaction_fop_failed(local, child_index); } call_count = afr_frame_return(frame); if (call_count == 0) afr_changelog_post_op_now(frame, this); return 0; } static int afr_changelog_fsync(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; int i = 0; int call_count = 0; afr_private_t *priv = NULL; dict_t *xdata = NULL; GF_UNUSED int ret = -1; local = frame->local; priv = this->private; call_count = AFR_COUNT(local->transaction.pre_op, priv->child_count); if (!call_count) { /* will go straight to unlock */ afr_changelog_post_op_now(frame, this); return 0; } local->call_count = call_count; xdata = dict_new(); if (xdata) { ret = dict_set_int32_sizen(xdata, "batch-fsync", 1); ret = dict_set_str(xdata, GLUSTERFS_INTERNAL_FOP_KEY, "yes"); } for (i = 0; i < priv->child_count; i++) { if (!local->transaction.pre_op[i]) continue; STACK_WIND_COOKIE(frame, afr_changelog_fsync_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->fsync, local->fd, 1, xdata); if (!--call_count) break; } if (xdata) dict_unref(xdata); return 0; } static int afr_changelog_post_op_safe(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; if (!local->fd || local->transaction.type != AFR_DATA_TRANSACTION) { afr_changelog_post_op_now(frame, this); return 0; } if (afr_changelog_pre_op_uninherit(frame, this) && afr_txn_nothing_failed(frame, this)) { /* just detected that this post-op is about to be optimized away as a new write() has already piggybacked on this frame's changelog. */ afr_changelog_post_op_now(frame, this); return 0; } /* Calling afr_changelog_post_op_now() now will result in issuing ->[f]xattrop(). Performing a hard POST-OP (->[f]xattrop() FOP) is a more responsible operation that what it might appear on the surface. The changelog of a file (in the xattr of the file on the server) stores information (pending count) about the state of the file on the OTHER server. This changelog is blindly trusted, and must therefore be updated in such a way it remains trustworthy. This implies that decrementing the pending count (essentially "clearing the dirty flag") must be done STRICTLY after we are sure that the operation on the other server has reached stable storage. While the backend filesystem on that server will eventually flush it to stable storage, we (being in userspace) have no mechanism to get notified when the write became "stable". This means we need take matter into our own hands and issue an fsync() EVEN IF THE APPLICATION WAS PERFORMING UNSTABLE WRITES, and get an acknowledgement for it. And we need to wait for the fsync() acknowledgement before initiating the hard POST-OP. However if the FD itself was opened in O_SYNC or O_DSYNC then we are already guaranteed that the writes were made stable as part of the FOP itself. The same holds true for NFS stable writes which happen on an anonymous FD with O_DSYNC or O_SYNC flag set in the writev() @flags param. For all other write types, mark a flag in the fdctx whenever an unstable write is witnessed. */ if (!afr_fd_has_witnessed_unstable_write(this, local->inode)) { afr_changelog_post_op_now(frame, this); return 0; } /* Check whether users want durability and perform fsync/post-op * accordingly. */ if (priv->ensure_durability) { /* Time to fsync() */ afr_changelog_fsync(frame, this); } else { afr_changelog_post_op_now(frame, this); } return 0; } void afr_changelog_post_op(call_frame_t *frame, xlator_t *this) { struct timespec delta = { 0, }; afr_private_t *priv = NULL; afr_local_t *local = frame->local; afr_lock_t *lock = NULL; gf_boolean_t post_op = _gf_true; struct list_head shared; priv = this->private; delta.tv_sec = priv->post_op_delay_secs; delta.tv_nsec = 0; INIT_LIST_HEAD(&shared); if (!local->transaction.eager_lock_on) goto out; lock = &local->inode_ctx->lock[local->transaction.type]; LOCK(&local->inode->lock); { list_del_init(&local->transaction.owner_list); list_add(&local->transaction.owner_list, &lock->post_op); __afr_transaction_wake_shared(local, &shared); if (!afr_is_delayed_changelog_post_op_needed(frame, this, delta.tv_sec)) { if (list_empty(&lock->owners)) lock->release = _gf_true; goto unlock; } GF_ASSERT(lock->delay_timer == NULL); lock->delay_timer = gf_timer_call_after( this->ctx, delta, afr_delayed_changelog_wake_up_cbk, local); if (!lock->delay_timer) { lock->release = _gf_true; } else { post_op = _gf_false; } } unlock: UNLOCK(&local->inode->lock); if (!list_empty(&shared)) { afr_lock_resume_shared(&shared); } out: if (post_op) { if (!local->transaction.eager_lock_on || lock->release) { afr_changelog_post_op_safe(frame, this); } else { afr_changelog_post_op_now(frame, this); } } } int afr_transaction_resume(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; local = frame->local; afr_restore_lk_owner(frame); afr_handle_symmetric_errors(frame, this); if (!local->pre_op_compat) /* new mode, pre-op was done along with OP */ afr_changelog_pre_op_update(frame, this); afr_changelog_post_op(frame, this); return 0; } /** * afr_transaction_fop_failed - inform that an fop failed */ void afr_transaction_fop_failed(afr_local_t *local, int child_index) { local->transaction.failed_subvols[child_index] = 1; } static gf_boolean_t __need_previous_lock_unlocked(afr_local_t *local) { afr_lock_t *lock = NULL; lock = &local->inode_ctx->lock[local->transaction.type]; if (!lock->acquired) return _gf_false; if (lock->acquired && lock->event_generation != local->event_generation) return _gf_true; return _gf_false; } static void __afr_eager_lock_handle(afr_local_t *local, gf_boolean_t *take_lock, gf_boolean_t *do_pre_op, afr_local_t **timer_local) { afr_lock_t *lock = NULL; afr_local_t *owner_local = NULL; xlator_t *this = local->transaction.frame->this; local->transaction.eager_lock_on = _gf_true; afr_set_lk_owner(local->transaction.frame, this, local->inode); lock = &local->inode_ctx->lock[local->transaction.type]; if (__need_previous_lock_unlocked(local)) { if (!list_empty(&lock->owners)) { lock->release = _gf_true; } else if (lock->delay_timer) { lock->release = _gf_true; if (gf_timer_call_cancel(this->ctx, lock->delay_timer)) { /* It will be put in frozen list * in the code flow below*/ } else { *timer_local = list_entry(lock->post_op.next, afr_local_t, transaction.owner_list); lock->delay_timer = NULL; } } } if (lock->release) { list_add_tail(&local->transaction.wait_list, &lock->frozen); *take_lock = _gf_false; goto out; } if (lock->delay_timer) { *take_lock = _gf_false; if (gf_timer_call_cancel(this->ctx, lock->delay_timer)) { list_add_tail(&local->transaction.wait_list, &lock->frozen); } else { *timer_local = list_entry(lock->post_op.next, afr_local_t, transaction.owner_list); afr_copy_inodelk_vars(&local->internal_lock, &(*timer_local)->internal_lock, this, 0); lock->delay_timer = NULL; *do_pre_op = _gf_true; list_add_tail(&local->transaction.owner_list, &lock->owners); } goto out; } if (!list_empty(&lock->owners)) { if (!lock->acquired || afr_has_lock_conflict(local, _gf_true)) { list_add_tail(&local->transaction.wait_list, &lock->waiting); *take_lock = _gf_false; goto out; } owner_local = list_entry(lock->owners.next, afr_local_t, transaction.owner_list); afr_copy_inodelk_vars(&local->internal_lock, &owner_local->internal_lock, this, 0); *take_lock = _gf_false; *do_pre_op = _gf_true; } if (lock->acquired) GF_ASSERT(!(*take_lock)); list_add_tail(&local->transaction.owner_list, &lock->owners); out: return; } static void afr_transaction_start(afr_local_t *local, xlator_t *this) { afr_private_t *priv = NULL; gf_boolean_t take_lock = _gf_true; gf_boolean_t do_pre_op = _gf_false; afr_local_t *timer_local = NULL; priv = this->private; if (local->transaction.type != AFR_DATA_TRANSACTION && local->transaction.type != AFR_METADATA_TRANSACTION) goto lock_phase; if (!priv->eager_lock) goto lock_phase; LOCK(&local->inode->lock); { __afr_eager_lock_handle(local, &take_lock, &do_pre_op, &timer_local); } UNLOCK(&local->inode->lock); lock_phase: if (!local->transaction.eager_lock_on) { afr_set_lk_owner(local->transaction.frame, this, local->transaction.frame->root); } if (take_lock) { afr_lock(local->transaction.frame, this); } else if (do_pre_op) { afr_changelog_pre_op(local->transaction.frame, this); } /*Always call delayed_changelog_wake_up_cbk after calling pre-op above * so that any inheriting can happen*/ if (timer_local) afr_delayed_changelog_wake_up_cbk(timer_local); } static int afr_write_txn_refresh_done(call_frame_t *frame, xlator_t *this, int err) { afr_local_t *local = frame->local; if (err) { AFR_SET_ERROR_AND_CHECK_SPLIT_BRAIN(-1, err); goto fail; } afr_transaction_start(local, this); return 0; fail: local->transaction.unwind(frame, this); AFR_STACK_DESTROY(frame); return 0; } static int afr_transaction_lockee_init(call_frame_t *frame) { afr_local_t *local = frame->local; afr_internal_lock_t *int_lock = &local->internal_lock; afr_private_t *priv = frame->this->private; int ret = 0; switch (local->transaction.type) { case AFR_DATA_TRANSACTION: case AFR_METADATA_TRANSACTION: ret = afr_add_inode_lockee(local, priv->child_count); break; case AFR_ENTRY_TRANSACTION: case AFR_ENTRY_RENAME_TRANSACTION: ret = afr_add_entry_lockee(local, &local->transaction.parent_loc, local->transaction.basename, priv->child_count); if (ret) { goto out; } if (local->op == GF_FOP_RENAME) { ret = afr_add_entry_lockee( local, &local->transaction.new_parent_loc, local->transaction.new_basename, priv->child_count); if (ret) { goto out; } if (local->newloc.inode && IA_ISDIR(local->newloc.inode->ia_type)) { ret = afr_add_entry_lockee(local, &local->newloc, NULL, priv->child_count); if (ret) { goto out; } } } else if (local->op == GF_FOP_RMDIR) { ret = afr_add_entry_lockee(local, &local->loc, NULL, priv->child_count); if (ret) { goto out; } } if (int_lock->lockee_count > 1) { qsort(int_lock->lockee, int_lock->lockee_count, sizeof(*int_lock->lockee), afr_entry_lockee_cmp); } break; } out: return ret; } int afr_transaction(call_frame_t *frame, xlator_t *this, afr_transaction_type type) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int ret = -1; int event_generation = 0; local = frame->local; priv = this->private; local->transaction.frame = frame; local->transaction.type = type; if (priv->quorum_count && !afr_has_quorum(local->child_up, priv, NULL)) { ret = -afr_quorum_errno(priv); goto out; } if (!afr_is_consistent_io_possible(local, priv, &ret)) { ret = -ret; /*op_errno to ret conversion*/ goto out; } if (priv->thin_arbiter_count && !afr_ta_has_quorum(priv, local)) { ret = -afr_quorum_errno(priv); goto out; } ret = afr_transaction_local_init(local, this); if (ret < 0) goto out; ret = afr_transaction_lockee_init(frame); if (ret) goto out; if (type != AFR_METADATA_TRANSACTION) { goto txn_start; } ret = afr_inode_get_readable(frame, local->inode, this, local->readable, &event_generation, type); if (ret < 0 || afr_is_inode_refresh_reqd(local->inode, this, priv->event_generation, event_generation)) { afr_inode_refresh(frame, this, local->inode, local->loc.gfid, afr_write_txn_refresh_done); ret = 0; goto out; } txn_start: ret = 0; afr_transaction_start(local, this); out: return ret; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-dir-read.h0000644000000000000000000000013114522202451023501 xustar000000000000000030 mtime=1699284265.613027269 30 atime=1699284265.612027266 29 ctime=1699284301.09813415 glusterfs-11.1/xlators/cluster/afr/src/afr-dir-read.h0000664000175100017510000000151714522202451023765 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __DIR_READ_H__ #define __DIR_READ_H__ int32_t afr_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata); int32_t afr_releasedir(xlator_t *this, fd_t *fd); int32_t afr_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata); int32_t afr_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *dict); #endif /* __DIR_READ_H__ */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-self-heal-name.c0000644000000000000000000000013214522202451024564 xustar000000000000000030 mtime=1699284265.618027284 30 atime=1699284265.618027284 30 ctime=1699284301.131134249 glusterfs-11.1/xlators/cluster/afr/src/afr-self-heal-name.c0000664000175100017510000004472514522202451025057 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "afr.h" #include "afr-self-heal.h" #include "afr-messages.h" static int __afr_selfheal_assign_gfid(xlator_t *this, inode_t *parent, uuid_t pargfid, const char *bname, inode_t *inode, struct afr_reply *replies, void *gfid, unsigned char *locked_on, int source, unsigned char *sources, gf_boolean_t is_gfid_absent, int *gfid_idx) { int ret = 0; int up_count = 0; int locked_count = 0; afr_private_t *priv = NULL; priv = this->private; gf_uuid_copy(parent->gfid, pargfid); if (is_gfid_absent) { /* Ensure all children of AFR are up before performing gfid heal, to * guard against the possibility of gfid split brain. */ up_count = AFR_COUNT(priv->child_up, priv->child_count); if (up_count != priv->child_count) { ret = -EIO; goto out; } locked_count = AFR_COUNT(locked_on, priv->child_count); if (locked_count != priv->child_count) { ret = -EIO; goto out; } } ret = afr_lookup_and_heal_gfid(this, parent, bname, inode, replies, source, sources, gfid, gfid_idx); out: return ret; } static int __afr_selfheal_name_impunge(call_frame_t *frame, xlator_t *this, inode_t *parent, uuid_t pargfid, const char *bname, inode_t *inode, struct afr_reply *replies, int gfid_idx) { int i = 0; afr_private_t *priv = NULL; int ret = 0; unsigned char *sources = NULL; priv = this->private; sources = alloca0(priv->child_count); gf_uuid_copy(parent->gfid, pargfid); for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret != 0) continue; if (gf_uuid_compare(replies[i].poststat.ia_gfid, replies[gfid_idx].poststat.ia_gfid) == 0) { sources[i] = 1; continue; } } for (i = 0; i < priv->child_count; i++) { if (sources[i]) continue; ret |= afr_selfheal_recreate_entry(frame, i, gfid_idx, sources, parent, bname, inode, replies); } return ret; } static int __afr_selfheal_name_expunge(xlator_t *this, inode_t *parent, uuid_t pargfid, const char *bname, inode_t *inode, struct afr_reply *replies) { int i = 0; afr_private_t *priv = NULL; int ret = 0; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret) continue; ret |= afr_selfheal_entry_delete(this, parent, bname, inode, i, replies); } return ret; } static gf_boolean_t afr_selfheal_name_need_heal_check(xlator_t *this, struct afr_reply *replies) { int i = 0; int first_idx = -1; gf_boolean_t need_heal = _gf_false; afr_private_t *priv = NULL; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if ((replies[i].op_ret == -1) && (replies[i].op_errno == ENODATA)) need_heal = _gf_true; if (first_idx == -1) { first_idx = i; continue; } if (replies[i].op_ret != replies[first_idx].op_ret) need_heal = _gf_true; if (gf_uuid_compare(replies[i].poststat.ia_gfid, replies[first_idx].poststat.ia_gfid)) need_heal = _gf_true; if ((replies[i].op_ret == 0) && (gf_uuid_is_null(replies[i].poststat.ia_gfid))) need_heal = _gf_true; } return need_heal; } static int afr_selfheal_name_type_mismatch_check(xlator_t *this, struct afr_reply *replies, int source, unsigned char *sources, uuid_t pargfid, const char *bname) { int i = 0; int type_idx = -1; ia_type_t inode_type = IA_INVAL; ia_type_t inode_type1 = IA_INVAL; afr_private_t *priv = NULL; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret != 0) continue; if (replies[i].poststat.ia_type == IA_INVAL) continue; if (inode_type == IA_INVAL) { inode_type = replies[i].poststat.ia_type; type_idx = i; continue; } inode_type1 = replies[i].poststat.ia_type; if (sources[i] || source == -1) { if ((sources[type_idx] || source == -1) && (inode_type != inode_type1)) { gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_SPLIT_BRAIN, "Type mismatch for /%s: " "%s on %s and %s on %s", uuid_utoa(pargfid), bname, gf_inode_type_to_str(inode_type1), priv->children[i]->name, gf_inode_type_to_str(inode_type), priv->children[type_idx]->name); gf_event(EVENT_AFR_SPLIT_BRAIN, "client-pid=%d;" "subvol=%s;type=file;" "file=/%s;count=2;" "child-%d=%s;type-%d=%s;child-%d=%s;" "type-%d=%s", this->ctx->cmd_args.client_pid, this->name, uuid_utoa(pargfid), bname, i, priv->children[i]->name, i, gf_inode_type_to_str(inode_type1), type_idx, priv->children[type_idx]->name, type_idx, gf_inode_type_to_str(inode_type)); return -EIO; } inode_type = replies[i].poststat.ia_type; type_idx = i; } } return 0; } static int afr_selfheal_name_gfid_mismatch_check(xlator_t *this, struct afr_reply *replies, int source, unsigned char *sources, int *gfid_idx, uuid_t pargfid, const char *bname, inode_t *inode, unsigned char *locked_on, dict_t *req, dict_t *rsp) { int i = 0; int gfid_idx_iter = -1; int ret = -1; void *gfid = NULL; void *gfid1 = NULL; afr_private_t *priv = NULL; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret != 0) continue; if (gf_uuid_is_null(replies[i].poststat.ia_gfid)) continue; if (!gfid) { gfid = &replies[i].poststat.ia_gfid; gfid_idx_iter = i; continue; } gfid1 = &replies[i].poststat.ia_gfid; if (sources[i] || source == -1) { if ((sources[gfid_idx_iter] || source == -1) && gf_uuid_compare(gfid, gfid1)) { ret = afr_gfid_split_brain_source( this, replies, inode, pargfid, bname, gfid_idx_iter, i, locked_on, gfid_idx, req, rsp); if (!ret && *gfid_idx >= 0) { ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg", "GFID split-brain resolved"); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_SET_FAILED, "Error setting gfid-" "heal-msg dict"); } return ret; } gfid = &replies[i].poststat.ia_gfid; gfid_idx_iter = i; } } *gfid_idx = gfid_idx_iter; return 0; } static gf_boolean_t afr_selfheal_name_source_empty_check(xlator_t *this, struct afr_reply *replies, unsigned char *sources, int source) { int i = 0; afr_private_t *priv = NULL; gf_boolean_t source_is_empty = _gf_true; priv = this->private; if (source == -1) { source_is_empty = _gf_false; goto out; } for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; if (replies[i].op_ret == -1 && replies[i].op_errno == ENOENT) continue; source_is_empty = _gf_false; break; } out: return source_is_empty; } static int __afr_selfheal_name_do(call_frame_t *frame, xlator_t *this, inode_t *parent, uuid_t pargfid, const char *bname, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, int source, unsigned char *locked_on, struct afr_reply *replies, void *gfid_req, dict_t *req, dict_t *rsp) { int gfid_idx = -1; int ret = -1; void *gfid = NULL; gf_boolean_t source_is_empty = _gf_true; gf_boolean_t need_heal = _gf_false; gf_boolean_t is_gfid_absent = _gf_false; need_heal = afr_selfheal_name_need_heal_check(this, replies); if (!need_heal) return 0; source_is_empty = afr_selfheal_name_source_empty_check(this, replies, sources, source); if (source_is_empty) { ret = __afr_selfheal_name_expunge(this, parent, pargfid, bname, inode, replies); if (ret == -EIO) ret = -1; return ret; } ret = afr_selfheal_name_type_mismatch_check(this, replies, source, sources, pargfid, bname); if (ret) return ret; ret = afr_selfheal_name_gfid_mismatch_check(this, replies, source, sources, &gfid_idx, pargfid, bname, inode, locked_on, req, rsp); if (ret) return ret; if (gfid_idx == -1) { if (!gfid_req || gf_uuid_is_null(gfid_req)) return -1; gfid = gfid_req; } else { gfid = &replies[gfid_idx].poststat.ia_gfid; if (source == -1) /* Either entry split-brain or dirty xattrs are present on parent.*/ source = gfid_idx; } is_gfid_absent = (gfid_idx == -1) ? _gf_true : _gf_false; ret = __afr_selfheal_assign_gfid(this, parent, pargfid, bname, inode, replies, gfid, locked_on, source, sources, is_gfid_absent, &gfid_idx); if (ret || (gfid_idx < 0)) return ret; ret = __afr_selfheal_name_impunge(frame, this, parent, pargfid, bname, inode, replies, gfid_idx); if (ret == -EIO) ret = -1; return ret; } static int __afr_selfheal_name_finalize_source(xlator_t *this, unsigned char *sources, unsigned char *healed_sinks, unsigned char *locked_on, uint64_t *witness) { int i = 0; afr_private_t *priv = NULL; int source = -1; int sources_count = 0; priv = this->private; sources_count = AFR_COUNT(sources, priv->child_count); if ((AFR_CMP(locked_on, healed_sinks, priv->child_count) == 0) || !sources_count || afr_does_witness_exist(this, witness)) { memset(sources, 0, sizeof(*sources) * priv->child_count); afr_mark_active_sinks(this, sources, locked_on, healed_sinks); return -1; } for (i = 0; i < priv->child_count; i++) { if (sources[i]) { source = i; break; } } return source; } static int __afr_selfheal_name_prepare(call_frame_t *frame, xlator_t *this, inode_t *parent, uuid_t pargfid, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, int *source_p) { int ret = -1; int source = -1; afr_private_t *priv = NULL; struct afr_reply *replies = NULL; uint64_t *witness = NULL; priv = this->private; replies = alloca0(priv->child_count * sizeof(*replies)); ret = afr_selfheal_unlocked_discover(frame, parent, pargfid, replies); if (ret) goto out; witness = alloca0(sizeof(*witness) * priv->child_count); ret = afr_selfheal_find_direction(frame, this, replies, AFR_ENTRY_TRANSACTION, locked_on, sources, sinks, witness, NULL); if (ret) goto out; /* Initialize the healed_sinks[] array optimistically to the intersection of to-be-healed (i.e sinks[]) and the list of servers which are up (i.e locked_on[]). As we encounter failures in the healing process, we will unmark the respective servers in the healed_sinks[] array. */ AFR_INTERSECT(healed_sinks, sinks, locked_on, priv->child_count); source = __afr_selfheal_name_finalize_source(this, sources, healed_sinks, locked_on, witness); if (source < 0) { /* If source is < 0 (typically split-brain), we perform a conservative merge of entries rather than erroring out */ } *source_p = source; out: if (replies) afr_replies_wipe(replies, priv->child_count); return ret; } static int afr_selfheal_name_do(call_frame_t *frame, xlator_t *this, inode_t *parent, uuid_t pargfid, const char *bname, void *gfid_req, dict_t *req, dict_t *rsp) { afr_private_t *priv = NULL; unsigned char *sources = NULL; unsigned char *sinks = NULL; unsigned char *healed_sinks = NULL; unsigned char *locked_on = NULL; int source = -1; struct afr_reply *replies = NULL; int ret = -1; inode_t *inode = NULL; dict_t *xattr = NULL; xattr = dict_new(); if (!xattr) return -ENOMEM; ret = dict_set_int32_sizen(xattr, GF_GFIDLESS_LOOKUP, 1); if (ret) { dict_unref(xattr); return -1; } priv = this->private; locked_on = alloca0(priv->child_count); sources = alloca0(priv->child_count); sinks = alloca0(priv->child_count); healed_sinks = alloca0(priv->child_count); replies = alloca0(priv->child_count * sizeof(*replies)); ret = afr_selfheal_entrylk(frame, this, parent, this->name, bname, locked_on); { if (ret < priv->child_count) { ret = -ENOTCONN; goto unlock; } ret = __afr_selfheal_name_prepare(frame, this, parent, pargfid, locked_on, sources, sinks, healed_sinks, &source); if (ret) goto unlock; inode = afr_selfheal_unlocked_lookup_on(frame, parent, bname, replies, locked_on, xattr); if (!inode) { ret = -ENOMEM; goto unlock; } ret = __afr_selfheal_name_do(frame, this, parent, pargfid, bname, inode, sources, sinks, healed_sinks, source, locked_on, replies, gfid_req, req, rsp); } unlock: afr_selfheal_unentrylk(frame, this, parent, this->name, bname, locked_on, NULL); if (inode) inode_unref(inode); if (replies) afr_replies_wipe(replies, priv->child_count); if (xattr) dict_unref(xattr); return ret; } static int afr_selfheal_name_unlocked_inspect(call_frame_t *frame, xlator_t *this, inode_t *parent, uuid_t pargfid, const char *bname, gf_boolean_t *need_heal) { afr_private_t *priv = NULL; int i = 0; struct afr_reply *replies = NULL; inode_t *inode = NULL; int first_idx = -1; afr_local_t *local = NULL; priv = this->private; local = frame->local; replies = alloca0(sizeof(*replies) * priv->child_count); inode = afr_selfheal_unlocked_lookup_on(frame, parent, bname, replies, local->child_up, NULL); if (!inode) return -ENOMEM; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if ((replies[i].op_ret == -1) && (replies[i].op_errno == ENODATA)) { *need_heal = _gf_true; break; } if (first_idx == -1) { first_idx = i; continue; } if (replies[i].op_ret != replies[first_idx].op_ret) { *need_heal = _gf_true; break; } if (gf_uuid_compare(replies[i].poststat.ia_gfid, replies[first_idx].poststat.ia_gfid)) { *need_heal = _gf_true; break; } } if (inode) inode_unref(inode); if (replies) afr_replies_wipe(replies, priv->child_count); return 0; } int afr_selfheal_name(xlator_t *this, uuid_t pargfid, const char *bname, void *gfid_req, dict_t *req, dict_t *rsp) { inode_t *parent = NULL; call_frame_t *frame = NULL; int ret = -1; gf_boolean_t need_heal = _gf_false; parent = afr_inode_find(this, pargfid); if (!parent) goto out; frame = afr_frame_create(this, NULL); if (!frame) goto out; ret = afr_selfheal_name_unlocked_inspect(frame, this, parent, pargfid, bname, &need_heal); if (ret) goto out; if (need_heal) { ret = afr_selfheal_name_do(frame, this, parent, pargfid, bname, gfid_req, req, rsp); if (ret) goto out; } ret = 0; out: if (parent) inode_unref(parent); if (frame) AFR_STACK_DESTROY(frame); return ret; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-lk-common.c0000644000000000000000000000013214522202451023702 xustar000000000000000030 mtime=1699284265.615027275 30 atime=1699284265.615027275 30 ctime=1699284301.119134213 glusterfs-11.1/xlators/cluster/afr/src/afr-lk-common.c0000664000175100017510000005447014522202451024173 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "afr-transaction.h" #include "afr-messages.h" #include #define LOCKED_NO 0x0 /* no lock held */ #define LOCKED_YES 0x1 /* for DATA, METADATA, ENTRY and higher_path */ #define LOCKED_LOWER 0x2 /* for lower path */ static void afr_lockee_cleanup(afr_lockee_t *lockee) { if (lockee->fd) { fd_unref(lockee->fd); lockee->fd = NULL; } else { loc_wipe(&lockee->loc); } GF_FREE(lockee->basename); lockee->basename = NULL; GF_FREE(lockee->locked_nodes); lockee->locked_nodes = NULL; return; } void afr_lockees_cleanup(afr_internal_lock_t *int_lock) { int i = 0; for (i = 0; i < int_lock->lockee_count; i++) { afr_lockee_cleanup(&int_lock->lockee[i]); } return; } int afr_entry_lockee_cmp(const void *l1, const void *l2) { const afr_lockee_t *r1 = l1; const afr_lockee_t *r2 = l2; int ret = 0; uuid_t gfid1 = {0}; uuid_t gfid2 = {0}; loc_gfid((loc_t *)&r1->loc, gfid1); loc_gfid((loc_t *)&r2->loc, gfid2); ret = gf_uuid_compare(gfid1, gfid2); /*Entrylks with NULL basename are the 'smallest'*/ if (ret == 0) { if (!r1->basename) return -1; if (!r2->basename) return 1; ret = strcmp(r1->basename, r2->basename); } if (ret <= 0) return -1; else return 1; } static int afr_lock_blocking(call_frame_t *frame, xlator_t *this, int child_index); void afr_set_lk_owner(call_frame_t *frame, xlator_t *this, void *lk_owner) { gf_msg_trace(this->name, 0, "Setting lk-owner=%llu", (unsigned long long)(unsigned long)lk_owner); set_lk_owner_from_ptr(&frame->root->lk_owner, lk_owner); } static int32_t internal_lock_count(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int32_t call_count = 0; int i = 0; local = frame->local; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) ++call_count; } return call_count; } int afr_add_entry_lockee(afr_local_t *local, loc_t *loc, char *basename, int child_count) { int ret = -ENOMEM; afr_internal_lock_t *int_lock = &local->internal_lock; afr_lockee_t *lockee = &int_lock->lockee[int_lock->lockee_count]; GF_ASSERT(int_lock->lockee_count < AFR_LOCKEE_COUNT_MAX); loc_copy(&lockee->loc, loc); lockee->basename = (basename) ? gf_strdup(basename) : NULL; if (basename && !lockee->basename) goto out; lockee->locked_count = 0; lockee->locked_nodes = GF_CALLOC(child_count, sizeof(*lockee->locked_nodes), gf_afr_mt_afr_node_character); if (!lockee->locked_nodes) goto out; ret = 0; int_lock->lockee_count++; out: if (ret) { afr_lockee_cleanup(lockee); } return ret; } int afr_add_inode_lockee(afr_local_t *local, int child_count) { int ret = -ENOMEM; afr_internal_lock_t *int_lock = &local->internal_lock; afr_lockee_t *lockee = &int_lock->lockee[int_lock->lockee_count]; if (local->fd) { lockee->fd = fd_ref(local->fd); } else { loc_copy(&lockee->loc, &local->loc); } lockee->locked_count = 0; lockee->locked_nodes = GF_CALLOC(child_count, sizeof(*lockee->locked_nodes), gf_afr_mt_afr_node_character); if (!lockee->locked_nodes) goto out; ret = 0; int_lock->lockee_count++; out: if (ret) { afr_lockee_cleanup(lockee); } return ret; } static int initialize_internal_lock_variables(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_internal_lock_t *int_lock = NULL; afr_private_t *priv = NULL; int i = 0; priv = this->private; local = frame->local; int_lock = &local->internal_lock; int_lock->lock_count = 0; int_lock->lock_op_ret = -1; int_lock->lock_op_errno = 0; int_lock->lk_attempted_count = 0; for (i = 0; i < AFR_LOCKEE_COUNT_MAX; i++) { if (!int_lock->lockee[i].locked_nodes) break; int_lock->lockee[i].locked_count = 0; memset(int_lock->lockee[i].locked_nodes, 0, sizeof(*int_lock->lockee[i].locked_nodes) * priv->child_count); } return 0; } static int afr_lockee_locked_nodes_count(afr_internal_lock_t *int_lock) { int call_count = 0; int i = 0; for (i = 0; i < int_lock->lockee_count; i++) call_count += int_lock->lockee[i].locked_count; return call_count; } int afr_locked_nodes_count(unsigned char *locked_nodes, int child_count) { int i = 0; int call_count = 0; for (i = 0; i < child_count; i++) { if (locked_nodes[i] & LOCKED_YES) call_count++; } return call_count; } static void afr_log_locks_failure(call_frame_t *frame, char *where, char *what, int op_errno) { xlator_t *this = frame->this; gf_lkowner_t *lk_owner = &frame->root->lk_owner; afr_local_t *local = frame->local; const char *fop = NULL; char *gfid = NULL; const char *name = NULL; fop = gf_fop_list[local->op]; switch (local->transaction.type) { case AFR_ENTRY_RENAME_TRANSACTION: case AFR_ENTRY_TRANSACTION: switch (local->op) { case GF_FOP_LINK: gfid = uuid_utoa(local->newloc.pargfid); name = local->newloc.name; break; default: gfid = uuid_utoa(local->loc.pargfid); name = local->loc.name; break; } gf_msg(this->name, GF_LOG_WARNING, op_errno, AFR_MSG_INTERNAL_LKS_FAILED, "Unable to do entry %s with lk-owner:%s on %s " "while attempting %s on {pgfid:%s, name:%s}.", what, lkowner_utoa(lk_owner), where, fop, gfid, name); break; case AFR_DATA_TRANSACTION: case AFR_METADATA_TRANSACTION: gfid = uuid_utoa(local->inode->gfid); gf_msg(this->name, GF_LOG_WARNING, op_errno, AFR_MSG_INTERNAL_LKS_FAILED, "Unable to do inode %s with lk-owner:%s on %s " "while attempting %s on gfid:%s.", what, lkowner_utoa(lk_owner), where, fop, gfid); break; } } static int32_t afr_unlock_common_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; afr_internal_lock_t *int_lock = NULL; int lockee_num = 0; int call_count = 0; int child_index = 0; int ret = 0; local = frame->local; int_lock = &local->internal_lock; priv = this->private; lockee_num = (int)((long)cookie) / priv->child_count; child_index = (int)((long)cookie) % priv->child_count; if (op_ret < 0 && op_errno != ENOTCONN && op_errno != EBADFD) { afr_log_locks_failure(frame, priv->children[child_index]->name, "unlock", op_errno); } int_lock->lockee[lockee_num].locked_nodes[child_index] &= LOCKED_NO; if (local->transaction.type == AFR_DATA_TRANSACTION && op_ret != 1) ret = afr_write_subvol_reset(frame, this); LOCK(&frame->lock); { call_count = --int_lock->lk_call_count; } UNLOCK(&frame->lock); if (call_count == 0) { int_lock->lock_cbk(frame, this); } return ret; } static void afr_internal_lock_wind(call_frame_t *frame, int32_t (*cbk)(call_frame_t *, void *, xlator_t *, int32_t, int32_t, dict_t *), void *cookie, int child, int lockee_num, gf_boolean_t blocking, gf_boolean_t unlock) { afr_local_t *local = frame->local; xlator_t *this = frame->this; afr_private_t *priv = this->private; afr_internal_lock_t *int_lock = &local->internal_lock; entrylk_cmd cmd = ENTRYLK_LOCK_NB; int32_t cmd1 = F_SETLK; struct gf_flock flock; switch (local->transaction.type) { case AFR_ENTRY_TRANSACTION: case AFR_ENTRY_RENAME_TRANSACTION: if (unlock) { cmd = ENTRYLK_UNLOCK; } else if (blocking) { /*Doesn't make sense to have blocking unlock*/ cmd = ENTRYLK_LOCK; } if (local->fd) { STACK_WIND_COOKIE(frame, cbk, cookie, priv->children[child], priv->children[child]->fops->fentrylk, int_lock->domain, int_lock->lockee[lockee_num].fd, int_lock->lockee[lockee_num].basename, cmd, ENTRYLK_WRLCK, NULL); } else { STACK_WIND_COOKIE(frame, cbk, cookie, priv->children[child], priv->children[child]->fops->entrylk, int_lock->domain, &int_lock->lockee[lockee_num].loc, int_lock->lockee[lockee_num].basename, cmd, ENTRYLK_WRLCK, NULL); } break; case AFR_DATA_TRANSACTION: case AFR_METADATA_TRANSACTION: gf_flock_copy(&flock, &int_lock->lockee[lockee_num].flock); if (unlock) { flock.l_type = F_UNLCK; } else if (blocking) { /*Doesn't make sense to have blocking unlock*/ cmd1 = F_SETLKW; } if (local->fd) { STACK_WIND_COOKIE( frame, cbk, cookie, priv->children[child], priv->children[child]->fops->finodelk, int_lock->domain, int_lock->lockee[lockee_num].fd, cmd1, &flock, NULL); } else { STACK_WIND_COOKIE( frame, cbk, cookie, priv->children[child], priv->children[child]->fops->inodelk, int_lock->domain, &int_lock->lockee[lockee_num].loc, cmd1, &flock, NULL); } break; } } static int afr_unlock_now(call_frame_t *frame, xlator_t *this) { afr_internal_lock_t *int_lock = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; int call_count = 0; int child_index = 0; int lockee_num = 0; int i = -1; local = frame->local; int_lock = &local->internal_lock; priv = this->private; call_count = afr_lockee_locked_nodes_count(int_lock); int_lock->lk_call_count = call_count; if (!call_count) { gf_msg_trace(this->name, 0, "No internal locks unlocked"); int_lock->lock_cbk(frame, this); goto out; } for (i = 0; i < int_lock->lockee_count * priv->child_count; i++) { lockee_num = i / priv->child_count; child_index = i % priv->child_count; if (int_lock->lockee[lockee_num].locked_nodes[child_index] & LOCKED_YES) { afr_internal_lock_wind(frame, afr_unlock_common_cbk, (void *)(long)i, child_index, lockee_num, _gf_false, _gf_true); if (!--call_count) break; } } out: return 0; } static int32_t afr_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { afr_internal_lock_t *int_lock = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; int cky = (long)cookie; int child_index = 0; int lockee_num = 0; priv = this->private; local = frame->local; int_lock = &local->internal_lock; child_index = ((int)cky) % priv->child_count; lockee_num = ((int)cky) / priv->child_count; LOCK(&frame->lock); { if (op_ret == -1) { if (op_errno == ENOSYS) { /* return ENOTSUP */ gf_msg(this->name, GF_LOG_ERROR, ENOSYS, AFR_MSG_LOCK_XLATOR_NOT_LOADED, "subvolume does not support locking. " "please load features/locks xlator on server"); local->op_ret = op_ret; int_lock->lock_op_ret = op_ret; } local->op_errno = op_errno; int_lock->lock_op_errno = op_errno; } int_lock->lk_attempted_count++; } UNLOCK(&frame->lock); if ((op_ret == -1) && (op_errno == ENOSYS)) { afr_unlock_now(frame, this); } else { if (op_ret == 0) { int_lock->lockee[lockee_num] .locked_nodes[child_index] |= LOCKED_YES; int_lock->lockee[lockee_num].locked_count++; int_lock->lock_count++; if (local->transaction.type == AFR_DATA_TRANSACTION) { LOCK(&local->inode->lock); { local->inode_ctx->lock_count++; } UNLOCK(&local->inode->lock); } } afr_lock_blocking(frame, this, cky + 1); } return 0; } static gf_boolean_t _is_lock_wind_needed(afr_local_t *local, int child_index) { if (!local->child_up[child_index]) return _gf_false; return _gf_true; } static gf_boolean_t is_blocking_locks_count_sufficient(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; afr_internal_lock_t *int_lock = NULL; int child = 0; int nlockee = 0; int lockee_count = 0; gf_boolean_t ret = _gf_true; local = frame->local; priv = this->private; int_lock = &local->internal_lock; lockee_count = int_lock->lockee_count; if (int_lock->lock_count == 0) { afr_log_locks_failure(frame, "any subvolume", "lock", int_lock->lock_op_errno); return _gf_false; } /* For FOPS that take multiple sets of locks (mkdir, rename), * there must be at least one brick on which the locks from * all lock sets were successful. */ for (child = 0; child < priv->child_count; child++) { ret = _gf_true; for (nlockee = 0; nlockee < lockee_count; nlockee++) { if (!(int_lock->lockee[nlockee].locked_nodes[child] & LOCKED_YES)) ret = _gf_false; } if (ret) return ret; } if (!ret) afr_log_locks_failure(frame, "all", "lock", int_lock->lock_op_errno); return ret; } static int afr_lock_blocking(call_frame_t *frame, xlator_t *this, int cookie) { afr_internal_lock_t *int_lock = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; uint64_t ctx = 0; int child_index = 0; int lockee_num = 0; local = frame->local; int_lock = &local->internal_lock; priv = this->private; child_index = cookie % priv->child_count; lockee_num = cookie / priv->child_count; if (local->fd) { ctx = fd_ctx_get(local->fd, this); if (!ctx) { gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_FD_CTX_GET_FAILED, "unable to get fd ctx for fd=%p", local->fd); local->op_ret = -1; int_lock->lock_op_ret = -1; afr_unlock_now(frame, this); return 0; } } if (int_lock->lk_expected_count == int_lock->lk_attempted_count) { if (!is_blocking_locks_count_sufficient(frame, this)) { local->op_ret = -1; int_lock->lock_op_ret = -1; afr_unlock_now(frame, this); return 0; } } if (int_lock->lk_expected_count == int_lock->lk_attempted_count) { /* we're done locking */ gf_msg_debug(this->name, 0, "we're done locking"); int_lock->lock_op_ret = 0; int_lock->lock_cbk(frame, this); return 0; } if (!_is_lock_wind_needed(local, child_index)) { afr_lock_blocking(frame, this, cookie + 1); return 0; } afr_internal_lock_wind(frame, afr_lock_cbk, (void *)(long)cookie, child_index, lockee_num, _gf_true, _gf_false); return 0; } int32_t afr_blocking_lock(call_frame_t *frame, xlator_t *this) { afr_internal_lock_t *int_lock = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; int up_count = 0; priv = this->private; local = frame->local; int_lock = &local->internal_lock; up_count = AFR_COUNT(local->child_up, priv->child_count); int_lock->lk_call_count = int_lock->lk_expected_count = (int_lock->lockee_count * up_count); initialize_internal_lock_variables(frame, this); afr_lock_blocking(frame, this, 0); return 0; } static int32_t afr_nb_internal_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { afr_internal_lock_t *int_lock = NULL; afr_local_t *local = NULL; int call_count = 0; int child_index = 0; int lockee_num = 0; afr_private_t *priv = NULL; priv = this->private; child_index = ((long)cookie) % priv->child_count; lockee_num = ((long)cookie) / priv->child_count; local = frame->local; int_lock = &local->internal_lock; if (op_ret == 0 && local->transaction.type == AFR_DATA_TRANSACTION) { LOCK(&local->inode->lock); { local->inode_ctx->lock_count++; } UNLOCK(&local->inode->lock); } LOCK(&frame->lock); { if (op_ret < 0) { if (op_errno == ENOSYS) { /* return ENOTSUP */ gf_msg(this->name, GF_LOG_ERROR, ENOSYS, AFR_MSG_LOCK_XLATOR_NOT_LOADED, "subvolume does not support " "locking. please load features/locks" " xlator on server"); local->op_ret = op_ret; int_lock->lock_op_ret = op_ret; int_lock->lock_op_errno = op_errno; local->op_errno = op_errno; } } else if (op_ret == 0) { int_lock->lockee[lockee_num] .locked_nodes[child_index] |= LOCKED_YES; int_lock->lockee[lockee_num].locked_count++; int_lock->lock_count++; } call_count = --int_lock->lk_call_count; } UNLOCK(&frame->lock); if (call_count == 0) { gf_msg_trace(this->name, 0, "Last locking reply received"); /* all locks successful. Proceed to call FOP */ if (int_lock->lock_count == int_lock->lk_expected_count) { gf_msg_trace(this->name, 0, "All servers locked. Calling the cbk"); int_lock->lock_op_ret = 0; int_lock->lock_cbk(frame, this); } /* Not all locks were successful. Unlock and try locking again, this time with serially blocking locks */ else { gf_msg_trace(this->name, 0, "%d servers locked. Trying again " "with blocking calls", int_lock->lock_count); afr_unlock_now(frame, this); } } return 0; } int afr_lock_nonblocking(call_frame_t *frame, xlator_t *this) { afr_internal_lock_t *int_lock = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; afr_fd_ctx_t *fd_ctx = NULL; int child = 0; int lockee_num = 0; int32_t call_count = 0; int i = 0; int ret = 0; local = frame->local; int_lock = &local->internal_lock; priv = this->private; initialize_internal_lock_variables(frame, this); if (local->fd) { fd_ctx = afr_fd_ctx_get(local->fd, this); if (!fd_ctx) { gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_FD_CTX_GET_FAILED, "unable to get fd ctx for fd=%p", local->fd); local->op_ret = -1; int_lock->lock_op_ret = -1; local->op_errno = EINVAL; int_lock->lock_op_errno = EINVAL; afr_unlock_now(frame, this); ret = -1; goto out; } } call_count = int_lock->lockee_count * internal_lock_count(frame, this); int_lock->lk_call_count = call_count; int_lock->lk_expected_count = call_count; if (!call_count) { gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_INFO_COMMON, "fd not open on any subvolumes. aborting."); afr_unlock_now(frame, this); goto out; } /* Send non-blocking lock calls only on up children and where the fd has been opened */ for (i = 0; i < int_lock->lockee_count * priv->child_count; i++) { child = i % priv->child_count; lockee_num = i / priv->child_count; if (local->child_up[child]) { afr_internal_lock_wind(frame, afr_nb_internal_lock_cbk, (void *)(long)i, child, lockee_num, _gf_false, _gf_false); if (!--call_count) break; } } out: return ret; } int32_t afr_unlock(call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_lock_t *lock = NULL; local = frame->local; if (!local->transaction.eager_lock_on) goto out; lock = &local->inode_ctx->lock[local->transaction.type]; LOCK(&local->inode->lock); { list_del_init(&local->transaction.owner_list); if (list_empty(&lock->owners) && list_empty(&lock->post_op)) { local->transaction.do_eager_unlock = _gf_true; /*TODO: Need to get metadata use on_disk and inherit/uninherit *GF_ASSERT (!local->inode_ctx->on_disk[local->transaction.type]); *GF_ASSERT (!local->inode_ctx->inherited[local->transaction.type]); */ GF_ASSERT(lock->release); } } UNLOCK(&local->inode->lock); if (!local->transaction.do_eager_unlock) { local->internal_lock.lock_cbk(frame, this); return 0; } out: afr_unlock_now(frame, this); return 0; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-inode-write.h0000644000000000000000000000013214522202451024241 xustar000000000000000030 mtime=1699284265.615027275 30 atime=1699284265.615027275 30 ctime=1699284301.095134141 glusterfs-11.1/xlators/cluster/afr/src/afr-inode-write.h0000664000175100017510000000452714522202451024530 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __INODE_WRITE_H__ #define __INODE_WRITE_H__ int32_t afr_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata); int32_t afr_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata); int32_t afr_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata); int afr_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *buf, int32_t valid, dict_t *xdata); int afr_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *buf, int32_t valid, dict_t *xdata); int32_t afr_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata); int32_t afr_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata); int32_t afr_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata); int32_t afr_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata); int afr_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata); int afr_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata); int afr_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata); int32_t afr_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata); int32_t afr_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata); int afr_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata); #endif /* __INODE_WRITE_H__ */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202462023143 xustar000000000000000030 mtime=1699284274.446053875 30 atime=1699284289.043097841 30 ctime=1699284301.089134123 glusterfs-11.1/xlators/cluster/afr/src/Makefile.in0000664000175100017510000006617714522202462023443 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/cluster/afr/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) afr_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am__objects_1 = afr-dir-read.lo afr-dir-write.lo afr-inode-read.lo \ afr-inode-write.lo afr-open.lo afr-transaction.lo \ afr-lk-common.lo afr-read-txn.lo libxlator.lo am__objects_2 = afr-self-heal-common.lo afr-self-heal-data.lo \ afr-self-heal-entry.lo afr-self-heal-metadata.lo \ afr-self-heald.lo afr-self-heal-name.lo am_afr_la_OBJECTS = $(am__objects_1) $(am__objects_2) afr.lo afr_la_OBJECTS = $(am_afr_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = afr_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(afr_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(afr_la_SOURCES) DIST_SOURCES = $(afr_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = afr.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster afr_common_source = afr-dir-read.c afr-dir-write.c afr-inode-read.c \ afr-inode-write.c afr-open.c afr-transaction.c afr-lk-common.c \ afr-read-txn.c \ $(top_builddir)/xlators/lib/src/libxlator.c AFR_SELFHEAL_SOURCES = afr-self-heal-common.c afr-self-heal-data.c \ afr-self-heal-entry.c afr-self-heal-metadata.c afr-self-heald.c \ afr-self-heal-name.c afr_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) afr_la_SOURCES = $(afr_common_source) $(AFR_SELFHEAL_SOURCES) afr.c afr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = afr.h afr-transaction.h afr-inode-write.h afr-inode-read.h \ afr-dir-read.h afr-dir-write.h afr-self-heal.h afr-mem-types.h \ afr-common.c afr-self-heald.h \ $(top_builddir)/xlators/lib/src/libxlator.h afr-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) \ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/xlators/lib/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/cluster/afr/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/cluster/afr/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } afr.la: $(afr_la_OBJECTS) $(afr_la_DEPENDENCIES) $(EXTRA_afr_la_DEPENDENCIES) $(AM_V_CCLD)$(afr_la_LINK) -rpath $(xlatordir) $(afr_la_OBJECTS) $(afr_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-dir-read.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-dir-write.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-inode-read.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-inode-write.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-lk-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-open.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-read-txn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-self-heal-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-self-heal-data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-self-heal-entry.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-self-heal-metadata.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-self-heal-name.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-self-heald.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr-transaction.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxlator.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libxlator.lo: $(top_builddir)/xlators/lib/src/libxlator.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxlator.lo -MD -MP -MF $(DEPDIR)/libxlator.Tpo -c -o libxlator.lo `test -f '$(top_builddir)/xlators/lib/src/libxlator.c' || echo '$(srcdir)/'`$(top_builddir)/xlators/lib/src/libxlator.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxlator.Tpo $(DEPDIR)/libxlator.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_builddir)/xlators/lib/src/libxlator.c' object='libxlator.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxlator.lo `test -f '$(top_builddir)/xlators/lib/src/libxlator.c' || echo '$(srcdir)/'`$(top_builddir)/xlators/lib/src/libxlator.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-xlatorLTLIBRARIES .MAKE: install-am install-data-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-hook install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-local uninstall-xlatorLTLIBRARIES uninstall-local: rm -f $(DESTDIR)$(xlatordir)/replicate.so install-data-hook: ln -sf afr.so $(DESTDIR)$(xlatordir)/replicate.so # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-self-heald.h0000644000000000000000000000013214522202451024017 xustar000000000000000030 mtime=1699284265.619027287 30 atime=1699284265.619027287 30 ctime=1699284301.105134171 glusterfs-11.1/xlators/cluster/afr/src/afr-self-heald.h0000664000175100017510000000326114522202451024300 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _AFR_SELF_HEALD_H #define _AFR_SELF_HEALD_H #include typedef struct { char *path; int child; } shd_event_t; typedef struct { uint64_t healed_count; uint64_t split_brain_count; uint64_t heal_failed_count; /* If start_time is 0, it means crawler is not in progress and stats are not valid */ time_t start_time; /* If start_time is NOT 0 and end_time is 0, it means cralwer is in progress */ time_t end_time; char *crawl_type; int child; } crawl_event_t; struct subvol_healer { xlator_t *this; crawl_event_t crawl_event; pthread_mutex_t mutex; pthread_cond_t cond; pthread_t thread; int subvol; gf_boolean_t local; gf_boolean_t running; gf_boolean_t rerun; }; typedef struct { struct subvol_healer *index_healers; struct subvol_healer *full_healers; eh_t *split_brain; eh_t **statistics; time_t timeout; uint32_t max_threads; uint32_t wait_qlength; uint32_t halo_max_latency_msec; gf_boolean_t iamshd; gf_boolean_t enabled; } afr_self_heald_t; int afr_selfheal_daemon_init(xlator_t *this); int afr_xl_op(xlator_t *this, dict_t *input, dict_t *output); int afr_shd_entry_purge(xlator_t *subvol, inode_t *inode, char *name, ia_type_t type); #endif /* !_AFR_SELF_HEALD_H */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-self-heal-data.c0000644000000000000000000000013214522202451024555 xustar000000000000000030 mtime=1699284265.617027281 30 atime=1699284265.617027281 30 ctime=1699284301.125134231 glusterfs-11.1/xlators/cluster/afr/src/afr-self-heal-data.c0000664000175100017510000006514114522202451025043 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "afr.h" #include "afr-self-heal.h" #include "protocol-common.h" #include "afr-messages.h" #include #include #define HAS_HOLES(i) ((i->ia_blocks * 512) < (i->ia_size)) static int __checksum_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, uint32_t weak, uint8_t *strong, dict_t *xdata) { afr_local_t *local = NULL; struct afr_reply *replies = NULL; int i = (long)cookie; local = frame->local; replies = local->replies; replies[i].valid = 1; replies[i].op_ret = op_ret; replies[i].op_errno = op_errno; if (xdata) { replies[i].buf_has_zeroes = dict_get_str_boolean( xdata, "buf-has-zeroes", _gf_false); replies[i].fips_mode_rchecksum = dict_get_str_boolean( xdata, "fips-mode-rchecksum", _gf_false); } if (strong) { if (replies[i].fips_mode_rchecksum) { memcpy(local->replies[i].checksum, strong, SHA256_DIGEST_LENGTH); } else { memcpy(local->replies[i].checksum, strong, MD5_DIGEST_LENGTH); } } syncbarrier_wake(&local->barrier); return 0; } static gf_boolean_t __afr_can_skip_data_block_heal(call_frame_t *frame, xlator_t *this, fd_t *fd, int source, unsigned char *healed_sinks, off_t offset, size_t size, struct iatt *poststat) { afr_private_t *priv = NULL; afr_local_t *local = NULL; unsigned char *wind_subvols = NULL; gf_boolean_t checksum_match = _gf_true; struct afr_reply *replies = NULL; dict_t *xdata = NULL; int i = 0; priv = this->private; local = frame->local; replies = local->replies; xdata = dict_new(); if (!xdata) goto out; if (dict_set_int32_sizen(xdata, "check-zero-filled", 1)) { dict_unref(xdata); goto out; } wind_subvols = alloca0(priv->child_count); for (i = 0; i < priv->child_count; i++) { if (i == source || healed_sinks[i]) wind_subvols[i] = 1; } AFR_ONLIST(wind_subvols, frame, __checksum_cbk, rchecksum, fd, offset, size, xdata); if (xdata) dict_unref(xdata); if (!replies[source].valid || replies[source].op_ret != 0) return _gf_false; for (i = 0; i < priv->child_count; i++) { if (i == source) continue; if (replies[i].valid) { if (memcmp(replies[source].checksum, replies[i].checksum, replies[source].fips_mode_rchecksum ? SHA256_DIGEST_LENGTH : MD5_DIGEST_LENGTH)) { checksum_match = _gf_false; break; } } } if (checksum_match) { if (HAS_HOLES(poststat)) return _gf_true; /* For non-sparse files, we might be better off writing the * zeroes to sinks to avoid mismatch of disk-usage in bricks. */ if (local->replies[source].buf_has_zeroes) return _gf_false; else return _gf_true; } out: return _gf_false; } static gf_boolean_t __afr_is_sink_zero_filled(xlator_t *this, fd_t *fd, size_t size, off_t offset, int sink) { afr_private_t *priv = NULL; struct iobref *iobref = NULL; struct iovec *iovec = NULL; int count = 0; int ret = 0; gf_boolean_t zero_filled = _gf_false; priv = this->private; ret = syncop_readv(priv->children[sink], fd, size, offset, 0, &iovec, &count, &iobref, NULL, NULL, NULL); if (ret < 0) goto out; ret = iov_0filled(iovec, count); if (!ret) zero_filled = _gf_true; out: if (iovec) GF_FREE(iovec); if (iobref) iobref_unref(iobref); return zero_filled; } static int __afr_selfheal_data_read_write(call_frame_t *frame, xlator_t *this, fd_t *fd, int source, unsigned char *healed_sinks, off_t offset, size_t size, struct afr_reply *replies, int type) { struct iovec *iovec = NULL; int count = 0; struct iobref *iobref = NULL; int ret = 0; int i = 0; afr_private_t *priv = NULL; priv = this->private; ret = syncop_readv(priv->children[source], fd, size, offset, 0, &iovec, &count, &iobref, NULL, NULL, NULL); if (ret <= 0) return ret; for (i = 0; i < priv->child_count; i++) { if (!healed_sinks[i]) continue; /* * TODO: Use fiemap() and discard() to heal holes * in the future. * * For now, * * - if the source had any holes at all, * AND * - if we are writing past the original file size * of the sink * AND * - is NOT the last block of the source file. if * the block contains EOF, it has to be written * in order to set the file size even if the * last block is 0-filled. * AND * - if the read buffer is filled with only 0's * * then, skip writing to this source. We don't depend * on the write to happen to update the size as we * have performed an ftruncate() upfront anyways. */ #define is_last_block(o, b, s) ((s >= o) && (s <= (o + b))) if (HAS_HOLES((&replies[source].poststat)) && offset >= replies[i].poststat.ia_size && !is_last_block(offset, size, replies[source].poststat.ia_size) && (iov_0filled(iovec, count) == 0)) continue; /* Avoid filling up sparse regions of the sink with 0-filled * writes.*/ if (type == AFR_SELFHEAL_DATA_FULL && HAS_HOLES((&replies[source].poststat)) && ((offset + size) <= replies[i].poststat.ia_size) && (iov_0filled(iovec, count) == 0) && __afr_is_sink_zero_filled(this, fd, size, offset, i)) { continue; } ret = syncop_writev(priv->children[i], fd, iovec, count, offset, iobref, 0, NULL, NULL, NULL, NULL); if (ret != iov_length(iovec, count)) { /* write() failed on this sink. unset the corresponding member in sinks[] (which is healed_sinks[] in the caller) so that this server does NOT get considered as successfully healed. */ healed_sinks[i] = 0; } } if (iovec) GF_FREE(iovec); if (iobref) iobref_unref(iobref); return ret; } static gf_boolean_t afr_source_sinks_locked(xlator_t *this, unsigned char *locked_on, int source, unsigned char *healed_sinks) { afr_private_t *priv = this->private; int i = 0; if (!locked_on[source]) return _gf_false; for (i = 0; i < priv->child_count; i++) { if (healed_sinks[i] && locked_on[i]) return _gf_true; } return _gf_false; } static int afr_selfheal_data_block(call_frame_t *frame, xlator_t *this, fd_t *fd, int source, unsigned char *healed_sinks, off_t offset, size_t size, int type, struct afr_reply *replies) { int ret = -1; afr_private_t *priv = NULL; unsigned char *data_lock = NULL; priv = this->private; data_lock = alloca0(priv->child_count); gf_msg_debug(this->name, 0, "gfid:%s, offset=%jd, size=%zu", uuid_utoa(fd->inode->gfid), offset, size); ret = afr_selfheal_inodelk(frame, this, fd->inode, this->name, offset, size, data_lock); { if (!afr_source_sinks_locked(this, data_lock, source, healed_sinks)) { ret = -ENOTCONN; goto unlock; } if (type == AFR_SELFHEAL_DATA_DIFF && __afr_can_skip_data_block_heal(frame, this, fd, source, healed_sinks, offset, size, &replies[source].poststat)) { ret = 0; goto unlock; } ret = __afr_selfheal_data_read_write( frame, this, fd, source, healed_sinks, offset, size, replies, type); } unlock: afr_selfheal_uninodelk(frame, this, fd->inode, this->name, offset, size, data_lock); return ret; } static int afr_selfheal_data_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, unsigned char *healed_sinks) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; local = frame->local; priv = this->private; if (!priv->ensure_durability) return 0; AFR_ONLIST(healed_sinks, frame, afr_sh_generic_fop_cbk, fsync, fd, 0, NULL); for (i = 0; i < priv->child_count; i++) if (healed_sinks[i] && local->replies[i].op_ret != 0) /* fsync() failed. Do NOT consider this server as successfully healed. Mark it so. */ healed_sinks[i] = 0; return 0; } static int afr_data_self_heal_type_get(afr_private_t *priv, unsigned char *healed_sinks, int source, struct afr_reply *replies) { int type = AFR_SELFHEAL_DATA_FULL; int i = 0; if (priv->data_self_heal_algorithm == AFR_SELFHEAL_DATA_DYNAMIC) { type = AFR_SELFHEAL_DATA_FULL; for (i = 0; i < priv->child_count; i++) { if (!healed_sinks[i] && i != source) continue; if (replies[i].poststat.ia_size) { type = AFR_SELFHEAL_DATA_DIFF; break; } } } else { type = priv->data_self_heal_algorithm; } return type; } static int afr_selfheal_data_do(call_frame_t *frame, xlator_t *this, fd_t *fd, int source, unsigned char *healed_sinks, struct afr_reply *replies) { afr_private_t *priv = NULL; off_t off = 0; size_t block = 0; int type = AFR_SELFHEAL_DATA_FULL; int ret = -1; call_frame_t *iter_frame = NULL; unsigned char arbiter_sink_status = 0; gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_SELF_HEAL_INFO, "performing data selfheal on %s", uuid_utoa(fd->inode->gfid)); priv = this->private; if (priv->arbiter_count) { arbiter_sink_status = healed_sinks[ARBITER_BRICK_INDEX]; healed_sinks[ARBITER_BRICK_INDEX] = 0; } block = 128 * 1024 * priv->data_self_heal_window_size; if (HAS_HOLES((&replies[source].poststat))) { /*Reduce the possibility of data-block allocations in case of files * with holes. Correct way to fix it would be to use seek fop while * healing data*/ block = 128 * 1024; } type = afr_data_self_heal_type_get(priv, healed_sinks, source, replies); iter_frame = afr_copy_frame(frame); if (!iter_frame) { ret = -ENOMEM; goto out; } for (off = 0; off < replies[source].poststat.ia_size; off += block) { if (AFR_COUNT(healed_sinks, priv->child_count) == 0) { ret = -ENOTCONN; goto out; } ret = afr_selfheal_data_block(iter_frame, this, fd, source, healed_sinks, off, block, type, replies); if (ret < 0) goto out; AFR_STACK_RESET(iter_frame); if (iter_frame->local == NULL) { ret = -ENOTCONN; goto out; } } ret = afr_selfheal_data_fsync(frame, this, fd, healed_sinks); out: if (arbiter_sink_status) healed_sinks[ARBITER_BRICK_INDEX] = arbiter_sink_status; if (iter_frame) AFR_STACK_DESTROY(iter_frame); return ret; } static int __afr_selfheal_truncate_sinks(call_frame_t *frame, xlator_t *this, fd_t *fd, unsigned char *healed_sinks, uint64_t size) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; local = frame->local; priv = this->private; /* This will send truncate on the arbiter brick as well if it is marked as * sink. If changelog is enabled on the volume it captures truncate as a * data transactions on the arbiter brick. This will help geo-rep to * properly sync the data from primary to secondary if arbiter is the ACTIVE * brick during syncing and which had got some entries healed for data as * part of self heal. */ AFR_ONLIST(healed_sinks, frame, afr_sh_generic_fop_cbk, ftruncate, fd, size, NULL); for (i = 0; i < priv->child_count; i++) if (healed_sinks[i] && local->replies[i].op_ret == -1) /* truncate() failed. Do NOT consider this server as successfully healed. Mark it so. */ healed_sinks[i] = 0; return 0; } static gf_boolean_t afr_has_source_witnesses(xlator_t *this, unsigned char *sources, uint64_t *witness) { int i = 0; afr_private_t *priv = NULL; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (sources[i] && witness[i]) return _gf_true; } return _gf_false; } static gf_boolean_t afr_does_size_mismatch(xlator_t *this, unsigned char *sources, struct afr_reply *replies) { int i = 0; afr_private_t *priv = NULL; struct iatt *min = NULL; struct iatt *max = NULL; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret < 0) continue; if (!sources[i]) continue; if (AFR_IS_ARBITER_BRICK(priv, i) && (replies[i].poststat.ia_size == 0)) continue; if (!min) min = &replies[i].poststat; if (!max) max = &replies[i].poststat; if (min->ia_size > replies[i].poststat.ia_size) min = &replies[i].poststat; if (max->ia_size < replies[i].poststat.ia_size) max = &replies[i].poststat; } if (min && max) { if (min->ia_size != max->ia_size) return _gf_true; } return _gf_false; } static void afr_mark_biggest_witness_as_source(xlator_t *this, unsigned char *sources, uint64_t *witness) { int i = 0; afr_private_t *priv = NULL; uint64_t biggest_witness = 0; priv = this->private; /* Find source with biggest witness count */ for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; if (biggest_witness < witness[i]) biggest_witness = witness[i]; } /* Mark files with less witness count as not source */ for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; if (witness[i] < biggest_witness) sources[i] = 0; } return; } /* This is a tie breaker function. Only one source be assigned here */ static void afr_mark_newest_file_as_source(xlator_t *this, unsigned char *sources, struct afr_reply *replies) { int i = 0; afr_private_t *priv = NULL; int source = -1; uint64_t max_ctime = 0; priv = this->private; /* Find source with latest ctime */ for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; if (max_ctime <= replies[i].poststat.ia_ctime) { source = i; max_ctime = replies[i].poststat.ia_ctime; } } /* Only mark one of the files as source to break ties */ memset(sources, 0, sizeof(*sources) * priv->child_count); sources[source] = 1; } static int __afr_selfheal_data_finalize_source( call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *locked_on, unsigned char *undid_pending, struct afr_reply *replies, uint64_t *witness) { afr_private_t *priv = NULL; int source = -1; int sources_count = 0; priv = this->private; sources_count = AFR_COUNT(sources, priv->child_count); if ((AFR_CMP(locked_on, healed_sinks, priv->child_count) == 0) || !sources_count) { /* split brain */ source = afr_mark_split_brain_source_sinks( frame, this, inode, sources, sinks, healed_sinks, locked_on, replies, AFR_DATA_TRANSACTION); if (source < 0) { gf_event(EVENT_AFR_SPLIT_BRAIN, "client-pid=%d;" "subvol=%s;type=data;" "file=%s", this->ctx->cmd_args.client_pid, this->name, uuid_utoa(inode->gfid)); return -EIO; } _afr_fav_child_reset_sink_xattrs( frame, this, inode, source, healed_sinks, undid_pending, AFR_DATA_TRANSACTION, locked_on, replies); goto out; } /* No split brain at this point. If we were called from * afr_heal_splitbrain_file(), abort.*/ if (afr_dict_contains_heal_op(frame)) return -EIO; /* If there are no witnesses/size-mismatches on sources we are done*/ if (!afr_does_size_mismatch(this, sources, replies) && !afr_has_source_witnesses(this, sources, witness)) goto out; afr_mark_largest_file_as_source(this, sources, replies); afr_mark_biggest_witness_as_source(this, sources, witness); afr_mark_newest_file_as_source(this, sources, replies); if (priv->arbiter_count) /* Choose non-arbiter brick as source for empty files. */ afr_mark_source_sinks_if_file_empty(this, sources, sinks, healed_sinks, locked_on, replies, AFR_DATA_TRANSACTION); out: afr_mark_active_sinks(this, sources, locked_on, healed_sinks); source = afr_choose_source_by_policy(priv, sources, AFR_DATA_TRANSACTION); return source; } /* * __afr_selfheal_data_prepare: * * This function inspects the on-disk xattrs and determines which subvols * are sources and sinks. * * The return value is the index of the subvolume to be used as the source * for self-healing, or -1 if no healing is necessary/split brain. */ int __afr_selfheal_data_prepare(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, struct afr_reply *replies, unsigned char *pflag) { int ret = -1; int source = -1; afr_private_t *priv = NULL; uint64_t *witness = NULL; priv = this->private; ret = afr_selfheal_unlocked_discover(frame, inode, inode->gfid, replies); if (ret) return ret; witness = alloca0(priv->child_count * sizeof(*witness)); ret = afr_selfheal_find_direction(frame, this, replies, AFR_DATA_TRANSACTION, locked_on, sources, sinks, witness, pflag); if (ret) return ret; /* Initialize the healed_sinks[] array optimistically to the intersection of to-be-healed (i.e sinks[]) and the list of servers which are up (i.e locked_on[]). As we encounter failures in the healing process, we will unmark the respective servers in the healed_sinks[] array. */ AFR_INTERSECT(healed_sinks, sinks, locked_on, priv->child_count); source = __afr_selfheal_data_finalize_source( frame, this, inode, sources, sinks, healed_sinks, locked_on, undid_pending, replies, witness); if (source < 0) return -EIO; return source; } static int __afr_selfheal_data(call_frame_t *frame, xlator_t *this, fd_t *fd, unsigned char *locked_on) { afr_private_t *priv = NULL; int ret = -1; unsigned char *sources = NULL; unsigned char *sinks = NULL; unsigned char *data_lock = NULL; unsigned char *healed_sinks = NULL; unsigned char *undid_pending = NULL; struct afr_reply *locked_replies = NULL; int source = -1; gf_boolean_t did_sh = _gf_true; gf_boolean_t is_arbiter_the_only_sink = _gf_false; gf_boolean_t empty_file = _gf_false; priv = this->private; sources = alloca0(priv->child_count); sinks = alloca0(priv->child_count); healed_sinks = alloca0(priv->child_count); data_lock = alloca0(priv->child_count); undid_pending = alloca0(priv->child_count); locked_replies = alloca0(sizeof(*locked_replies) * priv->child_count); ret = afr_selfheal_inodelk(frame, this, fd->inode, this->name, 0, 0, data_lock); { if (ret < priv->child_count) { gf_msg_debug(this->name, 0, "%s: Skipping " "self-heal as only %d number " "of subvolumes " "could be locked", uuid_utoa(fd->inode->gfid), ret); ret = -ENOTCONN; goto unlock; } ret = __afr_selfheal_data_prepare(frame, this, fd->inode, data_lock, sources, sinks, healed_sinks, undid_pending, locked_replies, NULL); if (ret < 0) goto unlock; if (AFR_COUNT(healed_sinks, priv->child_count) == 0) { did_sh = _gf_false; goto unlock; } source = ret; if (AFR_IS_ARBITER_BRICK(priv, source)) { empty_file = afr_is_file_empty_on_all_children(priv, locked_replies); if (empty_file) goto restore_time; did_sh = _gf_false; goto unlock; } ret = __afr_selfheal_truncate_sinks( frame, this, fd, healed_sinks, locked_replies[source].poststat.ia_size); if (ret < 0) goto unlock; if (priv->arbiter_count && AFR_COUNT(healed_sinks, priv->child_count) == 1 && healed_sinks[ARBITER_BRICK_INDEX]) { is_arbiter_the_only_sink = _gf_true; goto restore_time; } ret = 0; } unlock: afr_selfheal_uninodelk(frame, this, fd->inode, this->name, 0, 0, data_lock); if (ret < 0) goto out; if (!did_sh) goto out; ret = afr_selfheal_data_do(frame, this, fd, source, healed_sinks, locked_replies); if (ret) goto out; restore_time: afr_selfheal_restore_time(frame, this, fd->inode, source, healed_sinks, locked_replies); if (!is_arbiter_the_only_sink && !empty_file) { ret = afr_selfheal_inodelk(frame, this, fd->inode, this->name, 0, 0, data_lock); if (ret < priv->child_count) { ret = -ENOTCONN; did_sh = _gf_false; goto skip_undo_pending; } } ret = afr_selfheal_undo_pending( frame, this, fd->inode, sources, sinks, healed_sinks, undid_pending, AFR_DATA_TRANSACTION, locked_replies, data_lock); skip_undo_pending: afr_selfheal_uninodelk(frame, this, fd->inode, this->name, 0, 0, data_lock); out: if (did_sh) afr_log_selfheal(fd->inode->gfid, this, ret, "data", source, sources, healed_sinks); else ret = 1; if (locked_replies) afr_replies_wipe(locked_replies, priv->child_count); return ret; } static int afr_selfheal_data_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { afr_local_t *local = NULL; int i = (long)cookie; local = frame->local; local->replies[i].valid = 1; local->replies[i].op_ret = op_ret; local->replies[i].op_errno = op_errno; syncbarrier_wake(&local->barrier); return 0; } int afr_selfheal_data_open(xlator_t *this, inode_t *inode, fd_t **fd) { int ret = 0; fd_t *fd_tmp = NULL; loc_t loc = { 0, }; call_frame_t *frame = NULL; afr_local_t *local = NULL; afr_private_t *priv = NULL; int i = 0; priv = this->private; fd_tmp = fd_create(inode, 0); if (!fd_tmp) return -ENOMEM; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); frame = afr_frame_create(this, &ret); if (!frame) { ret = -ret; fd_unref(fd_tmp); goto out; } local = frame->local; AFR_ONLIST(local->child_up, frame, afr_selfheal_data_open_cbk, open, &loc, O_RDWR | O_LARGEFILE, fd_tmp, NULL); ret = -ENOTCONN; for (i = 0; i < priv->child_count; i++) { if (!local->replies[i].valid) continue; if (local->replies[i].op_ret < 0) { ret = -local->replies[i].op_errno; continue; } ret = 0; break; } if (ret < 0) { fd_unref(fd_tmp); goto out; } else { fd_bind(fd_tmp); } *fd = fd_tmp; out: loc_wipe(&loc); if (frame) AFR_STACK_DESTROY(frame); return ret; } int afr_selfheal_data(call_frame_t *frame, xlator_t *this, fd_t *fd) { afr_private_t *priv = NULL; unsigned char *locked_on = NULL; int ret = 0; inode_t *inode = fd->inode; priv = this->private; locked_on = alloca0(priv->child_count); ret = afr_selfheal_tie_breaker_inodelk(frame, this, inode, priv->sh_domain, 0, 0, locked_on); { if (ret < priv->child_count) { gf_msg_debug(this->name, 0, "%s: Skipping " "self-heal as only %d number of " "subvolumes could be locked", uuid_utoa(fd->inode->gfid), ret); /* Either less than two subvols available, or another selfheal (from another server) is in progress. Skip for now in any case there isn't anything to do. */ ret = -ENOTCONN; goto unlock; } ret = __afr_selfheal_data(frame, this, fd, locked_on); } unlock: afr_selfheal_uninodelk(frame, this, inode, priv->sh_domain, 0, 0, locked_on); return ret; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023130 xustar000000000000000030 mtime=1699284265.611027263 30 atime=1699284274.404053748 30 ctime=1699284301.091134129 glusterfs-11.1/xlators/cluster/afr/src/Makefile.am0000664000175100017510000000234314522202451023411 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = afr.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster afr_common_source = afr-dir-read.c afr-dir-write.c afr-inode-read.c \ afr-inode-write.c afr-open.c afr-transaction.c afr-lk-common.c \ afr-read-txn.c \ $(top_builddir)/xlators/lib/src/libxlator.c AFR_SELFHEAL_SOURCES = afr-self-heal-common.c afr-self-heal-data.c \ afr-self-heal-entry.c afr-self-heal-metadata.c afr-self-heald.c \ afr-self-heal-name.c afr_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) afr_la_SOURCES = $(afr_common_source) $(AFR_SELFHEAL_SOURCES) afr.c afr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = afr.h afr-transaction.h afr-inode-write.h afr-inode-read.h \ afr-dir-read.h afr-dir-write.h afr-self-heal.h afr-mem-types.h \ afr-common.c afr-self-heald.h \ $(top_builddir)/xlators/lib/src/libxlator.h afr-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) \ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/xlators/lib/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = uninstall-local: rm -f $(DESTDIR)$(xlatordir)/replicate.so install-data-hook: ln -sf afr.so $(DESTDIR)$(xlatordir)/replicate.so glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr.c0000644000000000000000000000013014522202451022006 xustar000000000000000029 mtime=1699284265.62002729 29 atime=1699284265.62002729 30 ctime=1699284301.132134252 glusterfs-11.1/xlators/cluster/afr/src/afr.c0000664000175100017510000013622714522202451022302 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include "afr-common.c" #include "afr-messages.h" struct volume_options options[]; static char *afr_favorite_child_policies[AFR_FAV_CHILD_POLICY_MAX + 1] = { [AFR_FAV_CHILD_NONE] = "none", [AFR_FAV_CHILD_BY_SIZE] = "size", [AFR_FAV_CHILD_BY_CTIME] = "ctime", [AFR_FAV_CHILD_BY_MTIME] = "mtime", [AFR_FAV_CHILD_BY_MAJORITY] = "majority", [AFR_FAV_CHILD_POLICY_MAX] = NULL, }; int32_t notify(xlator_t *this, int32_t event, void *data, ...) { int ret = -1; va_list ap; void *data2 = NULL; va_start(ap, data); data2 = va_arg(ap, dict_t *); va_end(ap); ret = afr_notify(this, event, data, data2); return ret; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_afr_mt_end); if (ret != 0) { return ret; } return ret; } static int xlator_subvolume_index(xlator_t *this, xlator_t *subvol) { int index = -1; int i = 0; xlator_list_t *list = NULL; list = this->children; while (list) { if (subvol == list->xlator || strcmp(subvol->name, list->xlator->name) == 0) { index = i; break; } list = list->next; i++; } return index; } static void fix_quorum_options(xlator_t *this, afr_private_t *priv, char *qtype, dict_t *options) { if (dict_get_sizen(options, "quorum-type") == NULL) { /* If user doesn't configure anything enable auto-quorum if the * replica has more than two subvolumes */ if (priv->child_count > 2) qtype = "auto"; } if (priv->quorum_count && strcmp(qtype, "fixed")) { gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_QUORUM_OVERRIDE, "quorum-type %s overriding quorum-count %u", qtype, priv->quorum_count); } if (!strcmp(qtype, "none")) { priv->quorum_count = 0; } else if (!strcmp(qtype, "auto")) { priv->quorum_count = AFR_QUORUM_AUTO; } } static int afr_set_favorite_child_policy(afr_private_t *priv, char *policy) { int index = -1; index = gf_get_index_by_elem(afr_favorite_child_policies, policy); if (index < 0 || index >= AFR_FAV_CHILD_POLICY_MAX) return -1; priv->fav_child_policy = index; return 0; } static void set_data_self_heal_algorithm(afr_private_t *priv, char *algo) { if (!algo) { priv->data_self_heal_algorithm = AFR_SELFHEAL_DATA_DYNAMIC; } else if (strcmp(algo, "full") == 0) { priv->data_self_heal_algorithm = AFR_SELFHEAL_DATA_FULL; } else if (strcmp(algo, "diff") == 0) { priv->data_self_heal_algorithm = AFR_SELFHEAL_DATA_DIFF; } else { priv->data_self_heal_algorithm = AFR_SELFHEAL_DATA_DYNAMIC; } } static void afr_handle_anon_inode_options(afr_private_t *priv, dict_t *options) { char *volfile_id_str = NULL; uuid_t anon_inode_gfid = {0}; /* If volume id is not present don't enable anything. */ if (dict_get_str(options, "volume-id", &volfile_id_str)) return; /* Note anon_inode_name is not supposed to change once assigned. */ if (!priv->anon_inode_name[0]) { int nr = snprintf(priv->anon_inode_name, NAME_MAX, "%s-%s", AFR_ANON_DIR_PREFIX, volfile_id_str); /* Check whether an output was not truncated. */ GF_ASSERT(nr < NAME_MAX); gf_uuid_parse(volfile_id_str, anon_inode_gfid); /* Flip a bit to make sure volfile-id and anon-gfid are not same. */ anon_inode_gfid[0] ^= 1; uuid_utoa_r(anon_inode_gfid, priv->anon_gfid_str); } } int reconfigure(xlator_t *this, dict_t *options) { afr_private_t *priv = NULL; xlator_t *read_subvol = NULL; int read_subvol_index = -1; time_t timeout_old = 0; int ret = -1; int index = -1; char *qtype = NULL; char *fav_child_policy = NULL; char *data_self_heal = NULL; char *data_self_heal_algorithm = NULL; char *locking_scheme = NULL; gf_boolean_t consistent_io = _gf_false; gf_boolean_t choose_local_old = _gf_false; gf_boolean_t enabled_old = _gf_false; priv = this->private; GF_OPTION_RECONF("metadata-splitbrain-forced-heal", priv->metadata_splitbrain_forced_heal, options, bool, out); GF_OPTION_RECONF("background-self-heal-count", priv->background_self_heal_count, options, uint32, out); GF_OPTION_RECONF("heal-wait-queue-length", priv->heal_wait_qlen, options, uint32, out); GF_OPTION_RECONF("metadata-self-heal", priv->metadata_self_heal, options, bool, out); GF_OPTION_RECONF("data-self-heal", data_self_heal, options, str, out); if (gf_string2boolean(data_self_heal, &priv->data_self_heal) == -1) goto out; GF_OPTION_RECONF("entry-self-heal", priv->entry_self_heal, options, bool, out); GF_OPTION_RECONF("data-self-heal-window-size", priv->data_self_heal_window_size, options, uint32, out); GF_OPTION_RECONF("data-self-heal-algorithm", data_self_heal_algorithm, options, str, out); set_data_self_heal_algorithm(priv, data_self_heal_algorithm); GF_OPTION_RECONF("halo-enabled", priv->halo_enabled, options, bool, out); GF_OPTION_RECONF("halo-shd-max-latency", priv->shd.halo_max_latency_msec, options, uint32, out); GF_OPTION_RECONF("halo-nfsd-max-latency", priv->nfsd.halo_max_latency_msec, options, uint32, out); GF_OPTION_RECONF("halo-max-latency", priv->halo_max_latency_msec, options, uint32, out); GF_OPTION_RECONF("halo-max-replicas", priv->halo_max_replicas, options, uint32, out); GF_OPTION_RECONF("halo-min-replicas", priv->halo_min_replicas, options, uint32, out); GF_OPTION_RECONF("read-subvolume", read_subvol, options, xlator, out); choose_local_old = priv->choose_local; GF_OPTION_RECONF("choose-local", priv->choose_local, options, bool, out); if (choose_local_old != priv->choose_local) { priv->read_child = -1; if (choose_local_old == _gf_false) priv->did_discovery = _gf_false; } GF_OPTION_RECONF("read-hash-mode", priv->hash_mode, options, uint32, out); if (read_subvol) { index = xlator_subvolume_index(this, read_subvol); if (index == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_INVALID_SUBVOL, "%s not a subvolume", read_subvol->name); goto out; } priv->read_child = index; } GF_OPTION_RECONF("read-subvolume-index", read_subvol_index, options, int32, out); if (read_subvol_index > -1) { index = read_subvol_index; if (index >= priv->child_count) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_INVALID_SUBVOL, "%d not a subvolume-index", index); goto out; } priv->read_child = index; } GF_OPTION_RECONF("pre-op-compat", priv->pre_op_compat, options, bool, out); GF_OPTION_RECONF("locking-scheme", locking_scheme, options, str, out); priv->granular_locks = (strcmp(locking_scheme, "granular") == 0); GF_OPTION_RECONF("full-lock", priv->full_lock, options, bool, out); GF_OPTION_RECONF("granular-entry-heal", priv->esh_granular, options, bool, out); GF_OPTION_RECONF("eager-lock", priv->eager_lock, options, bool, out); GF_OPTION_RECONF("optimistic-change-log", priv->optimistic_change_log, options, bool, out); GF_OPTION_RECONF("quorum-type", qtype, options, str, out); GF_OPTION_RECONF("quorum-count", priv->quorum_count, options, uint32, out); fix_quorum_options(this, priv, qtype, options); if (priv->quorum_count && !afr_has_quorum(priv->child_up, priv, NULL)) gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_QUORUM_FAIL, "Client-quorum is not met"); GF_OPTION_RECONF("post-op-delay-secs", priv->post_op_delay_secs, options, uint32, out); /* Reset this so we re-discover in case the topology changed. */ GF_OPTION_RECONF("ensure-durability", priv->ensure_durability, options, bool, out); enabled_old = priv->shd.enabled; GF_OPTION_RECONF("self-heal-daemon", priv->shd.enabled, options, bool, out); GF_OPTION_RECONF("iam-self-heal-daemon", priv->shd.iamshd, options, bool, out); timeout_old = priv->shd.timeout; GF_OPTION_RECONF("heal-timeout", priv->shd.timeout, options, time, out); GF_OPTION_RECONF("consistent-metadata", priv->consistent_metadata, options, bool, out); GF_OPTION_RECONF("shd-max-threads", priv->shd.max_threads, options, uint32, out); GF_OPTION_RECONF("shd-wait-qlength", priv->shd.wait_qlength, options, uint32, out); GF_OPTION_RECONF("favorite-child-policy", fav_child_policy, options, str, out); if (afr_set_favorite_child_policy(priv, fav_child_policy) == -1) goto out; priv->did_discovery = _gf_false; GF_OPTION_RECONF("consistent-io", consistent_io, options, bool, out); if (priv->quorum_count != 0) consistent_io = _gf_false; priv->consistent_io = consistent_io; afr_handle_anon_inode_options(priv, options); GF_OPTION_RECONF("use-anonymous-inode", priv->use_anon_inode, options, bool, out); if (priv->shd.enabled) { if ((priv->shd.enabled != enabled_old) || (timeout_old != priv->shd.timeout)) afr_selfheal_childup(this, priv); } ret = 0; out: return ret; } static int afr_pending_xattrs_init(afr_private_t *priv, xlator_t *this) { int ret = -1; int i = 0; char *ptr = NULL; char *ptr1 = NULL; char *xattrs_list = NULL; xlator_list_t *trav = NULL; int child_count = -1; trav = this->children; child_count = priv->child_count; if (priv->thin_arbiter_count) { /* priv->pending_key[THIN_ARBITER_BRICK_INDEX] is used as the * name of the thin arbiter file for persistence across add/ * removal of DHT subvols.*/ child_count++; } GF_OPTION_INIT("afr-pending-xattr", xattrs_list, str, out); priv->pending_key = GF_CALLOC(sizeof(*priv->pending_key), child_count, gf_afr_mt_char); if (!priv->pending_key) { ret = -ENOMEM; goto out; } if (!xattrs_list) { gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_NO_CHANGELOG, "Unable to fetch afr-pending-xattr option from volfile." " Falling back to using client translator names. "); while (i < child_count) { ret = gf_asprintf(&priv->pending_key[i], "%s.%s", AFR_XATTR_PREFIX, trav->xlator->name); if (ret == -1) { ret = -ENOMEM; goto out; } trav = trav->next; i++; } ret = 0; goto out; } ptr = ptr1 = gf_strdup(xattrs_list); if (!ptr) { ret = -ENOMEM; goto out; } for (i = 0, ptr = strtok(ptr, ","); ptr; ptr = strtok(NULL, ",")) { ret = gf_asprintf(&priv->pending_key[i], "%s.%s", AFR_XATTR_PREFIX, ptr); if (ret == -1) { ret = -ENOMEM; goto out; } i++; } ret = 0; out: GF_FREE(ptr1); return ret; } void afr_ta_init(afr_private_t *priv) { priv->thin_arbiter_count = 1; priv->child_count--; priv->ta_child_up = 0; priv->ta_bad_child_index = AFR_CHILD_UNKNOWN; priv->ta_notify_dom_lock_offset = 0; priv->ta_in_mem_txn_count = 0; priv->ta_on_wire_txn_count = 0; priv->release_ta_notify_dom_lock = _gf_false; INIT_LIST_HEAD(&priv->ta_waitq); INIT_LIST_HEAD(&priv->ta_onwireq); gf_uuid_clear(priv->ta_gfid); } int32_t init(xlator_t *this) { afr_private_t *priv = NULL; int child_count = 0; xlator_list_t *trav = NULL; int i = 0; int ret = -1; GF_UNUSED int op_errno = 0; xlator_t *read_subvol = NULL; int read_subvol_index = -1; char *qtype = NULL; char *fav_child_policy = NULL; char *thin_arbiter = NULL; char *data_self_heal = NULL; char *locking_scheme = NULL; char *data_self_heal_algorithm = NULL; if (!this->children) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_CHILD_MISCONFIGURED, "replicate translator needs more than one " "subvolume defined."); return -1; } if (!this->parents) { gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_VOL_MISCONFIGURED, "Volume is dangling."); } this->private = GF_CALLOC(1, sizeof(afr_private_t), gf_afr_mt_afr_private_t); if (!this->private) goto out; priv = this->private; INIT_LIST_HEAD(&priv->saved_locks); INIT_LIST_HEAD(&priv->lk_healq); LOCK_INIT(&priv->lock); child_count = xlator_subvolume_count(this); priv->child_count = child_count; priv->read_child = -1; GF_OPTION_INIT("arbiter-count", priv->arbiter_count, uint32, out); GF_OPTION_INIT("thin-arbiter", thin_arbiter, str, out); if (thin_arbiter && strlen(thin_arbiter) > 0) { afr_ta_init(priv); } INIT_LIST_HEAD(&priv->healing); INIT_LIST_HEAD(&priv->heal_waiting); priv->spb_choice_timeout = AFR_DEFAULT_SPB_CHOICE_TIMEOUT; GF_OPTION_INIT("afr-dirty-xattr", priv->afr_dirty, str, out); GF_OPTION_INIT("metadata-splitbrain-forced-heal", priv->metadata_splitbrain_forced_heal, bool, out); GF_OPTION_INIT("read-subvolume", read_subvol, xlator, out); if (read_subvol) { priv->read_child = xlator_subvolume_index(this, read_subvol); if (priv->read_child == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_INVALID_SUBVOL, "%s not a subvolume", read_subvol->name); goto out; } } GF_OPTION_INIT("read-subvolume-index", read_subvol_index, int32, out); if (read_subvol_index > -1) { if (read_subvol_index >= priv->child_count) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_INVALID_SUBVOL, "%d not a subvolume-index", read_subvol_index); goto out; } priv->read_child = read_subvol_index; } GF_OPTION_INIT("choose-local", priv->choose_local, bool, out); priv->pending_reads = GF_CALLOC(sizeof(*priv->pending_reads), priv->child_count, gf_afr_mt_atomic_t); GF_OPTION_INIT("read-hash-mode", priv->hash_mode, uint32, out); priv->favorite_child = -1; GF_OPTION_INIT("favorite-child-policy", fav_child_policy, str, out); if (afr_set_favorite_child_policy(priv, fav_child_policy) == -1) goto out; GF_OPTION_INIT("shd-max-threads", priv->shd.max_threads, uint32, out); GF_OPTION_INIT("shd-wait-qlength", priv->shd.wait_qlength, uint32, out); GF_OPTION_INIT("background-self-heal-count", priv->background_self_heal_count, uint32, out); GF_OPTION_INIT("heal-wait-queue-length", priv->heal_wait_qlen, uint32, out); GF_OPTION_INIT("data-self-heal", data_self_heal, str, out); if (gf_string2boolean(data_self_heal, &priv->data_self_heal) == -1) goto out; GF_OPTION_INIT("data-self-heal-algorithm", data_self_heal_algorithm, str, out); set_data_self_heal_algorithm(priv, data_self_heal_algorithm); GF_OPTION_INIT("data-self-heal-window-size", priv->data_self_heal_window_size, uint32, out); GF_OPTION_INIT("metadata-self-heal", priv->metadata_self_heal, bool, out); GF_OPTION_INIT("entry-self-heal", priv->entry_self_heal, bool, out); GF_OPTION_INIT("halo-shd-max-latency", priv->shd.halo_max_latency_msec, uint32, out); GF_OPTION_INIT("halo-max-latency", priv->halo_max_latency_msec, uint32, out); GF_OPTION_INIT("halo-max-replicas", priv->halo_max_replicas, uint32, out); GF_OPTION_INIT("halo-min-replicas", priv->halo_min_replicas, uint32, out); GF_OPTION_INIT("halo-enabled", priv->halo_enabled, bool, out); GF_OPTION_INIT("halo-nfsd-max-latency", priv->nfsd.halo_max_latency_msec, uint32, out); GF_OPTION_INIT("iam-nfs-daemon", priv->nfsd.iamnfsd, bool, out); GF_OPTION_INIT("optimistic-change-log", priv->optimistic_change_log, bool, out); GF_OPTION_INIT("pre-op-compat", priv->pre_op_compat, bool, out); GF_OPTION_INIT("locking-scheme", locking_scheme, str, out); priv->granular_locks = (strcmp(locking_scheme, "granular") == 0); GF_OPTION_INIT("full-lock", priv->full_lock, bool, out); GF_OPTION_INIT("granular-entry-heal", priv->esh_granular, bool, out); GF_OPTION_INIT("eager-lock", priv->eager_lock, bool, out); GF_OPTION_INIT("quorum-type", qtype, str, out); GF_OPTION_INIT("quorum-count", priv->quorum_count, uint32, out); fix_quorum_options(this, priv, qtype, this->options); GF_OPTION_INIT("post-op-delay-secs", priv->post_op_delay_secs, uint32, out); GF_OPTION_INIT("ensure-durability", priv->ensure_durability, bool, out); GF_OPTION_INIT("self-heal-daemon", priv->shd.enabled, bool, out); GF_OPTION_INIT("iam-self-heal-daemon", priv->shd.iamshd, bool, out); GF_OPTION_INIT("heal-timeout", priv->shd.timeout, time, out); GF_OPTION_INIT("consistent-metadata", priv->consistent_metadata, bool, out); GF_OPTION_INIT("consistent-io", priv->consistent_io, bool, out); afr_handle_anon_inode_options(priv, this->options); GF_OPTION_INIT("use-anonymous-inode", priv->use_anon_inode, bool, out); if (priv->quorum_count != 0) priv->consistent_io = _gf_false; priv->wait_count = 1; priv->local = GF_CALLOC(sizeof(unsigned char), child_count, gf_afr_mt_char); if (!priv->local) { ret = -ENOMEM; goto out; } priv->anon_inode = GF_CALLOC(sizeof(unsigned char), child_count, gf_afr_mt_char); priv->child_up = GF_CALLOC(sizeof(unsigned char), child_count, gf_afr_mt_char); priv->child_latency = GF_MALLOC(sizeof(*priv->child_latency) * child_count, gf_afr_mt_child_latency_t); priv->halo_child_up = GF_CALLOC(sizeof(unsigned char), child_count, gf_afr_mt_char); if (!priv->child_up || !priv->child_latency || !priv->halo_child_up || !priv->anon_inode) { ret = -ENOMEM; goto out; } /*Initialize to -ve ping timeout so that they are not considered * in child-up events until ping-event comes*/ for (i = 0; i < child_count; i++) priv->child_latency[i] = -1; priv->children = GF_CALLOC(sizeof(xlator_t *), child_count, gf_afr_mt_xlator_t); if (!priv->children) { ret = -ENOMEM; goto out; } ret = afr_pending_xattrs_init(priv, this); if (ret) goto out; trav = this->children; i = 0; while (i < child_count) { priv->children[i] = trav->xlator; trav = trav->next; i++; } ret = gf_asprintf(&priv->sh_domain, AFR_SH_DATA_DOMAIN_FMT, this->name); if (-1 == ret) { ret = -ENOMEM; goto out; } priv->last_event = GF_CALLOC(child_count, sizeof(*priv->last_event), gf_afr_mt_int32_t); if (!priv->last_event) { ret = -ENOMEM; goto out; } if (priv->shd.iamshd) { /* Number of hash bucket should be prime number so declare 131 total dentry hash buckets */ this->itable = inode_table_new(SHD_INODE_LRU_LIMIT, this, 131, 128); } else { this->itable = inode_table_new(SHD_INODE_LRU_LIMIT, this, 0, 0); } if (!this->itable) { ret = -ENOMEM; goto out; } if (priv->shd.iamshd) { ret = afr_selfheal_daemon_init(this); if (ret) { ret = -ENOMEM; goto out; } } /* keep more local here as we may need them for self-heal etc */ this->local_pool = mem_pool_new(afr_local_t, 512); if (!this->local_pool) { ret = -1; goto out; } ret = 0; out: return ret; } static void afr_destroy_healer_object(xlator_t *this, struct subvol_healer *healer) { int ret = -1; if (!healer) return; if (healer->running) { /* * If there are any resources to cleanup, We need * to do that gracefully using pthread_cleanup_push */ ret = gf_thread_cleanup_xint(healer->thread); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, AFR_MSG_SELF_HEAL_FAILED, "Failed to clean up healer threads."); healer->thread = 0; } pthread_cond_destroy(&healer->cond); pthread_mutex_destroy(&healer->mutex); } static void afr_selfheal_daemon_fini(xlator_t *this) { struct subvol_healer *healer = NULL; afr_self_heald_t *shd = NULL; afr_private_t *priv = NULL; int i = 0; priv = this->private; if (!priv) return; shd = &priv->shd; if (!shd->iamshd) return; for (i = 0; i < priv->child_count; i++) { healer = &shd->index_healers[i]; afr_destroy_healer_object(this, healer); healer = &shd->full_healers[i]; afr_destroy_healer_object(this, healer); if (shd->statistics[i]) eh_destroy(shd->statistics[i]); } GF_FREE(shd->index_healers); GF_FREE(shd->full_healers); GF_FREE(shd->statistics); if (shd->split_brain) eh_destroy(shd->split_brain); } void fini(xlator_t *this) { afr_private_t *priv = NULL; priv = this->private; afr_selfheal_daemon_fini(this); GF_ASSERT(list_empty(&priv->saved_locks)); LOCK(&priv->lock); if (priv->timer != NULL) { gf_timer_call_cancel(this->ctx, priv->timer); priv->timer = NULL; } UNLOCK(&priv->lock); if (this->local_pool != NULL) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; } this->private = NULL; afr_priv_destroy(priv); if (this->itable) { inode_table_destroy(this->itable); this->itable = NULL; } return; } struct xlator_fops fops = { .lookup = afr_lookup, .lk = afr_lk, .flush = afr_flush, .statfs = afr_statfs, .fsyncdir = afr_fsyncdir, .inodelk = afr_inodelk, .finodelk = afr_finodelk, .entrylk = afr_entrylk, .fentrylk = afr_fentrylk, .ipc = afr_ipc, .lease = afr_lease, /* inode read */ .access = afr_access, .stat = afr_stat, .fstat = afr_fstat, .readlink = afr_readlink, .getxattr = afr_getxattr, .fgetxattr = afr_fgetxattr, .readv = afr_readv, .seek = afr_seek, /* inode write */ .writev = afr_writev, .truncate = afr_truncate, .ftruncate = afr_ftruncate, .setxattr = afr_setxattr, .fsetxattr = afr_fsetxattr, .setattr = afr_setattr, .fsetattr = afr_fsetattr, .removexattr = afr_removexattr, .fremovexattr = afr_fremovexattr, .fallocate = afr_fallocate, .discard = afr_discard, .zerofill = afr_zerofill, .xattrop = afr_xattrop, .fxattrop = afr_fxattrop, .fsync = afr_fsync, /*inode open*/ .opendir = afr_opendir, .open = afr_open, /* dir read */ .readdir = afr_readdir, .readdirp = afr_readdirp, /* dir write */ .create = afr_create, .mknod = afr_mknod, .mkdir = afr_mkdir, .unlink = afr_unlink, .rmdir = afr_rmdir, .link = afr_link, .symlink = afr_symlink, .rename = afr_rename, }; struct xlator_dumpops dumpops = { .priv = afr_priv_dump, }; struct xlator_cbks cbks = { .release = afr_release, .releasedir = afr_releasedir, .forget = afr_forget, }; struct volume_options options[] = { {.key = {"read-subvolume"}, .type = GF_OPTION_TYPE_XLATOR, .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "inode-read fops happen only on one of the bricks in " "replicate. Afr will prefer the one specified using " "this option if it is not stale. Option value must be " "one of the xlator names of the children. " "Ex: -client-0 till " "-client-"}, {.key = {"read-subvolume-index"}, .type = GF_OPTION_TYPE_INT, .default_value = "-1", .op_version = {2}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "inode-read fops happen only on one of the bricks in " "replicate. AFR will prefer the one specified using " "this option if it is not stale. allowed options" " include -1 till replica-count - 1"}, {.key = {"read-hash-mode"}, .type = GF_OPTION_TYPE_INT, .min = 0, .max = 5, .default_value = "1", .op_version = {2}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "inode-read fops happen only on one of the bricks in " "replicate. AFR will prefer the one computed using " "the method specified using this option.\n" "0 = first readable child of AFR, starting from 1st child.\n" "1 = hash by GFID of file (all clients use " "same subvolume).\n" "2 = hash by GFID of file and client PID.\n" "3 = brick having the least outstanding read requests.\n" "4 = brick having the least network ping latency.\n" "5 = Hybrid mode between 3 and 4, ie least value among " "network-latency multiplied by outstanding-read-requests."}, { .key = {"choose-local"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "true", .op_version = {2}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "Choose a local subvolume (i.e. Brick) to read from" " if read-subvolume is not explicitly set.", }, {.key = {"background-self-heal-count"}, .type = GF_OPTION_TYPE_INT, .min = 0, .max = 256, .default_value = "8", .validate = GF_OPT_VALIDATE_MIN, .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate"}, .description = "This specifies the number of per client self-heal " "jobs that can perform parallel heals in the " "background."}, {.key = {"halo-shd-max-latency"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 99999, .default_value = "99999", .op_version = {GD_OP_VERSION_3_11_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate", "halo"}, .description = "Maximum latency for shd halo replication in msec."}, {.key = {"halo-enabled"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "False", .op_version = {GD_OP_VERSION_3_11_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate", "halo"}, .description = "Enable Halo (geo) replication mode."}, {.key = {"halo-nfsd-max-latency"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 99999, .default_value = "5", .op_version = {GD_OP_VERSION_3_11_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate", "halo"}, .description = "Maximum latency for nfsd halo replication in msec."}, {.key = {"halo-max-latency"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = AFR_HALO_MAX_LATENCY, .default_value = "5", .op_version = {GD_OP_VERSION_3_11_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate", "halo"}, .description = "Maximum latency for halo replication in msec."}, {.key = {"halo-max-replicas"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 99999, .default_value = "99999", .op_version = {GD_OP_VERSION_3_11_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate", "halo"}, .description = "The maximum number of halo replicas; replicas" " beyond this value will be written asynchronously" "via the SHD."}, {.key = {"halo-min-replicas"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 99999, .default_value = "2", .op_version = {GD_OP_VERSION_3_11_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate", "halo"}, .description = "The minimmum number of halo replicas, before adding " "out of region replicas."}, {.key = {"heal-wait-queue-length"}, .type = GF_OPTION_TYPE_INT, .min = 0, .max = 10000, /*Around 100MB with sizeof(afr_local_t)= 10496 bytes*/ .default_value = "128", .validate = GF_OPT_VALIDATE_MIN, .op_version = {GD_OP_VERSION_3_7_10}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate"}, .description = "This specifies the number of heals that can be queued" " for the parallel background self heal jobs."}, {.key = {"data-self-heal"}, .type = GF_OPTION_TYPE_STR, .value = {"1", "on", "yes", "true", "enable", "0", "off", "no", "false", "disable", "open"}, .default_value = "off", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "Using this option we can enable/disable data " "self-heal on the file. \"open\" means data " "self-heal action will only be triggered by file " "open operations."}, {.key = {"data-self-heal-algorithm"}, .type = GF_OPTION_TYPE_STR, .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "Select between \"full\", \"diff\". The " "\"full\" algorithm copies the entire file from " "source to sink. The \"diff\" algorithm copies to " "sink only those blocks whose checksums don't match " "with those of source. If no option is configured " "the option is chosen dynamically as follows: " "If the file does not exist on one of the sinks " "or empty file exists or if the source file size is " "about the same as page size the entire file will " "be read and written i.e \"full\" algo, " "otherwise \"diff\" algo is chosen.", .value = {"diff", "full"}}, {.key = {"data-self-heal-window-size"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 1024, .default_value = "8", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate"}, .description = "Maximum number of 128KB blocks per file for which " "self-heal process would be applied simultaneously."}, {.key = {"metadata-self-heal"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, /*.validate_fn = validate_replica*/ .description = "Using this option we can enable/disable metadata " "i.e. Permissions, ownerships, xattrs self-heal on " "the file/directory."}, {.key = {"entry-self-heal"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, /*.validate_fn = validate_replica*/ .description = "Using this option we can enable/disable entry " "self-heal on the directory."}, {.key = {"data-change-log"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "This option exists only for backward compatibility " "and configuring it doesn't have any effect"}, {.key = {"metadata-change-log"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "This option exists only for backward compatibility " "and configuring it doesn't have any effect"}, {.key = {"entry-change-log"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "This option exists only for backward compatibility " "and configuring it doesn't have any effect"}, {.key = {"optimistic-change-log"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "Entry/Metadata fops will not perform " "pre fop changelog operations in afr transaction " "if this option is enabled."}, {.key = {"inodelk-trace"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "Enabling this option logs inode lock/unlocks"}, {.key = {"entrylk-trace"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "Enabling this option logs entry lock/unlocks"}, {.key = {"pre-op-compat"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "Use separate pre-op xattrop() FOP rather than " "overloading xdata of the OP"}, {.key = {"eager-lock"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "Enable/Disable eager lock for replica volume. " "Lock phase of a transaction has two sub-phases. " "First is an attempt to acquire locks in parallel by " "broadcasting non-blocking lock requests. If lock " "acquisition fails on any server, then the held locks " "are unlocked and we revert to a blocking locks mode " "sequentially on one server after another. If this " "option is enabled the initial broadcasting lock " "request attempts to acquire a full lock on the entire file. " "If this fails, we revert back to the sequential " "\"regional\" blocking locks as before. In the case " "where such an \"eager\" lock is granted in the " "non-blocking phase, it gives rise to an opportunity " "for optimization. i.e, if the next write transaction " "on the same FD arrives before the unlock phase of " "the first transaction, it \"takes over\" the full " "file lock. Similarly if yet another data transaction " "arrives before the unlock phase of the \"optimized\" " "transaction, that in turn \"takes over\" the lock as " "well. The actual unlock now happens at the end of " "the last \"optimized\" transaction." }, {.key = {"self-heal-daemon"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE, .tags = {"replicate"}, /*.validate_fn = validate_replica_heal_enable_disable*/ .description = "This option applies to only self-heal-daemon. " "Index directory crawl and automatic healing of files " "will not be performed if this option is turned off."}, {.key = {"iam-self-heal-daemon"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "This option differentiates if the replicate " "translator is running as part of self-heal-daemon " "or not."}, {.key = {"iam-nfs-daemon"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "This option differentiates if the replicate " "translator is running as part of an NFS daemon " "or not."}, { .key = {"quorum-type"}, .type = GF_OPTION_TYPE_STR, .value = {"none", "auto", "fixed"}, .default_value = "none", .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, /*.option = quorum-type*/ .description = "If value is \"fixed\" only allow writes if " "quorum-count bricks are present. If value is " "\"auto\" only allow writes if more than half of " "bricks, or exactly half including the first, are " "present.", }, { .key = {"quorum-count"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = INT_MAX, .default_value = 0, .op_version = {1}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate"}, /*.option = quorum-count*/ /*.validate_fn = validate_quorum_count*/ .description = "If quorum-type is \"fixed\" only allow writes if " "this many bricks are present. Other quorum types " "will OVERWRITE this value.", }, { .key = {"quorum-reads"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "no", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "This option has been removed. Reads are not allowed " "if quorum is not met.", }, { .key = {"node-uuid"}, .type = GF_OPTION_TYPE_STR, .description = "Local glusterd uuid string, used in starting " "self-heal-daemon so that it can crawl only on " "local index directories.", }, { .key = {"post-op-delay-secs"}, .type = GF_OPTION_TYPE_INT, .min = 0, .max = INT_MAX, .default_value = "1", .op_version = {2}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate"}, .description = "Time interval induced artificially before " "post-operation phase of the transaction to " "enhance overlap of adjacent write operations.", }, { .key = {"self-heal-readdir-size"}, .type = GF_OPTION_TYPE_SIZET, .description = "This option exists only for backward compatibility " "and configuring it doesn't have any effect", .min = 1024, .max = 131072, .op_version = {2}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE, .tags = {"replicate"}, .default_value = "1KB", }, { .key = {"ensure-durability"}, .type = GF_OPTION_TYPE_BOOL, .op_version = {3}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "Afr performs fsyncs for transactions if this " "option is on to make sure the changelogs/data is " "written to the disk. Please note that disabling this " "option can lead to bad data if the data couldn't be " "synced by the brick machine's kernel, because of " "hardware failure etc.", .default_value = "on", }, { .key = {"afr-dirty-xattr"}, .type = GF_OPTION_TYPE_STR, .default_value = AFR_DIRTY_DEFAULT, }, {.key = {"afr-pending-xattr"}, .type = GF_OPTION_TYPE_STR, .description = "Comma separated list of xattrs that are used to " "capture information on pending heals."}, { .key = {"metadata-splitbrain-forced-heal"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", }, {.key = {"heal-timeout"}, .type = GF_OPTION_TYPE_INT, .min = 5, .max = INT_MAX, .default_value = "600", .op_version = {2}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate"}, .description = "Time interval for checking the need to self-heal " "in self-heal-daemon."}, { .key = {"consistent-metadata"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "no", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "If this option is enabled, readdirp will force " "lookups on those entries read whose read child is " "not the same as that of the parent. This will " "guarantee that all read operations on a file serve " "attributes from the same subvol as long as it holds " " a good copy of the file/dir.", }, {.key = {"arbiter-count"}, .type = GF_OPTION_TYPE_INT, .description = "subset of child_count. Has to be 0 or 1."}, { .key = {"thin-arbiter"}, .type = GF_OPTION_TYPE_STR, .op_version = {GD_OP_VERSION_4_1_0}, .flags = OPT_FLAG_SETTABLE, .tags = {"replicate"}, .description = "contains host:path of thin abriter brick", }, {.key = {"shd-max-threads"}, .type = GF_OPTION_TYPE_INT, .min = SHD_MIN_THREADS, .max = SHD_MAX_THREADS, .default_value = TOSTRING(SHD_DEFAULT_THREADS), .op_version = {GD_OP_VERSION_3_7_12}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate"}, .description = "Maximum number of parallel heals SHD can do per local " "brick. This can substantially lower heal times, but can " "also crush your bricks if you don't have the storage " "hardware to support this."}, { .key = {"shd-wait-qlength"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 655536, .default_value = "1024", .op_version = {GD_OP_VERSION_3_7_12}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"replicate"}, .description = "This option can be used to control number of heals" " that can wait in SHD per subvolume.", }, { .key = {"locking-scheme"}, .type = GF_OPTION_TYPE_STR, .value = {"full", "granular"}, .default_value = "full", .op_version = {GD_OP_VERSION_3_7_12}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "If this option is set to granular, self-heal will " "stop being compatible with afr-v1, which helps afr " "be more granular while self-healing", }, {.key = {"full-lock"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "yes", .op_version = {GD_OP_VERSION_3_13_2}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE, .tags = {"replicate"}, .description = "If this option is disabled, then the IOs will take " "range locks same as versions till 3.13.1."}, { .key = {"granular-entry-heal"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "no", .op_version = {GD_OP_VERSION_3_8_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "If this option is enabled, self-heal will resort to " "granular way of recording changelogs and doing entry " "self-heal.", }, { .key = {"favorite-child-policy"}, .type = GF_OPTION_TYPE_STR, .value = {"none", "size", "ctime", "mtime", "majority"}, .default_value = "none", .op_version = {GD_OP_VERSION_3_7_12}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "This option can be used to automatically resolve " "split-brains using various policies without user " "intervention. \"size\" picks the file with the " "biggest size as the source. \"ctime\" and \"mtime\" " "pick the file with the latest ctime and mtime " "respectively as the source. \"majority\" picks a file" " with identical mtime and size in more than half the " "number of bricks in the replica.", }, { .key = {"consistent-io"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "no", .description = "If this option is enabled, i/o will fail even if " "one of the bricks is down in the replicas", }, {.key = {"use-compound-fops"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "no", .op_version = {GD_OP_VERSION_3_8_4}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"replicate"}, .description = "This option exists only for backward compatibility " "and configuring it doesn't have any effect"}, {.key = {"use-anonymous-inode"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "no", .op_version = {GD_OP_VERSION_8_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE, .tags = {"replicate"}, .description = "Setting this option heals directory renames efficiently"}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "replicate", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-dir-write.h0000644000000000000000000000013214522202451023721 xustar000000000000000030 mtime=1699284265.613027269 30 atime=1699284265.613027269 30 ctime=1699284301.099134153 glusterfs-11.1/xlators/cluster/afr/src/afr-dir-write.h0000664000175100017510000000260714522202451024205 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __DIR_WRITE_H__ #define __DIR_WRITE_H__ int32_t afr_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata); int32_t afr_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata); int32_t afr_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata); int32_t afr_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata); int32_t afr_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata); int32_t afr_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata); int32_t afr_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata); int afr_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *oldloc, mode_t umask, dict_t *params); #endif /* __DIR_WRITE_H__ */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-inode-read.c0000644000000000000000000000013214522202451024015 xustar000000000000000030 mtime=1699284265.614027272 30 atime=1699284265.613027269 30 ctime=1699284301.112134192 glusterfs-11.1/xlators/cluster/afr/src/afr-inode-read.c0000664000175100017510000014140214522202451024276 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include "libxlator.h" // for gf_get_max_stime() #include #include #include #include #include #include #include "afr-transaction.h" #include "afr-messages.h" /* * Quota size xattrs are not maintained by afr. There is a * possibility that they differ even when both the directory changelog xattrs * suggest everything is fine. So if there is at least one 'source' check among * the sources which has the maximum quota size. Otherwise check among all the * available ones for maximum quota size. This way if there is a source and * stale copies it always votes for the 'source'. * */ int afr_handle_quota_size(afr_local_t *local, xlator_t *this) { unsigned char *readable = NULL; afr_private_t *priv = NULL; struct afr_reply *replies = NULL; int i = 0; int ret = 0; quota_meta_t size = { 0, }; quota_meta_t max_size = { 0, }; int readable_cnt = 0; int read_subvol = -1; priv = this->private; replies = local->replies; readable = alloca0(priv->child_count); afr_inode_read_subvol_get(local->inode, this, readable, 0, 0); readable_cnt = AFR_COUNT(readable, priv->child_count); for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret == -1) continue; if (readable_cnt && !readable[i]) continue; if (!replies[i].xdata) continue; ret = quota_dict_get_meta(replies[i].xdata, QUOTA_SIZE_KEY, SLEN(QUOTA_SIZE_KEY), &size); if (ret == -1) continue; if (read_subvol == -1) read_subvol = i; if (size.size > max_size.size || (size.file_count + size.dir_count) > (max_size.file_count + max_size.dir_count)) read_subvol = i; if (size.size > max_size.size) max_size.size = size.size; if (size.file_count > max_size.file_count) max_size.file_count = size.file_count; if (size.dir_count > max_size.dir_count) max_size.dir_count = size.dir_count; } if (max_size.size == 0 && max_size.file_count == 0 && max_size.dir_count == 0) return read_subvol; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid || replies[i].op_ret == -1) continue; if (readable_cnt && !readable[i]) continue; if (!replies[i].xdata) continue; quota_dict_set_meta(replies[i].xdata, QUOTA_SIZE_KEY, &max_size, IA_IFDIR); } return read_subvol; } /* {{{ access */ static int afr_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; afr_read_txn_continue(frame, this, (long)cookie); return 0; } AFR_STACK_UNWIND(access, frame, op_ret, op_errno, xdata); return 0; } static int afr_access_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_private_t *priv = NULL; afr_local_t *local = NULL; priv = this->private; local = frame->local; if (subvol == -1) { AFR_STACK_UNWIND(access, frame, local->op_ret, local->op_errno, 0); return 0; } STACK_WIND_COOKIE(frame, afr_access_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->access, &local->loc, local->cont.access.mask, local->xdata_req); return 0; } int afr_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int mask, dict_t *xdata) { afr_local_t *local = NULL; int op_errno = 0; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_ACCESS; loc_copy(&local->loc, loc); local->cont.access.mask = mask; if (xdata) local->xdata_req = dict_ref(xdata); afr_read_txn(frame, this, loc->inode, afr_access_wind, AFR_METADATA_TRANSACTION); return 0; out: AFR_STACK_UNWIND(access, frame, -1, op_errno, NULL); return 0; } /* }}} */ /* {{{ stat */ static int afr_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; afr_read_txn_continue(frame, this, (long)cookie); return 0; } AFR_STACK_UNWIND(stat, frame, op_ret, op_errno, buf, xdata); return 0; } static int afr_stat_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_private_t *priv = NULL; afr_local_t *local = NULL; priv = this->private; local = frame->local; if (subvol == -1) { AFR_STACK_UNWIND(stat, frame, local->op_ret, local->op_errno, 0, 0); return 0; } STACK_WIND_COOKIE( frame, afr_stat_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->stat, &local->loc, local->xdata_req); return 0; } int afr_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { afr_local_t *local = NULL; int op_errno = 0; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_STAT; loc_copy(&local->loc, loc); if (xdata) local->xdata_req = dict_ref(xdata); afr_read_txn(frame, this, loc->inode, afr_stat_wind, AFR_DATA_TRANSACTION); return 0; out: AFR_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL); return 0; } /* }}} */ /* {{{ fstat */ static int afr_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; afr_read_txn_continue(frame, this, (long)cookie); return 0; } AFR_STACK_UNWIND(fstat, frame, op_ret, op_errno, buf, xdata); return 0; } static int afr_fstat_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_private_t *priv = NULL; afr_local_t *local = NULL; priv = this->private; local = frame->local; if (subvol == -1) { AFR_STACK_UNWIND(fstat, frame, local->op_ret, local->op_errno, 0, 0); return 0; } STACK_WIND_COOKIE( frame, afr_fstat_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->fstat, local->fd, local->xdata_req); return 0; } int32_t afr_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { afr_local_t *local = NULL; int op_errno = 0; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_FSTAT; local->fd = fd_ref(fd); if (xdata) local->xdata_req = dict_ref(xdata); afr_fix_open(fd, this); afr_read_txn(frame, this, fd->inode, afr_fstat_wind, AFR_DATA_TRANSACTION); return 0; out: AFR_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, NULL); return 0; } /* }}} */ /* {{{ readlink */ static int afr_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, const char *buf, struct iatt *sbuf, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = -1; local->op_errno = op_errno; afr_read_txn_continue(frame, this, (long)cookie); return 0; } AFR_STACK_UNWIND(readlink, frame, op_ret, op_errno, buf, sbuf, xdata); return 0; } static int afr_readlink_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; if (subvol == -1) { AFR_STACK_UNWIND(readlink, frame, local->op_ret, local->op_errno, 0, 0, 0); return 0; } STACK_WIND_COOKIE(frame, afr_readlink_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->readlink, &local->loc, local->cont.readlink.size, local->xdata_req); return 0; } int afr_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { afr_local_t *local = NULL; int32_t op_errno = 0; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_READLINK; loc_copy(&local->loc, loc); local->cont.readlink.size = size; if (xdata) local->xdata_req = dict_ref(xdata); afr_read_txn(frame, this, loc->inode, afr_readlink_wind, AFR_DATA_TRANSACTION); return 0; out: AFR_STACK_UNWIND(readlink, frame, -1, op_errno, 0, 0, 0); return 0; } /* }}} */ /* {{{ getxattr */ struct _xattr_key { char *key; struct list_head list; }; static int __gather_xattr_keys(dict_t *dict, char *key, data_t *value, void *data) { struct list_head *list = data; struct _xattr_key *xkey = NULL; if (!strncmp(key, AFR_XATTR_PREFIX, SLEN(AFR_XATTR_PREFIX))) { xkey = GF_MALLOC(sizeof(*xkey), gf_afr_mt_xattr_key); if (!xkey) return -1; xkey->key = key; INIT_LIST_HEAD(&xkey->list); list_add_tail(&xkey->list, list); } return 0; } static void afr_filter_xattrs(dict_t *dict) { struct list_head keys = { 0, }; struct _xattr_key *key = NULL; struct _xattr_key *tmp = NULL; INIT_LIST_HEAD(&keys); dict_foreach(dict, __gather_xattr_keys, (void *)&keys); list_for_each_entry_safe(key, tmp, &keys, list) { dict_del(dict, key->key); list_del_init(&key->list); GF_FREE(key); } } static gf_boolean_t afr_getxattr_ignorable_errnos(int32_t op_errno) { if (op_errno == ENODATA || op_errno == ENOTSUP || op_errno == ERANGE || op_errno == ENAMETOOLONG) return _gf_true; return _gf_false; } static int afr_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret < 0 && !afr_getxattr_ignorable_errnos(op_errno)) { local->op_ret = op_ret; local->op_errno = op_errno; afr_read_txn_continue(frame, this, (long)cookie); return 0; } if (dict) afr_filter_xattrs(dict); AFR_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } static int afr_getxattr_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; if (subvol == -1) { AFR_STACK_UNWIND(getxattr, frame, local->op_ret, local->op_errno, NULL, NULL); return 0; } STACK_WIND_COOKIE(frame, afr_getxattr_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->getxattr, &local->loc, local->cont.getxattr.name, local->xdata_req); return 0; } static int32_t afr_getxattr_unwind(call_frame_t *frame, int op_ret, int op_errno, dict_t *dict, dict_t *xdata) { AFR_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } static int32_t afr_fgetxattr_clrlk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; xlator_t **children = NULL; dict_t *xattr = NULL; char *tmp_report = NULL; char lk_summary[1024] = { 0, }; int serz_len = 0; int32_t callcnt = 0; long int cky = 0; int ret = 0; int keylen = 0; int children_keylen = 0; priv = this->private; children = priv->children; local = frame->local; cky = (long)cookie; keylen = strlen(local->cont.getxattr.name); children_keylen = strlen(children[cky]->name); LOCK(&frame->lock); { callcnt = --local->call_count; if (op_ret == -1) local->replies[cky].op_errno = op_errno; if (!local->dict) local->dict = dict_new(); if (local->dict) { ret = dict_get_strn(dict, local->cont.getxattr.name, keylen, &tmp_report); if (ret) goto unlock; ret = dict_set_dynstrn(local->dict, children[cky]->name, children_keylen, gf_strdup(tmp_report)); if (ret) goto unlock; } } unlock: UNLOCK(&frame->lock); if (!callcnt) { xattr = dict_new(); if (!xattr) { op_ret = -1; op_errno = ENOMEM; goto unwind; } ret = dict_serialize_value_with_delim(local->dict, lk_summary, &serz_len, '\n'); if (ret) { op_ret = -1; op_errno = ENOMEM; goto unwind; } if (serz_len == -1) snprintf(lk_summary, sizeof(lk_summary), "No locks cleared."); ret = dict_set_dynstrn(xattr, local->cont.getxattr.name, keylen, gf_strdup(lk_summary)); if (ret) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_DICT_SET_FAILED, "Error setting dictionary"); goto unwind; } op_errno = afr_final_errno(local, priv); unwind: AFR_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, xattr, xdata); if (xattr) dict_unref(xattr); } return ret; } static int32_t afr_getxattr_clrlk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; xlator_t **children = NULL; dict_t *xattr = NULL; char *tmp_report = NULL; char lk_summary[1024] = { 0, }; int serz_len = 0; int32_t callcnt = 0; long int cky = 0; int ret = 0; int keylen = 0; int children_keylen = 0; priv = this->private; children = priv->children; local = frame->local; cky = (long)cookie; keylen = strlen(local->cont.getxattr.name); children_keylen = strlen(children[cky]->name); LOCK(&frame->lock); { callcnt = --local->call_count; if (op_ret == -1) local->replies[cky].op_errno = op_errno; if (!local->dict) local->dict = dict_new(); if (local->dict) { ret = dict_get_strn(dict, local->cont.getxattr.name, keylen, &tmp_report); if (ret) goto unlock; ret = dict_set_dynstrn(local->dict, children[cky]->name, children_keylen, gf_strdup(tmp_report)); if (ret) goto unlock; } } unlock: UNLOCK(&frame->lock); if (!callcnt) { xattr = dict_new(); if (!xattr) { op_ret = -1; op_errno = ENOMEM; goto unwind; } ret = dict_serialize_value_with_delim(local->dict, lk_summary, &serz_len, '\n'); if (ret) { op_ret = -1; op_errno = ENOMEM; goto unwind; } if (serz_len == -1) snprintf(lk_summary, sizeof(lk_summary), "No locks cleared."); ret = dict_set_dynstrn(xattr, local->cont.getxattr.name, keylen, gf_strdup(lk_summary)); if (ret) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, AFR_MSG_DICT_SET_FAILED, "Error setting dictionary"); goto unwind; } op_errno = afr_final_errno(local, priv); unwind: AFR_STACK_UNWIND(getxattr, frame, op_ret, op_errno, xattr, xdata); if (xattr) dict_unref(xattr); } return ret; } /** * node-uuid cbk uses next child querying mechanism */ static int32_t afr_getxattr_node_uuid_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; xlator_t **children = NULL; int unwind = 1; int curr_call_child = 0; priv = this->private; children = priv->children; local = frame->local; if (op_ret == -1) { /** query the _next_ child */ /** * _current_ becomes _next_ * If done with all children and yet no success; give up ! */ curr_call_child = (int)((long)cookie); if (++curr_call_child == priv->child_count) goto unwind; gf_msg_debug(this->name, op_errno, "op_ret (-1): Re-querying afr-child (%d/%d)", curr_call_child, priv->child_count); unwind = 0; STACK_WIND_COOKIE( frame, afr_getxattr_node_uuid_cbk, (void *)(long)curr_call_child, children[curr_call_child], children[curr_call_child]->fops->getxattr, &local->loc, local->cont.getxattr.name, local->xdata_req); } unwind: if (unwind) AFR_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } /** * list-node-uuids cbk returns the list of node_uuids for the subvolume. */ static int32_t afr_getxattr_list_node_uuids_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_local_t *local = NULL; afr_private_t *priv = NULL; int32_t callcnt = 0; int ret = 0; char *xattr_serz = NULL; long cky = 0; int32_t tlen = 0; local = frame->local; priv = this->private; cky = (long)cookie; LOCK(&frame->lock); { callcnt = --local->call_count; local->replies[cky].valid = 1; local->replies[cky].op_ret = op_ret; local->replies[cky].op_errno = op_errno; if (op_ret < 0) goto unlock; local->op_ret = 0; if (!local->xdata_rsp && xdata) local->xdata_rsp = dict_ref(xdata); local->replies[cky].xattr = dict_ref(dict); } unlock: UNLOCK(&frame->lock); if (!callcnt) { if (local->op_ret != 0) { /* All bricks gave an error. */ local->op_errno = afr_final_errno(local, priv); goto unwind; } /*Since we store the UUID0_STR as node uuid for down bricks and *for non zero op_ret, assigning length to priv->child_count *number of uuids*/ local->cont.getxattr.xattr_len = (SLEN(UUID0_STR) + 2) * priv->child_count; if (!local->dict) local->dict = dict_new(); if (!local->dict) { local->op_ret = -1; local->op_errno = ENOMEM; goto unwind; } xattr_serz = GF_CALLOC(local->cont.getxattr.xattr_len, sizeof(char), gf_common_mt_char); if (!xattr_serz) { local->op_ret = -1; local->op_errno = ENOMEM; goto unwind; } ret = afr_serialize_xattrs_with_delimiter( frame, this, xattr_serz, local->cont.getxattr.xattr_len, UUID0_STR, &tlen, ' '); if (ret) { local->op_ret = -1; local->op_errno = ENOMEM; GF_FREE(xattr_serz); goto unwind; } ret = dict_set_dynstr_sizen(local->dict, GF_XATTR_LIST_NODE_UUIDS_KEY, xattr_serz); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Cannot set node_uuid key in dict"); local->op_ret = -1; local->op_errno = ENOMEM; if (ret == -EINVAL) GF_FREE(xattr_serz); } else { local->op_ret = local->cont.getxattr.xattr_len - 1; local->op_errno = 0; } unwind: AFR_STACK_UNWIND(getxattr, frame, local->op_ret, local->op_errno, local->dict, local->xdata_rsp); } return ret; } static int32_t afr_getxattr_quota_size_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { int idx = (long)cookie; int call_count = 0; afr_local_t *local = frame->local; int read_subvol = -1; local->replies[idx].valid = 1; local->replies[idx].op_ret = op_ret; local->replies[idx].op_errno = op_errno; if (dict) local->replies[idx].xdata = dict_ref(dict); call_count = afr_frame_return(frame); if (call_count == 0) { local->inode = inode_ref(local->loc.inode); read_subvol = afr_handle_quota_size(local, this); if (read_subvol != -1) { op_ret = local->replies[read_subvol].op_ret; op_errno = local->replies[read_subvol].op_errno; dict = local->replies[read_subvol].xdata; } AFR_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); } return 0; } static int32_t afr_update_local_dicts(call_frame_t *frame, dict_t *dict, dict_t *xdata) { afr_local_t *local; dict_t *local_dict; dict_t *local_xdata; int32_t ret; local = frame->local; local_dict = NULL; local_xdata = NULL; ret = -ENOMEM; if ((dict != NULL) && (local->dict == NULL)) { local_dict = dict_new(); if (local_dict == NULL) { goto done; } } if ((xdata != NULL) && (local->xdata_rsp == NULL)) { local_xdata = dict_new(); if (local_xdata == NULL) { goto done; } } if ((local_dict != NULL) || (local_xdata != NULL)) { /* TODO: Maybe it would be better to preallocate both dicts before * sending the requests. This way we don't need to use a LOCK() * here. */ LOCK(&frame->lock); if ((local_dict != NULL) && (local->dict == NULL)) { local->dict = local_dict; local_dict = NULL; } if ((local_xdata != NULL) && (local->xdata_rsp == NULL)) { local->xdata_rsp = local_xdata; local_xdata = NULL; } UNLOCK(&frame->lock); } if (dict != NULL) { if (dict_copy(dict, local->dict) == NULL) { goto done; } } if (xdata != NULL) { if (dict_copy(xdata, local->xdata_rsp) == NULL) { goto done; } } ret = 0; done: if (local_dict != NULL) { dict_unref(local_dict); } if (local_xdata != NULL) { dict_unref(local_xdata); } return ret; } static void afr_getxattr_lockinfo_cbk_common(call_frame_t *frame, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata, bool is_fgetxattr) { int len = 0; char *lockinfo_buf = NULL; dict_t *lockinfo = NULL, *newdict = NULL; afr_local_t *local = NULL; local = frame->local; if ((op_ret >= 0) && (dict != NULL)) { op_ret = dict_get_ptr_and_len(dict, GF_XATTR_LOCKINFO_KEY, (void **)&lockinfo_buf, &len); if (lockinfo_buf != NULL) { lockinfo = dict_new(); if (lockinfo == NULL) { op_ret = -1; } else { op_ret = dict_unserialize(lockinfo_buf, len, &lockinfo); } } } if ((op_ret >= 0) && ((lockinfo != NULL) || (xdata != NULL))) { op_ret = afr_update_local_dicts(frame, lockinfo, xdata); if (lockinfo != NULL) { dict_unref(lockinfo); } } if (op_ret < 0) { local->op_ret = -1; local->op_errno = ENOMEM; } if (uatomic_sub_return(&local->call_count, 1) == 0) { newdict = dict_new(); if (!newdict) { local->op_ret = -1; local->op_errno = op_errno = ENOMEM; goto unwind; } op_ret = dict_allocate_and_serialize( local->dict, (char **)&lockinfo_buf, (unsigned int *)&len); if (op_ret != 0) { local->op_ret = -1; local->op_errno = op_errno = ENOMEM; goto unwind; } op_ret = dict_set_dynptr(newdict, GF_XATTR_LOCKINFO_KEY, (void *)lockinfo_buf, len); if (op_ret < 0) { GF_FREE(lockinfo_buf); local->op_ret = op_ret = -1; local->op_errno = op_errno = -op_ret; goto unwind; } unwind: /* TODO: These unwinds use op_ret and op_errno instead of local->op_ret * and local->op_errno. This doesn't seem right because any * failure during processing of each answer could be silently * ignored. This is kept this was the old behavior and because * local->op_ret is initialized as -1 and local->op_errno is * initialized as EUCLEAN, which makes these values useless. */ if (is_fgetxattr) { AFR_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, newdict, local->xdata_rsp); } else { AFR_STACK_UNWIND(getxattr, frame, op_ret, op_errno, newdict, local->xdata_rsp); } if (newdict != NULL) { dict_unref(newdict); } } } static int32_t afr_getxattr_lockinfo_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_getxattr_lockinfo_cbk_common(frame, op_ret, op_errno, dict, xdata, false); return 0; } static int32_t afr_fgetxattr_lockinfo_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_getxattr_lockinfo_cbk_common(frame, op_ret, op_errno, dict, xdata, true); return 0; } static int32_t afr_fgetxattr_pathinfo_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_local_t *local = NULL; int32_t callcnt = 0; int ret = 0; char *xattr = NULL; char *xattr_serz = NULL; int keylen = 0; char xattr_cky[1024] = { 0, }; int xattr_cky_len = 0; dict_t *nxattr = NULL; long cky = 0; int32_t padding = 0; int32_t tlen = 0; if (!frame || !frame->local || !this) { gf_msg("", GF_LOG_ERROR, 0, AFR_MSG_INVALID_ARG, "possible NULL deref"); goto out; } local = frame->local; cky = (long)cookie; keylen = strlen(local->cont.getxattr.name); xattr_cky_len = snprintf(xattr_cky, sizeof(xattr_cky), "%s-%ld", local->cont.getxattr.name, cky); LOCK(&frame->lock); { callcnt = --local->call_count; if (op_ret < 0) { local->op_errno = op_errno; } else { local->op_ret = op_ret; if (!local->xdata_rsp && xdata) local->xdata_rsp = dict_ref(xdata); } if (!dict || (op_ret < 0)) goto unlock; if (!local->dict) { local->dict = dict_new(); if (!local->dict) goto unlock; } ret = dict_get_strn(dict, local->cont.getxattr.name, keylen, &xattr); if (ret) goto unlock; xattr = gf_strdup(xattr); ret = dict_set_dynstrn(local->dict, xattr_cky, xattr_cky_len, xattr); if (ret) { UNLOCK(&frame->lock); gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Cannot set xattr cookie key"); goto post_unlock; } local->cont.getxattr.xattr_len += strlen(xattr) + 1; } unlock: UNLOCK(&frame->lock); post_unlock: if (!callcnt) { if (!local->cont.getxattr.xattr_len) goto unwind; nxattr = dict_new(); if (!nxattr) goto unwind; /* extra bytes for decorations (brackets and <>'s) */ padding += strlen(this->name) + SLEN(AFR_PATHINFO_HEADER) + 4; local->cont.getxattr.xattr_len += (padding + 2); xattr_serz = GF_MALLOC(local->cont.getxattr.xattr_len, gf_common_mt_char); if (!xattr_serz) goto unwind; /* the xlator info */ int xattr_serz_len = sprintf( xattr_serz, "(<" AFR_PATHINFO_HEADER "%s> ", this->name); /* actual series of pathinfo */ ret = dict_serialize_value_with_delim( local->dict, xattr_serz + xattr_serz_len, &tlen, ' '); if (ret) { GF_FREE(xattr_serz); goto unwind; } /* closing part */ *(xattr_serz + padding + tlen) = ')'; *(xattr_serz + padding + tlen + 1) = '\0'; ret = dict_set_dynstrn(nxattr, local->cont.getxattr.name, keylen, xattr_serz); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Cannot set pathinfo key in dict"); if (ret == -EINVAL) GF_FREE(xattr_serz); } unwind: AFR_STACK_UNWIND(fgetxattr, frame, local->op_ret, local->op_errno, nxattr, local->xdata_rsp); if (nxattr) dict_unref(nxattr); } out: return ret; } static int32_t afr_getxattr_pathinfo_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_local_t *local = NULL; int32_t callcnt = 0; int ret = 0; char *xattr = NULL; char *xattr_serz = NULL; char xattr_cky[1024] = { 0, }; int keylen = 0; int xattr_cky_len = 0; dict_t *nxattr = NULL; long cky = 0; int32_t padding = 0; int32_t tlen = 0; if (!frame || !frame->local || !this) { gf_msg("", GF_LOG_ERROR, 0, AFR_MSG_INVALID_ARG, "possible NULL deref"); goto out; } local = frame->local; cky = (long)cookie; keylen = strlen(local->cont.getxattr.name); xattr_cky_len = snprintf(xattr_cky, sizeof(xattr_cky), "%s-%ld", local->cont.getxattr.name, cky); LOCK(&frame->lock); { callcnt = --local->call_count; if (op_ret < 0) { local->op_errno = op_errno; } else { local->op_ret = op_ret; if (!local->xdata_rsp && xdata) local->xdata_rsp = dict_ref(xdata); } if (!dict || (op_ret < 0)) goto unlock; if (!local->dict) { local->dict = dict_new(); if (!local->dict) goto unlock; } ret = dict_get_strn(dict, local->cont.getxattr.name, keylen, &xattr); if (ret) goto unlock; xattr = gf_strdup(xattr); ret = dict_set_dynstrn(local->dict, xattr_cky, xattr_cky_len, xattr); if (ret) { UNLOCK(&frame->lock); gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Cannot set xattr cookie key"); goto post_unlock; } local->cont.getxattr.xattr_len += strlen(xattr) + 1; } unlock: UNLOCK(&frame->lock); post_unlock: if (!callcnt) { if (!local->cont.getxattr.xattr_len) goto unwind; nxattr = dict_new(); if (!nxattr) goto unwind; /* extra bytes for decorations (brackets and <>'s) */ padding += strlen(this->name) + SLEN(AFR_PATHINFO_HEADER) + 4; local->cont.getxattr.xattr_len += (padding + 2); xattr_serz = GF_MALLOC(local->cont.getxattr.xattr_len, gf_common_mt_char); if (!xattr_serz) goto unwind; /* the xlator info */ int xattr_serz_len = sprintf( xattr_serz, "(<" AFR_PATHINFO_HEADER "%s> ", this->name); /* actual series of pathinfo */ ret = dict_serialize_value_with_delim( local->dict, xattr_serz + xattr_serz_len, &tlen, ' '); if (ret) { GF_FREE(xattr_serz); goto unwind; } /* closing part */ *(xattr_serz + padding + tlen) = ')'; *(xattr_serz + padding + tlen + 1) = '\0'; ret = dict_set_dynstrn(nxattr, local->cont.getxattr.name, keylen, xattr_serz); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, AFR_MSG_DICT_SET_FAILED, "Cannot set pathinfo key in dict"); if (ret == -EINVAL) GF_FREE(xattr_serz); } unwind: AFR_STACK_UNWIND(getxattr, frame, local->op_ret, local->op_errno, nxattr, local->xdata_rsp); if (nxattr) dict_unref(nxattr); } out: return ret; } static int afr_aggregate_stime_xattr(dict_t *this, char *key, data_t *value, void *data) { int ret = 0; if (fnmatch(GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0) ret = gf_get_max_stime(THIS, data, key, value); return ret; } static int32_t afr_common_getxattr_stime_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_local_t *local = NULL; int32_t callcnt = 0; if (!frame || !frame->local || !this) { gf_msg("", GF_LOG_ERROR, 0, AFR_MSG_INVALID_ARG, "possible NULL deref"); goto out; } local = frame->local; LOCK(&frame->lock); { callcnt = --local->call_count; if (!dict || (op_ret < 0)) { local->op_errno = op_errno; goto cleanup; } if (!local->dict) local->dict = dict_copy_with_ref(dict, NULL); else dict_foreach(dict, afr_aggregate_stime_xattr, local->dict); local->op_ret = 0; } cleanup: UNLOCK(&frame->lock); if (!callcnt) { AFR_STACK_UNWIND(getxattr, frame, local->op_ret, local->op_errno, local->dict, xdata); } out: return 0; } static gf_boolean_t afr_is_special_xattr(const char *name, fop_getxattr_cbk_t *cbk, gf_boolean_t is_fgetxattr) { gf_boolean_t is_spl = _gf_true; GF_ASSERT(cbk); if (!cbk || !name) { is_spl = _gf_false; goto out; } if (!strcmp(name, GF_XATTR_PATHINFO_KEY) || !strcmp(name, GF_XATTR_USER_PATHINFO_KEY)) { if (is_fgetxattr) { *cbk = afr_fgetxattr_pathinfo_cbk; } else { *cbk = afr_getxattr_pathinfo_cbk; } } else if (!strncmp(name, GF_XATTR_CLRLK_CMD, SLEN(GF_XATTR_CLRLK_CMD)) || !strncmp(name, GF_XATTR_INTRLK_CMD, SLEN(GF_XATTR_INTRLK_CMD))) { if (is_fgetxattr) { *cbk = afr_fgetxattr_clrlk_cbk; } else { *cbk = afr_getxattr_clrlk_cbk; } } else if (!strncmp(name, GF_XATTR_LOCKINFO_KEY, SLEN(GF_XATTR_LOCKINFO_KEY))) { if (is_fgetxattr) { *cbk = afr_fgetxattr_lockinfo_cbk; } else { *cbk = afr_getxattr_lockinfo_cbk; } } else if (fnmatch(GF_XATTR_STIME_PATTERN, name, FNM_NOESCAPE) == 0) { *cbk = afr_common_getxattr_stime_cbk; } else if (strcmp(name, QUOTA_SIZE_KEY) == 0) { *cbk = afr_getxattr_quota_size_cbk; } else if (!strcmp(name, GF_XATTR_LIST_NODE_UUIDS_KEY)) { *cbk = afr_getxattr_list_node_uuids_cbk; } else { is_spl = _gf_false; } out: return is_spl; } static void afr_getxattr_all_subvols(afr_private_t *priv, call_frame_t *frame, const char *name, loc_t *loc, fop_getxattr_cbk_t cbk) { afr_local_t *local = NULL; int i = 0; int call_count = 0; local = frame->local; // local->call_count set in afr_local_init call_count = local->call_count; if (!strcmp(name, GF_XATTR_LIST_NODE_UUIDS_KEY)) { GF_FREE(local->cont.getxattr.name); local->cont.getxattr.name = gf_strdup(GF_XATTR_NODE_UUID_KEY); } // If up-children count is 0, afr_local_init would have failed already // and the call would have unwound so not handling it here. for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { STACK_WIND_COOKIE(frame, cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->getxattr, loc, local->cont.getxattr.name, NULL); if (!--call_count) break; } } return; } static int afr_marker_populate_args(call_frame_t *frame, int type, int *gauge, xlator_t **subvols) { xlator_t *this = frame->this; afr_private_t *priv = this->private; memcpy(subvols, priv->children, sizeof(*subvols) * priv->child_count); if (type == MARKER_XTIME_TYPE) { /*Don't error out on ENOENT/ENOTCONN */ gauge[MCNT_NOTFOUND] = 0; gauge[MCNT_ENOTCONN] = 0; } return priv->child_count; } static int afr_handle_heal_xattrs(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *heal_op) { int ret = -1; afr_spb_status_t *data = NULL; if (!strcmp(heal_op, GF_HEAL_INFO)) { afr_get_heal_info(frame, this, loc); ret = 0; goto out; } if (!strcmp(heal_op, GF_AFR_HEAL_SBRAIN)) { afr_heal_splitbrain_file(frame, this, loc); ret = 0; goto out; } if (!strcmp(heal_op, GF_AFR_SBRAIN_STATUS)) { data = GF_CALLOC(1, sizeof(*data), gf_afr_mt_spb_status_t); if (!data) { ret = 1; goto out; } data->frame = frame; data->loc = loc; ret = synctask_new(this->ctx->env, afr_get_split_brain_status, afr_get_split_brain_status_cbk, NULL, data); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN_STATUS, "Failed to create" " synctask. Unable to fetch split-brain status" " for %s.", loc->name); ret = 1; goto out; } goto out; } out: if (ret == 1) { AFR_STACK_UNWIND(getxattr, frame, -1, ENOMEM, NULL, NULL); if (data) GF_FREE(data); ret = 0; } return ret; } int32_t afr_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; xlator_t **children = NULL; int i = 0; int32_t op_errno = 0; int ret = -1; fop_getxattr_cbk_t cbk = NULL; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; priv = this->private; children = priv->children; loc_copy(&local->loc, loc); local->op = GF_FOP_GETXATTR; if (xdata) local->xdata_req = dict_ref(xdata); if (!name) goto no_name; local->cont.getxattr.name = gf_strdup(name); if (!local->cont.getxattr.name) { op_errno = ENOMEM; goto out; } if (!strncmp(name, AFR_XATTR_PREFIX, SLEN(AFR_XATTR_PREFIX))) { op_errno = ENODATA; goto out; } if (cluster_handle_marker_getxattr(frame, loc, name, priv->vol_uuid, afr_getxattr_unwind, afr_marker_populate_args) == 0) return 0; ret = afr_handle_heal_xattrs(frame, this, &local->loc, name); if (ret == 0) return 0; /* * Heal daemons don't have IO threads ... and as a result they * send this getxattr down and eventually crash :( */ GF_CHECK_XATTR_KEY_AND_GOTO(name, IO_THREADS_QUEUE_SIZE_KEY, op_errno, out); /* * Special xattrs which need responses from all subvols */ if (afr_is_special_xattr(name, &cbk, 0)) { afr_getxattr_all_subvols(priv, frame, name, loc, cbk); return 0; } if (XATTR_IS_NODE_UUID(name)) { i = 0; STACK_WIND_COOKIE(frame, afr_getxattr_node_uuid_cbk, (void *)(long)i, children[i], children[i]->fops->getxattr, loc, name, xdata); return 0; } no_name: afr_read_txn(frame, this, local->loc.inode, afr_getxattr_wind, AFR_METADATA_TRANSACTION); ret = 0; out: if (ret < 0) AFR_STACK_UNWIND(getxattr, frame, -1, op_errno, NULL, NULL); return 0; } /* {{{ fgetxattr */ static int32_t afr_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = -1; local->op_errno = op_errno; afr_read_txn_continue(frame, this, (long)cookie); return 0; } if (dict) afr_filter_xattrs(dict); AFR_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, dict, xdata); return 0; } static int afr_fgetxattr_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; if (subvol == -1) { AFR_STACK_UNWIND(fgetxattr, frame, local->op_ret, local->op_errno, NULL, NULL); return 0; } STACK_WIND_COOKIE(frame, afr_fgetxattr_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->fgetxattr, local->fd, local->cont.getxattr.name, local->xdata_req); return 0; } static void afr_fgetxattr_all_subvols(afr_private_t *priv, call_frame_t *frame, fop_fgetxattr_cbk_t cbk) { afr_local_t *local = NULL; int i = 0; int call_count = 0; local = frame->local; // local->call_count set in afr_local_init call_count = local->call_count; // If up-children count is 0, afr_local_init would have failed already // and the call would have unwound so not handling it here. for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { STACK_WIND_COOKIE(frame, cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->fgetxattr, local->fd, local->cont.getxattr.name, NULL); if (!--call_count) break; } } return; } int afr_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { afr_local_t *local = NULL; int32_t op_errno = 0; fop_fgetxattr_cbk_t cbk = NULL; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_FGETXATTR; local->fd = fd_ref(fd); if (name) { local->cont.getxattr.name = gf_strdup(name); if (!local->cont.getxattr.name) { op_errno = ENOMEM; goto out; } } if (xdata) local->xdata_req = dict_ref(xdata); /* pathinfo gets handled only in getxattr(), but we need to handle * lockinfo. * If we are doing fgetxattr with lockinfo as the key then we * collect information from all children. */ if (afr_is_special_xattr(name, &cbk, 1)) { afr_fgetxattr_all_subvols(this->private, frame, cbk); return 0; } afr_fix_open(fd, this); afr_read_txn(frame, this, fd->inode, afr_fgetxattr_wind, AFR_METADATA_TRANSACTION); return 0; out: AFR_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL); return 0; } /* }}} */ /* {{{ readv */ static int afr_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *buf, struct iobref *iobref, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = -1; local->op_errno = op_errno; afr_read_txn_continue(frame, this, (long)cookie); return 0; } AFR_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, buf, iobref, xdata); return 0; } static int afr_readv_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; if (subvol == -1) { AFR_STACK_UNWIND(readv, frame, local->op_ret, local->op_errno, 0, 0, 0, 0, 0); return 0; } STACK_WIND_COOKIE( frame, afr_readv_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->readv, local->fd, local->cont.readv.size, local->cont.readv.offset, local->cont.readv.flags, local->xdata_req); return 0; } int afr_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { afr_local_t *local = NULL; int32_t op_errno = 0; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_READ; local->fd = fd_ref(fd); local->cont.readv.size = size; local->cont.readv.offset = offset; local->cont.readv.flags = flags; if (xdata) local->xdata_req = dict_ref(xdata); afr_fix_open(fd, this); afr_read_txn(frame, this, fd->inode, afr_readv_wind, AFR_DATA_TRANSACTION); return 0; out: AFR_STACK_UNWIND(readv, frame, -1, op_errno, 0, 0, 0, 0, 0); return 0; } /* }}} */ /* {{{ seek */ static int afr_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata) { afr_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = -1; local->op_errno = op_errno; afr_read_txn_continue(frame, this, (long)cookie); return 0; } AFR_STACK_UNWIND(seek, frame, op_ret, op_errno, offset, xdata); return 0; } static int afr_seek_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; local = frame->local; priv = this->private; if (subvol == -1) { AFR_STACK_UNWIND(seek, frame, local->op_ret, local->op_errno, 0, NULL); return 0; } STACK_WIND_COOKIE( frame, afr_seek_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->seek, local->fd, local->cont.seek.offset, local->cont.seek.what, local->xdata_req); return 0; } int afr_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { afr_local_t *local = NULL; int32_t op_errno = 0; AFR_ERROR_OUT_IF_FDCTX_INVALID(fd, this, op_errno, out); local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_SEEK; local->fd = fd_ref(fd); local->cont.seek.offset = offset; local->cont.seek.what = what; if (xdata) local->xdata_req = dict_ref(xdata); afr_fix_open(fd, this); afr_read_txn(frame, this, fd->inode, afr_seek_wind, AFR_DATA_TRANSACTION); return 0; out: AFR_STACK_UNWIND(seek, frame, -1, op_errno, 0, NULL); return 0; } /* }}} */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-dir-read.c0000644000000000000000000000013214522202451023475 xustar000000000000000030 mtime=1699284265.612027266 30 atime=1699284265.612027266 30 ctime=1699284301.109134183 glusterfs-11.1/xlators/cluster/afr/src/afr-dir-read.c0000664000175100017510000002331114522202451023754 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include "afr-transaction.h" static int32_t afr_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { afr_local_t *local = NULL; int call_count = -1; int32_t child_index = 0; afr_fd_ctx_t *fd_ctx = NULL; local = frame->local; fd_ctx = local->fd_ctx; child_index = (long)cookie; local->replies[child_index].valid = 1; local->replies[child_index].op_ret = op_ret; local->replies[child_index].op_errno = op_errno; LOCK(&frame->lock); { if (op_ret == -1) { local->op_errno = op_errno; fd_ctx->opened_on[child_index] = AFR_FD_NOT_OPENED; } else { local->op_ret = op_ret; fd_ctx->opened_on[child_index] = AFR_FD_OPENED; if (!local->xdata_rsp && xdata) local->xdata_rsp = dict_ref(xdata); } call_count = --local->call_count; } UNLOCK(&frame->lock); if (call_count == 0) { afr_handle_replies_quorum(frame, this); AFR_STACK_UNWIND(opendir, frame, local->op_ret, local->op_errno, local->fd, NULL); } return 0; } int afr_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { afr_private_t *priv = NULL; afr_local_t *local = NULL; int i = 0; int call_count = -1; int32_t op_errno = ENOMEM; afr_fd_ctx_t *fd_ctx = NULL; priv = this->private; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; local->op = GF_FOP_OPENDIR; if (priv->quorum_count && !afr_has_quorum(local->child_up, priv, NULL)) { op_errno = afr_quorum_errno(priv); goto out; } if (!afr_is_consistent_io_possible(local, priv, &op_errno)) goto out; fd_ctx = afr_fd_ctx_get(fd, this); if (!fd_ctx) goto out; loc_copy(&local->loc, loc); local->fd = fd_ref(fd); local->fd_ctx = fd_ctx; call_count = local->call_count; for (i = 0; i < priv->child_count; i++) { if (local->child_up[i]) { STACK_WIND_COOKIE(frame, afr_opendir_cbk, (void *)(long)i, priv->children[i], priv->children[i]->fops->opendir, loc, fd, NULL); if (!--call_count) break; } } return 0; out: AFR_STACK_UNWIND(opendir, frame, -1, op_errno, fd, NULL); return 0; } static int afr_validate_read_subvol(inode_t *inode, xlator_t *this, int par_read_subvol) { int gen = 0; int entry_read_subvol = 0; unsigned char *data_readable = NULL; unsigned char *metadata_readable = NULL; afr_private_t *priv = NULL; priv = this->private; data_readable = alloca0(priv->child_count); metadata_readable = alloca0(priv->child_count); afr_inode_read_subvol_get(inode, this, data_readable, metadata_readable, &gen); if (gen != priv->event_generation || !data_readable[par_read_subvol] || !metadata_readable[par_read_subvol]) return -1; /* Once the control reaches the following statement, it means that the * parent's read subvol is perfectly readable. So calling * either afr_data_subvol_get() or afr_metadata_subvol_get() would * yield the same result. Hence, choosing afr_data_subvol_get() below. */ if (!priv->consistent_metadata) return 0; /* For an inode fetched through readdirp which is yet to be linked, * inode ctx would not be initialised (yet). So this function returns * -1 above due to gen being 0, which is why it is OK to pass NULL for * read_subvol_args here. */ entry_read_subvol = afr_data_subvol_get(inode, this, NULL, NULL, NULL, NULL); if (entry_read_subvol != par_read_subvol) return -1; return 0; } static int32_t afr_readdir_transform_entries(pid_t pid, xlator_t *this, gf_dirent_t *subvol_entries, int subvol, gf_dirent_t *entries, fd_t *fd) { int ret; gf_dirent_t *entry = NULL; gf_dirent_t *tmp = NULL; afr_private_t *priv = NULL; gf_boolean_t need_heal = _gf_false; gf_boolean_t validate_subvol = _gf_false; int32_t count = 0; gf_boolean_t is_root_gfid = __is_root_gfid(fd->inode->gfid); priv = this->private; need_heal = afr_get_need_heal(priv); validate_subvol = need_heal | priv->consistent_metadata; list_for_each_entry_safe(entry, tmp, &subvol_entries->list, list) { /* we can skip afr_is_private_directory() check unless it's root gfid * which we check once (above) for all entries */ if (is_root_gfid) { if (afr_is_private_directory(priv, entry->d_name, pid)) { continue; } } list_move_tail(&entry->list, &entries->list); count++; if (!validate_subvol) continue; if (entry->inode) { ret = afr_validate_read_subvol(entry->inode, this, subvol); if (ret != 0) { inode_unref(entry->inode); entry->inode = NULL; continue; } } } return count; } static int32_t afr_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *subvol_entries, dict_t *xdata) { afr_local_t *local = NULL; gf_dirent_t entries; INIT_LIST_HEAD(&entries.list); local = frame->local; if (op_ret < 0 && !local->cont.readdir.offset) { /* failover only if this was first readdir, detected by offset == 0 */ local->op_ret = op_ret; local->op_errno = op_errno; afr_read_txn_continue(frame, this, (long)cookie); return 0; } if (op_ret >= 0) op_ret = afr_readdir_transform_entries(frame->root->pid, this, subvol_entries, (long)cookie, &entries, local->fd); AFR_STACK_UNWIND(readdir, frame, op_ret, op_errno, &entries, xdata); gf_dirent_free(&entries); return 0; } static int afr_readdir_wind(call_frame_t *frame, xlator_t *this, int subvol) { afr_local_t *local = NULL; afr_private_t *priv = NULL; afr_fd_ctx_t *fd_ctx = NULL; priv = this->private; local = frame->local; fd_ctx = afr_fd_ctx_get(local->fd, this); if (!fd_ctx) { local->op_errno = EINVAL; local->op_ret = -1; } if (subvol == -1 || !fd_ctx) { AFR_STACK_UNWIND(readdir, frame, local->op_ret, local->op_errno, 0, 0); return 0; } fd_ctx->readdir_subvol = subvol; if (local->op == GF_FOP_READDIR) STACK_WIND_COOKIE(frame, afr_readdir_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->readdir, local->fd, local->cont.readdir.size, local->cont.readdir.offset, local->xdata_req); else STACK_WIND_COOKIE(frame, afr_readdir_cbk, (void *)(long)subvol, priv->children[subvol], priv->children[subvol]->fops->readdirp, local->fd, local->cont.readdir.size, local->cont.readdir.offset, local->xdata_req); return 0; } static int afr_do_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, int whichop, dict_t *dict) { afr_local_t *local = NULL; int32_t op_errno = 0; int subvol = -1; afr_fd_ctx_t *fd_ctx = NULL; local = AFR_FRAME_INIT(frame, op_errno); if (!local) goto out; fd_ctx = afr_fd_ctx_get(fd, this); if (!fd_ctx) { op_errno = EINVAL; goto out; } local->op = whichop; local->fd = fd_ref(fd); local->cont.readdir.size = size; local->cont.readdir.offset = offset; local->xdata_req = (dict) ? dict_ref(dict) : NULL; subvol = fd_ctx->readdir_subvol; if (offset == 0 || subvol == -1) { /* First readdir has option of failing over and selecting an appropriate read subvolume */ afr_read_txn(frame, this, fd->inode, afr_readdir_wind, AFR_DATA_TRANSACTION); } else { /* But continued readdirs MUST stick to the same subvolume without an option to failover */ afr_readdir_wind(frame, this, subvol); } return 0; out: AFR_STACK_UNWIND(readdir, frame, -1, op_errno, NULL, NULL); return 0; } int32_t afr_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { afr_do_readdir(frame, this, fd, size, offset, GF_FOP_READDIR, xdata); return 0; } int32_t afr_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *dict) { afr_do_readdir(frame, this, fd, size, offset, GF_FOP_READDIRP, dict); return 0; } int32_t afr_releasedir(xlator_t *this, fd_t *fd) { afr_cleanup_fd_ctx(this, fd); return 0; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-transaction.h0000644000000000000000000000013014522202451024336 xustar000000000000000029 mtime=1699284265.62002729 29 atime=1699284265.62002729 30 ctime=1699284301.094134138 glusterfs-11.1/xlators/cluster/afr/src/afr-transaction.h0000664000175100017510000000401414522202451024616 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __TRANSACTION_H__ #define __TRANSACTION_H__ #include "afr.h" void afr_transaction_fop_failed(afr_local_t *local, int child_index); int32_t afr_transaction(call_frame_t *frame, xlator_t *this, afr_transaction_type type); int afr_set_pending_dict(afr_private_t *priv, dict_t *xattr, int32_t **pending); void afr_delayed_changelog_wake_up(xlator_t *this, fd_t *fd); void __mark_all_success(call_frame_t *frame, xlator_t *this); gf_boolean_t afr_txn_nothing_failed(call_frame_t *frame, xlator_t *this); int afr_read_txn(call_frame_t *frame, xlator_t *this, inode_t *inode, afr_read_txn_wind_t readfn, afr_transaction_type type); int afr_read_txn_continue(call_frame_t *frame, xlator_t *this, int subvol); void afr_pending_read_increment(afr_private_t *priv, int child_index); void afr_pending_read_decrement(afr_private_t *priv, int child_index); call_frame_t * afr_transaction_detach_fop_frame(call_frame_t *frame); gf_boolean_t afr_has_quorum(unsigned char *subvols, afr_private_t *priv, call_frame_t *frame); gf_boolean_t afr_needs_changelog_update(afr_local_t *local); void afr_zero_fill_stat(afr_local_t *local); void afr_pick_error_xdata(afr_local_t *local, unsigned int child_count, inode_t *inode1, unsigned char *readable1, inode_t *inode2, unsigned char *readable2); int afr_transaction_resume(call_frame_t *frame, xlator_t *this); int afr_lock(call_frame_t *frame, xlator_t *this); void afr_delayed_changelog_wake_up_cbk(void *data); int afr_release_notify_lock_for_ta(void *opaque); int afr_ta_lock_release_done(int ret, call_frame_t *ta_frame, void *opaque); #endif /* __TRANSACTION_H__ */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-self-heal-metadata.c0000644000000000000000000000013114522202451025423 xustar000000000000000030 mtime=1699284265.618027284 30 atime=1699284265.618027284 29 ctime=1699284301.12813424 glusterfs-11.1/xlators/cluster/afr/src/afr-self-heal-metadata.c0000664000175100017510000004011114522202451025700 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "afr.h" #include "afr-self-heal.h" #include "protocol-common.h" #include #define AFR_HEAL_ATTR (GF_SET_ATTR_UID | GF_SET_ATTR_GID | GF_SET_ATTR_MODE) static gf_boolean_t _afr_ignorable_key_match(dict_t *d, char *k, data_t *val, void *mdata) { return afr_is_xattr_ignorable(k); } static void afr_delete_ignorable_xattrs(dict_t *xattr) { dict_foreach_match(xattr, _afr_ignorable_key_match, NULL, dict_remove_foreach_fn, NULL); } static int __afr_selfheal_metadata_do(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, unsigned char *healed_sinks, struct afr_reply *locked_replies) { int ret = -1; loc_t loc = { 0, }; dict_t *xattr = NULL; dict_t *old_xattr = NULL; afr_private_t *priv = NULL; int i = 0; priv = this->private; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_SELF_HEAL_INFO, "performing metadata selfheal on %s", uuid_utoa(inode->gfid)); ret = syncop_getxattr(priv->children[source], &loc, &xattr, NULL, NULL, NULL); if (ret < 0) { ret = -EIO; goto out; } afr_delete_ignorable_xattrs(xattr); for (i = 0; i < priv->child_count; i++) { if (old_xattr) { dict_unref(old_xattr); old_xattr = NULL; } if (!healed_sinks[i]) continue; ret = syncop_setattr(priv->children[i], &loc, &locked_replies[source].poststat, AFR_HEAL_ATTR, NULL, NULL, NULL, NULL); if (ret) healed_sinks[i] = 0; ret = syncop_getxattr(priv->children[i], &loc, &old_xattr, 0, NULL, NULL); if (old_xattr) { afr_delete_ignorable_xattrs(old_xattr); ret = syncop_removexattr(priv->children[i], &loc, "", old_xattr, NULL); if (ret) healed_sinks[i] = 0; } ret = syncop_setxattr(priv->children[i], &loc, xattr, 0, NULL, NULL); if (ret) healed_sinks[i] = 0; } ret = 0; out: loc_wipe(&loc); if (xattr) dict_unref(xattr); if (old_xattr) dict_unref(old_xattr); return ret; } static uint64_t mtime_ns(struct iatt *ia) { uint64_t ret; ret = (((uint64_t)(ia->ia_mtime)) * 1000000000) + (uint64_t)(ia->ia_mtime_nsec); return ret; } /* * When directory content is modified, [mc]time is updated. On * Linux, the filesystem does it, while at least on NetBSD, the * kernel file-system independent code does it. This means that * when entries are added while bricks are down, the kernel sends * a SETATTR [mc]time which will cause metadata split brain for * the directory. In this case, clear the split brain by finding * the source with the most recent modification date. */ static int afr_dirtime_splitbrain_source(call_frame_t *frame, xlator_t *this, struct afr_reply *replies, unsigned char *locked_on) { afr_private_t *priv = NULL; int source = -1; struct iatt source_ia; struct iatt child_ia; uint64_t mtime = 0; int i; int ret = -1; priv = this->private; for (i = 0; i < priv->child_count; i++) { if (!locked_on[i]) continue; if (!replies[i].valid) continue; if (replies[i].op_ret != 0) continue; if (mtime_ns(&replies[i].poststat) <= mtime) continue; mtime = mtime_ns(&replies[i].poststat); source = i; } if (source == -1) goto out; source_ia = replies[source].poststat; if (source_ia.ia_type != IA_IFDIR) goto out; for (i = 0; i < priv->child_count; i++) { if (i == source) continue; if (!replies[i].valid) continue; if (replies[i].op_ret != 0) continue; child_ia = replies[i].poststat; if (!IA_EQUAL(source_ia, child_ia, gfid) || !IA_EQUAL(source_ia, child_ia, type) || !IA_EQUAL(source_ia, child_ia, prot) || !IA_EQUAL(source_ia, child_ia, uid) || !IA_EQUAL(source_ia, child_ia, gid) || !afr_xattrs_are_equal( replies[source].xdata, replies[i].xdata, AFR_IS_ARBITER_BRICK(priv, i) ? _gf_true : _gf_false)) goto out; } /* * Metadata split brain is just about [amc]time * We return our source. */ ret = source; out: return ret; } static int __afr_selfheal_metadata_mark_pending_xattrs(call_frame_t *frame, xlator_t *this, inode_t *inode, struct afr_reply *replies, unsigned char *sources) { int ret = 0; int i = 0; int m_idx = 0; afr_private_t *priv = NULL; int raw[AFR_NUM_CHANGE_LOGS] = {0}; dict_t *xattr = NULL; priv = this->private; m_idx = afr_index_for_transaction_type(AFR_METADATA_TRANSACTION); raw[m_idx] = 1; xattr = dict_new(); if (!xattr) return -ENOMEM; for (i = 0; i < priv->child_count; i++) { if (sources[i]) continue; ret = dict_set_static_bin(xattr, priv->pending_key[i], raw, sizeof(int) * AFR_NUM_CHANGE_LOGS); if (ret) { ret = -1; goto out; } } for (i = 0; i < priv->child_count; i++) { if (!sources[i]) continue; ret = afr_selfheal_post_op(frame, this, inode, i, xattr, NULL); if (ret < 0) { gf_msg(this->name, GF_LOG_INFO, -ret, AFR_MSG_SELF_HEAL_INFO, "Failed to set pending metadata xattr on child %d for %s", i, uuid_utoa(inode->gfid)); goto out; } } afr_replies_wipe(replies, priv->child_count); ret = afr_selfheal_unlocked_discover(frame, inode, inode->gfid, replies); out: if (xattr) dict_unref(xattr); return ret; } /* * Look for mismatching uid/gid or mode or user xattrs even if * AFR xattrs don't say so, and pick one arbitrarily as winner. */ static int __afr_selfheal_metadata_finalize_source(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, unsigned char *locked_on, struct afr_reply *replies) { int i = 0; afr_private_t *priv = NULL; struct iatt srcstat = { 0, }; int source = -1; int sources_count = 0; int ret = 0; priv = this->private; sources_count = AFR_COUNT(sources, priv->child_count); if ((AFR_CMP(locked_on, healed_sinks, priv->child_count) == 0) || !sources_count) { source = afr_mark_split_brain_source_sinks( frame, this, inode, sources, sinks, healed_sinks, locked_on, replies, AFR_METADATA_TRANSACTION); if (source >= 0) { _afr_fav_child_reset_sink_xattrs( frame, this, inode, source, healed_sinks, undid_pending, AFR_METADATA_TRANSACTION, locked_on, replies); goto out; } /* If this is a directory mtime/ctime only split brain use the most recent */ source = afr_dirtime_splitbrain_source(frame, this, replies, locked_on); if (source != -1) { gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_SPLIT_BRAIN, "clear time " "split brain on %s", uuid_utoa(replies[source].poststat.ia_gfid)); sources[source] = 1; healed_sinks[source] = 0; goto out; } if (!priv->metadata_splitbrain_forced_heal) { gf_event(EVENT_AFR_SPLIT_BRAIN, "client-pid=%d;" "subvol=%s;" "type=metadata;file=%s", this->ctx->cmd_args.client_pid, this->name, uuid_utoa(inode->gfid)); return -EIO; } /* Metadata split brain, select one subvol arbitrarily */ for (i = 0; i < priv->child_count; i++) { if (locked_on[i] && healed_sinks[i]) { sources[i] = 1; healed_sinks[i] = 0; break; } } } /* No split brain at this point. If we were called from * afr_heal_splitbrain_file(), abort.*/ if (afr_dict_contains_heal_op(frame)) return -EIO; source = afr_choose_source_by_policy(priv, sources, AFR_METADATA_TRANSACTION); srcstat = replies[source].poststat; for (i = 0; i < priv->child_count; i++) { if (!sources[i] || i == source) continue; if (!IA_EQUAL(srcstat, replies[i].poststat, type) || !IA_EQUAL(srcstat, replies[i].poststat, uid) || !IA_EQUAL(srcstat, replies[i].poststat, gid) || !IA_EQUAL(srcstat, replies[i].poststat, prot)) { gf_msg_debug(this->name, 0, "%s: iatt mismatch " "for source(%d) vs (%d)", uuid_utoa(replies[source].poststat.ia_gfid), source, i); sources[i] = 0; healed_sinks[i] = 1; } } for (i = 0; i < priv->child_count; i++) { if (!sources[i] || i == source) continue; if (!afr_xattrs_are_equal( replies[source].xdata, replies[i].xdata, AFR_IS_ARBITER_BRICK(priv, i) ? _gf_true : _gf_false)) { gf_msg_debug(this->name, 0, "%s: xattr mismatch " "for source(%d) vs (%d)", uuid_utoa(replies[source].poststat.ia_gfid), source, i); sources[i] = 0; healed_sinks[i] = 1; } } if ((sources_count == priv->child_count) && (source > -1) && (AFR_COUNT(healed_sinks, priv->child_count) != 0)) { ret = __afr_selfheal_metadata_mark_pending_xattrs(frame, this, inode, replies, sources); if (ret < 0) return ret; } out: afr_mark_active_sinks(this, sources, locked_on, healed_sinks); return source; } int __afr_selfheal_metadata_prepare(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, struct afr_reply *replies, unsigned char *pflag) { int ret = -1; int source = -1; afr_private_t *priv = NULL; int i = 0; uint64_t *witness = NULL; priv = this->private; ret = afr_selfheal_unlocked_discover(frame, inode, inode->gfid, replies); if (ret) return ret; witness = alloca0(sizeof(*witness) * priv->child_count); ret = afr_selfheal_find_direction(frame, this, replies, AFR_METADATA_TRANSACTION, locked_on, sources, sinks, witness, pflag); if (ret) return ret; /* Initialize the healed_sinks[] array optimistically to the intersection of to-be-healed (i.e sinks[]) and the list of servers which are up (i.e locked_on[]). As we encounter failures in the healing process, we will unmark the respective servers in the healed_sinks[] array. */ AFR_INTERSECT(healed_sinks, sinks, locked_on, priv->child_count); /* If any source has witness, pick first * witness source and make everybody else sinks */ for (i = 0; i < priv->child_count; i++) { if (sources[i] && witness[i]) { source = i; break; } } if (source != -1) { for (i = 0; i < priv->child_count; i++) { if (i != source && sources[i]) { sources[i] = 0; healed_sinks[i] = 1; } } } source = __afr_selfheal_metadata_finalize_source( frame, this, inode, sources, sinks, healed_sinks, undid_pending, locked_on, replies); if (source < 0) return -EIO; return source; } int afr_selfheal_metadata(call_frame_t *frame, xlator_t *this, inode_t *inode) { afr_private_t *priv = NULL; int ret = -1; unsigned char *sources = NULL; unsigned char *sinks = NULL; unsigned char *data_lock = NULL; unsigned char *healed_sinks = NULL; unsigned char *undid_pending = NULL; struct afr_reply *locked_replies = NULL; gf_boolean_t did_sh = _gf_true; int source = -1; priv = this->private; sources = alloca0(priv->child_count); sinks = alloca0(priv->child_count); healed_sinks = alloca0(priv->child_count); undid_pending = alloca0(priv->child_count); data_lock = alloca0(priv->child_count); locked_replies = alloca0(sizeof(*locked_replies) * priv->child_count); ret = afr_selfheal_tie_breaker_inodelk(frame, this, inode, this->name, LLONG_MAX - 1, 0, data_lock); { if (ret < priv->child_count) { ret = -ENOTCONN; goto unlock; } ret = __afr_selfheal_metadata_prepare( frame, this, inode, data_lock, sources, sinks, healed_sinks, undid_pending, locked_replies, NULL); if (ret < 0) goto unlock; source = ret; if (AFR_COUNT(healed_sinks, priv->child_count) == 0) { did_sh = _gf_false; goto unlock; } ret = __afr_selfheal_metadata_do(frame, this, inode, source, healed_sinks, locked_replies); if (ret) goto unlock; afr_selfheal_restore_time(frame, this, inode, source, healed_sinks, locked_replies); ret = afr_selfheal_undo_pending( frame, this, inode, sources, sinks, healed_sinks, undid_pending, AFR_METADATA_TRANSACTION, locked_replies, data_lock); } unlock: afr_selfheal_uninodelk(frame, this, inode, this->name, LLONG_MAX - 1, 0, data_lock); if (did_sh) afr_log_selfheal(inode->gfid, this, ret, "metadata", source, sources, healed_sinks); else ret = 1; if (locked_replies) afr_replies_wipe(locked_replies, priv->child_count); return ret; } int afr_selfheal_metadata_by_stbuf(xlator_t *this, struct iatt *stbuf) { inode_t *inode = NULL; inode_t *link_inode = NULL; call_frame_t *frame = NULL; int ret = 0; if (gf_uuid_is_null(stbuf->ia_gfid)) { ret = -EINVAL; goto out; } inode = inode_new(this->itable); if (!inode) { ret = -ENOMEM; goto out; } link_inode = inode_link(inode, NULL, NULL, stbuf); if (!link_inode) { ret = -ENOMEM; goto out; } frame = afr_frame_create(this, &ret); if (!frame) { ret = -ret; goto out; } ret = afr_selfheal_metadata(frame, this, link_inode); out: if (inode) inode_unref(inode); if (link_inode) inode_unref(link_inode); if (frame) AFR_STACK_DESTROY(frame); return ret; } glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-messages.h0000644000000000000000000000013114522202451023621 xustar000000000000000030 mtime=1699284265.615027275 30 atime=1699284265.615027275 29 ctime=1699284301.10813418 glusterfs-11.1/xlators/cluster/afr/src/afr-messages.h0000664000175100017510000002317714522202451024113 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _AFR_MESSAGES_H_ #define _AFR_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID( AFR, AFR_MSG_QUORUM_FAIL, AFR_MSG_QUORUM_MET, AFR_MSG_QUORUM_OVERRIDE, AFR_MSG_INVALID_CHILD_UP, AFR_MSG_SUBVOL_UP, AFR_MSG_SUBVOLS_DOWN, AFR_MSG_ENTRY_UNLOCK_FAIL, AFR_MSG_SPLIT_BRAIN, AFR_MSG_OPEN_FAIL, AFR_MSG_UNLOCK_FAIL, AFR_MSG_REPLACE_BRICK_STATUS, AFR_MSG_GFID_NULL, AFR_MSG_FD_CREATE_FAILED, AFR_MSG_DICT_SET_FAILED, AFR_MSG_EXPUNGING_FILE_OR_DIR, AFR_MSG_MIGRATION_IN_PROGRESS, AFR_MSG_CHILD_MISCONFIGURED, AFR_MSG_VOL_MISCONFIGURED, AFR_MSG_INTERNAL_LKS_FAILED, AFR_MSG_INVALID_FD, AFR_MSG_LOCK_INFO, AFR_MSG_LOCK_XLATOR_NOT_LOADED, AFR_MSG_FD_CTX_GET_FAILED, AFR_MSG_INVALID_SUBVOL, DEPRECATED_AFR_MSG_PUMP_XLATOR_ERROR, AFR_MSG_SELF_HEAL_INFO, AFR_MSG_READ_SUBVOL_ERROR, AFR_MSG_DICT_GET_FAILED, AFR_MSG_INFO_COMMON, AFR_MSG_SPLIT_BRAIN_CHOICE_ERROR, AFR_MSG_LOCAL_CHILD, AFR_MSG_INVALID_DATA, AFR_MSG_INVALID_ARG, AFR_MSG_INDEX_DIR_GET_FAILED, AFR_MSG_FSYNC_FAILED, AFR_MSG_FAVORITE_CHILD, AFR_MSG_SELF_HEAL_FAILED, AFR_MSG_SPLIT_BRAIN_STATUS, AFR_MSG_ADD_BRICK_STATUS, AFR_MSG_NO_CHANGELOG, AFR_MSG_TIMER_CREATE_FAIL, AFR_MSG_SBRAIN_FAV_CHILD_POLICY, AFR_MSG_INODE_CTX_GET_FAILED, AFR_MSG_THIN_ARB, AFR_MSG_THIN_ARB_XATTROP_FAILED, AFR_MSG_THIN_ARB_LOC_POP_FAILED, AFR_MSG_GET_PEND_VAL, AFR_MSG_THIN_ARB_SKIP_SHD, AFR_MSG_UNKNOWN_SET, AFR_MSG_NO_XL_ID, AFR_MSG_SELF_HEAL_INFO_START, AFR_MSG_SELF_HEAL_INFO_FINISH, AFR_MSG_INCRE_COUNT, AFR_MSG_ADD_TO_OUTPUT_FAILED, AFR_MSG_SET_TIME_FAILED, AFR_MSG_GFID_MISMATCH_DETECTED, AFR_MSG_GFID_HEAL_MSG, AFR_MSG_THIN_ARB_LOOKUP_FAILED, AFR_MSG_DICT_CREATE_FAILED, AFR_MSG_NO_MAJORITY_TO_RESOLVE, AFR_MSG_TYPE_MISMATCH, AFR_MSG_SIZE_POLICY_NOT_APPLICABLE, AFR_MSG_NO_CHILD_SELECTED, AFR_MSG_INVALID_CHILD, AFR_MSG_RESOLVE_CONFLICTING_DATA, SERROR_GETTING_SRC_BRICK, SNO_DIFF_IN_MTIME, SNO_BIGGER_FILE, SALL_BRICKS_UP_TO_RESOLVE, AFR_MSG_UNLOCK_FAILED, AFR_MSG_POST_OP_FAILED, AFR_MSG_TA_FRAME_CREATE_FAILED, AFR_MSG_SET_KEY_XATTROP_FAILED, AFR_MSG_BLOCKING_ENTRYLKS_FAILED, AFR_MSG_FOP_FAILED, AFR_MSG_CLEAN_UP_FAILED, AFR_MSG_UNABLE_TO_FETCH, AFR_MSG_XATTR_SET_FAILED, AFR_MSG_SPLIT_BRAIN_REPLICA, AFR_MSG_INODE_CTX_FAILED, AFR_MSG_LOOKUP_FAILED, AFR_MSG_ALL_SUBVOLS_DOWN, AFR_MSG_RELEASE_LOCK_FAILED, AFR_MSG_CLEAR_TIME_SPLIT_BRAIN, AFR_MSG_READ_FAILED, AFR_MSG_LAUNCH_FAILED, AFR_MSG_READ_SUBVOL_NOT_UP, AFR_MSG_LK_HEAL_DOM, AFR_MSG_NEW_BRICK, AFR_MSG_SPLIT_BRAIN_SET_FAILED, AFR_MSG_SPLIT_BRAIN_DETERMINE_FAILED, AFR_MSG_HEALER_SPAWN_FAILED, AFR_MSG_ADD_CRAWL_EVENT_FAILED, AFR_MSG_NULL_DEREF, AFR_MSG_SET_PEND_XATTR, AFR_MSG_INTERNAL_ATTR); #define AFR_MSG_DICT_GET_FAILED_STR "Dict get failed" #define AFR_MSG_DICT_SET_FAILED_STR "Dict set failed" #define AFR_MSG_HEALER_SPAWN_FAILED_STR "Healer spawn failed" #define AFR_MSG_ADD_CRAWL_EVENT_FAILED_STR "Adding crawl event failed" #define AFR_MSG_INVALID_ARG_STR "Invalid argument" #define AFR_MSG_INDEX_DIR_GET_FAILED_STR "unable to get index-dir on " #define AFR_MSG_THIN_ARB_LOOKUP_FAILED_STR "Failed lookup on file" #define AFR_MSG_DICT_CREATE_FAILED_STR "Failed to create dict." #define AFR_MSG_THIN_ARB_XATTROP_FAILED_STR "Xattrop failed." #define AFR_MSG_THIN_ARB_LOC_POP_FAILED_STR \ "Failed to populate loc for thin-arbiter" #define AFR_MSG_GET_PEND_VAL_STR "Error getting value of pending" #define AFR_MSG_THIN_ARB_SKIP_SHD_STR "I am not the god shd. skipping." #define AFR_MSG_UNKNOWN_SET_STR "Unknown set" #define AFR_MSG_NO_XL_ID_STR "xl does not have id" #define AFR_MSG_SELF_HEAL_INFO_START_STR "starting full sweep on" #define AFR_MSG_SELF_HEAL_INFO_FINISH_STR "finished full sweep on" #define AFR_MSG_INCRE_COUNT_STR "Could not increment the counter." #define AFR_MSG_ADD_TO_OUTPUT_FAILED_STR "Could not add to output" #define AFR_MSG_SET_TIME_FAILED_STR "Could not set time" #define AFR_MSG_GFID_HEAL_MSG_STR "Error setting gfid-heal-msg dict" #define AFR_MSG_NO_MAJORITY_TO_RESOLVE_STR \ "No majority to resolve gfid split brain" #define AFR_MSG_GFID_MISMATCH_DETECTED_STR "Gfid mismatch dectected" #define AFR_MSG_SELF_HEAL_INFO_STR "performing selfheal" #define AFR_MSG_TYPE_MISMATCH_STR "TYPE mismatch" #define AFR_MSG_SIZE_POLICY_NOT_APPLICABLE_STR \ "Size policy is not applicable to directories." #define AFR_MSG_NO_CHILD_SELECTED_STR \ "No child selected by favorite-child policy" #define AFR_MSG_INVALID_CHILD_STR "Invalid child" #define AFR_MSG_RESOLVE_CONFLICTING_DATA_STR \ "selected as authentic to resolve conflicting data" #define SERROR_GETTING_SRC_BRICK_STR "Error getting the source brick" #define SNO_DIFF_IN_MTIME_STR "No difference in mtime" #define SNO_BIGGER_FILE_STR "No bigger file" #define SALL_BRICKS_UP_TO_RESOLVE_STR \ "All the bricks should be up to resolve the gfid split brain" #define AFR_MSG_UNLOCK_FAILED_STR "Failed to unlock" #define AFR_MSG_POST_OP_FAILED_STR "Post-op on thin-arbiter failed" #define AFR_MSG_TA_FRAME_CREATE_FAILED_STR "Failed to create ta_frame" #define AFR_MSG_SET_KEY_XATTROP_FAILED_STR "Could not set key during xattrop" #define AFR_MSG_BLOCKING_ENTRYLKS_FAILED_STR "Blocking entrylks failed" #define AFR_MSG_FSYNC_FAILED_STR "fsync failed" #define AFR_MSG_QUORUM_FAIL_STR "quorum is not met" #define AFR_MSG_FOP_FAILED_STR "Failing Fop" #define AFR_MSG_INVALID_SUBVOL_STR "not a subvolume" #define AFR_MSG_VOL_MISCONFIGURED_STR "Volume is dangling" #define AFR_MSG_CHILD_MISCONFIGURED_STR \ "replicate translator needs more than one subvolume defined" #define AFR_MSG_CLEAN_UP_FAILED_STR "Failed to clean up healer threads" #define AFR_MSG_QUORUM_OVERRIDE_STR "overriding quorum-count" #define AFR_MSG_UNABLE_TO_FETCH_STR \ "Unable to fetch afr-pending-xattr option from volfile. Falling back to " \ "using client translator names" #define AFR_MSG_NULL_DEREF_STR "possible NULL deref" #define AFR_MSG_XATTR_SET_FAILED_STR "Cannot set xattr cookie key" #define AFR_MSG_SPLIT_BRAIN_STATUS_STR "Failed to create synctask" #define AFR_MSG_SUBVOLS_DOWN_STR "All subvolumes are not up" #define AFR_MSG_SPLIT_BRAIN_CHOICE_ERROR_STR \ "Failed to cancel split-brain choice" #define AFR_MSG_SPLIT_BRAIN_REPLICA_STR \ "Cannot set replica. File is not in data/metadata split-brain" #define AFR_MSG_INODE_CTX_FAILED_STR "Failed to get inode_ctx" #define AFR_MSG_READ_SUBVOL_ERROR_STR "no read subvols" #define AFR_MSG_LOCAL_CHILD_STR "selecting local read-child" #define AFR_MSG_LOOKUP_FAILED_STR "Failed to lookup/create thin-arbiter id file" #define AFR_MSG_TIMER_CREATE_FAIL_STR \ "Cannot create timer for delayed initialization" #define AFR_MSG_SUBVOL_UP_STR "Subvolume came back up; going online" #define AFR_MSG_ALL_SUBVOLS_DOWN_STR \ "All subvolumes are down. Going offline until atleast one of them is up" #define AFR_MSG_RELEASE_LOCK_FAILED_STR "Failed to release lock" #define AFR_MSG_INVALID_CHILD_UP_STR "Received child_up from invalid subvolume" #define AFR_MSG_QUORUM_MET_STR "Client-quorum is met" #define AFR_MSG_EXPUNGING_FILE_OR_DIR_STR "expunging file or dir" #define AFR_MSG_SELF_HEAL_FAILED_STR "Invalid" #define AFR_MSG_SPLIT_BRAIN_STR "Skipping conservative mergeon the file" #define AFR_MSG_CLEAR_TIME_SPLIT_BRAIN_STR "clear time split brain" #define AFR_MSG_READ_FAILED_STR "Failing read since good brick is down" #define AFR_MSG_LAUNCH_FAILED_STR "Failed to launch synctask" #define AFR_MSG_READ_SUBVOL_NOT_UP_STR \ "read subvolume in this generation is not up" #define AFR_MSG_INTERNAL_LKS_FAILED_STR \ "Unable to work with lk-owner while attempting fop" #define AFR_MSG_LOCK_XLATOR_NOT_LOADED_STR \ "subvolume does not support locking. please load features/locks xlator " \ "on server." #define AFR_MSG_FD_CTX_GET_FAILED_STR "unable to get fd ctx" #define AFR_MSG_INFO_COMMON_STR "fd not open on any subvolumes, aborting." #define AFR_MSG_REPLACE_BRICK_STATUS_STR "Couldn't acquire lock on any child." #define AFR_MSG_NEW_BRICK_STR "New brick" #define AFR_MSG_SPLIT_BRAIN_SET_FAILED_STR \ "Failed to set split-brain choice to -1" #define AFR_MSG_SPLIT_BRAIN_DETERMINE_FAILED_STR \ "Failed to determine split-brain. Aborting split-brain-choice set" #define AFR_MSG_OPEN_FAIL_STR "Failed to open subvolume" #define AFR_MSG_SET_PEND_XATTR_STR "Set of pending xattr" #define AFR_MSG_INTERNAL_ATTR_STR "is an internal extended attribute" #endif /* !_AFR_MESSAGES_H_ */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-mem-types.h0000644000000000000000000000013214522202451023733 xustar000000000000000030 mtime=1699284265.615027275 30 atime=1699284265.615027275 30 ctime=1699284301.102134162 glusterfs-11.1/xlators/cluster/afr/src/afr-mem-types.h0000664000175100017510000000202114522202451024205 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __AFR_MEM_TYPES_H__ #define __AFR_MEM_TYPES_H__ #include enum gf_afr_mem_types_ { gf_afr_mt_afr_fd_ctx_t = gf_common_mt_end + 1, gf_afr_mt_afr_private_t, gf_afr_mt_int32_t, gf_afr_mt_char, gf_afr_mt_xattr_key, gf_afr_mt_dict_t, gf_afr_mt_xlator_t, gf_afr_mt_afr_node_character, gf_afr_mt_inode_ctx_t, gf_afr_mt_shd_event_t, gf_afr_mt_reply_t, gf_afr_mt_subvol_healer_t, gf_afr_mt_spbc_timeout_t, gf_afr_mt_spb_status_t, gf_afr_mt_empty_brick_t, gf_afr_mt_child_latency_t, gf_afr_mt_atomic_t, gf_afr_mt_lk_heal_info_t, gf_afr_mt_gf_lock, gf_afr_mt_end }; #endif glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr-inode-read.h0000644000000000000000000000013214522202451024022 xustar000000000000000030 mtime=1699284265.614027272 30 atime=1699284265.614027272 30 ctime=1699284301.096134144 glusterfs-11.1/xlators/cluster/afr/src/afr-inode-read.h0000664000175100017510000000255514522202451024310 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __INODE_READ_H__ #define __INODE_READ_H__ int32_t afr_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata); int32_t afr_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata); int32_t afr_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata); int32_t afr_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata); int32_t afr_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata); int32_t afr_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata); int32_t afr_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata); int afr_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata); int afr_handle_quota_size(afr_local_t *local, xlator_t *this); #endif /* __INODE_READ_H__ */ glusterfs-11.1/xlators/cluster/afr/src/PaxHeaders.9031/afr.h0000644000000000000000000000013114522202451022014 xustar000000000000000030 mtime=1699284265.621027293 29 atime=1699284265.62002729 30 ctime=1699284301.092134132 glusterfs-11.1/xlators/cluster/afr/src/afr.h0000664000175100017510000011775014522202451022307 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __AFR_H__ #define __AFR_H__ #include #include #include "afr-mem-types.h" #include #include "afr-self-heald.h" #include "afr-messages.h" #define SHD_INODE_LRU_LIMIT 1 #define AFR_PATHINFO_HEADER "REPLICATE:" #define AFR_SH_DATA_DOMAIN_FMT "%s:self-heal" #define AFR_DIRTY_DEFAULT AFR_XATTR_PREFIX ".dirty" #define AFR_DIRTY (((afr_private_t *)(THIS->private))->afr_dirty) #define AFR_LOCKEE_COUNT_MAX 3 #define AFR_NUM_CHANGE_LOGS 3 /*data + metadata + entry*/ #define AFR_DEFAULT_SPB_CHOICE_TIMEOUT 300 /*in seconds*/ #define ARBITER_BRICK_INDEX 2 #define THIN_ARBITER_BRICK_INDEX 2 #define AFR_TA_DOM_NOTIFY "afr.ta.dom-notify" #define AFR_TA_DOM_MODIFY "afr.ta.dom-modify" #define AFR_LK_HEAL_DOM "afr.lock-heal.domain" #define AFR_HALO_MAX_LATENCY 99999 #define AFR_ANON_DIR_PREFIX ".glusterfs-anonymous-inode" #define PFLAG_PENDING (1 << 0) #define PFLAG_SBRAIN (1 << 1) typedef int (*afr_lock_cbk_t)(call_frame_t *frame, xlator_t *this); typedef int (*afr_read_txn_wind_t)(call_frame_t *frame, xlator_t *this, int subvol); typedef int (*afr_inode_refresh_cbk_t)(call_frame_t *frame, xlator_t *this, int err); typedef int (*afr_changelog_resume_t)(call_frame_t *frame, xlator_t *this); #define AFR_COUNT(array, max) \ ({ \ int __i; \ int __res = 0; \ for (__i = 0; __i < max; __i++) \ if (array[__i]) \ __res++; \ __res; \ }) #define AFR_INTERSECT(dst, src1, src2, max) \ ({ \ int __i; \ for (__i = 0; __i < max; __i++) \ dst[__i] = src1[__i] && src2[__i]; \ }) #define AFR_CMP(a1, a2, len) \ ({ \ int __cmp = 0; \ int __i; \ for (__i = 0; __i < len; __i++) \ if (a1[__i] != a2[__i]) { \ __cmp = 1; \ break; \ } \ __cmp; \ }) #define AFR_IS_ARBITER_BRICK(priv, index) \ ((priv->arbiter_count == 1) && (index == ARBITER_BRICK_INDEX)) #define AFR_SET_ERROR_AND_CHECK_SPLIT_BRAIN(ret, errnum) \ do { \ local->op_ret = ret; \ local->op_errno = errnum; \ if (local->op_errno == EIO) \ gf_msg(this->name, GF_LOG_ERROR, local->op_errno, \ AFR_MSG_SPLIT_BRAIN, \ "Failing %s on gfid %s: " \ "split-brain observed.", \ gf_fop_list[local->op], uuid_utoa(local->inode->gfid)); \ } while (0) #define AFR_ERROR_OUT_IF_FDCTX_INVALID(__fd, __this, __error, __label) \ do { \ afr_fd_ctx_t *__fd_ctx = NULL; \ __fd_ctx = afr_fd_ctx_get(__fd, __this); \ if (__fd_ctx && __fd_ctx->is_fd_bad) { \ __error = EBADF; \ goto __label; \ } \ } while (0) typedef enum { AFR_READ_POLICY_FIRST_UP, AFR_READ_POLICY_GFID_HASH, AFR_READ_POLICY_GFID_PID_HASH, AFR_READ_POLICY_LESS_LOAD, AFR_READ_POLICY_LEAST_LATENCY, AFR_READ_POLICY_LOAD_LATENCY_HYBRID, } afr_read_hash_mode_t; typedef enum { AFR_FAV_CHILD_NONE, AFR_FAV_CHILD_BY_SIZE, AFR_FAV_CHILD_BY_CTIME, AFR_FAV_CHILD_BY_MTIME, AFR_FAV_CHILD_BY_MAJORITY, AFR_FAV_CHILD_POLICY_MAX, } afr_favorite_child_policy; typedef enum { AFR_SELFHEAL_DATA_FULL = 0, AFR_SELFHEAL_DATA_DIFF, AFR_SELFHEAL_DATA_DYNAMIC, } afr_data_self_heal_type_t; typedef enum { AFR_CHILD_UNKNOWN = -1, AFR_CHILD_ZERO, AFR_CHILD_ONE, AFR_CHILD_THIN_ARBITER, } afr_child_index; typedef enum { TA_WAIT_FOR_NOTIFY_LOCK_REL, /*FOP came after notify domain lock upcall notification and waiting for its release.*/ TA_GET_INFO_FROM_TA_FILE, /*FOP needs post-op on ta file to get *info about which brick is bad.*/ TA_INFO_IN_MEMORY_SUCCESS, /*Bad brick info is in memory and fop failed *on BAD brick - Success*/ TA_INFO_IN_MEMORY_FAILED, /*Bad brick info is in memory and fop failed *on GOOD brick - Failed*/ TA_SUCCESS, /*FOP succeeded on both data bricks.*/ } afr_ta_fop_state_t; struct afr_nfsd { uint32_t halo_max_latency_msec; gf_boolean_t iamnfsd; }; typedef struct _afr_lk_heal_info { fd_t *fd; struct gf_flock flock; int32_t cmd; dict_t *xdata_req; unsigned char *locked_nodes; struct list_head pos; gf_lkowner_t lk_owner; pid_t pid; int32_t *child_up_event_gen; int32_t *child_down_event_gen; } afr_lk_heal_info_t; typedef struct _afr_private { gf_lock_t lock; /* to guard access to child_count, etc */ unsigned int child_count; /* total number of children */ unsigned int arbiter_count; /*subset of child_count. Has to be 0 or 1.*/ xlator_t **children; int favorite_child; /* subvolume to be preferred in resolving split-brain cases */ /* For thin-arbiter. */ uuid_t ta_gfid; unsigned int thin_arbiter_count; /* 0 or 1 at the moment.*/ int ta_bad_child_index; int ta_event_gen; unsigned int ta_in_mem_txn_count; unsigned int ta_on_wire_txn_count; struct list_head ta_waitq; struct list_head ta_onwireq; unsigned char *anon_inode; unsigned char *child_up; unsigned char *halo_child_up; int64_t *child_latency; unsigned char *local; char **pending_key; afr_data_self_heal_type_t data_self_heal_algorithm; unsigned int data_self_heal_window_size; /* max number of pipelined read/writes */ struct list_head heal_waiting; /*queue for files that need heal*/ uint32_t heal_wait_qlen; /*configurable queue length for heal_waiting*/ int32_t heal_waiters; /* No. of elements currently in wait queue.*/ struct list_head healing; /* queue for files that are undergoing background heal*/ uint32_t background_self_heal_count; /*configurable queue length for healing queue*/ int32_t healers; /* No. of elements currently undergoing background heal*/ gf_boolean_t release_ta_notify_dom_lock; gf_boolean_t metadata_self_heal; /* on/off */ gf_boolean_t entry_self_heal; /* on/off */ gf_boolean_t metadata_splitbrain_forced_heal; /* on/off */ int read_child; /* read-subvolume */ gf_atomic_t *pending_reads; /*No. of pending read cbks per child.*/ gf_timer_t *timer; /* launched when parent up is received */ unsigned int wait_count; /* # of servers to wait for success */ unsigned char ta_child_up; gf_boolean_t optimistic_change_log; gf_boolean_t eager_lock; gf_boolean_t pre_op_compat; /* on/off */ uint32_t post_op_delay_secs; unsigned int quorum_count; off_t ta_notify_dom_lock_offset; afr_favorite_child_policy fav_child_policy; /*Policy to use for automatic resolution of split-brains.*/ afr_read_hash_mode_t hash_mode; /* for when read_child is not set */ int32_t *last_event; /* @event_generation: Keeps count of number of events received which can potentially impact consistency decisions. The events are CHILD_UP and CHILD_DOWN, when we have to recalculate the freshness/staleness of copies to detect if changes had happened while the other server was down. CHILD_DOWN and CHILD_UP can also be received on network disconnect/reconnects and not necessarily server going down/up. Recalculating freshness/staleness on network events is equally important as we might have had a network split brain. */ uint32_t event_generation; char vol_uuid[GF_UUID_BUF_SIZE]; gf_boolean_t choose_local; gf_boolean_t did_discovery; gf_boolean_t ensure_durability; gf_boolean_t halo_enabled; gf_boolean_t consistent_metadata; gf_boolean_t need_heal; gf_boolean_t granular_locks; char *sh_domain; char *afr_dirty; uint64_t spb_choice_timeout; afr_self_heald_t shd; struct afr_nfsd nfsd; gf_boolean_t use_anon_inode; uint32_t halo_max_latency_msec; uint32_t halo_max_replicas; uint32_t halo_min_replicas; gf_boolean_t full_lock; gf_boolean_t esh_granular; gf_boolean_t consistent_io; gf_boolean_t data_self_heal; /* on/off */ /*For lock healing.*/ struct list_head saved_locks; struct list_head lk_healq; /*For anon-inode handling */ char anon_inode_name[NAME_MAX + 1]; char anon_gfid_str[GF_UUID_BUF_SIZE]; } afr_private_t; typedef enum { AFR_DATA_TRANSACTION, /* truncate, write, ... */ AFR_METADATA_TRANSACTION, /* chmod, chown, ... */ AFR_ENTRY_TRANSACTION, /* create, rmdir, ... */ AFR_ENTRY_RENAME_TRANSACTION, /* rename */ } afr_transaction_type; /* xattr format: trusted.afr.volume = [x y z] x - data pending y - metadata pending z - entry pending */ static inline int afr_index_for_transaction_type(afr_transaction_type type) { switch (type) { case AFR_DATA_TRANSACTION: return 0; case AFR_METADATA_TRANSACTION: return 1; case AFR_ENTRY_TRANSACTION: case AFR_ENTRY_RENAME_TRANSACTION: return 2; } return -1; /* make gcc happy */ } static inline int afr_index_from_ia_type(ia_type_t type) { switch (type) { case IA_IFDIR: return afr_index_for_transaction_type(AFR_ENTRY_TRANSACTION); case IA_IFREG: return afr_index_for_transaction_type(AFR_DATA_TRANSACTION); default: return -1; } } typedef struct { loc_t loc; fd_t *fd; char *basename; unsigned char *locked_nodes; int locked_count; struct gf_flock flock; } afr_lockee_t; int afr_entry_lockee_cmp(const void *l1, const void *l2); typedef struct { loc_t *lk_loc; afr_lockee_t lockee[AFR_LOCKEE_COUNT_MAX]; afr_lock_cbk_t lock_cbk; int32_t lock_count; int32_t lockee_count; int32_t lk_call_count; int32_t lk_expected_count; int32_t lk_attempted_count; int32_t lock_op_ret; int32_t lock_op_errno; char *domain; /* Domain on which inode/entry lock/unlock in progress. */ } afr_internal_lock_t; struct afr_reply { int valid; int32_t op_ret; dict_t *xattr; /*For xattrop*/ dict_t *xdata; struct iatt poststat; struct iatt postparent; struct iatt prestat; struct iatt preparent; struct iatt preparent2; struct iatt postparent2; int32_t op_errno; /* For rchecksum */ uint8_t checksum[SHA256_DIGEST_LENGTH]; gf_boolean_t buf_has_zeroes; gf_boolean_t fips_mode_rchecksum; /* For lookup */ int8_t need_heal; }; typedef enum { AFR_FD_NOT_OPENED, AFR_FD_OPENED, AFR_FD_OPENING } afr_fd_open_status_t; typedef struct { afr_fd_open_status_t *opened_on; /* which subvolumes the fd is open on */ int flags; /* the subvolume on which the latest sequence of readdirs (starting at offset 0) has begun. Till the next readdir request with 0 offset arrives, we continue to read off this subvol. */ int readdir_subvol; /* lock-healing related members. */ gf_boolean_t is_fd_bad; afr_lk_heal_info_t *lk_heal_info; } afr_fd_ctx_t; typedef enum { AFR_FOP_LOCK_PARALLEL, AFR_FOP_LOCK_SERIAL, AFR_FOP_LOCK_QUORUM_FAILED, } afr_fop_lock_state_t; typedef struct _afr_inode_lock_t { /* @num_inodelks: Number of inodelks queried from the server, as queried through xdata in FOPs. Currently, used to decide if eager-locking must be temporarily disabled. */ int32_t num_inodelks; unsigned int event_generation; gf_timer_t *delay_timer; struct list_head owners; /*Transactions that are performing fop*/ struct list_head post_op; /*Transactions that are done with the fop *So can not conflict with the fops*/ struct list_head waiting; /*Transaction that are waiting for *conflicting transactions to complete*/ struct list_head frozen; /*Transactions that need to go as part of * next batch of eager-lock*/ gf_boolean_t release; gf_boolean_t acquired; } afr_lock_t; typedef struct _afr_inode_ctx { uint64_t read_subvol; uint64_t write_subvol; int lock_count; int spb_choice; gf_timer_t *timer; unsigned int *pre_op_done[AFR_NUM_CHANGE_LOGS]; int inherited[AFR_NUM_CHANGE_LOGS]; int on_disk[AFR_NUM_CHANGE_LOGS]; /*Only 2 types of transactions support eager-locks now. DATA/METADATA*/ afr_lock_t lock[2]; /* @open_fd_count: Number of open FDs queried from the server, as queried through xdata in FOPs. Currently, used to decide if eager-locking must be temporarily disabled. */ uint32_t open_fd_count; gf_boolean_t need_refresh; /* set if any write on this fd was a non stable write (i.e, without O_SYNC or O_DSYNC) */ gf_boolean_t witnessed_unstable_write; } afr_inode_ctx_t; typedef struct _afr_local { glusterfs_fop_t op; unsigned int call_count; /* @event_generation: copy of priv->event_generation taken at the time of starting the transaction. The copy is made so that we have a stable value through the various phases of the transaction. */ unsigned int event_generation; uint32_t open_fd_count; int32_t num_inodelks; int32_t op_ret; int32_t op_errno; int dirty[AFR_NUM_CHANGE_LOGS]; int32_t **pending; loc_t loc; loc_t newloc; fd_t *fd; afr_fd_ctx_t *fd_ctx; /* @child_up: copy of priv->child_up taken at the time of transaction start. The copy is taken so that we have a stable child_up array through the phases of the transaction as priv->child_up[i] can keep changing through time. */ unsigned char *child_up; /* @read_attempted: array of flags representing subvolumes where read operations of the read transaction have already been attempted. The array is first pre-filled with down subvolumes, and as reads are performed on other subvolumes, those are set as well. This way if the read operation fails we do not retry on that subvolume again. */ unsigned char *read_attempted; /* @readfn: pointer to function which will perform the read operation on a given subvolume. Used in read transactions. */ afr_read_txn_wind_t readfn; /* @inode: the inode on which the read txn is performed on. ref'ed and copied from either fd->inode or loc.inode */ inode_t *inode; /* @parent[2]: parent inode[s] on which directory transactions are performed. */ inode_t *parent; inode_t *parent2; /* @readable: array of flags representing servers from which a read can be performed. This is the output of afr_inode_refresh() */ unsigned char *readable; unsigned char *readable2; /*For rename transaction*/ afr_inode_refresh_cbk_t refreshfn; /* @refreshinode: Inode currently getting refreshed. */ inode_t *refreshinode; dict_t *xattr_req; dict_t *dict; int read_subvol; /* Current read subvolume */ int optimistic_change_log; afr_internal_lock_t internal_lock; /*To handle setattr/setxattr on yet to be linked inode from dht*/ uuid_t refreshgfid; /* @refreshed: the inode was "refreshed" (i.e, pending xattrs from all subvols freshly inspected and inode ctx updated accordingly) as part of this transaction already. */ gf_boolean_t refreshed; gf_boolean_t update_num_inodelks; gf_boolean_t update_open_fd_count; /* @pre_op_compat: compatibility mode of pre-op. send a separate pre-op and op operations as part of transaction, rather than combining */ gf_boolean_t pre_op_compat; /* Is the current writev() going to perform a stable write? i.e, is fd->flags or @flags writev param have O_SYNC or O_DSYNC? */ gf_boolean_t stable_write; /* This write appended to the file. Nnot necessarily O_APPEND, just means the offset of write was at the end of file. */ gf_boolean_t append_write; /* This struct contains the arguments for the "continuation" (scheme-like) of fops */ struct { struct { struct statvfs buf; unsigned char buf_set; } statfs; struct { fd_t *fd; int32_t flags; } open; struct { struct gf_flock user_flock; struct gf_flock ret_flock; unsigned char *locked_nodes; int32_t cmd; /* For lock healing only. */ unsigned char *dom_locked_nodes; int32_t *dom_lock_op_ret; int32_t *dom_lock_op_errno; struct gf_flock *getlk_rsp; } lk; /* inode read */ struct { int32_t mask; } access; struct { size_t size; } readlink; struct { char *name; long xattr_len; } getxattr; struct { size_t size; off_t offset; uint32_t flags; } readv; /* dir read */ struct { uint32_t *checksum; int success_count; } opendir; struct { size_t size; off_t offset; dict_t *dict; } readdir; /* inode write */ struct { struct iatt prebuf; struct iatt postbuf; } inode_wfop; // common structure for all inode-write-fops struct { struct iovec *vector; struct iobref *iobref; off_t offset; int32_t count; uint32_t flags; } writev; struct { off_t offset; } truncate; struct { off_t offset; } ftruncate; struct { struct iatt in_buf; int32_t valid; } setattr; struct { struct iatt in_buf; int32_t valid; } fsetattr; struct { dict_t *dict; int32_t flags; } setxattr; struct { dict_t *dict; int32_t flags; } fsetxattr; struct { char *name; } removexattr; struct { dict_t *xattr; gf_xattrop_flags_t optype; } xattrop; /* dir write */ struct { inode_t *inode; struct iatt buf; struct iatt preparent; struct iatt postparent; struct iatt prenewparent; struct iatt postnewparent; } dir_fop; // common structure for all dir fops struct { fd_t *fd; dict_t *params; int32_t flags; mode_t mode; } create; struct { dict_t *params; dev_t dev; mode_t mode; } mknod; struct { dict_t *params; int32_t mode; } mkdir; struct { dict_t *params; char *linkpath; } symlink; struct { off_t offset; size_t len; int32_t mode; } fallocate; struct { off_t offset; size_t len; } discard; struct { off_t offset; off_t len; } zerofill; struct { char *volume; int32_t cmd; int32_t in_cmd; void *xdata; struct gf_flock in_flock; struct gf_flock flock; } inodelk; struct { char *volume; char *basename; void *xdata; entrylk_cmd in_cmd; entrylk_cmd cmd; entrylk_type type; } entrylk; struct { off_t offset; gf_seek_what_t what; } seek; struct { struct gf_lease user_lease; struct gf_lease ret_lease; unsigned char *locked_nodes; } lease; struct { int flags; } rmdir; struct { int32_t datasync; } fsync; struct { uuid_t gfid_req; gf_boolean_t needs_fresh_lookup; } lookup; } cont; struct { char *basename; char *new_basename; loc_t parent_loc; loc_t new_parent_loc; /* stub to resume on destruction of the transaction frame */ call_stub_t *resume_stub; struct list_head owner_list; struct list_head wait_list; unsigned char *pre_op; /* Changelog xattr dict for [f]xattrop*/ dict_t **changelog_xdata; unsigned char *pre_op_sources; /* @failed_subvols: subvolumes on which a pre-op or a FOP failed. */ unsigned char *failed_subvols; call_frame_t *main_frame; /*Fop frame*/ call_frame_t *frame; /*Transaction frame*/ int (*wind)(call_frame_t *frame, xlator_t *this, int subvol); int (*unwind)(call_frame_t *frame, xlator_t *this); off_t start, len; afr_transaction_type type; int32_t in_flight_sb_errno; /* This is where the cause of the failure on the last good copy of the file is stored. */ /* @changelog_resume: function to be called after changlogging (either pre-op or post-op) is done */ afr_changelog_resume_t changelog_resume; gf_boolean_t eager_lock_on; gf_boolean_t do_eager_unlock; /* @dirtied: flag which indicates whether we set dirty flag in the OP. Typically true when we are performing operation on more than one subvol and optimistic changelog is disabled A 'true' value set in @dirtied flag means an 'undirtying' has to be done in POST-OP phase. */ gf_boolean_t dirtied; /* @inherited: flag which indicates that the dirty flags of the previous transaction were inherited */ gf_boolean_t inherited; /* @no_uninherit: flag which indicates that a pre_op_uninherit() must _not_ be attempted (and returned as failure) always. This flag is set when a hard pre-op is performed, but not accounted for it in fd_ctx->on_disk[]. Such transactions are "isolated" from the pre-op piggybacking entirely and therefore uninherit must not be attempted. */ gf_boolean_t no_uninherit; gf_boolean_t in_flight_sb; /* Indicator for occurrence of split-brain while in the middle of a txn. */ /* @uninherit_done: @uninherit_value: The above pair variables make pre_op_uninherit() idempotent. Both are FALSE initially. The first call to pre_op_uninherit sets @uninherit_done to TRUE and the return value to @uninherit_value. Further calls will check for @uninherit_done to be TRUE and if so will simply return @uninherit_value. */ gf_boolean_t uninherit_done; gf_boolean_t uninherit_value; gf_boolean_t disable_delayed_post_op; } transaction; syncbarrier_t barrier; /* extra data for fops */ dict_t *xdata_req; dict_t *xdata_rsp; dict_t *xattr_rsp; /*for [f]xattrop*/ mode_t umask; int xflag; struct afr_reply *replies; /* For client side background heals. */ struct list_head healer; call_frame_t *heal_frame; afr_inode_ctx_t *inode_ctx; /*For thin-arbiter transactions.*/ int ta_failed_subvol; int ta_event_gen; struct list_head ta_waitq; struct list_head ta_onwireq; afr_ta_fop_state_t fop_state; afr_fop_lock_state_t fop_lock_state; gf_lkowner_t saved_lk_owner; unsigned char read_txn_query_child; unsigned char ta_child_up; gf_boolean_t do_discovery; gf_boolean_t need_full_crawl; gf_boolean_t is_read_txn; gf_boolean_t is_new_entry; /* For fix_open */ unsigned char *need_open; } afr_local_t; typedef struct afr_spbc_timeout { call_frame_t *frame; loc_t *loc; int spb_child_index; gf_boolean_t d_spb; gf_boolean_t m_spb; } afr_spbc_timeout_t; typedef struct afr_spb_status { call_frame_t *frame; loc_t *loc; } afr_spb_status_t; typedef struct afr_empty_brick_args { call_frame_t *frame; char *op_type; loc_t loc; int empty_index; } afr_empty_brick_args_t; typedef struct afr_read_subvol_args { ia_type_t ia_type; uuid_t gfid; } afr_read_subvol_args_t; int afr_inode_get_readable(call_frame_t *frame, inode_t *inode, xlator_t *this, unsigned char *readable, int *event_p, int type); int afr_inode_read_subvol_get(inode_t *inode, xlator_t *this, unsigned char *data_subvols, unsigned char *metadata_subvols, int *event_generation); int afr_inode_need_refresh_set(inode_t *inode, xlator_t *this); int afr_read_subvol_select_by_policy(inode_t *inode, xlator_t *this, unsigned char *readable, afr_read_subvol_args_t *args); int afr_read_subvol_get(inode_t *inode, xlator_t *this, int *subvol_p, unsigned char *readables, int *event_p, afr_transaction_type type, afr_read_subvol_args_t *args); #define afr_data_subvol_get(i, t, s, r, e, a) \ afr_read_subvol_get(i, t, s, r, e, AFR_DATA_TRANSACTION, a) #define afr_metadata_subvol_get(i, t, s, r, e, a) \ afr_read_subvol_get(i, t, s, r, e, AFR_METADATA_TRANSACTION, a) int afr_inode_refresh(call_frame_t *frame, xlator_t *this, inode_t *inode, uuid_t gfid, afr_inode_refresh_cbk_t cbk); int32_t afr_notify(xlator_t *this, int32_t event, void *data, void *data2); int afr_add_entry_lockee(afr_local_t *local, loc_t *loc, char *basename, int child_count); int afr_add_inode_lockee(afr_local_t *local, int child_count); void afr_lockees_cleanup(afr_internal_lock_t *int_lock); void afr_set_lk_owner(call_frame_t *frame, xlator_t *this, void *lk_owner); int32_t afr_unlock(call_frame_t *frame, xlator_t *this); int afr_lock_nonblocking(call_frame_t *frame, xlator_t *this); int afr_blocking_lock(call_frame_t *frame, xlator_t *this); afr_fd_ctx_t * afr_fd_ctx_get(fd_t *fd, xlator_t *this); int afr_locked_nodes_count(unsigned char *locked_nodes, int child_count); int afr_replies_interpret(afr_local_t *local, xlator_t *this, inode_t *inode, gf_boolean_t *start_heal); void afr_local_replies_wipe(afr_local_t *local, afr_private_t *priv); void afr_local_cleanup(afr_local_t *local, xlator_t *this); int afr_frame_return(call_frame_t *frame); int afr_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata); void afr_cleanup_fd_ctx(xlator_t *this, fd_t *fd); #define AFR_STACK_UNWIND(fop, frame, op_ret, op_errno, params...) \ do { \ afr_local_t *__local = NULL; \ xlator_t *__this = NULL; \ int32_t __op_ret = 0; \ int32_t __op_errno = 0; \ \ __op_ret = op_ret; \ __op_errno = op_errno; \ if (frame) { \ __local = frame->local; \ __this = frame->this; \ afr_handle_inconsistent_fop(frame, &__op_ret, &__op_errno); \ if (__local && __local->is_read_txn) \ afr_pending_read_decrement(__this->private, \ __local->read_subvol); \ if (__local && __local->xdata_req && \ afr_is_lock_mode_mandatory(__local->xdata_req)) \ afr_dom_lock_release(frame); \ frame->local = NULL; \ } \ \ STACK_UNWIND_STRICT(fop, frame, __op_ret, __op_errno, params); \ if (__local) { \ afr_local_cleanup(__local, __this); \ mem_put(__local); \ } \ } while (0) #define AFR_STACK_DESTROY(frame) \ do { \ afr_local_t *__local = NULL; \ xlator_t *__this = NULL; \ __local = frame->local; \ __this = frame->this; \ frame->local = NULL; \ STACK_DESTROY(frame->root); \ if (__local) { \ afr_local_cleanup(__local, __this); \ mem_put(__local); \ } \ } while (0); #define AFR_FRAME_INIT(frame, op_errno) \ ({ \ xlator_t *__this = frame->this; \ frame->local = mem_get0(__this->local_pool); \ if (caa_likely(frame->local)) { \ if (afr_local_init(frame->local, __this->private, &op_errno)) { \ afr_local_cleanup(frame->local, __this); \ mem_put(frame->local); \ frame->local = NULL; \ } \ } else { \ op_errno = ENOMEM; \ } \ frame->local; \ }) #define AFR_STACK_RESET(frame) \ do { \ afr_local_t *__local = NULL; \ xlator_t *__this = NULL; \ __local = frame->local; \ __this = frame->this; \ frame->local = NULL; \ int __opr; \ STACK_RESET(frame->root); \ if (__local) { \ afr_local_cleanup(__local, __this); \ mem_put(__local); \ } \ AFR_FRAME_INIT(frame, __opr); \ } while (0) /* allocate and return a string that is the basename of argument */ static inline char * AFR_BASENAME(const char *str) { char *__tmp_str = NULL; char *__basename_str = NULL; __tmp_str = gf_strdup(str); __basename_str = gf_strdup(basename(__tmp_str)); GF_FREE(__tmp_str); return __basename_str; } call_frame_t * afr_copy_frame(call_frame_t *base); int afr_transaction_local_init(afr_local_t *local, xlator_t *this); int afr_local_init(afr_local_t *local, afr_private_t *priv, int32_t *op_errno); int afr_higher_errno(int32_t old_errno, int32_t new_errno); int afr_final_errno(afr_local_t *local, afr_private_t *priv); int afr_xattr_req_prepare(xlator_t *this, dict_t *xattr_req); void afr_fix_open(fd_t *fd, xlator_t *this); void afr_matrix_cleanup(int32_t **pending, unsigned int m); int32_t ** afr_matrix_create(unsigned int m, unsigned int n); int ** afr_mark_pending_changelog(afr_private_t *priv, unsigned char *pending, dict_t *xattr, ia_type_t iat); /* * Special value indicating we should use the "auto" quorum method instead of * a fixed value (including zero to turn off quorum enforcement). */ #define AFR_QUORUM_AUTO INT_MAX int afr_fd_report_unstable_write(xlator_t *this, afr_local_t *local); gf_boolean_t afr_fd_has_witnessed_unstable_write(xlator_t *this, inode_t *inode); void afr_reply_wipe(struct afr_reply *reply); void afr_replies_wipe(struct afr_reply *replies, int count); gf_boolean_t afr_xattrs_are_equal(dict_t *dict1, dict_t *dict2, gf_boolean_t is_arbiter); gf_boolean_t afr_is_xattr_ignorable(char *key); int afr_get_heal_info(call_frame_t *frame, xlator_t *this, loc_t *loc); int afr_heal_splitbrain_file(call_frame_t *frame, xlator_t *this, loc_t *loc); int afr_get_split_brain_status(void *opaque); int afr_get_split_brain_status_cbk(int ret, call_frame_t *frame, void *opaque); int afr_inode_split_brain_choice_set(inode_t *inode, xlator_t *this, int spb_choice); int afr_split_brain_read_subvol_get(inode_t *inode, xlator_t *this, call_frame_t *frame, int *spb_subvol); int afr_get_child_index_from_name(xlator_t *this, char *name); int afr_is_split_brain(call_frame_t *frame, xlator_t *this, inode_t *inode, uuid_t gfid, gf_boolean_t *d_spb, gf_boolean_t *m_spb); int afr_set_split_brain_choice(int ret, call_frame_t *frame, void *opaque); gf_boolean_t afr_get_need_heal(afr_private_t *priv); int afr_selfheal_data_open(xlator_t *this, inode_t *inode, fd_t **fd); int afr_set_in_flight_sb_status(xlator_t *this, call_frame_t *frame, inode_t *inode); int32_t afr_quorum_errno(afr_private_t *priv); gf_boolean_t afr_is_consistent_io_possible(afr_local_t *local, afr_private_t *priv, int32_t *op_errno); void afr_handle_inconsistent_fop(call_frame_t *frame, int32_t *op_ret, int32_t *op_errno); gf_boolean_t afr_is_inode_refresh_reqd(inode_t *inode, xlator_t *this, int event_gen1, int event_gen2); int afr_serialize_xattrs_with_delimiter(call_frame_t *frame, xlator_t *this, char *buf, size_t size, const char *default_str, int32_t *serz_len, char delimiter); gf_boolean_t afr_is_symmetric_error(call_frame_t *frame, xlator_t *this); afr_inode_ctx_t * __afr_inode_ctx_get(xlator_t *this, inode_t *inode); uint64_t afr_write_subvol_get(call_frame_t *frame, xlator_t *this); int afr_write_subvol_set(call_frame_t *frame, xlator_t *this); int afr_write_subvol_reset(call_frame_t *frame, xlator_t *this); int afr_set_inode_local(xlator_t *this, afr_local_t *local, inode_t *inode); int afr_fill_ta_loc(xlator_t *this, loc_t *loc, gf_boolean_t is_gfid_based_fop); int afr_ta_post_op_lock(xlator_t *this, loc_t *loc); int afr_ta_post_op_unlock(xlator_t *this, loc_t *loc); gf_boolean_t afr_is_pending_set(xlator_t *this, dict_t *xdata, int type); int __afr_get_up_children_count(afr_private_t *priv); call_frame_t * afr_ta_frame_create(xlator_t *this); gf_boolean_t afr_ta_has_quorum(afr_private_t *priv, afr_local_t *local); void afr_ta_lock_release_synctask(xlator_t *this); void afr_ta_locked_priv_invalidate(afr_private_t *priv); gf_boolean_t afr_lookup_has_quorum(call_frame_t *frame, const unsigned int up_children_count); void afr_mark_new_entry_changelog(call_frame_t *frame, xlator_t *this); void afr_handle_replies_quorum(call_frame_t *frame, xlator_t *this); gf_boolean_t afr_ta_dict_contains_pending_xattr(dict_t *dict, afr_private_t *priv, int child); void afr_selfheal_childup(xlator_t *this, afr_private_t *priv); gf_boolean_t afr_is_lock_mode_mandatory(dict_t *xdata); void afr_dom_lock_release(call_frame_t *frame); void afr_fill_success_replies(afr_local_t *local, afr_private_t *priv, unsigned char *replies); gf_boolean_t afr_is_private_directory(afr_private_t *priv, const char *name, pid_t pid); #endif /* __AFR_H__ */ glusterfs-11.1/xlators/cluster/afr/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202462022354 xustar000000000000000030 mtime=1699284274.393053715 30 atime=1699284289.020097772 30 ctime=1699284301.044133987 glusterfs-11.1/xlators/cluster/afr/Makefile.in0000664000175100017510000005271014522202462022640 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/cluster/afr DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/cluster/afr/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/cluster/afr/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/cluster/afr/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451022340 xustar000000000000000030 mtime=1699284265.611027263 30 atime=1699284274.369053643 29 ctime=1699284301.04513399 glusterfs-11.1/xlators/cluster/afr/Makefile.am0000664000175100017510000000003514522202451022616 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/cluster/PaxHeaders.9031/ec0000644000000000000000000000013214522202515020050 xustar000000000000000030 mtime=1699284301.279134695 30 atime=1699284309.685160013 30 ctime=1699284301.279134695 glusterfs-11.1/xlators/cluster/ec/0002775000175100017510000000000014522202515020406 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/cluster/ec/PaxHeaders.9031/src0000644000000000000000000000013214522202515020637 xustar000000000000000030 mtime=1699284301.378134993 30 atime=1699284309.685160013 30 ctime=1699284301.378134993 glusterfs-11.1/xlators/cluster/ec/src/0002775000175100017510000000000014522202515021175 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-c.h0000644000000000000000000000013114522202451022602 xustar000000000000000030 mtime=1699284265.633027329 30 atime=1699284265.633027329 29 ctime=1699284301.36713496 glusterfs-11.1/xlators/cluster/ec/src/ec-code-c.h0000664000175100017510000000140514522202451023062 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_CODE_C_H__ #define __EC_CODE_C_H__ #include "ec-types.h" void ec_code_c_prepare(ec_gf_t *gf, uint32_t *values, uint32_t count); void ec_code_c_linear(void *dst, void *src, uint64_t offset, uint32_t *values, uint32_t count); void ec_code_c_interleaved(void *dst, void **src, uint64_t offset, uint32_t *values, uint32_t count); #endif /* __EC_CODE_C_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-common.c0000644000000000000000000000013214522202451022734 xustar000000000000000030 mtime=1699284265.635027335 30 atime=1699284265.634027332 30 ctime=1699284301.326134836 glusterfs-11.1/xlators/cluster/ec/src/ec-common.c0000664000175100017510000024675014522202451023231 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifdef __FreeBSD__ #include #else #include #endif #include #include "ec-mem-types.h" #include "ec-types.h" #include "ec-helpers.h" #include "ec-combine.h" #include "ec-common.h" #include "ec-fops.h" #include "ec-method.h" #include "ec.h" #include "ec-messages.h" #define EC_INVALID_INDEX UINT32_MAX void ec_update_fd_status(fd_t *fd, xlator_t *xl, int idx, int32_t ret_status) { ec_fd_t *fd_ctx; if (fd == NULL) return; LOCK(&fd->lock); { fd_ctx = __ec_fd_get(fd, xl); if (fd_ctx) { if (ret_status >= 0) fd_ctx->fd_status[idx] = EC_FD_OPENED; else fd_ctx->fd_status[idx] = EC_FD_NOT_OPENED; } } UNLOCK(&fd->lock); } static uintptr_t ec_fd_ctx_need_open(fd_t *fd, xlator_t *this, uintptr_t mask) { int i = 0; int count = 0; ec_t *ec = NULL; ec_fd_t *fd_ctx = NULL; uintptr_t need_open = 0; ec = this->private; fd_ctx = ec_fd_get(fd, this); if (!fd_ctx) return count; LOCK(&fd->lock); { for (i = 0; i < ec->nodes; i++) { if ((fd_ctx->fd_status[i] == EC_FD_NOT_OPENED) && ((ec->xl_up & (1 << i)) != 0) && ((mask & (1 << i)) != 0)) { fd_ctx->fd_status[i] = EC_FD_OPENING; need_open |= (1 << i); count++; } } } UNLOCK(&fd->lock); /* If fd needs to open on minimum number of nodes * then ignore fixing the fd as it has been * requested from heal operation. */ if (count >= ec->fragments) { need_open = 0; } return need_open; } static gf_boolean_t ec_is_fd_fixable(fd_t *fd) { if (!fd || !fd->inode) return _gf_false; else if (fd_is_anonymous(fd)) return _gf_false; else if (gf_uuid_is_null(fd->inode->gfid)) return _gf_false; return _gf_true; } static void ec_fix_open(ec_fop_data_t *fop, uintptr_t mask) { uintptr_t need_open = 0; int ret = 0; int32_t flags = 0; loc_t loc = { 0, }; if (!ec_is_fd_fixable(fop->fd)) goto out; /* Evaluate how many remote fd's to be opened */ need_open = ec_fd_ctx_need_open(fop->fd, fop->xl, mask); if (need_open == 0) { goto out; } loc.inode = inode_ref(fop->fd->inode); gf_uuid_copy(loc.gfid, fop->fd->inode->gfid); ret = loc_path(&loc, NULL); if (ret < 0) { goto out; } flags = fop->fd->flags & (~(O_TRUNC | O_APPEND | O_CREAT | O_EXCL)); if (IA_IFDIR == fop->fd->inode->ia_type) { ec_opendir(fop->frame, fop->xl, need_open, EC_MINIMUM_ONE | EC_FOP_NO_PROPAGATE_ERROR, NULL, NULL, &fop->loc[0], fop->fd, NULL); } else { ec_open(fop->frame, fop->xl, need_open, EC_MINIMUM_ONE | EC_FOP_NO_PROPAGATE_ERROR, NULL, NULL, &loc, flags, fop->fd, NULL); } out: loc_wipe(&loc); } static off_t ec_range_end_get(off_t fl_start, uint64_t fl_size) { if (fl_size > 0) { if (fl_size >= EC_RANGE_FULL) { /* Infinity */ fl_start = LLONG_MAX; } else { fl_start += fl_size - 1; if (fl_start < 0) { /* Overflow */ fl_start = LLONG_MAX; } } } return fl_start; } static gf_boolean_t ec_is_range_conflict(ec_lock_link_t *l1, ec_lock_link_t *l2) { return ((l1->fl_end >= l2->fl_start) && (l2->fl_end >= l1->fl_start)); } static gf_boolean_t ec_lock_conflict(ec_lock_link_t *l1, ec_lock_link_t *l2) { ec_t *ec = l1->fop->xl->private; /* Fops like access/stat won't have to worry what the other fops are * modifying as the fop is wound only to one brick. So it can be * executed in parallel*/ if (l1->fop->minimum == EC_MINIMUM_ONE || l2->fop->minimum == EC_MINIMUM_ONE) return _gf_false; if ((l1->fop->flags & EC_FLAG_LOCK_SHARED) && (l2->fop->flags & EC_FLAG_LOCK_SHARED)) return _gf_false; if (!ec->parallel_writes) { return _gf_true; } return ec_is_range_conflict(l1, l2); } static uint32_t ec_select_first_by_read_policy(ec_t *ec, ec_fop_data_t *fop) { if (ec->read_policy == EC_ROUND_ROBIN) { return ec->idx; } else if (ec->read_policy == EC_GFID_HASH) { if (fop->use_fd) { return SuperFastHash((char *)fop->fd->inode->gfid, sizeof(fop->fd->inode->gfid)) % ec->nodes; } else { if (gf_uuid_is_null(fop->loc[0].gfid)) loc_gfid(&fop->loc[0], fop->loc[0].gfid); return SuperFastHash((char *)fop->loc[0].gfid, sizeof(fop->loc[0].gfid)) % ec->nodes; } } return 0; } static gf_boolean_t ec_child_valid(ec_t *ec, ec_fop_data_t *fop, uint32_t idx) { return (idx < ec->nodes) && (((fop->remaining >> idx) & 1) == 1); } static uint32_t ec_child_next(ec_t *ec, ec_fop_data_t *fop, uint32_t idx) { while (!ec_child_valid(ec, fop, idx)) { if (++idx >= ec->nodes) { idx = 0; } if (idx == fop->first) { return EC_INVALID_INDEX; } } return idx; } static int32_t ec_heal_report(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, uintptr_t mask, uintptr_t good, uintptr_t bad, uint32_t pending, dict_t *xdata) { if (op_ret < 0) { gf_msg(this->name, GF_LOG_DEBUG, op_errno, EC_MSG_HEAL_FAIL, "Heal failed"); } else { if ((mask & ~good) != 0) { gf_msg(this->name, GF_LOG_DEBUG, 0, EC_MSG_HEAL_SUCCESS, "Heal succeeded on %d/%d " "subvolumes", gf_bits_count(mask & ~(good | bad)), gf_bits_count(mask & ~good)); } } return 0; } static uintptr_t ec_fop_needs_name_heal(ec_t *ec, ec_fop_data_t *fop) { ec_cbk_data_t *cbk = NULL; ec_cbk_data_t *enoent_cbk = NULL; if (fop->id != GF_FOP_LOOKUP) return 0; if (!fop->loc[0].name || strlen(fop->loc[0].name) == 0) return 0; list_for_each_entry(cbk, &fop->cbk_list, list) { if (cbk->op_ret < 0 && cbk->op_errno == ENOENT) { enoent_cbk = cbk; break; } } if (!enoent_cbk) return 0; return ec->xl_up & ~enoent_cbk->mask; } static int32_t ec_fop_needs_heal(ec_t *ec, ec_fop_data_t *fop) { if (fop->lock_count == 0) { /* * if fop->lock_count is zero that means it saw version mismatch * without any locks so it can't be trusted. If we launch a heal * based on this it will lead to INODELKs which will affect I/O * performance. Considering self-heal-daemon and operations on * the inode from client which take locks can still trigger the * heal we can choose to not attempt a heal when fop->lock_count * is zero. */ return 0; } return (ec->xl_up & ~(fop->remaining | fop->good)) != 0; } static void ec_check_status(ec_fop_data_t *fop) { ec_t *ec = fop->xl->private; int32_t partial = 0; char str1[32], str2[32], str3[32], str4[32], str5[32]; if (!ec_fop_needs_name_heal(ec, fop) && !ec_fop_needs_heal(ec, fop)) { return; } if (fop->answer && fop->answer->op_ret >= 0) { if ((fop->id == GF_FOP_LOOKUP) || (fop->id == GF_FOP_STAT) || (fop->id == GF_FOP_FSTAT)) { partial = fop->answer->iatt[0].ia_type == IA_IFDIR; } else if (fop->id == GF_FOP_OPENDIR) { partial = 1; } } gf_msg( fop->xl->name, GF_LOG_WARNING, 0, EC_MSG_OP_FAIL_ON_SUBVOLS, "Operation failed on %d of %d subvolumes.(up=%s, mask=%s, " "remaining=%s, good=%s, bad=%s," "(Least significant bit represents first client/brick of subvol), %s)", gf_bits_count(ec->xl_up & ~(fop->remaining | fop->good)), ec->nodes, ec_bin(str1, sizeof(str1), ec->xl_up, ec->nodes), ec_bin(str2, sizeof(str2), fop->mask, ec->nodes), ec_bin(str3, sizeof(str3), fop->remaining, ec->nodes), ec_bin(str4, sizeof(str4), fop->good, ec->nodes), ec_bin(str5, sizeof(str5), ec->xl_up & ~(fop->remaining | fop->good), ec->nodes), ec_msg_str(fop)); if (fop->use_fd) { if (fop->fd != NULL) { ec_fheal(NULL, fop->xl, -1, EC_MINIMUM_ONE, ec_heal_report, NULL, fop->fd, partial, NULL); } } else { ec_heal(NULL, fop->xl, -1, EC_MINIMUM_ONE, ec_heal_report, NULL, &fop->loc[0], partial, NULL); if (fop->loc[1].inode != NULL) { ec_heal(NULL, fop->xl, -1, EC_MINIMUM_ONE, ec_heal_report, NULL, &fop->loc[1], partial, NULL); } } } void ec_update_good(ec_fop_data_t *fop, uintptr_t good) { fop->good = good; /* Fops that are executed only on one brick do not have enough information * to decide if healing is needed or not. */ if ((fop->expected != 1) && (fop->parent == NULL)) { ec_check_status(fop); } } void ec_lock_update_good(ec_lock_t *lock, ec_fop_data_t *fop) { /* Fops that are executed only on one brick do not have enough information * to update the global mask of good bricks. */ if (fop->expected == 1) { return; } /* When updating the good mask of the lock, we only take into consideration * those bits corresponding to the bricks where the fop has been executed. * Bad bricks are removed from good_mask, but once marked as bad it's never * set to good until the lock is released and reacquired */ lock->good_mask &= fop->good | fop->remaining; } void __ec_fop_set_error(ec_fop_data_t *fop, int32_t error) { if ((error != 0) && (fop->error == 0)) { fop->error = error; } } void ec_fop_set_error(ec_fop_data_t *fop, int32_t error) { LOCK(&fop->lock); __ec_fop_set_error(fop, error); UNLOCK(&fop->lock); } gf_boolean_t ec_cbk_set_error(ec_cbk_data_t *cbk, int32_t error, gf_boolean_t ro) { if ((error != 0) && (cbk->op_ret >= 0)) { /* If cbk->op_errno was 0, it means that the fop succeeded and this * error has happened while processing the answer. If the operation was * read-only, there's no problem (i.e. we simply return the generated * error code). However if it caused a modification, we must return EIO * to indicate that the operation has been partially executed. */ cbk->op_errno = ro ? error : EIO; cbk->op_ret = -1; ec_fop_set_error(cbk->fop, cbk->op_errno); } return (cbk->op_ret < 0); } ec_cbk_data_t * ec_fop_prepare_answer(ec_fop_data_t *fop, gf_boolean_t ro) { ec_cbk_data_t *cbk; int32_t err; cbk = fop->answer; if (cbk == NULL) { ec_fop_set_error(fop, EIO); return NULL; } if (cbk->op_ret < 0) { ec_fop_set_error(fop, cbk->op_errno); } err = ec_dict_combine(cbk, EC_COMBINE_XDATA); if (ec_cbk_set_error(cbk, -err, ro)) { return NULL; } return cbk; } void ec_sleep(ec_fop_data_t *fop) { LOCK(&fop->lock); GF_ASSERT(fop->refs > 0); fop->refs++; fop->jobs++; UNLOCK(&fop->lock); } static int32_t ec_check_complete(ec_fop_data_t *fop, ec_resume_f resume) { int32_t error = -1; LOCK(&fop->lock); GF_ASSERT(fop->resume == NULL); if (--fop->jobs != 0) { ec_trace("WAIT", fop, "resume=%p", resume); fop->resume = resume; } else { error = fop->error; fop->error = 0; } UNLOCK(&fop->lock); return error; } void ec_resume(ec_fop_data_t *fop, int32_t error) { ec_resume_f resume = NULL; LOCK(&fop->lock); __ec_fop_set_error(fop, error); if (--fop->jobs == 0) { resume = fop->resume; fop->resume = NULL; if (resume != NULL) { ec_trace("RESUME", fop, "error=%d", error); if (fop->error != 0) { error = fop->error; } fop->error = 0; } } UNLOCK(&fop->lock); if (resume != NULL) { resume(fop, error); } ec_fop_data_release(fop); } void ec_resume_parent(ec_fop_data_t *fop) { ec_fop_data_t *parent; int32_t error = 0; parent = fop->parent; if (parent != NULL) { if ((fop->fop_flags & EC_FOP_NO_PROPAGATE_ERROR) == 0) { error = fop->error; } ec_trace("RESUME_PARENT", fop, "error=%u", error); fop->parent = NULL; ec_resume(parent, error); } } static gf_boolean_t ec_is_recoverable_error(int32_t op_errno) { switch (op_errno) { case ENOTCONN: case ESTALE: case ENOENT: case EBADFD: /*Opened fd but brick is disconnected*/ case EIO: /*Backend-fs crash like XFS/ext4 etc*/ return _gf_true; } return _gf_false; } void ec_complete(ec_fop_data_t *fop) { ec_cbk_data_t *cbk = NULL; int32_t resume = 0, update = 0; int healing_count = 0; LOCK(&fop->lock); ec_trace("COMPLETE", fop, ""); if (--fop->winds == 0) { if (fop->answer == NULL) { if (!list_empty(&fop->cbk_list)) { cbk = list_entry(fop->cbk_list.next, ec_cbk_data_t, list); healing_count = gf_bits_count(cbk->mask & fop->healing); /* fop shouldn't be treated as success if it is not * successful on at least fop->minimum good copies*/ if ((cbk->count - healing_count) >= fop->minimum) { fop->answer = cbk; update = 1; } } resume = 1; } } UNLOCK(&fop->lock); /* ec_update_good() locks inode->lock. This may cause deadlocks with fop->lock when used in another order. Since ec_update_good() will not be called more than once for each fop, it can be called from outside the fop->lock locked region. */ if (update) { ec_update_good(fop, cbk->mask); } if (resume) { ec_resume(fop, 0); } ec_fop_data_release(fop); } /* There could be already granted locks sitting on the bricks, unlock for which * must be wound at all costs*/ static gf_boolean_t ec_must_wind(ec_fop_data_t *fop) { if ((fop->id == GF_FOP_INODELK) || (fop->id == GF_FOP_FINODELK) || (fop->id == GF_FOP_LK)) { if (fop->flock.l_type == F_UNLCK) return _gf_true; } else if ((fop->id == GF_FOP_ENTRYLK) || (fop->id == GF_FOP_FENTRYLK)) { if (fop->entrylk_cmd == ENTRYLK_UNLOCK) return _gf_true; } return _gf_false; } static gf_boolean_t ec_internal_op(ec_fop_data_t *fop) { if (ec_must_wind(fop)) return _gf_true; if (fop->id == GF_FOP_XATTROP) return _gf_true; if (fop->id == GF_FOP_FXATTROP) return _gf_true; if (fop->id == GF_FOP_OPEN) return _gf_true; return _gf_false; } char * ec_msg_str(ec_fop_data_t *fop) { loc_t *loc1 = NULL; loc_t *loc2 = NULL; ec_fop_data_t *parent = fop->parent; if (fop->errstr) return fop->errstr; if (!fop->use_fd) { loc1 = &fop->loc[0]; loc2 = &fop->loc[1]; if (fop->id == GF_FOP_RENAME) { char gfid2[64]; gf_asprintf(&fop->errstr, "FOP : '%s' failed on '%s' and '%s' with gfids " "%s and %s respectively. Parent FOP: %s", ec_fop_name(fop->id), loc1->path, loc2->path, uuid_utoa(loc1->gfid), uuid_utoa_r(loc2->gfid, gfid2), parent ? ec_fop_name(parent->id) : "No Parent"); } else { gf_asprintf( &fop->errstr, "FOP : '%s' failed on '%s' with gfid %s. Parent FOP: %s", ec_fop_name(fop->id), loc1->path, uuid_utoa(loc1->gfid), parent ? ec_fop_name(parent->id) : "No Parent"); } } else { gf_asprintf(&fop->errstr, "FOP : '%s' failed on gfid %s. Parent FOP: %s", ec_fop_name(fop->id), uuid_utoa(fop->fd->inode->gfid), parent ? ec_fop_name(parent->id) : "No Parent"); } return fop->errstr; } static void ec_log_insufficient_vol(ec_fop_data_t *fop, ec_t *ec, int32_t have, uint32_t need, int32_t loglevel) { char str1[32], str2[32], str3[32]; gf_msg(ec->xl->name, loglevel, 0, EC_MSG_CHILDS_INSUFFICIENT, "Insufficient available children for this request: " "Have : %d, Need : %u : Child UP : %s " "Mask: %s, Healing : %s : %s ", have, need, ec_bin(str1, sizeof(str1), ec->xl_up, ec->nodes), ec_bin(str2, sizeof(str2), fop->mask, ec->nodes), ec_bin(str3, sizeof(str3), fop->healing, ec->nodes), ec_msg_str(fop)); } static gf_boolean_t ec_is_data_fop(glusterfs_fop_t fop) { switch (fop) { case GF_FOP_WRITE: case GF_FOP_TRUNCATE: case GF_FOP_FTRUNCATE: case GF_FOP_FALLOCATE: case GF_FOP_DISCARD: case GF_FOP_ZEROFILL: return _gf_true; default: return _gf_false; } return _gf_false; } static int32_t ec_child_select(ec_fop_data_t *fop) { ec_t *ec = fop->xl->private; int32_t first = 0, num = 0; ec_fop_cleanup(fop); fop->mask &= ec->node_mask; /* Wind the fop on same subvols as parent for any internal extra fops like * head/tail read in case of writev fop. Unlocks shouldn't do this because * unlock should go on all subvols where lock is performed*/ if (fop->parent && !ec_internal_op(fop)) { fop->mask &= (fop->parent->mask & ~fop->parent->healing); if (ec_is_data_fop(fop->id)) { fop->healing |= fop->parent->healing; } } if ((fop->mask & ~ec->xl_up) != 0) { gf_msg(fop->xl->name, GF_LOG_WARNING, 0, EC_MSG_OP_EXEC_UNAVAIL, "Executing operation with " "some subvolumes unavailable. (%" PRIXPTR "). %s ", fop->mask & ~ec->xl_up, ec_msg_str(fop)); fop->mask &= ec->xl_up; } switch (fop->minimum) { case EC_MINIMUM_ALL: fop->minimum = gf_bits_count(fop->mask); if (fop->minimum >= ec->fragments) { break; } case EC_MINIMUM_MIN: fop->minimum = ec->fragments; break; case EC_MINIMUM_ONE: fop->minimum = 1; } if (ec->read_policy == EC_ROUND_ROBIN) { first = ec->idx; if (++first >= ec->nodes) { first = 0; } ec->idx = first; } num = gf_bits_count(fop->mask); /*Unconditionally wind on healing subvolumes*/ fop->mask |= fop->healing; fop->remaining = fop->mask; fop->received = 0; ec_trace("SELECT", fop, ""); if ((num < fop->minimum) && (num < ec->fragments)) { ec_log_insufficient_vol(fop, ec, num, fop->minimum, GF_LOG_ERROR); return 0; } if (!fop->parent && fop->lock_count && (fop->locks[0].update[EC_DATA_TXN] || fop->locks[0].update[EC_METADATA_TXN])) { if (ec->quorum_count && (num < ec->quorum_count)) { ec_log_insufficient_vol(fop, ec, num, ec->quorum_count, GF_LOG_ERROR); return 0; } } return 1; } void ec_dispatch_next(ec_fop_data_t *fop, uint32_t idx) { uint32_t i = EC_INVALID_INDEX; ec_t *ec = fop->xl->private; LOCK(&fop->lock); i = ec_child_next(ec, fop, idx); if (i < EC_MAX_NODES) { idx = i; fop->remaining ^= 1ULL << idx; ec_trace("EXECUTE", fop, "idx=%d", idx); fop->winds++; fop->refs++; } UNLOCK(&fop->lock); if (i < EC_MAX_NODES) { fop->wind(ec, fop, idx); } } static void ec_dispatch_mask(ec_fop_data_t *fop, uintptr_t mask) { ec_t *ec = fop->xl->private; int32_t count, idx; count = gf_bits_count(mask); LOCK(&fop->lock); ec_trace("EXECUTE", fop, "mask=%lX", mask); fop->remaining ^= mask; fop->winds += count; fop->refs += count; UNLOCK(&fop->lock); idx = 0; while (mask != 0) { if ((mask & 1) != 0) { fop->wind(ec, fop, idx); } idx++; mask >>= 1; } } static void ec_dispatch_start(ec_fop_data_t *fop) { fop->answer = NULL; fop->good = 0; INIT_LIST_HEAD(&fop->cbk_list); if (fop->lock_count > 0) { ec_owner_copy(fop->frame, &fop->req_frame->root->lk_owner); } } void ec_dispatch_one(ec_fop_data_t *fop) { ec_dispatch_start(fop); if (ec_child_select(fop)) { ec_sleep(fop); fop->expected = 1; fop->first = ec_select_first_by_read_policy(fop->xl->private, fop); ec_dispatch_next(fop, fop->first); } } gf_boolean_t ec_dispatch_one_retry(ec_fop_data_t *fop, ec_cbk_data_t **cbk) { ec_cbk_data_t *tmp; tmp = ec_fop_prepare_answer(fop, _gf_true); if (cbk != NULL) { *cbk = tmp; } if ((tmp != NULL) && (tmp->op_ret < 0) && ec_is_recoverable_error(tmp->op_errno)) { GF_ASSERT(fop->mask & (1ULL << tmp->idx)); fop->mask ^= (1ULL << tmp->idx); if (fop->mask) { return _gf_true; } } return _gf_false; } void ec_dispatch_inc(ec_fop_data_t *fop) { ec_dispatch_start(fop); if (ec_child_select(fop)) { ec_sleep(fop); fop->expected = gf_bits_count(fop->remaining); fop->first = 0; ec_dispatch_next(fop, 0); } } void ec_dispatch_all(ec_fop_data_t *fop) { ec_dispatch_start(fop); if (ec_child_select(fop)) { ec_sleep(fop); fop->expected = gf_bits_count(fop->remaining); fop->first = 0; ec_dispatch_mask(fop, fop->remaining); } } void ec_dispatch_min(ec_fop_data_t *fop) { ec_t *ec = fop->xl->private; uintptr_t mask; uint32_t idx; int32_t count; ec_dispatch_start(fop); if (ec_child_select(fop)) { ec_sleep(fop); fop->expected = count = ec->fragments; fop->first = ec_select_first_by_read_policy(fop->xl->private, fop); idx = fop->first - 1; mask = 0; while (count-- > 0) { idx = ec_child_next(ec, fop, idx + 1); if (idx < EC_MAX_NODES) mask |= 1ULL << idx; } ec_dispatch_mask(fop, mask); } } void ec_succeed_all(ec_fop_data_t *fop) { ec_dispatch_start(fop); if (ec_child_select(fop)) { fop->expected = gf_bits_count(fop->remaining); fop->first = 0; /* Simulate a successful execution on all bricks */ ec_trace("SUCCEED", fop, ""); fop->good = fop->remaining; fop->remaining = 0; } } static ec_lock_t * ec_lock_allocate(ec_fop_data_t *fop, loc_t *loc) { ec_t *ec = fop->xl->private; ec_lock_t *lock; int32_t err; if ((loc->inode == NULL) || (gf_uuid_is_null(loc->gfid) && gf_uuid_is_null(loc->inode->gfid))) { gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_INVALID_INODE, "Trying to lock based on an invalid " "inode"); __ec_fop_set_error(fop, EINVAL); return NULL; } lock = mem_get0(ec->lock_pool); if (lock != NULL) { lock->good_mask = UINTPTR_MAX; INIT_LIST_HEAD(&lock->owners); INIT_LIST_HEAD(&lock->waiting); INIT_LIST_HEAD(&lock->frozen); err = ec_loc_from_loc(fop->xl, &lock->loc, loc); if (err != 0) { mem_put(lock); lock = NULL; __ec_fop_set_error(fop, -err); } } return lock; } static void ec_lock_destroy(ec_lock_t *lock) { loc_wipe(&lock->loc); if (lock->fd != NULL) { fd_unref(lock->fd); } mem_put(lock); } static int ec_lock_compare(ec_lock_t *lock1, ec_lock_t *lock2) { return gf_uuid_compare(lock1->loc.gfid, lock2->loc.gfid); } static void ec_lock_insert(ec_fop_data_t *fop, ec_lock_t *lock, uint32_t flags, loc_t *base, off_t fl_start, uint64_t fl_size) { ec_lock_link_t *link; /* This check is only prepared for up to 2 locks per fop. If more locks * are needed this must be changed. */ if ((fop->lock_count > 0) && (ec_lock_compare(fop->locks[0].lock, lock) < 0)) { fop->first_lock = fop->lock_count; } else { /* When the first lock is added to the current fop, request lock * counts from locks xlator to be able to determine if there is * contention and release the lock sooner. */ if (fop->xdata == NULL) { fop->xdata = dict_new(); if (fop->xdata == NULL) { ec_fop_set_error(fop, ENOMEM); return; } } if (dict_set_str(fop->xdata, GLUSTERFS_INODELK_DOM_COUNT, fop->xl->name) != 0) { ec_fop_set_error(fop, ENOMEM); return; } } link = &fop->locks[fop->lock_count++]; link->lock = lock; link->fop = fop; link->update[EC_DATA_TXN] = (flags & EC_UPDATE_DATA) != 0; link->update[EC_METADATA_TXN] = (flags & EC_UPDATE_META) != 0; link->base = base; link->fl_start = fl_start; link->fl_end = ec_range_end_get(fl_start, fl_size); lock->refs_pending++; } static void ec_lock_prepare_inode_internal(ec_fop_data_t *fop, loc_t *loc, uint32_t flags, loc_t *base, off_t fl_start, uint64_t fl_size) { ec_lock_t *lock = NULL; ec_inode_t *ctx; if ((fop->parent != NULL) || (fop->error != 0) || (loc->inode == NULL)) { return; } LOCK(&loc->inode->lock); ctx = __ec_inode_get(loc->inode, fop->xl); if (ctx == NULL) { __ec_fop_set_error(fop, ENOMEM); goto unlock; } if (ctx->inode_lock != NULL) { lock = ctx->inode_lock; /* If there's another lock, make sure that it's not the same. Otherwise * do not insert it. * * This can only happen on renames where source and target names are * in the same directory. */ if ((fop->lock_count > 0) && (fop->locks[0].lock == lock)) { /* Combine data/meta updates */ fop->locks[0].update[EC_DATA_TXN] |= (flags & EC_UPDATE_DATA) != 0; fop->locks[0].update[EC_METADATA_TXN] |= (flags & EC_UPDATE_META) != 0; /* Only one base inode is allowed per fop, so there shouldn't be * overwrites here. */ if (base != NULL) { fop->locks[0].base = base; } goto update_query; } ec_trace("LOCK_INODELK", fop, "lock=%p, inode=%p. Lock already " "acquired", lock, loc->inode); goto insert; } lock = ec_lock_allocate(fop, loc); if (lock == NULL) { goto unlock; } ec_trace("LOCK_CREATE", fop, "lock=%p", lock); lock->flock.l_type = F_WRLCK; lock->flock.l_whence = SEEK_SET; lock->ctx = ctx; ctx->inode_lock = lock; insert: ec_lock_insert(fop, lock, flags, base, fl_start, fl_size); update_query: lock->query |= (flags & EC_QUERY_INFO) != 0; unlock: UNLOCK(&loc->inode->lock); } void ec_lock_prepare_inode(ec_fop_data_t *fop, loc_t *loc, uint32_t flags, off_t fl_start, uint64_t fl_size) { ec_lock_prepare_inode_internal(fop, loc, flags, NULL, fl_start, fl_size); } void ec_lock_prepare_parent_inode(ec_fop_data_t *fop, loc_t *loc, loc_t *base, uint32_t flags) { loc_t tmp; int32_t err; if (fop->error != 0) { return; } err = ec_loc_parent(fop->xl, loc, &tmp); if (err != 0) { ec_fop_set_error(fop, -err); return; } if ((flags & EC_INODE_SIZE) != 0) { flags ^= EC_INODE_SIZE; } else { base = NULL; } ec_lock_prepare_inode_internal(fop, &tmp, flags, base, 0, EC_RANGE_FULL); loc_wipe(&tmp); } void ec_lock_prepare_fd(ec_fop_data_t *fop, fd_t *fd, uint32_t flags, off_t fl_start, uint64_t fl_size) { loc_t loc; int32_t err; if (fop->error != 0) { return; } err = ec_loc_from_fd(fop->xl, &loc, fd); if (err != 0) { ec_fop_set_error(fop, -err); return; } ec_lock_prepare_inode_internal(fop, &loc, flags, NULL, fl_start, fl_size); loc_wipe(&loc); } static gf_boolean_t ec_config_check(xlator_t *xl, ec_config_t *config) { ec_t *ec; ec = xl->private; if ((config->version != EC_CONFIG_VERSION) || (config->algorithm != EC_CONFIG_ALGORITHM) || (config->gf_word_size != EC_GF_BITS) || (config->bricks != ec->nodes) || (config->redundancy != ec->redundancy) || (config->chunk_size != EC_METHOD_CHUNK_SIZE)) { uint32_t data_bricks; /* This combination of version/algorithm requires the following values. Incorrect values for these fields are a sign of corruption: redundancy > 0 redundancy * 2 < bricks gf_word_size must be a power of 2 chunk_size (in bits) must be a multiple of gf_word_size * (bricks - redundancy) */ data_bricks = config->bricks - config->redundancy; if ((config->redundancy < 1) || (config->redundancy * 2 >= config->bricks) || !ec_is_power_of_2(config->gf_word_size) || ((config->chunk_size * 8) % (config->gf_word_size * data_bricks) != 0)) { gf_msg(xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_INVALID_CONFIG, "Invalid or corrupted config"); } else { gf_msg(xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_INVALID_CONFIG, "Unsupported config " "(V=%u, A=%u, W=%u, " "N=%u, R=%u, S=%u)", config->version, config->algorithm, config->gf_word_size, config->bricks, config->redundancy, config->chunk_size); } return _gf_false; } return _gf_true; } static gf_boolean_t ec_set_dirty_flag(ec_lock_link_t *link, ec_inode_t *ctx, uint64_t *dirty) { gf_boolean_t set_dirty = _gf_false; if (link->update[EC_DATA_TXN] && !ctx->dirty[EC_DATA_TXN]) { if (!link->optimistic_changelog) dirty[EC_DATA_TXN] = 1; } if (link->update[EC_METADATA_TXN] && !ctx->dirty[EC_METADATA_TXN]) { if (!link->optimistic_changelog) dirty[EC_METADATA_TXN] = 1; } if (dirty[EC_METADATA_TXN] || dirty[EC_DATA_TXN]) { set_dirty = _gf_true; } return set_dirty; } static int32_t ec_prepare_update_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { struct list_head list; ec_fop_data_t *fop = cookie, *parent, *tmp; ec_lock_link_t *parent_link = fop->data; ec_lock_link_t *link = NULL; ec_lock_t *lock = NULL; ec_inode_t *ctx; gf_boolean_t release = _gf_false; uint64_t provided_flags = 0; uint64_t dirty[EC_VERSION_SIZE] = {0, 0}; lock = parent_link->lock; parent = parent_link->fop; ctx = lock->ctx; INIT_LIST_HEAD(&list); provided_flags = EC_PROVIDED_FLAGS(parent_link->waiting_flags); LOCK(&lock->loc.inode->lock); list_for_each_entry(link, &lock->owners, owner_list) { if ((link->waiting_flags & provided_flags) != 0) { link->waiting_flags ^= (link->waiting_flags & provided_flags); if (EC_NEEDED_FLAGS(link->waiting_flags) == 0) list_add_tail(&link->fop->cbk_list, &list); } } if (op_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, op_errno, EC_MSG_SIZE_VERS_GET_FAIL, "Failed to get size and version : %s", ec_msg_str(fop)); goto unlock; } if (EC_FLAGS_HAVE(provided_flags, EC_FLAG_XATTROP)) { op_errno = -ec_dict_del_array(dict, EC_XATTR_VERSION, ctx->pre_version, EC_VERSION_SIZE); if (op_errno != 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, EC_MSG_VER_XATTR_GET_FAIL, "Unable to get version xattr. %s", ec_msg_str(fop)); goto unlock; } ctx->post_version[0] += ctx->pre_version[0]; ctx->post_version[1] += ctx->pre_version[1]; ctx->have_version = _gf_true; if (lock->loc.inode->ia_type == IA_IFREG || lock->loc.inode->ia_type == IA_INVAL) { op_errno = -ec_dict_del_number(dict, EC_XATTR_SIZE, &ctx->pre_size); if (op_errno != 0) { if (lock->loc.inode->ia_type == IA_IFREG) { gf_msg(this->name, GF_LOG_ERROR, op_errno, EC_MSG_SIZE_XATTR_GET_FAIL, "Unable to get size xattr. %s", ec_msg_str(fop)); goto unlock; } } else { ctx->post_size = ctx->pre_size; ctx->have_size = _gf_true; } op_errno = -ec_dict_del_config(dict, EC_XATTR_CONFIG, &ctx->config); if (op_errno != 0) { if ((lock->loc.inode->ia_type == IA_IFREG) || (op_errno != ENODATA)) { gf_msg(this->name, GF_LOG_ERROR, op_errno, EC_MSG_CONFIG_XATTR_GET_FAIL, "Unable to get config xattr. %s", ec_msg_str(fop)); goto unlock; } } else { if (!ec_config_check(parent->xl, &ctx->config)) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, EC_MSG_CONFIG_XATTR_INVALID, "Invalid config xattr"); op_errno = EINVAL; goto unlock; } ctx->have_config = _gf_true; } } ctx->have_info = _gf_true; } ec_set_dirty_flag(fop->data, ctx, dirty); if (dirty[EC_METADATA_TXN] && (EC_FLAGS_HAVE(provided_flags, EC_FLAG_METADATA_DIRTY))) { GF_ASSERT(!ctx->dirty[EC_METADATA_TXN]); ctx->dirty[EC_METADATA_TXN] = 1; } if (dirty[EC_DATA_TXN] && (EC_FLAGS_HAVE(provided_flags, EC_FLAG_DATA_DIRTY))) { GF_ASSERT(!ctx->dirty[EC_DATA_TXN]); ctx->dirty[EC_DATA_TXN] = 1; } op_errno = 0; unlock: lock->waiting_flags ^= provided_flags; if (op_errno == 0) { /* If the fop fails on any of the good bricks, it is important to mark * it dirty and update versions right away if dirty was not set before. */ if (lock->good_mask & ~(fop->good | fop->remaining)) { release = _gf_true; } if (parent_link->update[0] && !parent_link->dirty[0]) { lock->release |= release; } if (parent_link->update[1] && !parent_link->dirty[1]) { lock->release |= release; } /* We don't allow the main fop to be executed on bricks that have not * succeeded the initial xattrop. */ ec_lock_update_good(lock, fop); /*As of now only data healing marks bricks as healing*/ lock->healing |= fop->healing; } UNLOCK(&lock->loc.inode->lock); while (!list_empty(&list)) { tmp = list_entry(list.next, ec_fop_data_t, cbk_list); list_del_init(&tmp->cbk_list); if (op_errno == 0) { tmp->mask &= fop->good; /*As of now only data healing marks bricks as healing*/ if (ec_is_data_fop(tmp->id)) { tmp->healing |= fop->healing; } } ec_resume(tmp, op_errno); } return 0; } static gf_boolean_t ec_set_needed_flag(ec_lock_t *lock, ec_lock_link_t *link, uint64_t flag) { uint64_t current; link->waiting_flags |= EC_FLAG_NEEDS(flag); current = EC_NEEDED_FLAGS(lock->waiting_flags); if (!EC_FLAGS_HAVE(current, flag)) { lock->waiting_flags |= EC_FLAG_NEEDS(flag); link->waiting_flags |= EC_FLAG_PROVIDES(flag); return _gf_true; } return _gf_false; } static uint64_t ec_set_xattrop_flags_and_params(ec_lock_t *lock, ec_lock_link_t *link, uint64_t *dirty) { uint64_t oldflags = 0; uint64_t newflags = 0; ec_inode_t *ctx = lock->ctx; oldflags = EC_NEEDED_FLAGS(lock->waiting_flags); if (lock->query && !ctx->have_info) { ec_set_needed_flag(lock, link, EC_FLAG_XATTROP); } if (dirty[EC_DATA_TXN]) { if (!ec_set_needed_flag(lock, link, EC_FLAG_DATA_DIRTY)) { dirty[EC_DATA_TXN] = 0; } } if (dirty[EC_METADATA_TXN]) { if (!ec_set_needed_flag(lock, link, EC_FLAG_METADATA_DIRTY)) { dirty[EC_METADATA_TXN] = 0; } } newflags = EC_NEEDED_FLAGS(lock->waiting_flags); return oldflags ^ newflags; } static void ec_get_size_version(ec_lock_link_t *link) { loc_t loc; ec_lock_t *lock; ec_inode_t *ctx; ec_fop_data_t *fop; dict_t *dict = NULL; dict_t *xdata = NULL; ec_t *ec = NULL; int32_t error = 0; gf_boolean_t set_dirty = _gf_false; uint64_t allzero[EC_VERSION_SIZE] = {0, 0}; uint64_t dirty[EC_VERSION_SIZE] = {0, 0}; lock = link->lock; ctx = lock->ctx; fop = link->fop; ec = fop->xl->private; uint64_t changed_flags = 0; if (ec->optimistic_changelog && !(ec->node_mask & ~link->lock->good_mask) && !ec_is_data_fop(fop->id)) link->optimistic_changelog = _gf_true; LOCK(&lock->loc.inode->lock); set_dirty = ec_set_dirty_flag(link, ctx, dirty); /* If ec metadata has already been retrieved, do not try again. */ if (ctx->have_info) { if (ec_is_data_fop(fop->id)) { fop->healing |= lock->healing; } if (!set_dirty) goto unlock; } /* Determine if there's something we need to retrieve for the current * operation. */ if (!set_dirty && !lock->query && (lock->loc.inode->ia_type != IA_IFREG) && (lock->loc.inode->ia_type != IA_INVAL)) { goto unlock; } changed_flags = ec_set_xattrop_flags_and_params(lock, link, dirty); if (link->waiting_flags) { /* This fop needs to wait until all its flags are cleared which * potentially can be cleared by other xattrops that are already * wound*/ ec_sleep(fop); } else { GF_ASSERT(!changed_flags); } unlock: UNLOCK(&lock->loc.inode->lock); if (!changed_flags) goto out; dict = dict_new(); if (dict == NULL) { error = -ENOMEM; goto out; } if (EC_FLAGS_HAVE(changed_flags, EC_FLAG_XATTROP)) { /* Once we know that an xattrop will be needed, * we try to get all available information in a * single call. */ error = ec_dict_set_array(dict, EC_XATTR_VERSION, allzero, EC_VERSION_SIZE); if (error != 0) { goto out; } if (lock->loc.inode->ia_type == IA_IFREG || lock->loc.inode->ia_type == IA_INVAL) { error = ec_dict_set_number(dict, EC_XATTR_SIZE, 0); if (error == 0) { error = ec_dict_set_number(dict, EC_XATTR_CONFIG, 0); } if (error != 0) { goto out; } xdata = dict_new(); if (xdata == NULL || dict_set_int32(xdata, GF_GET_SIZE, 1)) { error = -ENOMEM; goto out; } } } if (memcmp(allzero, dirty, sizeof(allzero))) { error = ec_dict_set_array(dict, EC_XATTR_DIRTY, dirty, EC_VERSION_SIZE); if (error != 0) { goto out; } } fop->frame->root->uid = 0; fop->frame->root->gid = 0; /* For normal fops, ec_[f]xattrop() must succeed on at least * EC_MINIMUM_MIN bricks, however when this is called as part of a * self-heal operation the mask of target bricks (fop->mask) could * contain less than EC_MINIMUM_MIN bricks, causing the xattrop to * always fail. Thus we always use the same minimum used for the main * fop. */ if (lock->fd == NULL) { error = ec_loc_from_loc(fop->xl, &loc, &lock->loc); if (error != 0) { goto out; } if (gf_uuid_is_null(loc.pargfid)) { if (loc.parent != NULL) { inode_unref(loc.parent); loc.parent = NULL; } GF_FREE((char *)loc.path); loc.path = NULL; loc.name = NULL; } ec_xattrop(fop->frame, fop->xl, fop->mask, fop->minimum, ec_prepare_update_cbk, link, &loc, GF_XATTROP_ADD_ARRAY64, dict, xdata); loc_wipe(&loc); } else { ec_fxattrop(fop->frame, fop->xl, fop->mask, fop->minimum, ec_prepare_update_cbk, link, lock->fd, GF_XATTROP_ADD_ARRAY64, dict, xdata); } error = 0; out: fop->frame->root->uid = fop->uid; fop->frame->root->gid = fop->gid; if (dict != NULL) { dict_unref(dict); } if (xdata != NULL) { dict_unref(xdata); } if (error != 0) { ec_fop_set_error(fop, -error); } } gf_boolean_t __ec_get_inode_size(ec_fop_data_t *fop, inode_t *inode, uint64_t *size) { ec_inode_t *ctx; gf_boolean_t found = _gf_false; ctx = __ec_inode_get(inode, fop->xl); if (ctx == NULL) { goto out; } if (ctx->have_size) { *size = ctx->post_size; found = _gf_true; } out: return found; } gf_boolean_t ec_get_inode_size(ec_fop_data_t *fop, inode_t *inode, uint64_t *size) { gf_boolean_t found = _gf_false; LOCK(&inode->lock); { found = __ec_get_inode_size(fop, inode, size); } UNLOCK(&inode->lock); return found; } gf_boolean_t __ec_set_inode_size(ec_fop_data_t *fop, inode_t *inode, uint64_t size) { ec_inode_t *ctx; gf_boolean_t found = _gf_false; ctx = __ec_inode_get(inode, fop->xl); if (ctx == NULL) { goto out; } /* Normal fops always have ctx->have_size set. However self-heal calls this * to prepare the inode, so ctx->have_size will be false. In this case we * prepare both pre_size and post_size, and set have_size and have_info to * true. */ if (!ctx->have_size) { ctx->pre_size = size; ctx->have_size = ctx->have_info = _gf_true; } ctx->post_size = size; found = _gf_true; out: return found; } gf_boolean_t ec_set_inode_size(ec_fop_data_t *fop, inode_t *inode, uint64_t size) { gf_boolean_t found = _gf_false; LOCK(&inode->lock); { found = __ec_set_inode_size(fop, inode, size); } UNLOCK(&inode->lock); return found; } static void ec_release_stripe_cache(ec_inode_t *ctx) { ec_stripe_list_t *stripe_cache = NULL; ec_stripe_t *stripe = NULL; stripe_cache = &ctx->stripe_cache; while (!list_empty(&stripe_cache->lru)) { stripe = list_first_entry(&stripe_cache->lru, ec_stripe_t, lru); list_del(&stripe->lru); GF_FREE(stripe); } stripe_cache->count = 0; stripe_cache->max = 0; } void ec_clear_inode_info(ec_fop_data_t *fop, inode_t *inode) { ec_inode_t *ctx; LOCK(&inode->lock); ctx = __ec_inode_get(inode, fop->xl); if (ctx == NULL) { goto unlock; } ec_release_stripe_cache(ctx); ctx->have_info = _gf_false; ctx->have_config = _gf_false; ctx->have_version = _gf_false; ctx->have_size = _gf_false; memset(&ctx->config, 0, sizeof(ctx->config)); memset(ctx->pre_version, 0, sizeof(ctx->pre_version)); memset(ctx->post_version, 0, sizeof(ctx->post_version)); ctx->pre_size = ctx->post_size = 0; memset(ctx->dirty, 0, sizeof(ctx->dirty)); unlock: UNLOCK(&inode->lock); } static int32_t ec_get_real_size_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { ec_fop_data_t *fop = cookie; ec_lock_link_t *link; if (op_ret >= 0) { link = fop->data; link->size = buf->ia_size; } else { /* Prevent failure of parent fop. */ fop->error = 0; } return 0; } /* This function is used to get the trusted.ec.size xattr from a file when * no lock is needed on the inode. This is only required to maintain iatt * structs on fops that manipulate directory entries but do not operate * directly on the inode, like link, rename, ... * * Any error processing this request is ignored. In the worst case, an invalid * or not up to date value in the iatt could cause some cache invalidation. */ static void ec_get_real_size(ec_lock_link_t *link) { ec_fop_data_t *fop; dict_t *xdata; if (link->base == NULL || link->base->inode == NULL) { return; } if (link->base->inode->ia_type != IA_IFREG) { return; } fop = link->fop; if (ec_get_inode_size(fop, link->base->inode, &link->size)) { return; } xdata = dict_new(); if (xdata == NULL) { return; } if (ec_dict_set_number(xdata, EC_XATTR_SIZE, 0) != 0) { goto out; } /* Send a simple lookup. A single answer is considered ok since this value * is only used to return an iatt struct related to an inode that is not * locked and have not suffered any operation. */ ec_lookup(fop->frame, fop->xl, fop->mask, 1, ec_get_real_size_cbk, link, link->base, xdata); out: if (xdata != NULL) { dict_unref(xdata); } } static void ec_lock_update_fd(ec_lock_t *lock, ec_fop_data_t *fop) { /* If the fop has an fd available, attach it to the lock structure to be * able to do fxattrop calls instead of xattrop. */ if (fop->use_fd && (lock->fd == NULL)) { lock->fd = __fd_ref(fop->fd); } } static gf_boolean_t ec_link_has_lock_conflict(ec_lock_link_t *link, gf_boolean_t waitlist_check) { ec_lock_link_t *trav_link = NULL; list_for_each_entry(trav_link, &link->lock->owners, owner_list) { if (ec_lock_conflict(trav_link, link)) return _gf_true; } if (!waitlist_check) return _gf_false; list_for_each_entry(trav_link, &link->lock->waiting, wait_list) { if (ec_lock_conflict(trav_link, link)) return _gf_true; } return _gf_false; } static void ec_lock_wake_shared(ec_lock_t *lock, struct list_head *list) { ec_fop_data_t *fop; ec_lock_link_t *link; gf_boolean_t conflict = _gf_false; while (!conflict && !list_empty(&lock->waiting)) { link = list_entry(lock->waiting.next, ec_lock_link_t, wait_list); fop = link->fop; /* If lock is not acquired, at most one fop can be assigned as owner. * The following fops will need to wait in the lock->waiting queue * until the lock has been fully acquired. */ conflict = !lock->acquired; /* If the fop is not shareable, only this fop can be assigned as owner. * Other fops will need to wait until this one finishes. */ if (ec_link_has_lock_conflict(link, _gf_false)) { conflict = _gf_true; } /* If only one fop is allowed, it can be assigned as the owner of the * lock only if there weren't any other owner. */ if (conflict && !list_empty(&lock->owners)) { break; } list_move_tail(&link->wait_list, list); list_add_tail(&link->owner_list, &lock->owners); lock->refs_owners++; ec_lock_update_fd(lock, fop); } } static void ec_lock_apply(ec_lock_link_t *link) { ec_fop_data_t *fop = link->fop; fop->mask &= link->lock->good_mask; fop->locked++; ec_get_size_version(link); ec_get_real_size(link); } static gf_boolean_t ec_lock_acquire(ec_lock_link_t *link); static void ec_lock_resume_shared(struct list_head *list) { ec_lock_link_t *link; while (!list_empty(list)) { link = list_entry(list->next, ec_lock_link_t, wait_list); list_del_init(&link->wait_list); if (link->lock->acquired) { ec_lock_apply(link); ec_lock(link->fop); } else { GF_ASSERT(list_empty(list)); ec_lock_acquire(link); } ec_resume(link->fop, 0); } } static void ec_lock_acquired(ec_lock_link_t *link) { struct list_head list; ec_lock_t *lock; ec_fop_data_t *fop; lock = link->lock; fop = link->fop; ec_trace("LOCKED", fop, "lock=%p", lock); INIT_LIST_HEAD(&list); LOCK(&lock->loc.inode->lock); lock->acquired = _gf_true; if (lock->contention) { lock->release = _gf_true; lock->contention = _gf_false; } ec_lock_update_fd(lock, fop); ec_lock_wake_shared(lock, &list); UNLOCK(&lock->loc.inode->lock); ec_lock_apply(link); if (fop->use_fd && (link->update[EC_DATA_TXN] || link->update[EC_METADATA_TXN])) { /* Try to reopen closed fd's only if lock has succeeded. */ ec_fix_open(fop, lock->mask); } ec_lock_resume_shared(&list); } static int32_t ec_locked(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = cookie; ec_lock_link_t *link = NULL; ec_lock_t *lock = NULL; link = fop->data; lock = link->lock; if (op_ret >= 0) { lock->mask = lock->good_mask = fop->good; lock->healing = 0; ec_lock_acquired(link); ec_lock(fop->parent); } else { LOCK(&lock->loc.inode->lock); { lock->contention = _gf_false; } UNLOCK(&lock->loc.inode->lock); gf_msg(this->name, GF_LOG_WARNING, op_errno, EC_MSG_PREOP_LOCK_FAILED, "Failed to complete preop lock"); } return 0; } static gf_boolean_t ec_lock_acquire(ec_lock_link_t *link) { ec_lock_t *lock; ec_fop_data_t *fop; gf_lkowner_t lk_owner; lock = link->lock; fop = link->fop; if (!lock->acquired) { set_lk_owner_from_ptr(&lk_owner, lock); ec_trace("LOCK_ACQUIRE", fop, "lock=%p, inode=%p", lock, lock->loc.inode); lock->flock.l_type = F_WRLCK; ec_inodelk(fop->frame, fop->xl, &lk_owner, -1, EC_MINIMUM_ALL, ec_locked, link, fop->xl->name, &lock->loc, F_SETLKW, &lock->flock, NULL); return _gf_false; } ec_trace("LOCK_REUSE", fop, "lock=%p", lock); ec_lock_acquired(link); return _gf_true; } static ec_lock_link_t * ec_lock_timer_cancel(xlator_t *xl, ec_lock_t *lock) { ec_lock_link_t *timer_link; /* If we don't have any timer, there's nothing to cancel. */ if (lock->timer == NULL) { return NULL; } /* We are trying to access a lock that has an unlock timer active. * This means that the lock must be idle, i.e. no fop can be in the * owner, waiting or frozen lists. It also means that the lock cannot * have been marked as being released (this is done without timers). * There should only be one owner reference, but it's possible that * some fops are being prepared to use this lock. */ GF_ASSERT((lock->refs_owners == 1) && list_empty(&lock->owners) && list_empty(&lock->waiting)); /* We take the timer_link before cancelling the timer, since a * successful cancellation will destroy it. It must not be NULL * because it references the fop responsible for the delayed unlock * that we are currently trying to cancel. */ timer_link = lock->timer->data; GF_ASSERT(timer_link != NULL); if (gf_timer_call_cancel(xl->ctx, lock->timer) < 0) { /* It's too late to avoid the execution of the timer callback. * Since we need to be sure that the callback has access to all * needed resources, we cannot resume the execution of the * timer fop now. This will be done in the callback. */ timer_link = NULL; } else { /* The timer has been cancelled. The fop referenced by * timer_link holds the last reference. The caller is * responsible to release it when not needed anymore. */ ec_trace("UNLOCK_CANCELLED", timer_link->fop, "lock=%p", lock); } /* We have two options here: * * 1. The timer has been successfully cancelled. * * This is the easiest case and we can continue with the currently * acquired lock. * * 2. The timer callback has already been fired. * * In this case we have not been able to cancel the timer before * the timer callback has been fired, but we also know that * lock->timer != NULL. This means that the timer callback is still * trying to acquire the inode mutex that we currently own. We are * safe until we release it. In this case we can safely clear * lock->timer. This will cause that the timer callback does nothing * once it acquires the mutex. */ lock->timer = NULL; return timer_link; } static gf_boolean_t ec_lock_assign_owner(ec_lock_link_t *link) { ec_fop_data_t *fop; ec_lock_t *lock; ec_lock_link_t *timer_link = NULL; gf_boolean_t assigned = _gf_false; /* The link cannot be in any list because we have just finished preparing * it. */ GF_ASSERT(list_empty(&link->wait_list)); fop = link->fop; lock = link->lock; LOCK(&lock->loc.inode->lock); /* Since the link has just been prepared but it's not active yet, the * refs_pending must be one at least (the ref owned by this link). */ GF_ASSERT(lock->refs_pending > 0); /* The link is not pending any more. It will be assigned to the owner, * waiting or frozen list. */ lock->refs_pending--; if (lock->release) { ec_trace("LOCK_QUEUE_FREEZE", fop, "lock=%p", lock); /* When lock->release is set, we'll unlock the lock as soon as * possible, meaning that we won't use a timer. */ GF_ASSERT(lock->timer == NULL); /* The lock is marked to be released. We can still have owners and fops * in the waiting ilist f they have been added before the lock has been * marked to be released. However new fops are put into the frozen list * to wait for the next unlock/lock cycle. */ list_add_tail(&link->wait_list, &lock->frozen); goto unlock; } /* The lock is not marked to be released, so the frozen list should be * empty. */ GF_ASSERT(list_empty(&lock->frozen)); timer_link = ec_lock_timer_cancel(fop->xl, lock); if (!list_empty(&lock->owners)) { /* There are other owners of this lock. We can only take ownership if * the lock is already acquired and doesn't have conflict with existing * owners, or waiters(to prevent starvation). * Otherwise we need to wait. */ if (!lock->acquired || ec_link_has_lock_conflict(link, _gf_true)) { ec_trace("LOCK_QUEUE_WAIT", fop, "lock=%p", lock); list_add_tail(&link->wait_list, &lock->waiting); goto unlock; } } list_add_tail(&link->owner_list, &lock->owners); /* If timer_link is not NULL, it means that we have inherited the owner * reference assigned to the timer fop. In this case we simply reuse it. * Otherwise we need to increase the number of owners. */ if (timer_link == NULL) { lock->refs_owners++; } assigned = _gf_true; unlock: if (!assigned) { /* We have not been able to take ownership of this lock. The fop must * be put to sleep. */ ec_sleep(fop); } UNLOCK(&lock->loc.inode->lock); /* If we have cancelled the timer, we need to resume the fop that was * waiting for it. */ if (timer_link != NULL) { ec_resume(timer_link->fop, 0); } return assigned; } static void ec_lock_next_owner(ec_lock_link_t *link, ec_cbk_data_t *cbk, gf_boolean_t release) { struct list_head list; ec_lock_t *lock = link->lock; ec_fop_data_t *fop = link->fop; ec_inode_t *ctx = lock->ctx; INIT_LIST_HEAD(&list); LOCK(&lock->loc.inode->lock); ec_trace("LOCK_DONE", fop, "lock=%p", lock); /* Current link must belong to the owner list of the lock. We don't * decrement lock->refs_owners here because the inode mutex is released * before ec_unlock() is called and we need to know when the last owner * unlocks the lock to do proper cleanup. lock->refs_owners is used for * this task. */ GF_ASSERT((lock->refs_owners > 0) && !list_empty(&link->owner_list)); list_del_init(&link->owner_list); lock->release |= release; if ((fop->error == 0) && (cbk != NULL) && (cbk->op_ret >= 0)) { if (link->update[0]) { ctx->post_version[0]++; } if (link->update[1]) { ctx->post_version[1]++; } /* If the fop fails on any of the good bricks, it is important to mark * it dirty and update versions right away. */ if (link->update[0] || link->update[1]) { if (lock->good_mask & ~(fop->good | fop->remaining)) { lock->release = _gf_true; } } } if (fop->healing) { lock->healing = fop->healing & (fop->good | fop->remaining); } ec_lock_update_good(lock, fop); ec_lock_wake_shared(lock, &list); UNLOCK(&lock->loc.inode->lock); ec_lock_resume_shared(&list); } void ec_lock(ec_fop_data_t *fop) { ec_lock_link_t *link; /* There is a chance that ec_resume is called on fop even before ec_sleep. * Which can result in refs == 0 for fop leading to use after free in this * function when it calls ec_sleep so do ec_sleep at start and ec_resume at * the end of this function.*/ ec_sleep(fop); while (fop->locked < fop->lock_count) { /* Since there are only up to 2 locks per fop, this xor will change * the order of the locks if fop->first_lock is 1. */ link = &fop->locks[fop->locked ^ fop->first_lock]; if (!ec_lock_assign_owner(link) || !ec_lock_acquire(link)) { break; } } ec_resume(fop, 0); } static void ec_lock_unfreeze(ec_lock_link_t *link) { struct list_head list; ec_lock_t *lock; gf_boolean_t destroy = _gf_false; lock = link->lock; INIT_LIST_HEAD(&list); LOCK(&lock->loc.inode->lock); /* The lock must be marked to be released here, since we have just released * it and any attempt to assign it to more fops must have added them to the * frozen list. We can only have one active reference here: the one that * is processing this unfreeze. */ GF_ASSERT(lock->release && (lock->refs_owners == 1)); lock->release = _gf_false; lock->refs_owners = 0; lock->acquired = _gf_false; /* We are unfreezing a lock. This means that the lock has already been * released. In this state it shouldn't have a pending timer nor have any * owner, and the waiting list should be empty. Only the frozen list can * contain some fop. */ GF_ASSERT((lock->timer == NULL) && list_empty(&lock->waiting) && list_empty(&lock->owners)); /* We move all frozen fops to the waiting list. */ list_splice_init(&lock->frozen, &lock->waiting); /* If we don't have any fop waiting nor there are any prepared fops using * this lock, we can finally dispose it. */ destroy = list_empty(&lock->waiting) && (lock->refs_pending == 0); if (destroy) { ec_trace("LOCK_DESTROY", link->fop, "lock=%p", lock); lock->ctx->inode_lock = NULL; } else { ec_trace("LOCK_UNFREEZE", link->fop, "lock=%p", lock); ec_lock_wake_shared(lock, &list); } UNLOCK(&lock->loc.inode->lock); ec_lock_resume_shared(&list); if (destroy) { ec_lock_destroy(lock); } } static int32_t ec_unlocked(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = cookie; ec_lock_link_t *link = fop->data; if (op_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, op_errno, EC_MSG_UNLOCK_FAILED, "entry/inode unlocking failed :(%s)", ec_msg_str(link->fop)); } else { ec_trace("UNLOCKED", link->fop, "lock=%p", link->lock); } ec_lock_unfreeze(link); return 0; } static void ec_unlock_lock(ec_lock_link_t *link) { ec_lock_t *lock; ec_fop_data_t *fop; gf_lkowner_t lk_owner; lock = link->lock; fop = link->fop; lock->unlock_now = _gf_false; ec_clear_inode_info(fop, lock->loc.inode); if ((lock->mask != 0) && lock->acquired) { set_lk_owner_from_ptr(&lk_owner, lock); lock->flock.l_type = F_UNLCK; ec_trace("UNLOCK_INODELK", fop, "lock=%p, inode=%p", lock, lock->loc.inode); ec_inodelk(fop->frame, fop->xl, &lk_owner, lock->mask, EC_MINIMUM_ONE, ec_unlocked, link, fop->xl->name, &lock->loc, F_SETLK, &lock->flock, NULL); } else { ec_lock_unfreeze(link); } } static void ec_inode_bad_inc(inode_t *inode, xlator_t *xl) { ec_inode_t *ctx = NULL; LOCK(&inode->lock); { ctx = __ec_inode_get(inode, xl); if (ctx == NULL) { goto unlock; } ctx->bad_version++; } unlock: UNLOCK(&inode->lock); } static int32_t ec_update_size_version_done(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata) { ec_fop_data_t *fop = cookie; ec_lock_link_t *link; ec_lock_t *lock; ec_inode_t *ctx; link = fop->data; lock = link->lock; ctx = lock->ctx; if (op_ret < 0) { if (link->lock->fd == NULL) { ec_inode_bad_inc(link->lock->loc.inode, this); } else { ec_inode_bad_inc(link->lock->fd->inode, this); } gf_msg(fop->xl->name, fop_log_level(fop->id, op_errno), op_errno, EC_MSG_SIZE_VERS_UPDATE_FAIL, "Failed to update version and size. %s", ec_msg_str(fop)); } else { fop->parent->good &= fop->good; ec_lock_update_good(lock, fop); if (ec_dict_del_array(xattr, EC_XATTR_VERSION, ctx->post_version, EC_VERSION_SIZE) == 0) { ctx->pre_version[0] = ctx->post_version[0]; ctx->pre_version[1] = ctx->post_version[1]; ctx->have_version = _gf_true; } if (ec_dict_del_number(xattr, EC_XATTR_SIZE, &ctx->post_size) == 0) { ctx->pre_size = ctx->post_size; ctx->have_size = _gf_true; } if ((ec_dict_del_config(xdata, EC_XATTR_CONFIG, &ctx->config) == 0) && ec_config_check(fop->xl, &ctx->config)) { ctx->have_config = _gf_true; } ctx->have_info = _gf_true; } /* If we are here because of fop's and other than unlock request, * that means we are still holding a lock. That make sure * lock->unlock_now can not be modified. */ if (lock->unlock_now) { ec_unlock_lock(fop->data); } return 0; } static void ec_update_size_version(ec_lock_link_t *link, uint64_t *version, uint64_t size, uint64_t *dirty) { ec_fop_data_t *fop; ec_lock_t *lock; ec_inode_t *ctx; dict_t *dict = NULL; uintptr_t update_on = 0; int32_t err = -ENOMEM; fop = link->fop; lock = link->lock; ctx = lock->ctx; ec_trace("UPDATE", fop, "version=%ld/%ld, size=%ld, dirty=%ld/%ld", version[0], version[1], size, dirty[0], dirty[1]); dict = dict_new(); if (dict == NULL) { goto out; } /* If we don't have version information or it has been modified, we * update it. */ if (!ctx->have_version || (version[0] != 0) || (version[1] != 0)) { err = ec_dict_set_array(dict, EC_XATTR_VERSION, version, EC_VERSION_SIZE); if (err != 0) { goto out; } } if (size != 0) { /* If size has been changed, we should already * know the previous size of the file. */ GF_ASSERT(ctx->have_size); err = ec_dict_set_number(dict, EC_XATTR_SIZE, size); if (err != 0) { goto out; } } if (dirty[0] || dirty[1]) { err = ec_dict_set_array(dict, EC_XATTR_DIRTY, dirty, EC_VERSION_SIZE); if (err != 0) { goto out; } } /* If config information is not known, we request it now. */ if ((lock->loc.inode->ia_type == IA_IFREG) && !ctx->have_config) { /* A failure requesting this xattr is ignored because it's not * absolutely required right now. */ (void)ec_dict_set_number(dict, EC_XATTR_CONFIG, 0); } fop->frame->root->uid = 0; fop->frame->root->gid = 0; update_on = lock->good_mask | lock->healing; if (link->lock->fd == NULL) { ec_xattrop(fop->frame, fop->xl, update_on, EC_MINIMUM_MIN, ec_update_size_version_done, link, &link->lock->loc, GF_XATTROP_ADD_ARRAY64, dict, NULL); } else { ec_fxattrop(fop->frame, fop->xl, update_on, EC_MINIMUM_MIN, ec_update_size_version_done, link, link->lock->fd, GF_XATTROP_ADD_ARRAY64, dict, NULL); } fop->frame->root->uid = fop->uid; fop->frame->root->gid = fop->gid; dict_unref(dict); return; out: if (dict != NULL) { dict_unref(dict); } ec_fop_set_error(fop, -err); gf_msg(fop->xl->name, GF_LOG_ERROR, -err, EC_MSG_SIZE_VERS_UPDATE_FAIL, "Unable to update version and size. %s", ec_msg_str(fop)); if (lock->unlock_now) { ec_unlock_lock(fop->data); } } static gf_boolean_t ec_update_info(ec_lock_link_t *link) { ec_lock_t *lock; ec_inode_t *ctx; uint64_t version[2] = {0, 0}; uint64_t dirty[2] = {0, 0}; uint64_t size; ec_t *ec = NULL; uintptr_t mask; lock = link->lock; ctx = lock->ctx; ec = link->fop->xl->private; /* pre_version[*] will be 0 if have_version is false */ version[EC_DATA_TXN] = ctx->post_version[EC_DATA_TXN] - ctx->pre_version[EC_DATA_TXN]; version[EC_METADATA_TXN] = ctx->post_version[EC_METADATA_TXN] - ctx->pre_version[EC_METADATA_TXN]; size = ctx->post_size - ctx->pre_size; /* If we set the dirty flag for update fop, we have to unset it. * If fop has failed on some bricks, leave the dirty as marked. */ if (lock->unlock_now) { if (version[EC_DATA_TXN]) { /*A data fop will have difference in post and pre version *and for data fop we send writes on healing bricks also */ mask = lock->good_mask | lock->healing; } else { mask = lock->good_mask; } /* Ensure that nodes are up while doing final * metadata update.*/ if (!(ec->node_mask & ~(mask)) && !(ec->node_mask & ~ec->xl_up)) { if (ctx->dirty[EC_DATA_TXN] != 0) { dirty[EC_DATA_TXN] = -1; } if (ctx->dirty[EC_METADATA_TXN] != 0) { dirty[EC_METADATA_TXN] = -1; } /*If everything is fine and we already *have version xattr set on entry, there *is no need to update version again*/ if (ctx->pre_version[EC_DATA_TXN]) { version[EC_DATA_TXN] = 0; } if (ctx->pre_version[EC_METADATA_TXN]) { version[EC_METADATA_TXN] = 0; } } else { link->optimistic_changelog = _gf_false; ec_set_dirty_flag(link, ctx, dirty); } memset(ctx->dirty, 0, sizeof(ctx->dirty)); } if ((version[EC_DATA_TXN] != 0) || (version[EC_METADATA_TXN] != 0) || (dirty[EC_DATA_TXN] != 0) || (dirty[EC_METADATA_TXN] != 0)) { ec_update_size_version(link, version, size, dirty); return _gf_true; } return _gf_false; } static void ec_unlock_now(ec_lock_link_t *link) { ec_lock_t *lock; lock = link->lock; ec_trace("UNLOCK_NOW", link->fop, "lock=%p", link->lock); /*At this point, lock is not being used by any fop and *can not be reused by any fop as it is going to be released. *lock->unlock_now can not be modified at any other place. */ lock->unlock_now = _gf_true; if (!ec_update_info(link)) { ec_unlock_lock(link); } ec_resume(link->fop, 0); } void ec_lock_release(ec_t *ec, inode_t *inode) { ec_lock_t *lock; ec_inode_t *ctx; ec_lock_link_t *timer_link = NULL; LOCK(&inode->lock); ctx = __ec_inode_get(inode, ec->xl); if (ctx == NULL) { goto done; } lock = ctx->inode_lock; if ((lock == NULL) || lock->release) { goto done; } gf_msg_debug(ec->xl->name, 0, "Releasing inode %p due to lock contention", inode); if (!lock->acquired) { /* This happens if some bricks already got the lock while inodelk is in * progress. Set release to true after lock is acquired*/ lock->contention = _gf_true; goto done; } /* The lock is not marked to be released, so the frozen list should be * empty. */ GF_ASSERT(list_empty(&lock->frozen)); timer_link = ec_lock_timer_cancel(ec->xl, lock); /* We mark the lock to be released as soon as possible. */ lock->release = _gf_true; done: UNLOCK(&inode->lock); /* If we have cancelled the timer, we need to start the unlock of the * inode. If there was a timer but we have been unable to cancel it * because it was just triggered, the timer callback will take care * of releasing the inode. */ if (timer_link != NULL) { ec_unlock_now(timer_link); } } static void ec_unlock_timer_add(ec_lock_link_t *link); static void ec_unlock_timer_del(ec_lock_link_t *link) { ec_lock_t *lock; inode_t *inode; gf_boolean_t now = _gf_false; /* If we are here, it means that the timer has expired before having * been cancelled. This guarantees that 'link' is still valid because * the fop that contains it must be pending (if timer cancellation in * ec_lock_assign_owner() fails, the fop is left sleeping). * * At the same time, the fop still has a reference to the lock, so * it must also be valid. */ lock = link->lock; /* 'lock' must have a valid inode since it can only be destroyed * when the lock itself is destroyed, but we have a reference to the * lock to avoid this. */ inode = lock->loc.inode; LOCK(&inode->lock); if (lock->timer != NULL) { ec_trace("UNLOCK_DELAYED", link->fop, "lock=%p", lock); /* The unlock timer has expired without anyone cancelling it. * This means that it shouldn't have any owner, and the waiting * and frozen lists should be empty. It must have only one * owner reference, but there can be fops being prepared * though. * */ GF_ASSERT(!lock->release && (lock->refs_owners == 1) && list_empty(&lock->owners) && list_empty(&lock->waiting) && list_empty(&lock->frozen)); gf_timer_call_cancel(link->fop->xl->ctx, lock->timer); lock->timer = NULL; /* Any fop being processed from now on, will need to wait * until the next unlock/lock cycle. */ lock->release = now = _gf_true; } UNLOCK(&inode->lock); if (now) { ec_unlock_now(link); } else { /* The timer has been cancelled just after firing it but before * getting here. This means that another fop has used the lock * and everything should be handled as if this callback were * have not been executed. However we still have an owner * reference. * * We need to release our reference. If this is not the last * reference (the most common case because another fop has * taken another ref) we only need to decrement the counter. * Otherwise we have been delayed enough so that the other fop * has had time to acquire the reference, do its operation and * release it. At the time of releasing it, the fop did found * that the ref counter was > 1 (our reference), so the delayed * unlock timer wasn't started. We need to start it again if we * are the last reference. * * ec_unlock_timer_add() handles both cases. */ ec_unlock_timer_add(link); /* We need to resume the fop that was waiting for the delayed * unlock. */ ec_resume(link->fop, 0); } } static void ec_unlock_timer_cbk(void *data) { ec_unlock_timer_del(data); } static gf_boolean_t ec_eager_lock_used(ec_t *ec, ec_fop_data_t *fop) { /* Fops with no locks at this point mean that they are sent as sub-fops * of other higher level fops. In this case we simply assume that the * parent fop will take correct care of the eager lock. */ if (fop->lock_count == 0) { return _gf_true; } /* We may have more than one lock, but this only happens in the rename * fop, and both locks will reference an inode of the same type (a * directory in this case), so we only need to check the first lock. */ if (fop->locks[0].lock->loc.inode->ia_type == IA_IFREG) { return ec->eager_lock; } return ec->other_eager_lock; } static uint32_t ec_eager_lock_timeout(ec_t *ec, ec_lock_t *lock) { if (lock->loc.inode->ia_type == IA_IFREG) { return ec->eager_lock_timeout; } return ec->other_eager_lock_timeout; } static gf_boolean_t ec_lock_delay_create(ec_lock_link_t *link) { struct timespec delay; ec_fop_data_t *fop = link->fop; ec_lock_t *lock = link->lock; delay.tv_sec = ec_eager_lock_timeout(fop->xl->private, lock); delay.tv_nsec = 0; lock->timer = gf_timer_call_after(fop->xl->ctx, delay, ec_unlock_timer_cbk, link); if (lock->timer == NULL) { gf_msg(fop->xl->name, GF_LOG_WARNING, ENOMEM, EC_MSG_UNLOCK_DELAY_FAILED, "Unable to delay an unlock"); return _gf_false; } return _gf_true; } static void ec_unlock_timer_add(ec_lock_link_t *link) { ec_fop_data_t *fop = link->fop; ec_lock_t *lock = link->lock; gf_boolean_t now = _gf_false; ec_t *ec = fop->xl->private; LOCK(&lock->loc.inode->lock); /* We are trying to unlock the lock. We can have multiple scenarios here, * but all of them need to have lock->timer == NULL: * * 1. There are other owners currently running that can call ec_unlock(). * * None of them can have started the timer until the last one. But this * call should be the consequence of this lastest one. * * 2. There are fops in the waiting or frozen lists. * * These fops cannot call ec_unlock(). So we should be here. * * We must reach here with at least one owner reference. */ GF_ASSERT((lock->timer == NULL) && (lock->refs_owners > 0)); /* If the fop detects that a heal is needed, we mark the lock to be * released as soon as possible. */ lock->release |= ec_fop_needs_heal(ec, fop); if (lock->refs_owners > 1) { ec_trace("UNLOCK_SKIP", fop, "lock=%p", lock); /* If there are other owners we cannot do anything else with the lock. * Note that the current fop has already been removed from the owners * list in ec_lock_reuse(). */ lock->refs_owners--; UNLOCK(&lock->loc.inode->lock); } else if (lock->acquired) { /* There are no other owners and the lock is acquired. If there were * fops waiting, at least one of them should have been promoted to an * owner, so the waiting list should be empty. */ GF_ASSERT(list_empty(&lock->owners) && list_empty(&lock->waiting)); /* If everything goes as expected this fop will be put to sleep until * the timer callback is executed. */ ec_sleep(fop); /* If the lock needs to be released, or ec is shutting down, do not * delay lock release. */ if (!lock->release && !ec->shutdown) { ec_trace("UNLOCK_DELAY", fop, "lock=%p, release=%d", lock, lock->release); if (!ec_lock_delay_create(link)) { /* We are unable to create a new timer. We immediately release * the lock. */ lock->release = now = _gf_true; } } else { ec_trace("UNLOCK_FORCE", fop, "lock=%p, release=%d", lock, lock->release); lock->release = now = _gf_true; } UNLOCK(&lock->loc.inode->lock); if (now) { ec_unlock_now(link); } } else { /* There are no owners and the lock is not acquired. This can only * happen if a lock attempt has failed and we get to the unlock step * of the fop. As in the previous case, the waiting list must be * empty. */ GF_ASSERT(list_empty(&lock->owners) && list_empty(&lock->waiting)); /* We need to mark the lock to be released to correctly handle fops * that may get in after we release the inode mutex but before * ec_lock_unfreeze() is processed. */ lock->release = _gf_true; UNLOCK(&lock->loc.inode->lock); ec_lock_unfreeze(link); } } void ec_unlock(ec_fop_data_t *fop) { int32_t i; for (i = 0; i < fop->lock_count; i++) { ec_unlock_timer_add(&fop->locks[i]); } } void ec_flush_size_version(ec_fop_data_t *fop) { GF_ASSERT(fop->lock_count == 1); ec_update_info(&fop->locks[0]); } static void ec_update_stripe(ec_t *ec, ec_stripe_list_t *stripe_cache, ec_stripe_t *stripe, ec_fop_data_t *fop) { off_t base; /* On write fops, we only update existing fragments if the write has * succeeded. Otherwise, we remove them from the cache. */ if ((fop->id == GF_FOP_WRITE) && (fop->answer != NULL) && (fop->answer->op_ret >= 0)) { base = stripe->frag_offset - fop->frag_range.first; base *= ec->fragments; /* We check if the stripe offset falls inside the real region * modified by the write fop (a write request is allowed, * though uncommon, to write less bytes than requested). The * current write fop implementation doesn't allow partial * writes of fragments, so if there's no error, we are sure * that a full stripe has been completely modified or not * touched at all. The value of op_ret may not be a multiple * of the stripe size because it depends on the requested * size by the user, so we update the stripe if the write has * modified at least one byte (meaning ec has written the full * stripe). */ if (base < fop->answer->op_ret + fop->head) { memcpy(stripe->data, fop->vector[0].iov_base + base, ec->stripe_size); list_move_tail(&stripe->lru, &stripe_cache->lru); GF_ATOMIC_INC(ec->stats.stripe_cache.updates); } } else { stripe->frag_offset = -1; list_move(&stripe->lru, &stripe_cache->lru); GF_ATOMIC_INC(ec->stats.stripe_cache.invals); } } static void ec_update_cached_stripes(ec_fop_data_t *fop) { uint64_t first; uint64_t last; ec_stripe_t *stripe = NULL; ec_inode_t *ctx = NULL; ec_stripe_list_t *stripe_cache = NULL; inode_t *inode = NULL; struct list_head *temp; struct list_head sentinel; first = fop->frag_range.first; /* 'last' represents the first stripe not touched by the operation */ last = fop->frag_range.last; /* If there are no modified stripes, we don't need to do anything * else. */ if (last <= first) { return; } if (!fop->use_fd) { inode = fop->loc[0].inode; } else { inode = fop->fd->inode; } LOCK(&inode->lock); ctx = __ec_inode_get(inode, fop->xl); if (ctx == NULL) { goto out; } stripe_cache = &ctx->stripe_cache; /* Since we'll be moving elements of the list to the tail, we might * end in an infinite loop. To avoid it, we insert a sentinel element * into the list, so that it will be used to detect when we have * traversed all existing elements once. */ list_add_tail(&sentinel, &stripe_cache->lru); temp = stripe_cache->lru.next; while (temp != &sentinel) { stripe = list_entry(temp, ec_stripe_t, lru); temp = temp->next; if ((first <= stripe->frag_offset) && (stripe->frag_offset < last)) { ec_update_stripe(fop->xl->private, stripe_cache, stripe, fop); } } list_del(&sentinel); out: UNLOCK(&inode->lock); } void ec_lock_reuse(ec_fop_data_t *fop) { ec_cbk_data_t *cbk; ec_t *ec = NULL; int32_t i, count; gf_boolean_t release = _gf_false; ec = fop->xl->private; cbk = fop->answer; if (ec_eager_lock_used(ec, fop) && cbk != NULL) { if (cbk->xdata != NULL) { if ((dict_get_int32(cbk->xdata, GLUSTERFS_INODELK_COUNT, &count) == 0) && (count > 1)) { release = _gf_true; } if (release) { gf_msg_debug(fop->xl->name, 0, "Lock contention detected"); } } } else { /* If eager lock is disabled or if we haven't get * an answer with enough quorum, we always release * the lock. */ release = _gf_true; } ec_update_cached_stripes(fop); for (i = 0; i < fop->lock_count; i++) { ec_lock_next_owner(&fop->locks[i], cbk, release); } } static void __ec_manager(ec_fop_data_t *fop, int32_t error) { ec_t *ec = fop->xl->private; do { ec_trace("MANAGER", fop, "error=%d", error); if (!ec_must_wind(fop)) { if (ec->xl_up_count < ec->fragments) { error = ENOTCONN; } } if (error != 0) { fop->error = error; fop->state = -fop->state; } if ((fop->state == EC_STATE_END) || (fop->state == -EC_STATE_END)) { ec_fop_data_release(fop); break; } /* At each state, fop must not be used anywhere else and there * shouldn't be any pending subfop going on. */ GF_ASSERT(fop->jobs == 0); /* While the manager is running we need to avoid that subfops launched * from it could finish and call ec_resume() before the fop->handler * has completed. This could lead to the same manager being executed * by two threads concurrently. ec_check_complete() will take care of * this reference. */ fop->jobs = 1; fop->state = fop->handler(fop, fop->state); GF_ASSERT(fop->state >= 0); error = ec_check_complete(fop, __ec_manager); } while (error >= 0); } void ec_manager(ec_fop_data_t *fop, int32_t error) { GF_ASSERT(fop->jobs == 0); GF_ASSERT(fop->winds == 0); GF_ASSERT(fop->error == 0); if (fop->state == EC_STATE_START) { fop->state = EC_STATE_INIT; } __ec_manager(fop, error); } gf_boolean_t __ec_is_last_fop(ec_t *ec) { if ((list_empty(&ec->pending_fops)) && (GF_ATOMIC_GET(ec->async_fop_count) == 0)) { return _gf_true; } return _gf_false; } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code.c0000644000000000000000000000013214522202451022356 xustar000000000000000030 mtime=1699284265.634027332 30 atime=1699284265.633027329 30 ctime=1699284301.340134879 glusterfs-11.1/xlators/cluster/ec/src/ec-code.c0000664000175100017510000006337714522202451022655 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include "ec-mem-types.h" #include "ec-code.h" #include "ec-messages.h" #include "ec-code-c.h" #include "ec-helpers.h" #ifdef USE_EC_DYNAMIC_X64 #include "ec-code-x64.h" #endif #ifdef USE_EC_DYNAMIC_SSE #include "ec-code-sse.h" #endif #ifdef USE_EC_DYNAMIC_AVX #include "ec-code-avx.h" #endif #define EC_CODE_SIZE (1024 * 64) #define EC_CODE_ALIGN 4096 #define EC_CODE_CHUNK_MIN_SIZE 512 #define EC_PROC_BUFFER_SIZE 4096 #define PROC_CPUINFO "/proc/cpuinfo" struct _ec_code_proc; typedef struct _ec_code_proc ec_code_proc_t; struct _ec_code_proc { int32_t fd; gf_boolean_t eof; gf_boolean_t error; gf_boolean_t skip; ssize_t size; ssize_t pos; char buffer[EC_PROC_BUFFER_SIZE]; }; static ec_code_gen_t *ec_code_gen_table[] = { #ifdef USE_EC_DYNAMIC_AVX &ec_code_gen_avx, #endif #ifdef USE_EC_DYNAMIC_SSE &ec_code_gen_sse, #endif #ifdef USE_EC_DYNAMIC_X64 &ec_code_gen_x64, #endif NULL}; static void ec_code_arg_set(ec_code_arg_t *arg, uint32_t value) { arg->value = value; } static void ec_code_arg_assign(ec_code_builder_t *builder, ec_code_op_t *op, ec_code_arg_t *arg, uint32_t reg) { arg->value = reg; if (builder->regs <= reg) { builder->regs = reg + 1; } } static void ec_code_arg_use(ec_code_builder_t *builder, ec_code_op_t *op, ec_code_arg_t *arg, uint32_t reg) { arg->value = reg; } static void ec_code_arg_update(ec_code_builder_t *builder, ec_code_op_t *op, ec_code_arg_t *arg, uint32_t reg) { arg->value = reg; } static ec_code_op_t * ec_code_op_next(ec_code_builder_t *builder) { ec_code_op_t *op; op = &builder->ops[builder->count++]; memset(op, 0, sizeof(ec_code_op_t)); return op; } static void ec_code_load(ec_code_builder_t *builder, uint32_t bit, uint32_t offset) { ec_code_op_t *op; op = ec_code_op_next(builder); op->op = EC_GF_OP_LOAD; ec_code_arg_assign(builder, op, &op->arg1, builder->map[bit]); ec_code_arg_set(&op->arg2, offset); ec_code_arg_set(&op->arg3, bit); } static void ec_code_store(ec_code_builder_t *builder, uint32_t reg, uint32_t bit) { ec_code_op_t *op; op = ec_code_op_next(builder); op->op = EC_GF_OP_STORE; ec_code_arg_use(builder, op, &op->arg1, builder->map[reg]); ec_code_arg_set(&op->arg2, 0); ec_code_arg_set(&op->arg3, bit); } static void ec_code_copy(ec_code_builder_t *builder, uint32_t dst, uint32_t src) { ec_code_op_t *op; op = ec_code_op_next(builder); op->op = EC_GF_OP_COPY; ec_code_arg_assign(builder, op, &op->arg1, builder->map[dst]); ec_code_arg_use(builder, op, &op->arg2, builder->map[src]); ec_code_arg_set(&op->arg3, 0); } static void ec_code_xor2(ec_code_builder_t *builder, uint32_t dst, uint32_t src) { ec_code_op_t *op; op = ec_code_op_next(builder); op->op = EC_GF_OP_XOR2; ec_code_arg_update(builder, op, &op->arg1, builder->map[dst]); ec_code_arg_use(builder, op, &op->arg2, builder->map[src]); ec_code_arg_set(&op->arg3, 0); } static void ec_code_xor3(ec_code_builder_t *builder, uint32_t dst, uint32_t src1, uint32_t src2) { ec_code_op_t *op; if (builder->code->gen->xor3 == NULL) { ec_code_copy(builder, dst, src1); ec_code_xor2(builder, dst, src2); return; } op = ec_code_op_next(builder); op->op = EC_GF_OP_XOR3; ec_code_arg_assign(builder, op, &op->arg1, builder->map[dst]); ec_code_arg_use(builder, op, &op->arg2, builder->map[src1]); ec_code_arg_use(builder, op, &op->arg3, builder->map[src2]); } static void ec_code_xorm(ec_code_builder_t *builder, uint32_t bit, uint32_t offset) { ec_code_op_t *op; op = ec_code_op_next(builder); op->op = EC_GF_OP_XORM; ec_code_arg_update(builder, op, &op->arg1, builder->map[bit]); ec_code_arg_set(&op->arg2, offset); ec_code_arg_set(&op->arg3, bit); } static void ec_code_dup(ec_code_builder_t *builder, ec_gf_op_t *op) { switch (op->op) { case EC_GF_OP_COPY: ec_code_copy(builder, op->arg1, op->arg2); break; case EC_GF_OP_XOR2: ec_code_xor2(builder, op->arg1, op->arg2); break; case EC_GF_OP_XOR3: ec_code_xor3(builder, op->arg1, op->arg2, op->arg3); break; default: break; } } static void ec_code_gf_load(ec_code_builder_t *builder, uint32_t offset) { uint32_t i; for (i = 0; i < builder->code->gf->bits; i++) { ec_code_load(builder, i, offset); } } static void ec_code_gf_load_xor(ec_code_builder_t *builder, uint32_t offset) { uint32_t i; for (i = 0; i < builder->code->gf->bits; i++) { ec_code_xorm(builder, i, offset); } } static void ec_code_gf_store(ec_code_builder_t *builder) { uint32_t i; for (i = 0; i < builder->code->gf->bits; i++) { ec_code_store(builder, i, i); } } static void ec_code_gf_clear(ec_code_builder_t *builder) { uint32_t i; ec_code_xor2(builder, 0, 0); for (i = 0; i < builder->code->gf->bits; i++) { ec_code_store(builder, 0, i); } } static void ec_code_gf_mul(ec_code_builder_t *builder, uint32_t value) { ec_gf_mul_t *mul; ec_gf_op_t *op; uint32_t map[EC_GF_MAX_REGS]; int32_t i; mul = builder->code->gf->table[value]; for (op = mul->ops; op->op != EC_GF_OP_END; op++) { ec_code_dup(builder, op); } for (i = 0; i < mul->regs; i++) { map[i] = builder->map[mul->map[i]]; } memcpy(builder->map, map, sizeof(uint32_t) * mul->regs); } static ec_code_builder_t * ec_code_prepare(ec_code_t *code, uint32_t count, uint32_t width, gf_boolean_t linear) { ec_code_builder_t *builder; uint32_t i; count *= code->gf->bits + code->gf->max_ops; count += code->gf->bits; builder = GF_MALLOC( sizeof(ec_code_builder_t) + sizeof(ec_code_op_t) * count, ec_mt_ec_code_builder_t); if (builder == NULL) { return EC_ERR(ENOMEM); } builder->address = 0; builder->code = code; builder->size = 0; builder->count = 0; builder->regs = 0; builder->error = 0; builder->bits = code->gf->bits; builder->width = width; builder->data = NULL; builder->linear = linear; builder->base = -1; for (i = 0; i < EC_GF_MAX_REGS; i++) { builder->map[i] = i; } return builder; } static size_t ec_code_space_size(void) { return (sizeof(ec_code_space_t) + 15) & ~15; } static size_t ec_code_chunk_size(void) { return (sizeof(ec_code_chunk_t) + 15) & ~15; } static ec_code_chunk_t * ec_code_chunk_from_space(ec_code_space_t *space) { return (ec_code_chunk_t *)((uintptr_t)space + ec_code_space_size()); } static void * ec_code_to_executable(ec_code_space_t *space, void *addr) { return (void *)((uintptr_t)addr - (uintptr_t)space + (uintptr_t)space->exec); } static void * ec_code_from_executable(ec_code_space_t *space, void *addr) { return (void *)((uintptr_t)addr - (uintptr_t)space->exec + (uintptr_t)space); } static void * ec_code_func_from_chunk(ec_code_chunk_t *chunk, void **exec) { void *addr; addr = (void *)((uintptr_t)chunk + ec_code_chunk_size()); *exec = ec_code_to_executable(chunk->space, addr); return addr; } static ec_code_chunk_t * ec_code_chunk_from_func(ec_code_func_linear_t func) { ec_code_chunk_t *chunk; chunk = (ec_code_chunk_t *)((uintptr_t)func - ec_code_chunk_size()); return ec_code_from_executable(chunk->space, chunk); } static ec_code_chunk_t * ec_code_chunk_split(ec_code_chunk_t *chunk, size_t size) { ec_code_chunk_t *extra; ssize_t avail; avail = chunk->size - size - ec_code_chunk_size(); if (avail > 0) { extra = (ec_code_chunk_t *)((uintptr_t)chunk + chunk->size - avail); extra->space = chunk->space; extra->size = avail; list_add(&extra->list, &chunk->list); chunk->size = size; } list_del_init(&chunk->list); return chunk; } static gf_boolean_t ec_code_chunk_touch(ec_code_chunk_t *prev, ec_code_chunk_t *next) { uintptr_t end; end = (uintptr_t)prev + ec_code_chunk_size() + prev->size; return (end == (uintptr_t)next); } static ec_code_space_t * ec_code_space_create(ec_code_t *code, size_t size) { char path[] = GLUSTERFS_LIBEXECDIR "/ec-code-dynamic.XXXXXX"; ec_code_space_t *space; void *exec; int32_t fd, err; /* We need to create memory areas to store the generated dynamic code. * Obviously these areas need to be written to be able to create the * code and they also need to be executable to execute it. * * However it's a bad practice to have a memory region that is both * writable *and* executable. In fact, selinux forbids this and causes * attempts to do so to fail (unless specifically configured). * * To solve the problem we'll use two distinct memory areas mapped to * the same physical storage. One of the memory areas will have write * permission, and the other will have execute permission. Both areas * will have the same contents. The physical storage will be a regular * file that will be mmapped to both areas. */ /* We need to create a temporary file as the backend storage for the * memory mapped areas. */ /* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */ fd = mkstemp(path); if (fd < 0) { err = errno; gf_msg(THIS->name, GF_LOG_ERROR, err, EC_MSG_DYN_CREATE_FAILED, "Unable to create a temporary file for the ec dynamic " "code"); space = EC_ERR(err); goto done; } /* Once created we don't need to keep it in the file system. It will * still exist until we close the last file descriptor or unmap the * memory areas bound to the file. */ sys_unlink(path); size = (size + EC_CODE_ALIGN - 1) & ~(EC_CODE_ALIGN - 1); if (sys_ftruncate(fd, size) < 0) { err = errno; gf_msg(THIS->name, GF_LOG_ERROR, err, EC_MSG_DYN_CREATE_FAILED, "Unable to resize the file for the ec dynamic code"); space = EC_ERR(err); goto done_close; } /* This creates an executable memory area to be able to run the * generated fragments of code. */ exec = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); if (exec == MAP_FAILED) { err = errno; gf_msg(THIS->name, GF_LOG_ERROR, err, EC_MSG_DYN_CREATE_FAILED, "Unable to map the executable area for the ec dynamic " "code"); space = EC_ERR(err); goto done_close; } /* It's not important to check the return value of mlock(). If it fails * everything will continue to work normally. */ mlock(exec, size); /* This maps a read/write memory area to be able to create the dynamici * code. */ space = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (space == MAP_FAILED) { err = errno; gf_msg(THIS->name, GF_LOG_ERROR, err, EC_MSG_DYN_CREATE_FAILED, "Unable to map the writable area for the ec dynamic " "code"); space = EC_ERR(err); munmap(exec, size); goto done_close; } space->exec = exec; space->size = size; space->code = code; list_add_tail(&space->list, &code->spaces); INIT_LIST_HEAD(&space->chunks); done_close: /* If everything has succeeded, we already have the memory areas * mapped. We don't need the file descriptor anymore because the * backend storage will be there until the mmap()'d regions are * unmapped. */ sys_close(fd); done: return space; } static void ec_code_space_destroy(ec_code_space_t *space) { list_del_init(&space->list); munmap(space->exec, space->size); munmap(space, space->size); } static void ec_code_chunk_merge(ec_code_chunk_t *chunk) { ec_code_chunk_t *item, *tmp; list_for_each_entry_safe(item, tmp, &chunk->space->chunks, list) { if ((uintptr_t)item > (uintptr_t)chunk) { list_add_tail(&chunk->list, &item->list); if (ec_code_chunk_touch(chunk, item)) { chunk->size += item->size + ec_code_chunk_size(); list_del_init(&item->list); } goto check; } if (ec_code_chunk_touch(item, chunk)) { item->size += chunk->size + ec_code_chunk_size(); list_del_init(&item->list); chunk = item; } } list_add_tail(&chunk->list, &chunk->space->chunks); check: if (chunk->size == chunk->space->size - ec_code_space_size() - ec_code_chunk_size()) { ec_code_space_destroy(chunk->space); } } static ec_code_chunk_t * ec_code_space_alloc(ec_code_t *code, size_t size) { ec_code_space_t *space; ec_code_chunk_t *chunk; size_t map_size; /* To minimize fragmentation, we only allocate chunks of sizes multiples * of EC_CODE_CHUNK_MIN_SIZE. */ size = ((size + ec_code_chunk_size() + EC_CODE_CHUNK_MIN_SIZE - 1) & ~(EC_CODE_CHUNK_MIN_SIZE - 1)) - ec_code_chunk_size(); list_for_each_entry(space, &code->spaces, list) { list_for_each_entry(chunk, &space->chunks, list) { if (chunk->size >= size) { goto out; } } } map_size = EC_CODE_SIZE - ec_code_space_size() - ec_code_chunk_size(); if (map_size < size) { map_size = size; } space = ec_code_space_create(code, map_size); if (EC_IS_ERR(space)) { return (ec_code_chunk_t *)space; } chunk = ec_code_chunk_from_space(space); chunk->size = map_size - ec_code_space_size() - ec_code_chunk_size(); list_add(&chunk->list, &space->chunks); out: chunk->space = space; return ec_code_chunk_split(chunk, size); } static ec_code_chunk_t * ec_code_alloc(ec_code_t *code, uint32_t size) { ec_code_chunk_t *chunk; LOCK(&code->lock); chunk = ec_code_space_alloc(code, size); UNLOCK(&code->lock); return chunk; } static void ec_code_free(ec_code_chunk_t *chunk) { gf_lock_t *lock; lock = &chunk->space->code->lock; LOCK(lock); ec_code_chunk_merge(chunk); UNLOCK(lock); } static int32_t ec_code_write(ec_code_builder_t *builder) { ec_code_gen_t *gen; ec_code_op_t *op; uint32_t i; builder->error = 0; builder->size = 0; builder->address = 0; builder->base = -1; gen = builder->code->gen; gen->prolog(builder); for (i = 0; i < builder->count; i++) { op = &builder->ops[i]; switch (op->op) { case EC_GF_OP_LOAD: gen->load(builder, op->arg1.value, op->arg2.value, op->arg3.value); break; case EC_GF_OP_STORE: gen->store(builder, op->arg1.value, op->arg3.value); break; case EC_GF_OP_COPY: gen->copy(builder, op->arg1.value, op->arg2.value); break; case EC_GF_OP_XOR2: gen->xor2(builder, op->arg1.value, op->arg2.value); break; case EC_GF_OP_XOR3: gen->xor3(builder, op->arg1.value, op->arg2.value, op->arg3.value); break; case EC_GF_OP_XORM: gen->xorm(builder, op->arg1.value, op->arg2.value, op->arg3.value); break; default: break; } } gen->epilog(builder); return builder->error; } static void * ec_code_compile(ec_code_builder_t *builder) { ec_code_chunk_t *chunk; void *func; int32_t err; err = ec_code_write(builder); if (err != 0) { return EC_ERR(err); } chunk = ec_code_alloc(builder->code, builder->size); if (EC_IS_ERR(chunk)) { return chunk; } builder->data = ec_code_func_from_chunk(chunk, &func); err = ec_code_write(builder); if (err != 0) { ec_code_free(chunk); return EC_ERR(err); } GF_FREE(builder); return func; } ec_code_t * ec_code_create(ec_gf_t *gf, ec_code_gen_t *gen) { ec_code_t *code; code = GF_MALLOC(sizeof(ec_code_t), ec_mt_ec_code_t); if (code == NULL) { return EC_ERR(ENOMEM); } memset(code, 0, sizeof(ec_code_t)); INIT_LIST_HEAD(&code->spaces); LOCK_INIT(&code->lock); code->gf = gf; code->gen = gen; return code; } void ec_code_destroy(ec_code_t *code) { if (!list_empty(&code->spaces)) { } LOCK_DESTROY(&code->lock); GF_FREE(code); } static uint32_t ec_code_value_next(uint32_t *values, uint32_t count, uint32_t *offset) { uint32_t i, next; next = 0; for (i = *offset + 1; i < count; i++) { next = values[i]; if (next != 0) { break; } } *offset = i; return next; } static void * ec_code_build_dynamic(ec_code_t *code, uint32_t width, uint32_t *values, uint32_t count, gf_boolean_t linear) { ec_code_builder_t *builder; uint32_t offset, val, next; builder = ec_code_prepare(code, count, width, linear); if (EC_IS_ERR(builder)) { return builder; } offset = -1; next = ec_code_value_next(values, count, &offset); if (next != 0) { ec_code_gf_load(builder, offset); do { val = next; next = ec_code_value_next(values, count, &offset); if (next != 0) { ec_code_gf_mul(builder, ec_gf_div(code->gf, val, next)); ec_code_gf_load_xor(builder, offset); } } while (next != 0); ec_code_gf_mul(builder, val); ec_code_gf_store(builder); } else { ec_code_gf_clear(builder); } return ec_code_compile(builder); } static void * ec_code_build(ec_code_t *code, uint32_t width, uint32_t *values, uint32_t count, gf_boolean_t linear) { void *func; if (code->gen != NULL) { func = ec_code_build_dynamic(code, width, values, count, linear); if (!EC_IS_ERR(func)) { return func; } gf_msg_debug(THIS->name, GF_LOG_DEBUG, "Unable to generate dynamic code. Falling back " "to precompiled code"); /* The dynamic code generation shouldn't fail in normal * conditions, but if it fails at some point, it's very * probable that it will fail again, so we completely disable * dynamic code generation. */ code->gen = NULL; } ec_code_c_prepare(code->gf, values, count); if (linear) { return ec_code_c_linear; } return ec_code_c_interleaved; } ec_code_func_linear_t ec_code_build_linear(ec_code_t *code, uint32_t width, uint32_t *values, uint32_t count) { return (ec_code_func_linear_t)ec_code_build(code, width, values, count, _gf_true); } ec_code_func_interleaved_t ec_code_build_interleaved(ec_code_t *code, uint32_t width, uint32_t *values, uint32_t count) { return (ec_code_func_interleaved_t)ec_code_build(code, width, values, count, _gf_false); } void ec_code_release(ec_code_t *code, ec_code_func_t *func) { if ((func->linear != ec_code_c_linear) && (func->interleaved != ec_code_c_interleaved)) { ec_code_free(ec_code_chunk_from_func(func->linear)); } } void ec_code_error(ec_code_builder_t *builder, int32_t error) { if (builder->error == 0) { gf_msg(THIS->name, GF_LOG_ERROR, error, EC_MSG_DYN_CODEGEN_FAILED, "Failed to generate dynamic code"); builder->error = error; } } void ec_code_emit(ec_code_builder_t *builder, uint8_t *bytes, uint32_t count) { if (builder->error != 0) { return; } if (builder->data != NULL) { memcpy(builder->data + builder->size, bytes, count); } builder->size += count; builder->address += count; } static char * ec_code_proc_trim_left(char *text, ssize_t *length) { ssize_t len; for (len = *length; (len > 0) && isspace(*text); len--) { text++; } *length = len; return text; } static char * ec_code_proc_trim_right(char *text, ssize_t *length, char sep) { char *last; ssize_t len; len = *length; last = text; for (len = *length; (len > 0) && (*text != sep); len--) { if (!isspace(*text)) { last = text + 1; } text++; } *last = 0; *length = len; return text; } static char * ec_code_proc_line_parse(ec_code_proc_t *file, ssize_t *length) { char *text, *end; ssize_t len; len = file->size - file->pos; text = ec_code_proc_trim_left(file->buffer + file->pos, &len); end = ec_code_proc_trim_right(text, &len, '\n'); if (len == 0) { if (!file->eof) { if (text == file->buffer) { file->size = file->pos = 0; file->skip = _gf_true; } else { file->size = file->pos = end - text; memmove(file->buffer, text, file->pos + 1); } len = sys_read(file->fd, file->buffer + file->pos, sizeof(file->buffer) - file->pos - 1); if (len > 0) { file->size += len; } file->error = len < 0; file->eof = len <= 0; return NULL; } file->size = file->pos = 0; } else { file->pos = end - file->buffer + 1; } *length = end - text; if (file->skip) { file->skip = _gf_false; text = NULL; } return text; } static char * ec_code_proc_line(ec_code_proc_t *file, ssize_t *length) { char *text; text = NULL; while (!file->eof) { text = ec_code_proc_line_parse(file, length); if (text != NULL) { break; } } return text; } static char * ec_code_proc_split(char *text, ssize_t *length, char sep) { text = ec_code_proc_trim_right(text, length, sep); if (*length == 0) { return NULL; } (*length)--; text++; return ec_code_proc_trim_left(text, length); } static uint32_t ec_code_cpu_check(uint32_t idx, char *list, uint32_t count) { ec_code_gen_t *gen; char **ptr; char *table[count + 1]; uint32_t i; for (i = 0; i < count; i++) { table[i] = list; list += strlen(list) + 1; } gen = ec_code_gen_table[idx]; while (gen != NULL) { for (ptr = gen->flags; *ptr != NULL; ptr++) { for (i = 0; i < count; i++) { if (strcmp(*ptr, table[i]) == 0) { break; } } if (i >= count) { gen = ec_code_gen_table[++idx]; break; } } if (*ptr == NULL) { break; } } return idx; } ec_code_gen_t * ec_code_detect(xlator_t *xl, const char *def) { ec_code_proc_t file; ec_code_gen_t *gen = NULL; char *line, *data, *list; ssize_t length; uint32_t count, base, select; if (strcmp(def, "none") == 0) { gf_msg(xl->name, GF_LOG_INFO, 0, EC_MSG_EXTENSION_NONE, "Not using any cpu extensions"); return NULL; } file.fd = sys_open(PROC_CPUINFO, O_RDONLY, 0); if (file.fd < 0) { goto out; } file.size = file.pos = 0; file.eof = file.error = file.skip = _gf_false; select = 0; if (strcmp(def, "auto") != 0) { while (ec_code_gen_table[select] != NULL) { if (strcmp(ec_code_gen_table[select]->name, def) == 0) { break; } select++; } if (ec_code_gen_table[select] == NULL) { gf_msg(xl->name, GF_LOG_WARNING, EINVAL, EC_MSG_EXTENSION_UNKNOWN, "CPU extension '%s' is not known. Not using any cpu " "extensions", def); return NULL; } } else { def = NULL; } while ((line = ec_code_proc_line(&file, &length)) != NULL) { data = ec_code_proc_split(line, &length, ':'); if ((data != NULL) && (strcmp(line, "flags") == 0)) { list = data; count = 0; while ((data != NULL) && (*data != 0)) { count++; data = ec_code_proc_split(data, &length, ' '); } base = select; select = ec_code_cpu_check(select, list, count); if ((base != select) && (def != NULL)) { gf_msg(xl->name, GF_LOG_WARNING, ENOTSUP, EC_MSG_EXTENSION_UNSUPPORTED, "CPU extension '%s' is not supported", def); def = NULL; } } } if (file.error) { gf_msg(xl->name, GF_LOG_WARNING, 0, EC_MSG_EXTENSION_FAILED, "Unable to determine supported CPU extensions. Not using any " "cpu extensions"); gen = NULL; } else { gen = ec_code_gen_table[select]; if (gen == NULL) { gf_msg(xl->name, GF_LOG_INFO, 0, EC_MSG_EXTENSION_NONE, "Not using any cpu extensions"); } else { gf_msg(xl->name, GF_LOG_INFO, 0, EC_MSG_EXTENSION, "Using '%s' CPU extensions", gen->name); } } sys_close(file.fd); out: return gen; } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-sse.c0000644000000000000000000000013214522202451023146 xustar000000000000000030 mtime=1699284265.633027329 30 atime=1699284265.633027329 30 ctime=1699284301.351134912 glusterfs-11.1/xlators/cluster/ec/src/ec-code-sse.c0000664000175100017510000000637114522202451023434 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "ec-code-intel.h" static void ec_code_sse_prolog(ec_code_builder_t *builder) { builder->loop = builder->address; } static void ec_code_sse_epilog(ec_code_builder_t *builder) { ec_code_intel_op_add_i2r(builder, 16, REG_DX); ec_code_intel_op_add_i2r(builder, 16, REG_DI); ec_code_intel_op_test_i2r(builder, builder->width - 1, REG_DX); ec_code_intel_op_jne(builder, builder->loop); ec_code_intel_op_ret(builder, 0); } static void ec_code_sse_load(ec_code_builder_t *builder, uint32_t dst, uint32_t idx, uint32_t bit) { if (builder->linear) { ec_code_intel_op_mov_m2sse( builder, REG_SI, REG_DX, 1, idx * builder->width * builder->bits + bit * builder->width, dst); } else { if (builder->base != idx) { ec_code_intel_op_mov_m2r(builder, REG_SI, REG_NULL, 0, idx * 8, REG_AX); builder->base = idx; } ec_code_intel_op_mov_m2sse(builder, REG_AX, REG_DX, 1, bit * builder->width, dst); } } static void ec_code_sse_store(ec_code_builder_t *builder, uint32_t src, uint32_t bit) { ec_code_intel_op_mov_sse2m(builder, src, REG_DI, REG_NULL, 0, bit * builder->width); } static void ec_code_sse_copy(ec_code_builder_t *builder, uint32_t dst, uint32_t src) { ec_code_intel_op_mov_sse2sse(builder, src, dst); } static void ec_code_sse_xor2(ec_code_builder_t *builder, uint32_t dst, uint32_t src) { ec_code_intel_op_xor_sse2sse(builder, src, dst); } static void ec_code_sse_xorm(ec_code_builder_t *builder, uint32_t dst, uint32_t idx, uint32_t bit) { if (builder->linear) { ec_code_intel_op_xor_m2sse( builder, REG_SI, REG_DX, 1, idx * builder->width * builder->bits + bit * builder->width, dst); } else { if (builder->base != idx) { ec_code_intel_op_mov_m2r(builder, REG_SI, REG_NULL, 0, idx * 8, REG_AX); builder->base = idx; } ec_code_intel_op_xor_m2sse(builder, REG_AX, REG_DX, 1, bit * builder->width, dst); } } static char *ec_code_sse_needed_flags[] = {"sse2", NULL}; ec_code_gen_t ec_code_gen_sse = {.name = "sse", .flags = ec_code_sse_needed_flags, .width = 16, .prolog = ec_code_sse_prolog, .epilog = ec_code_sse_epilog, .load = ec_code_sse_load, .store = ec_code_sse_store, .copy = ec_code_sse_copy, .xor2 = ec_code_sse_xor2, .xor3 = NULL, .xorm = ec_code_sse_xorm}; glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-sse.h0000644000000000000000000000013114522202451023152 xustar000000000000000030 mtime=1699284265.633027329 30 atime=1699284265.633027329 29 ctime=1699284301.37713499 glusterfs-11.1/xlators/cluster/ec/src/ec-code-sse.h0000664000175100017510000000077214522202451023440 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_CODE_SSE_H__ #define __EC_CODE_SSE_H__ #include "ec-code.h" extern ec_code_gen_t ec_code_gen_sse; #endif /* __EC_CODE_SSE_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-inode-write.c0000644000000000000000000000013214522202451023672 xustar000000000000000030 mtime=1699284265.641027354 30 atime=1699284265.641027354 30 ctime=1699284301.335134864 glusterfs-11.1/xlators/cluster/ec/src/ec-inode-write.c0000664000175100017510000021170414522202451024156 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "ec-messages.h" #include "ec-helpers.h" #include "ec-common.h" #include "ec-combine.h" #include "ec-method.h" #include "ec-fops.h" #include "ec-mem-types.h" int32_t ec_update_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { ec_fop_data_t *fop = cookie; ec_cbk_data_t *cbk = NULL; ec_fop_data_t *parent = fop->parent; int i = 0; ec_trace("UPDATE_WRITEV_CBK", cookie, "ret=%d, errno=%d, parent-fop=%s", op_ret, op_errno, ec_fop_name(parent->id)); if (op_ret < 0) { ec_fop_set_error(parent, op_errno); goto out; } cbk = ec_cbk_data_allocate(parent->frame, this, parent, parent->id, 0, op_ret, op_errno); if (!cbk) { ec_fop_set_error(parent, ENOMEM); goto out; } if (xdata) cbk->xdata = dict_ref(xdata); if (prebuf) cbk->iatt[i++] = *prebuf; if (postbuf) cbk->iatt[i++] = *postbuf; LOCK(&parent->lock); { parent->good &= fop->good; if (gf_bits_count(parent->good) < parent->minimum) { __ec_fop_set_error(parent, EIO); } else if (fop->error == 0 && parent->answer == NULL) { parent->answer = cbk; } } UNLOCK(&parent->lock); out: return 0; } static int32_t ec_update_write(ec_fop_data_t *fop, uintptr_t mask, off_t offset, uint64_t size) { struct iobref *iobref = NULL; struct iobuf *iobuf = NULL; struct iovec vector; int32_t err = -ENOMEM; iobref = iobref_new(); if (iobref == NULL) { goto out; } iobuf = iobuf_get(fop->xl->ctx->iobuf_pool); if (iobuf == NULL) { goto out; } err = iobref_add(iobref, iobuf); if (err != 0) { goto out; } if (fop->locks[0].lock) ec_lock_update_good(fop->locks[0].lock, fop); vector.iov_base = iobuf->ptr; vector.iov_len = size; memset(vector.iov_base, 0, vector.iov_len); ec_writev(fop->frame, fop->xl, mask, fop->minimum, ec_update_writev_cbk, NULL, fop->fd, &vector, 1, offset, 0, iobref, NULL); err = 0; out: if (iobuf != NULL) { iobuf_unref(iobuf); } if (iobref != NULL) { iobref_unref(iobref); } return err; } int ec_inode_write_cbk(call_frame_t *frame, xlator_t *this, void *cookie, int op_ret, int op_errno, struct iatt *prestat, struct iatt *poststat, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int i = 0; int idx = 0; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; idx = (int32_t)(uintptr_t)cookie; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, fop->id, idx, op_ret, op_errno); if (!cbk) goto out; if (op_ret < 0) goto out; if (xdata) cbk->xdata = dict_ref(xdata); if (prestat) cbk->iatt[i++] = *prestat; if (poststat) cbk->iatt[i++] = *poststat; out: if (cbk) ec_combine(cbk, ec_combine_write); if (fop) ec_complete(fop); return 0; } /* FOP: removexattr */ int32_t ec_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, NULL, NULL, xdata); } void ec_wind_removexattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_removexattr_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->removexattr, &fop->loc[0], fop->str[0], fop->xdata); } void ec_xattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = cookie; switch (fop->id) { case GF_FOP_SETXATTR: if (fop->cbks.setxattr) { QUORUM_CBK(fop->cbks.setxattr, fop, frame, cookie, this, op_ret, op_errno, xdata); } break; case GF_FOP_REMOVEXATTR: if (fop->cbks.removexattr) { QUORUM_CBK(fop->cbks.removexattr, fop, frame, cookie, this, op_ret, op_errno, xdata); } break; case GF_FOP_FSETXATTR: if (fop->cbks.fsetxattr) { QUORUM_CBK(fop->cbks.fsetxattr, fop, frame, cookie, this, op_ret, op_errno, xdata); } break; case GF_FOP_FREMOVEXATTR: if (fop->cbks.fremovexattr) { QUORUM_CBK(fop->cbks.fremovexattr, fop, frame, cookie, this, op_ret, op_errno, xdata); } break; } } int32_t ec_manager_xattr(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: if (fop->fd == NULL) { ec_lock_prepare_inode(fop, &fop->loc[0], EC_UPDATE_META | EC_QUERY_INFO, 0, EC_RANGE_FULL); } else { ec_lock_prepare_fd(fop, fop->fd, EC_UPDATE_META | EC_QUERY_INFO, 0, EC_RANGE_FULL); } ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: ec_fop_prepare_answer(fop, _gf_false); return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); ec_xattr_cbk(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); ec_xattr_cbk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_removexattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_removexattr_cbk_t func, void *data, loc_t *loc, const char *name, dict_t *xdata) { ec_cbk_t callback = {.removexattr = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(REMOVEXATTR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_REMOVEXATTR, 0, target, fop_flags, ec_wind_removexattr, ec_manager_xattr, callback, data); if (fop == NULL) { goto out; } if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (name != NULL) { fop->str[0] = gf_strdup(name); if (fop->str[0] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: fremovexattr */ int32_t ec_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, NULL, NULL, xdata); } void ec_wind_fremovexattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_fremovexattr_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fremovexattr, fop->fd, fop->str[0], fop->xdata); } void ec_fremovexattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fremovexattr_cbk_t func, void *data, fd_t *fd, const char *name, dict_t *xdata) { ec_cbk_t callback = {.fremovexattr = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FREMOVEXATTR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FREMOVEXATTR, 0, target, fop_flags, ec_wind_fremovexattr, ec_manager_xattr, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (name != NULL) { fop->str[0] = gf_strdup(name); if (fop->str[0] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: setattr */ int32_t ec_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prestat, struct iatt *poststat, dict_t *xdata) { return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, prestat, poststat, xdata); } void ec_wind_setattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_setattr_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->setattr, &fop->loc[0], &fop->iatt, fop->int32, fop->xdata); } int32_t ec_manager_setattr(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: if (fop->fd == NULL) { ec_lock_prepare_inode(fop, &fop->loc[0], EC_UPDATE_META | EC_QUERY_INFO, 0, EC_RANGE_FULL); } else { ec_lock_prepare_fd(fop, fop->fd, EC_UPDATE_META | EC_QUERY_INFO, 0, EC_RANGE_FULL); } ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { if (cbk->iatt[0].ia_type == IA_IFREG) { ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2, cbk->count); /* This shouldn't fail because we have the inode locked. */ GF_ASSERT(ec_get_inode_size(fop, fop->locks[0].lock->loc.inode, &cbk->iatt[0].ia_size)); cbk->iatt[1].ia_size = cbk->iatt[0].ia_size; } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->id == GF_FOP_SETATTR) { if (fop->cbks.setattr != NULL) { QUORUM_CBK(fop->cbks.setattr, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } } else { if (fop->cbks.fsetattr != NULL) { QUORUM_CBK(fop->cbks.fsetattr, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->id == GF_FOP_SETATTR) { if (fop->cbks.setattr != NULL) { fop->cbks.setattr(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } } else { if (fop->cbks.fsetattr != NULL) { fop->cbks.fsetattr(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_setattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_setattr_cbk_t func, void *data, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { ec_cbk_t callback = {.setattr = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(SETATTR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_SETATTR, 0, target, fop_flags, ec_wind_setattr, ec_manager_setattr, callback, data); if (fop == NULL) { goto out; } fop->int32 = valid; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (stbuf != NULL) { fop->iatt = *stbuf; } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } /* FOP: fsetattr */ int32_t ec_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prestat, struct iatt *poststat, dict_t *xdata) { return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, prestat, poststat, xdata); } void ec_wind_fsetattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_fsetattr_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fsetattr, fop->fd, &fop->iatt, fop->int32, fop->xdata); } void ec_fsetattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fsetattr_cbk_t func, void *data, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { ec_cbk_t callback = {.fsetattr = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FSETATTR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FSETATTR, 0, target, fop_flags, ec_wind_fsetattr, ec_manager_setattr, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->int32 = valid; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (stbuf != NULL) { fop->iatt = *stbuf; } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } /* FOP: setxattr */ int32_t ec_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, NULL, NULL, xdata); } void ec_wind_setxattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_setxattr_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->setxattr, &fop->loc[0], fop->dict, fop->int32, fop->xdata); } void ec_setxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_setxattr_cbk_t func, void *data, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { ec_cbk_t callback = {.setxattr = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(SETXATTR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_SETXATTR, 0, target, fop_flags, ec_wind_setxattr, ec_manager_xattr, callback, data); if (fop == NULL) { goto out; } fop->int32 = flags; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (dict != NULL) { fop->dict = dict_copy_with_ref(dict, NULL); if (fop->dict == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_t *ec = fop->xl->private; int64_t val = 0; int ret = dict_get_int64(fop->dict, SQUOTA_LIMIT_KEY, &val); if (IS_SUCCESS(ret)) { /* divide the total usage to priv->fragments */ int64_t new_value = val / ec->fragments; ret = dict_set_int64(fop->dict, SQUOTA_LIMIT_KEY, new_value); if (IS_ERROR(ret)) { /* Add a debug log */ gf_msg(ec->xl->name, GF_LOG_DEBUG, ENOMEM, EC_MSG_DICT_REF_FAIL, "Failed to update the simple-quota limit"); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: fsetxattr */ int32_t ec_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSETXATTR, idx, op_ret, op_errno); if (cbk != NULL) { if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_fsetxattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_fsetxattr_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fsetxattr, fop->fd, fop->dict, fop->int32, fop->xdata); } void ec_fsetxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fsetxattr_cbk_t func, void *data, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { ec_cbk_t callback = {.fsetxattr = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FSETXATTR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FSETXATTR, 0, target, fop_flags, ec_wind_fsetxattr, ec_manager_xattr, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->int32 = flags; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (dict != NULL) { fop->dict = dict_copy_with_ref(dict, NULL); if (fop->dict == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /********************************************************************* * * File Operation : fallocate * *********************************************************************/ int32_t ec_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, prebuf, postbuf, xdata); } void ec_wind_fallocate(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_fallocate_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fallocate, fop->fd, fop->int32, fop->offset, fop->size, fop->xdata); } int32_t ec_manager_fallocate(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk = NULL; switch (state) { case EC_STATE_INIT: if (fop->size == 0) { ec_fop_set_error(fop, EINVAL); return EC_STATE_REPORT; } if (fop->int32 & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE | FALLOC_FL_ZERO_RANGE | FALLOC_FL_PUNCH_HOLE)) { ec_fop_set_error(fop, ENOTSUP); return EC_STATE_REPORT; } fop->user_size = fop->offset + fop->size; fop->head = ec_adjust_offset_down(fop->xl->private, &fop->offset, _gf_true); fop->size += fop->head; ec_adjust_size_up(fop->xl->private, &fop->size, _gf_true); /* Fall through */ case EC_STATE_LOCK: ec_lock_prepare_fd(fop, fop->fd, EC_UPDATE_DATA | EC_UPDATE_META | EC_QUERY_INFO, fop->offset, fop->size); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2, cbk->count); /* This shouldn't fail because we have the inode locked. */ LOCK(&fop->locks[0].lock->loc.inode->lock); { GF_ASSERT(__ec_get_inode_size(fop, fop->locks[0].lock->loc.inode, &cbk->iatt[0].ia_size)); /*If mode has FALLOC_FL_KEEP_SIZE keep the size */ if (fop->int32 & FALLOC_FL_KEEP_SIZE) { cbk->iatt[1].ia_size = cbk->iatt[0].ia_size; } else if (fop->user_size > cbk->iatt[0].ia_size) { cbk->iatt[1].ia_size = fop->user_size; /* This shouldn't fail because we have the inode * locked. */ GF_ASSERT(__ec_set_inode_size( fop, fop->locks[0].lock->loc.inode, cbk->iatt[1].ia_size)); } else { cbk->iatt[1].ia_size = cbk->iatt[0].ia_size; } } UNLOCK(&fop->locks[0].lock->loc.inode->lock); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.fallocate != NULL) { QUORUM_CBK(fop->cbks.fallocate, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.fallocate != NULL) { fop->cbks.fallocate(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_fallocate(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fallocate_cbk_t func, void *data, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { ec_cbk_t callback = {.fallocate = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FALLOCATE) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FALLOCATE, 0, target, fop_flags, ec_wind_fallocate, ec_manager_fallocate, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->int32 = mode; fop->offset = offset; fop->size = len; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } /********************************************************************* * * File Operation : Discard * *********************************************************************/ void ec_update_discard_write(ec_fop_data_t *fop, uintptr_t mask) { ec_t *ec = fop->xl->private; off_t off_head = 0; off_t off_tail = 0; uint64_t size_head = 0; uint64_t size_tail = 0; int error = 0; off_head = fop->offset * ec->fragments - fop->int32; if (fop->size == 0) { error = ec_update_write(fop, mask, off_head, fop->user_size); } else { size_head = fop->int32; size_tail = (off_head + fop->user_size) % ec->stripe_size; off_tail = off_head + fop->user_size - size_tail; if (size_head) { error = ec_update_write(fop, mask, off_head, size_head); if (error) { goto out; } } if (size_tail) { error = ec_update_write(fop, mask, off_tail, size_tail); } } out: if (error) ec_fop_set_error(fop, -error); } void ec_discard_adjust_offset_size(ec_fop_data_t *fop) { ec_t *ec = fop->xl->private; fop->user_size = fop->size; /* If discard length covers at least a fragment on brick, we will * perform discard operation(when fop->size is non-zero) else we just * write zeros. */ fop->int32 = ec_adjust_offset_up(ec, &fop->offset, _gf_true); fop->frag_range.first = fop->offset; if (fop->size < fop->int32) { fop->size = 0; } else { fop->size -= fop->int32; ec_adjust_size_down(ec, &fop->size, _gf_true); } fop->frag_range.last = fop->offset + fop->size; } int32_t ec_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, prebuf, postbuf, xdata); } void ec_wind_discard(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_discard_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->discard, fop->fd, fop->offset, fop->size, fop->xdata); } int32_t ec_manager_discard(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk = NULL; off_t fl_start = 0; uint64_t fl_size = 0; switch (state) { case EC_STATE_INIT: if ((fop->size <= 0) || (fop->offset < 0)) { ec_fop_set_error(fop, EINVAL); return EC_STATE_REPORT; } /* Because of the head/tail writes, "discard" happens on the * remaining regions, but we need to compute region including * head/tail writes so compute them separately*/ fl_start = fop->offset; fl_size = fop->size; fl_size += ec_adjust_offset_down(fop->xl->private, &fl_start, _gf_true); ec_adjust_size_up(fop->xl->private, &fl_size, _gf_true); ec_discard_adjust_offset_size(fop); /* Fall through */ case EC_STATE_LOCK: ec_lock_prepare_fd(fop, fop->fd, EC_UPDATE_DATA | EC_UPDATE_META | EC_QUERY_INFO, fl_start, fl_size); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: /* Dispatch discard fop only if we have whole fragment * to deallocate */ if (fop->size) { ec_dispatch_all(fop); return EC_STATE_DELAYED_START; } else { /* Assume discard to have succeeded on all bricks */ ec_succeed_all(fop); } /* Fall through */ case EC_STATE_DELAYED_START: if (fop->size) { if (fop->answer && fop->answer->op_ret == 0) ec_update_discard_write(fop, fop->answer->mask); } else { ec_update_discard_write(fop, fop->mask); } return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2, cbk->count); /* This shouldn't fail because we have the inode locked. */ GF_ASSERT(ec_get_inode_size(fop, fop->locks[0].lock->loc.inode, &cbk->iatt[0].ia_size)); cbk->iatt[1].ia_size = cbk->iatt[0].ia_size; } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.discard != NULL) { QUORUM_CBK(fop->cbks.discard, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_DELAYED_START: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.discard != NULL) { fop->cbks.discard(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_discard(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_discard_cbk_t func, void *data, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { ec_cbk_t callback = {.discard = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(DISCARD) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_DISCARD, 0, target, fop_flags, ec_wind_discard, ec_manager_discard, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->offset = offset; fop->size = len; if (fd != NULL) { fop->fd = fd_ref(fd); } if (xdata != NULL) { fop->xdata = dict_ref(xdata); } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } /********************************************************************* * * File Operation : truncate * *********************************************************************/ int32_t ec_update_truncate_write(ec_fop_data_t *fop, uintptr_t mask) { ec_t *ec = fop->xl->private; uint64_t size = fop->offset * ec->fragments - fop->user_size; return ec_update_write(fop, mask, fop->user_size, size); } int32_t ec_truncate_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { ec_fop_data_t *fop = cookie; int32_t err; fop->parent->good &= fop->good; if (op_ret >= 0) { fd_bind(fd); err = ec_update_truncate_write(fop->parent, fop->answer->mask); if (err != 0) { ec_fop_set_error(fop->parent, -err); } } return 0; } int32_t ec_truncate_clean(ec_fop_data_t *fop) { if (fop->fd == NULL) { fop->fd = fd_create(fop->loc[0].inode, fop->frame->root->pid); if (fop->fd == NULL) { return -ENOMEM; } ec_open(fop->frame, fop->xl, fop->answer->mask, fop->minimum, ec_truncate_open_cbk, fop, &fop->loc[0], O_RDWR, fop->fd, NULL); return 0; } else { return ec_update_truncate_write(fop, fop->answer->mask); } } int32_t ec_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prestat, struct iatt *poststat, dict_t *xdata) { return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, prestat, poststat, xdata); } void ec_wind_truncate(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_truncate_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->truncate, &fop->loc[0], fop->offset, fop->xdata); } int32_t ec_manager_truncate(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; off_t offset_down; switch (state) { case EC_STATE_INIT: fop->user_size = fop->offset; ec_adjust_offset_up(fop->xl->private, &fop->offset, _gf_true); fop->frag_range.first = fop->offset; fop->frag_range.last = UINT64_MAX; /* Fall through */ case EC_STATE_LOCK: offset_down = fop->user_size; ec_adjust_offset_down(fop->xl->private, &offset_down, _gf_true); if (fop->id == GF_FOP_TRUNCATE) { ec_lock_prepare_inode( fop, &fop->loc[0], EC_UPDATE_DATA | EC_UPDATE_META | EC_QUERY_INFO, offset_down, EC_RANGE_FULL); } else { ec_lock_prepare_fd( fop, fop->fd, EC_UPDATE_DATA | EC_UPDATE_META | EC_QUERY_INFO, offset_down, EC_RANGE_FULL); } ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { int32_t err; ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2, cbk->count); /* This shouldn't fail because we have the inode locked. */ /* Inode size doesn't need to be updated under locks, because * conflicting operations won't be in-flight */ GF_ASSERT(ec_get_inode_size(fop, fop->locks[0].lock->loc.inode, &cbk->iatt[0].ia_size)); cbk->iatt[1].ia_size = fop->user_size; /* This shouldn't fail because we have the inode locked. */ GF_ASSERT(ec_set_inode_size(fop, fop->locks[0].lock->loc.inode, fop->user_size)); if ((cbk->iatt[0].ia_size > cbk->iatt[1].ia_size) && (fop->user_size != fop->offset)) { err = ec_truncate_clean(fop); if (err != 0) { ec_cbk_set_error(cbk, -err, _gf_false); } } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->id == GF_FOP_TRUNCATE) { if (fop->cbks.truncate != NULL) { QUORUM_CBK(fop->cbks.truncate, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } } else { if (fop->cbks.ftruncate != NULL) { QUORUM_CBK(fop->cbks.ftruncate, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->id == GF_FOP_TRUNCATE) { if (fop->cbks.truncate != NULL) { fop->cbks.truncate(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } } else { if (fop->cbks.ftruncate != NULL) { fop->cbks.ftruncate(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_truncate(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_truncate_cbk_t func, void *data, loc_t *loc, off_t offset, dict_t *xdata) { ec_cbk_t callback = {.truncate = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(TRUNCATE) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_TRUNCATE, 0, target, fop_flags, ec_wind_truncate, ec_manager_truncate, callback, data); if (fop == NULL) { goto out; } fop->offset = offset; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } /* FOP: ftruncate */ int32_t ec_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prestat, struct iatt *poststat, dict_t *xdata) { return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, prestat, poststat, xdata); } void ec_wind_ftruncate(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_ftruncate_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->ftruncate, fop->fd, fop->offset, fop->xdata); } void ec_ftruncate(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_ftruncate_cbk_t func, void *data, fd_t *fd, off_t offset, dict_t *xdata) { ec_cbk_t callback = {.ftruncate = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FTRUNCATE) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FTRUNCATE, 0, target, fop_flags, ec_wind_ftruncate, ec_manager_truncate, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->offset = offset; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } /* FOP: writev */ static ec_stripe_t * ec_allocate_stripe(ec_t *ec, ec_stripe_list_t *stripe_cache) { ec_stripe_t *stripe = NULL; if (stripe_cache->count >= stripe_cache->max) { GF_ASSERT(!list_empty(&stripe_cache->lru)); stripe = list_first_entry(&stripe_cache->lru, ec_stripe_t, lru); list_move_tail(&stripe->lru, &stripe_cache->lru); GF_ATOMIC_INC(ec->stats.stripe_cache.evicts); } else { stripe = GF_MALLOC(sizeof(ec_stripe_t) + ec->stripe_size, ec_mt_ec_stripe_t); if (stripe != NULL) { stripe_cache->count++; list_add_tail(&stripe->lru, &stripe_cache->lru); GF_ATOMIC_INC(ec->stats.stripe_cache.allocs); } else { GF_ATOMIC_INC(ec->stats.stripe_cache.errors); } } return stripe; } static void ec_write_stripe_data(ec_t *ec, ec_fop_data_t *fop, ec_stripe_t *stripe) { off_t base; base = fop->size - ec->stripe_size; memcpy(stripe->data, fop->vector[0].iov_base + base, ec->stripe_size); stripe->frag_offset = fop->frag_range.last - ec->fragment_size; } static void ec_add_stripe_in_cache(ec_t *ec, ec_fop_data_t *fop) { ec_inode_t *ctx = NULL; ec_stripe_t *stripe = NULL; ec_stripe_list_t *stripe_cache = NULL; gf_boolean_t failed = _gf_true; LOCK(&fop->fd->inode->lock); ctx = __ec_inode_get(fop->fd->inode, fop->xl); if (ctx == NULL) { goto out; } stripe_cache = &ctx->stripe_cache; if (stripe_cache->max > 0) { stripe = ec_allocate_stripe(ec, stripe_cache); if (stripe == NULL) { goto out; } ec_write_stripe_data(ec, fop, stripe); } failed = _gf_false; out: UNLOCK(&fop->fd->inode->lock); if (failed) { gf_msg(ec->xl->name, GF_LOG_DEBUG, ENOMEM, EC_MSG_FILE_DESC_REF_FAIL, "Failed to create and add stripe in cache"); } } int32_t ec_writev_merge_tail(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { ec_t *ec = this->private; ec_fop_data_t *fop = frame->local; uint64_t size, base, tmp; if (op_ret >= 0) { tmp = 0; size = fop->size - fop->user_size - fop->head; base = ec->stripe_size - size; if (op_ret > base) { tmp = min(op_ret - base, size); ec_iov_copy_to(fop->vector[0].iov_base + fop->size - size, vector, count, base, tmp); size -= tmp; } if (size > 0) { memset(fop->vector[0].iov_base + fop->size - size, 0, size); } if (ec->stripe_cache) { ec_add_stripe_in_cache(ec, fop); } } return 0; } int32_t ec_writev_merge_head(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { ec_t *ec = this->private; ec_fop_data_t *fop = frame->local; uint64_t size, base; if (op_ret >= 0) { size = fop->head; base = 0; if (op_ret > 0) { base = min(op_ret, size); ec_iov_copy_to(fop->vector[0].iov_base, vector, count, 0, base); size -= base; } if (size > 0) { memset(fop->vector[0].iov_base + base, 0, size); } size = fop->size - fop->user_size - fop->head; if ((size > 0) && (fop->size == ec->stripe_size)) { ec_writev_merge_tail(frame, cookie, this, op_ret, op_errno, vector, count, stbuf, iobref, xdata); } } return 0; } static int ec_make_internal_fop_xdata(dict_t **xdata) { dict_t *dict = NULL; if (*xdata) return 0; dict = dict_new(); if (!dict) goto out; if (dict_set_str(dict, GLUSTERFS_INTERNAL_FOP_KEY, "yes")) goto out; *xdata = dict; return 0; out: if (dict) dict_unref(dict); return -1; } static int32_t ec_writev_prepare_buffers(ec_t *ec, ec_fop_data_t *fop) { struct iobref *iobref = NULL; struct iovec *iov; void *ptr; int32_t err; fop->user_size = iov_length(fop->vector, fop->int32); fop->head = ec_adjust_offset_down(ec, &fop->offset, _gf_false); fop->frag_range.first = fop->offset / ec->fragments; fop->size = fop->user_size + fop->head; ec_adjust_size_up(ec, &fop->size, _gf_false); fop->frag_range.last = fop->frag_range.first + fop->size / ec->fragments; if ((fop->int32 != 1) || (fop->head != 0) || (fop->size > fop->user_size) || !EC_ALIGN_CHECK(fop->vector[0].iov_base, EC_METHOD_WORD_SIZE)) { err = ec_buffer_alloc(ec->xl, fop->size, &iobref, &ptr); if (err != 0) { goto out; } ec_iov_copy_to(ptr + fop->head, fop->vector, fop->int32, 0, fop->user_size); fop->vector[0].iov_base = ptr; fop->vector[0].iov_len = fop->size; iobref_unref(fop->buffers); fop->buffers = iobref; } if (fop->int32 != 2) { iov = GF_MALLOC(VECTORSIZE(2), gf_common_mt_iovec); if (iov == NULL) { err = -ENOMEM; goto out; } iov[0].iov_base = fop->vector[0].iov_base; iov[0].iov_len = fop->vector[0].iov_len; GF_FREE(fop->vector); fop->vector = iov; } fop->vector[1].iov_len = fop->size / ec->fragments; err = ec_buffer_alloc(ec->xl, fop->vector[1].iov_len * ec->nodes, &fop->buffers, &fop->vector[1].iov_base); if (err != 0) { goto out; } err = 0; out: return err; } static void ec_merge_stripe_head_locked(ec_t *ec, ec_fop_data_t *fop, ec_stripe_t *stripe) { uint32_t head, size; head = fop->head; memcpy(fop->vector[0].iov_base, stripe->data, head); size = ec->stripe_size - head; if (size > fop->user_size) { head += fop->user_size; size = ec->stripe_size - head; memcpy(fop->vector[0].iov_base + head, stripe->data + head, size); } } static void ec_merge_stripe_tail_locked(ec_t *ec, ec_fop_data_t *fop, ec_stripe_t *stripe) { uint32_t head, tail; off_t offset; offset = fop->user_size + fop->head; tail = fop->size - offset; head = ec->stripe_size - tail; memcpy(fop->vector[0].iov_base + offset, stripe->data + head, tail); } static ec_stripe_t * ec_get_stripe_from_cache_locked(ec_t *ec, ec_fop_data_t *fop, uint64_t frag_offset) { ec_inode_t *ctx = NULL; ec_stripe_t *stripe = NULL; ec_stripe_list_t *stripe_cache = NULL; ctx = __ec_inode_get(fop->fd->inode, fop->xl); if (ctx == NULL) { GF_ATOMIC_INC(ec->stats.stripe_cache.errors); return NULL; } stripe_cache = &ctx->stripe_cache; list_for_each_entry(stripe, &stripe_cache->lru, lru) { if (stripe->frag_offset == frag_offset) { list_move_tail(&stripe->lru, &stripe_cache->lru); GF_ATOMIC_INC(ec->stats.stripe_cache.hits); return stripe; } } GF_ATOMIC_INC(ec->stats.stripe_cache.misses); return NULL; } static gf_boolean_t ec_get_and_merge_stripe(ec_t *ec, ec_fop_data_t *fop, ec_stripe_part_t which) { uint64_t frag_offset; ec_stripe_t *stripe = NULL; gf_boolean_t found = _gf_false; if (!ec->stripe_cache) { return found; } LOCK(&fop->fd->inode->lock); if (which == EC_STRIPE_HEAD) { frag_offset = fop->frag_range.first; stripe = ec_get_stripe_from_cache_locked(ec, fop, frag_offset); if (stripe) { ec_merge_stripe_head_locked(ec, fop, stripe); found = _gf_true; } } if (which == EC_STRIPE_TAIL) { frag_offset = fop->frag_range.last - ec->fragment_size; stripe = ec_get_stripe_from_cache_locked(ec, fop, frag_offset); if (stripe) { ec_merge_stripe_tail_locked(ec, fop, stripe); found = _gf_true; } } UNLOCK(&fop->fd->inode->lock); return found; } static uintptr_t ec_get_lock_good_mask(inode_t *inode, xlator_t *xl) { ec_lock_t *lock = NULL; ec_inode_t *ictx = NULL; LOCK(&inode->lock); { ictx = __ec_inode_get(inode, xl); if (ictx) lock = ictx->inode_lock; } UNLOCK(&inode->lock); if (lock) return lock->good_mask; return 0; } void ec_writev_start(ec_fop_data_t *fop) { ec_t *ec = fop->xl->private; ec_fd_t *ctx; fd_t *fd; dict_t *xdata = NULL; uint64_t tail, current; int32_t err = -ENOMEM; gf_boolean_t found_stripe = _gf_false; /* This shouldn't fail because we have the inode locked. */ GF_ASSERT(ec_get_inode_size(fop, fop->fd->inode, ¤t)); fd = fd_anonymous(fop->fd->inode); if (fd == NULL) { goto failed; } fop->frame->root->uid = 0; fop->frame->root->gid = 0; ctx = ec_fd_get(fop->fd, fop->xl); if (ctx != NULL) { if ((ctx->flags & O_APPEND) != 0) { /* Appending writes take full locks so size won't change because * of any parallel operations */ fop->offset = current; } } err = ec_writev_prepare_buffers(ec, fop); if (err != 0) { goto failed_fd; } tail = fop->size - fop->user_size - fop->head; if (fop->head > 0) { if (current > fop->offset) { found_stripe = ec_get_and_merge_stripe(ec, fop, EC_STRIPE_HEAD); if (!found_stripe) { if (ec_make_internal_fop_xdata(&xdata)) { err = -ENOMEM; goto failed_xdata; } ec_readv(fop->frame, fop->xl, ec_get_lock_good_mask(fop->fd->inode, fop->xl), EC_MINIMUM_MIN, ec_writev_merge_head, NULL, fd, ec->stripe_size, fop->offset, 0, xdata); } } else { memset(fop->vector[0].iov_base, 0, fop->head); memset(fop->vector[0].iov_base + fop->size - tail, 0, tail); if (ec->stripe_cache && (fop->size <= ec->stripe_size)) { ec_add_stripe_in_cache(ec, fop); } } } if ((tail > 0) && ((fop->head == 0) || (fop->size > ec->stripe_size))) { /* Current locking scheme will make sure the 'current' below will * never decrease while the fop is in progress, so the checks will * work as expected */ if (current > fop->offset + fop->head + fop->user_size) { found_stripe = ec_get_and_merge_stripe(ec, fop, EC_STRIPE_TAIL); if (!found_stripe) { if (ec_make_internal_fop_xdata(&xdata)) { err = -ENOMEM; goto failed_xdata; } ec_readv(fop->frame, fop->xl, ec_get_lock_good_mask(fop->fd->inode, fop->xl), EC_MINIMUM_MIN, ec_writev_merge_tail, NULL, fd, ec->stripe_size, fop->offset + fop->size - ec->stripe_size, 0, xdata); } } else { memset(fop->vector[0].iov_base + fop->size - tail, 0, tail); if (ec->stripe_cache) { ec_add_stripe_in_cache(ec, fop); } } } err = 0; failed_xdata: if (xdata) { dict_unref(xdata); } failed_fd: fd_unref(fd); failed: ec_fop_set_error(fop, -err); } int32_t ec_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prestat, struct iatt *poststat, dict_t *xdata) { ec_t *ec = NULL; if (this && this->private) { ec = this->private; if ((op_ret > 0) && ((op_ret % ec->fragment_size) != 0)) { op_ret = -1; op_errno = EIO; } } return ec_inode_write_cbk(frame, this, cookie, op_ret, op_errno, prestat, poststat, xdata); } void ec_wind_writev(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); struct iovec vector[1]; size_t size; size = fop->vector[1].iov_len; vector[0].iov_base = fop->vector[1].iov_base + idx * size; vector[0].iov_len = size; STACK_WIND_COOKIE(fop->frame, ec_writev_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->writev, fop->fd, vector, 1, fop->offset / ec->fragments, fop->uint32, fop->buffers, fop->xdata); } static void ec_writev_encode(ec_fop_data_t *fop) { ec_t *ec = fop->xl->private; void *blocks[ec->nodes]; uint32_t i; blocks[0] = fop->vector[1].iov_base; for (i = 1; i < ec->nodes; i++) { blocks[i] = blocks[i - 1] + fop->vector[1].iov_len; } ec_method_encode(&ec->matrix, fop->vector[0].iov_len, fop->vector[0].iov_base, blocks); } int32_t ec_manager_writev(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; ec_fd_t *ctx = NULL; ec_t *ec = fop->xl->private; off_t fl_start = 0; uint64_t fl_size = LONG_MAX; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ctx = ec_fd_get(fop->fd, fop->xl); if (ctx != NULL) { if ((ctx->flags & O_APPEND) == 0) { off_t user_size = 0; off_t head = 0; fl_start = fop->offset; user_size = iov_length(fop->vector, fop->int32); head = ec_adjust_offset_down(ec, &fl_start, _gf_true); fl_size = user_size + head; ec_adjust_size_up(ec, &fl_size, _gf_true); } } ec_lock_prepare_fd(fop, fop->fd, EC_UPDATE_DATA | EC_UPDATE_META | EC_QUERY_INFO, fl_start, fl_size); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_writev_start(fop); return EC_STATE_DELAYED_START; case EC_STATE_DELAYED_START: /* Restore uid, gid if they were changed to do some partial * reads. */ fop->frame->root->uid = fop->uid; fop->frame->root->gid = fop->gid; ec_writev_encode(fop); ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { ec_t *ec = fop->xl->private; uint64_t size; ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2, cbk->count); /* This shouldn't fail because we have the inode locked. */ LOCK(&fop->fd->inode->lock); { GF_ASSERT(__ec_get_inode_size(fop, fop->fd->inode, &cbk->iatt[0].ia_size)); cbk->iatt[1].ia_size = cbk->iatt[0].ia_size; size = fop->offset + fop->head + fop->user_size; if (size > cbk->iatt[0].ia_size) { /* Only update inode size if this is a top level fop. * Otherwise this is an internal write and the top * level fop should take care of the real inode size. */ if (fop->parent == NULL) { /* This shouldn't fail because we have the inode * locked. */ GF_ASSERT( __ec_set_inode_size(fop, fop->fd->inode, size)); } cbk->iatt[1].ia_size = size; } } UNLOCK(&fop->fd->inode->lock); if (fop->error == 0) { cbk->op_ret *= ec->fragments; if (cbk->op_ret < fop->head) { cbk->op_ret = 0; } else { cbk->op_ret -= fop->head; } if (cbk->op_ret > fop->user_size) { cbk->op_ret = fop->user_size; } } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.writev != NULL) { QUORUM_CBK(fop->cbks.writev, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_DELAYED_START: /* We have failed while doing partial reads. We need to restore * original uid, gid. */ fop->frame->root->uid = fop->uid; fop->frame->root->gid = fop->gid; /* Fall through */ case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.writev != NULL) { fop->cbks.writev(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_writev(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_writev_cbk_t func, void *data, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { ec_cbk_t callback = {.writev = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(WRITE) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_WRITE, 0, target, fop_flags, ec_wind_writev, ec_manager_writev, callback, data); if (fop == NULL) { goto out; } fop->int32 = count; fop->offset = offset; fop->uint32 = flags; fop->use_fd = 1; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (count > 0) { fop->vector = iov_dup(vector, count); if (fop->vector == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a " "vector list."); goto out; } fop->int32 = count; } if (iobref != NULL) { fop->buffers = iobref_ref(iobref); if (fop->buffers == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_BUF_REF_FAIL, "Failed to reference a " "buffer."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-x64.h0000644000000000000000000000013214522202451023002 xustar000000000000000030 mtime=1699284265.633027329 30 atime=1699284265.633027329 30 ctime=1699284301.376134987 glusterfs-11.1/xlators/cluster/ec/src/ec-code-x64.h0000664000175100017510000000077214522202451023267 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_CODE_X64_H__ #define __EC_CODE_X64_H__ #include "ec-code.h" extern ec_code_gen_t ec_code_gen_x64; #endif /* __EC_CODE_X64_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-c.c0000644000000000000000000000013214522202451022576 xustar000000000000000030 mtime=1699284265.632027326 30 atime=1699284265.631027323 30 ctime=1699284301.342134884 glusterfs-11.1/xlators/cluster/ec/src/ec-code-c.c0000664000175100017510000126652514522202451023076 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "ec-method.h" #include "ec-code-c.h" #define WIDTH (EC_METHOD_WORD_SIZE / sizeof(uint64_t)) static void gf8_muladd_00(void *out, void *in) { memcpy(out, in, EC_METHOD_WORD_SIZE * 8); } static void gf8_muladd_01(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { out_ptr[0] ^= in_ptr[0]; out_ptr[WIDTH] ^= in_ptr[WIDTH]; out_ptr[WIDTH * 2] ^= in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] ^= in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] ^= in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] ^= in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] ^= in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] ^= in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_02(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in7; out1 = in0; out7 = in6; out5 = in4; out6 = in5; out3 = in2 ^ in7; out4 = in3 ^ in7; out2 = in1 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_03(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in0 ^ in7; tmp0 = in2 ^ in7; out1 = in0 ^ in1; out7 = in6 ^ in7; out5 = in4 ^ in5; out6 = in5 ^ in6; out4 = in3 ^ in4 ^ in7; out2 = tmp0 ^ in1; out3 = tmp0 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_04(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in6; out1 = in7; out7 = in5; out6 = in4; tmp0 = in6 ^ in7; out2 = in0 ^ in6; out5 = in3 ^ in7; out3 = tmp0 ^ in1; out4 = tmp0 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_05(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in0 ^ in6; out1 = in1 ^ in7; out7 = in5 ^ in7; out6 = in4 ^ in6; out2 = out0 ^ in2; out3 = out1 ^ in3 ^ in6; out5 = out7 ^ in3; out4 = out6 ^ in2 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_06(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in6 ^ in7; tmp0 = in1 ^ in6; out1 = in0 ^ in7; out7 = in5 ^ in6; out6 = in4 ^ in5; out4 = in2 ^ in3 ^ in6; out5 = in3 ^ in4 ^ in7; out3 = tmp0 ^ in2; out2 = tmp0 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_07(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in6; tmp1 = in5 ^ in6; tmp2 = in0 ^ in7; tmp3 = tmp0 ^ in3; out6 = tmp1 ^ in4; out7 = tmp1 ^ in7; out0 = tmp2 ^ in6; out1 = tmp2 ^ in1; out3 = tmp3 ^ in1; out4 = tmp3 ^ in4; out5 = out4 ^ out7 ^ in2; out2 = tmp0 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_08(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in5; out1 = in6; out7 = in4; out6 = in3 ^ in7; out3 = in0 ^ in5 ^ in6; out5 = in2 ^ in6 ^ in7; out2 = in5 ^ in7; out4 = out2 ^ in1 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_09(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in0 ^ in5; tmp0 = in3 ^ in6; out1 = in1 ^ in6; out7 = in4 ^ in7; out2 = in2 ^ in5 ^ in7; out3 = tmp0 ^ out0; out6 = tmp0 ^ in7; out4 = out1 ^ out7 ^ in5; out5 = out2 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_0A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in5 ^ in7; out1 = in0 ^ in6; out7 = in4 ^ in6; out2 = in1 ^ in5; out6 = out0 ^ in3; out3 = out0 ^ out1 ^ in2; out5 = out7 ^ in2 ^ in7; out4 = out2 ^ in3 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_0B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in5; tmp1 = in0 ^ in6; tmp2 = in4 ^ in7; out0 = in0 ^ in5 ^ in7; out2 = tmp0 ^ in1; out1 = tmp1 ^ in1; out6 = tmp1 ^ out0 ^ in3; out7 = tmp2 ^ in6; out4 = tmp2 ^ out6 ^ in1; out3 = out6 ^ in0 ^ in2; out5 = tmp0 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_0C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in5 ^ in6; out1 = in6 ^ in7; out7 = in4 ^ in5; tmp0 = in1 ^ in5; tmp1 = in0 ^ in7; out5 = in2 ^ in3 ^ in6; out6 = in3 ^ in4 ^ in7; out2 = tmp1 ^ out0; out4 = tmp0 ^ in2; out3 = tmp0 ^ tmp1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_0D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in4 ^ in5; tmp1 = in5 ^ in6; out1 = in1 ^ in6 ^ in7; out7 = tmp0 ^ in7; out4 = tmp0 ^ in1 ^ in2; out0 = tmp1 ^ in0; tmp2 = tmp1 ^ in3; out6 = tmp2 ^ out7; out2 = out0 ^ in2 ^ in7; out3 = out0 ^ out1 ^ in3; out5 = tmp2 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_0E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; tmp1 = in2 ^ in5; tmp2 = in5 ^ in6; out1 = in0 ^ in6 ^ in7; out3 = tmp0 ^ tmp1; out2 = tmp0 ^ tmp2; tmp3 = tmp1 ^ in3; out7 = tmp2 ^ in4; out0 = tmp2 ^ in7; out4 = tmp3 ^ in1 ^ in7; out5 = tmp3 ^ out7; out6 = out0 ^ out5 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_0F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in6 ^ in7; tmp1 = tmp0 ^ in1; tmp2 = tmp0 ^ in5; out1 = tmp1 ^ in0; out7 = tmp2 ^ in4; out0 = tmp2 ^ in0; out6 = out7 ^ in3; out5 = out6 ^ in2 ^ in7; tmp3 = tmp1 ^ out0 ^ in2; out4 = tmp1 ^ out5; out2 = tmp3 ^ in6; out3 = tmp3 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_10(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in4; out1 = in5; out7 = in3 ^ in7; tmp0 = in6 ^ in7; out2 = in4 ^ in6; tmp1 = out2 ^ in5; out6 = tmp0 ^ in2; out3 = tmp0 ^ tmp1; out5 = out2 ^ out3 ^ in1; out4 = tmp1 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_11(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out7 = in3; out0 = in0 ^ in4; out1 = in1 ^ in5; out6 = in2 ^ in7; out4 = in0 ^ in5 ^ in6; out5 = in1 ^ in6 ^ in7; out2 = in2 ^ in4 ^ in6; out3 = in3 ^ in4 ^ in5 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_12(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in4 ^ in7; out1 = in0 ^ in5; out3 = in2 ^ in4 ^ in5; tmp0 = out0 ^ in6; out2 = tmp0 ^ in1; tmp1 = tmp0 ^ in3; out6 = tmp0 ^ out3; out5 = out2 ^ in5; out7 = tmp1 ^ in4; out4 = tmp1 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_13(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out7 = in3 ^ in6; tmp0 = in0 ^ in5; tmp1 = in4 ^ in7; out6 = in2 ^ in5 ^ in7; out4 = tmp0 ^ out7 ^ in7; out1 = tmp0 ^ in1; out0 = tmp1 ^ in0; out5 = tmp1 ^ in1 ^ in6; out3 = tmp1 ^ out6 ^ in3; out2 = out5 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_14(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in4 ^ in6; out1 = in5 ^ in7; out2 = in0 ^ in4; tmp0 = out0 ^ in5; out7 = out1 ^ in3; tmp1 = out1 ^ in2; out3 = tmp0 ^ in1; out6 = tmp0 ^ tmp1; out4 = tmp1 ^ out2; out5 = out3 ^ in3 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_15(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out7 = in3 ^ in5; tmp0 = in0 ^ in4; out1 = in1 ^ in5 ^ in7; out5 = in1 ^ in3 ^ in6; out0 = tmp0 ^ in6; out2 = tmp0 ^ in2; out3 = out5 ^ in4 ^ in5; out6 = out2 ^ in0 ^ in7; out4 = tmp0 ^ out6 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_16(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in5; tmp1 = in4 ^ in7; tmp2 = in2 ^ in3 ^ in4; out1 = tmp0 ^ in7; out4 = tmp0 ^ tmp2; out0 = tmp1 ^ in6; tmp3 = tmp1 ^ in1; out6 = out0 ^ in2 ^ in5; out2 = tmp3 ^ in0; out3 = out6 ^ in1; out7 = tmp2 ^ out6; out5 = tmp3 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_17(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in5; tmp1 = in3 ^ in6; tmp2 = tmp0 ^ in4; out4 = tmp0 ^ in0 ^ in3; out7 = tmp1 ^ in5; tmp3 = tmp1 ^ in1; out6 = tmp2 ^ in7; out5 = tmp3 ^ in4; out3 = tmp3 ^ out6; out0 = out3 ^ out4 ^ in1; out2 = out3 ^ out7 ^ in0; out1 = tmp2 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_18(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in4 ^ in5; out1 = in5 ^ in6; tmp0 = in4 ^ in7; out5 = in1 ^ in2 ^ in5; out6 = in2 ^ in3 ^ in6; out2 = tmp0 ^ out1; out7 = tmp0 ^ in3; tmp1 = tmp0 ^ in0; out3 = tmp1 ^ in6; out4 = tmp1 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_19(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out5 = in1 ^ in2; out7 = in3 ^ in4; tmp0 = in0 ^ in7; out6 = in2 ^ in3; out1 = in1 ^ in5 ^ in6; out0 = in0 ^ in4 ^ in5; out4 = tmp0 ^ in1; tmp1 = tmp0 ^ in6; out2 = tmp1 ^ out0 ^ in2; out3 = tmp1 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_1A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in4 ^ in5; tmp1 = in5 ^ in6; tmp2 = tmp0 ^ in1; out0 = tmp0 ^ in7; out1 = tmp1 ^ in0; tmp3 = tmp1 ^ in3; out5 = tmp2 ^ in2; out2 = tmp2 ^ in6; out7 = tmp3 ^ out0; out6 = tmp3 ^ in2; out4 = tmp3 ^ out2 ^ in0; out3 = tmp0 ^ out1 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_1B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in4; tmp1 = in2 ^ in5; tmp2 = in3 ^ in6; out5 = tmp0 ^ in1; tmp3 = tmp0 ^ in0; out6 = tmp1 ^ in3; out0 = tmp1 ^ tmp3 ^ in7; out7 = tmp2 ^ in4; tmp4 = out5 ^ in6; out3 = tmp2 ^ tmp3; out2 = tmp4 ^ in5; out4 = tmp4 ^ out3; out1 = tmp3 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_1C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in3; tmp1 = in4 ^ in6; tmp2 = in5 ^ in7; out6 = tmp0 ^ tmp1; out0 = tmp1 ^ in5; out1 = tmp2 ^ in6; tmp3 = tmp2 ^ in1; tmp4 = tmp2 ^ in4; out2 = tmp4 ^ in0; out7 = tmp4 ^ in3; out5 = tmp0 ^ tmp3; out3 = tmp3 ^ out2; out4 = out3 ^ in2 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_1D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in3; tmp1 = in0 ^ in4; tmp2 = in3 ^ in4; tmp3 = in2 ^ in7; out3 = tmp0 ^ tmp1; out5 = tmp0 ^ tmp3; tmp4 = tmp1 ^ in5; out6 = tmp2 ^ in2; out7 = tmp2 ^ in5; out2 = tmp3 ^ tmp4; out4 = out3 ^ out6 ^ in6; out0 = tmp4 ^ in6; out1 = out2 ^ out4 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_1E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in4; tmp1 = in2 ^ in7; tmp2 = tmp0 ^ in1; out3 = tmp1 ^ tmp2; out2 = tmp2 ^ in5; out4 = out3 ^ in3 ^ in6; tmp3 = out4 ^ in7; out6 = tmp3 ^ out2 ^ in4; out7 = tmp1 ^ out6; out0 = out7 ^ in3; out1 = tmp0 ^ out0; out5 = tmp3 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_1F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in4 ^ in6; tmp1 = tmp0 ^ in5; out7 = tmp1 ^ in3; out0 = tmp1 ^ in0 ^ in7; out6 = out7 ^ in2 ^ in6; out1 = out0 ^ in1 ^ in4; out4 = out0 ^ out6 ^ in1; out3 = tmp0 ^ out4; out2 = out4 ^ out7 ^ in7; out5 = out3 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_20(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in4; out0 = in3 ^ in7; tmp0 = in3 ^ in4; tmp1 = in6 ^ in7; out2 = out0 ^ in5; out4 = tmp0 ^ in5; out3 = tmp0 ^ tmp1; out7 = tmp1 ^ in2; out6 = tmp1 ^ in1 ^ in5; out5 = out2 ^ out3 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_21(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in1 ^ in4; tmp0 = in4 ^ in6; out4 = in3 ^ in5; out7 = in2 ^ in6; out0 = in0 ^ in3 ^ in7; out6 = in1 ^ in5 ^ in7; out3 = tmp0 ^ in7; out5 = tmp0 ^ in0; out2 = out4 ^ in2 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_22(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in3; out1 = in0 ^ in4; out7 = in2 ^ in7; out4 = in4 ^ in5 ^ in7; out5 = in0 ^ in5 ^ in6; out6 = in1 ^ in6 ^ in7; out3 = in2 ^ in3 ^ in4 ^ in6; out2 = in1 ^ in3 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_23(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out7 = in2; out0 = in0 ^ in3; out4 = in5 ^ in7; out5 = in0 ^ in6; out6 = in1 ^ in7; out3 = in2 ^ in4 ^ in6; out1 = in0 ^ in1 ^ in4; out2 = out4 ^ out6 ^ in2 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_24(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in4 ^ in7; tmp0 = in3 ^ in4; out0 = in3 ^ in6 ^ in7; out3 = tmp0 ^ in1; tmp1 = out0 ^ in5; out6 = tmp1 ^ out3; out2 = tmp1 ^ in0; out7 = tmp1 ^ in2 ^ in3; out5 = out2 ^ in4; out4 = tmp0 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_25(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in1 ^ in4; tmp0 = in2 ^ in5; out1 = out3 ^ in7; out7 = tmp0 ^ in6; out6 = out1 ^ in5; out4 = out7 ^ in3 ^ in7; out2 = out4 ^ in0; out0 = tmp0 ^ out2; out5 = out0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_26(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in3 ^ in6; tmp0 = in4 ^ in7; out7 = in2 ^ in5 ^ in7; tmp1 = out0 ^ in0 ^ in5; out1 = tmp0 ^ in0; tmp2 = tmp0 ^ in6; out2 = tmp1 ^ in1; out5 = tmp1 ^ in7; out6 = tmp2 ^ in1; out4 = tmp2 ^ out7; out3 = out0 ^ out6 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_27(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out7 = in2 ^ in5; out0 = in0 ^ in3 ^ in6; out6 = in1 ^ in4 ^ in7; out4 = out7 ^ in6; out2 = out0 ^ out7 ^ in1; out5 = out0 ^ in7; out1 = out6 ^ in0; out3 = out6 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_28(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in3; out1 = in4 ^ in6; out0 = in3 ^ in5 ^ in7; tmp0 = out1 ^ in7; tmp1 = out0 ^ in4; out7 = tmp0 ^ in2; tmp2 = tmp0 ^ in1; out3 = tmp1 ^ in0; out6 = tmp1 ^ tmp2; out4 = tmp2 ^ in3; out5 = out3 ^ in2 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_29(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in2 ^ in3; tmp0 = in1 ^ in3; tmp1 = in4 ^ in6; tmp2 = in0 ^ in4 ^ in7; out6 = tmp0 ^ in5; out4 = tmp0 ^ in6 ^ in7; out1 = tmp1 ^ in1; out7 = tmp1 ^ in2; out3 = tmp2 ^ in5; out5 = tmp2 ^ in2; out0 = out3 ^ in3 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_2A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in3 ^ in5; tmp0 = in1 ^ in3; tmp1 = in0 ^ in4; out7 = in2 ^ in4 ^ in7; out3 = tmp1 ^ out0 ^ in2; out2 = tmp0 ^ in7; out6 = tmp0 ^ in6; out1 = tmp1 ^ in6; out5 = tmp1 ^ out7 ^ in5; out4 = out1 ^ in0 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_2B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in1 ^ in6; out7 = in2 ^ in4; tmp0 = in0 ^ in5; tmp1 = in2 ^ in7; out6 = in1 ^ in3; out1 = out4 ^ in0 ^ in4; out3 = tmp0 ^ out7; out0 = tmp0 ^ in3; out5 = tmp1 ^ in0; out2 = tmp1 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_2C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in5; tmp1 = in2 ^ in3 ^ in4; tmp2 = tmp0 ^ in6; out4 = tmp1 ^ in1; out5 = tmp1 ^ in0 ^ in5; tmp3 = tmp2 ^ in4; out6 = tmp2 ^ out4; out7 = tmp3 ^ in7; out2 = tmp3 ^ out5; out3 = out6 ^ in0; out0 = tmp1 ^ out7; out1 = tmp0 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_2D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in3; out4 = tmp0 ^ in1; tmp1 = tmp0 ^ in0; out2 = tmp1 ^ in6; out5 = tmp1 ^ in4; tmp2 = out2 ^ in2; tmp3 = tmp2 ^ in5; out0 = tmp3 ^ in7; out7 = tmp3 ^ out5; out6 = out4 ^ out7 ^ in6; out3 = tmp2 ^ out6; out1 = out0 ^ out6 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_2E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in4 ^ in7; out0 = in3 ^ in5 ^ in6; tmp1 = tmp0 ^ in0; tmp2 = tmp0 ^ in2; out1 = tmp1 ^ in6; out4 = tmp2 ^ in1; out7 = tmp2 ^ in5; out3 = out0 ^ out4 ^ in0; out2 = out3 ^ out7 ^ in7; out6 = tmp1 ^ out2; out5 = tmp1 ^ out7 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_2F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3; tmp1 = in2 ^ in5; out4 = in1 ^ in2 ^ in7; out6 = in1 ^ in3 ^ in4; out5 = tmp0 ^ in2; tmp2 = tmp0 ^ in6; out7 = tmp1 ^ in4; out0 = tmp2 ^ in5; out2 = tmp2 ^ out4; out1 = tmp2 ^ out6 ^ in7; out3 = tmp1 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_30(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in4 ^ in5; tmp0 = in3 ^ in6; tmp1 = in4 ^ in7; out6 = in1 ^ in2 ^ in5; out3 = tmp0 ^ in5; out4 = tmp0 ^ in0; out7 = tmp0 ^ in2; out0 = tmp1 ^ in3; out2 = tmp1 ^ out3; out5 = tmp1 ^ in0 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_31(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in5 ^ in6; tmp0 = in4 ^ in5; tmp1 = in0 ^ in3 ^ in4; tmp2 = out3 ^ in2; out1 = tmp0 ^ in1; out0 = tmp1 ^ in7; out4 = tmp1 ^ in6; out6 = tmp2 ^ in1; out2 = tmp2 ^ out0 ^ in0; out5 = out1 ^ in0 ^ in7; out7 = tmp0 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_32(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in3 ^ in4; out7 = in2 ^ in3; tmp0 = in5 ^ in6; tmp1 = in0 ^ in7; out6 = in1 ^ in2; out1 = in0 ^ in4 ^ in5; out2 = tmp0 ^ out0 ^ in1; out3 = tmp0 ^ out7 ^ in7; out4 = tmp1 ^ in6; out5 = tmp1 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_33(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in3; tmp1 = in0 ^ in4; tmp2 = in1 ^ in5; out6 = in1 ^ in2 ^ in6; out7 = tmp0 ^ in7; out0 = tmp1 ^ in3; out1 = tmp1 ^ tmp2; tmp3 = tmp2 ^ in7; tmp4 = tmp2 ^ in4 ^ in6; out5 = tmp3 ^ in0; out3 = tmp3 ^ out6; out4 = tmp4 ^ out5; out2 = tmp0 ^ tmp4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_34(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in4; tmp1 = in4 ^ in5; tmp2 = tmp0 ^ in1; tmp3 = tmp0 ^ in6; out1 = tmp1 ^ in7; tmp4 = tmp1 ^ in2; out5 = tmp2 ^ in0; out3 = tmp2 ^ out1; out0 = tmp3 ^ in7; out7 = tmp3 ^ tmp4; out6 = tmp4 ^ in1; out2 = out3 ^ out5 ^ in3; out4 = tmp4 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_35(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in6; tmp1 = in5 ^ in7; out7 = tmp0 ^ tmp1 ^ in3; out3 = tmp1 ^ in1; out1 = out3 ^ in4; tmp2 = out1 ^ in7; out5 = tmp2 ^ in0 ^ in3; out6 = tmp0 ^ tmp2; out0 = out3 ^ out5 ^ in6; out4 = tmp0 ^ out0; out2 = out4 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_36(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in0 ^ in2; tmp0 = in1 ^ in3; out0 = in3 ^ in4 ^ in6; out6 = in1 ^ in2 ^ in4; out5 = tmp0 ^ in0; tmp1 = out5 ^ in5; out2 = tmp1 ^ in4; out3 = tmp1 ^ out4; out1 = tmp0 ^ out2 ^ in7; out7 = out3 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_37(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in2; tmp1 = in2 ^ in4; tmp2 = tmp0 ^ in6; out3 = tmp0 ^ in5; out4 = tmp1 ^ in0; out6 = tmp2 ^ in4; out1 = out3 ^ out4 ^ in7; tmp3 = out4 ^ in1 ^ in3; out7 = tmp3 ^ out1; out2 = tmp3 ^ in5; out5 = tmp1 ^ out2; out0 = tmp2 ^ tmp3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_38(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in0 ^ in3; tmp0 = in3 ^ in4; tmp1 = in5 ^ in7; tmp2 = out3 ^ in1; out2 = tmp0 ^ in6; out0 = tmp0 ^ tmp1; out4 = tmp1 ^ tmp2; out7 = out2 ^ in2; out1 = out2 ^ in3 ^ in5; out6 = out4 ^ in0 ^ in2; out5 = tmp2 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_39(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in0; tmp0 = in1 ^ in5; tmp1 = tmp0 ^ in4; out1 = tmp1 ^ in6; out5 = out1 ^ in0 ^ in2; tmp2 = tmp0 ^ out5; out2 = tmp2 ^ in0 ^ in3; out7 = out2 ^ in7; out6 = tmp1 ^ out7; out4 = tmp2 ^ out6; out0 = out4 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_3A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; tmp1 = in0 ^ in2; tmp2 = in3 ^ in4; tmp3 = in1 ^ in6; tmp4 = in3 ^ in7; out4 = tmp0 ^ in5; out5 = tmp1 ^ tmp3; out3 = tmp1 ^ tmp4; out0 = tmp2 ^ in5; out7 = tmp2 ^ in2; tmp5 = tmp3 ^ in4; out2 = tmp4 ^ tmp5; out1 = tmp5 ^ out4; out6 = tmp0 ^ out3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_3B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in6; tmp1 = in2 ^ in7; tmp2 = tmp0 ^ in3; out3 = tmp1 ^ in0; out6 = tmp1 ^ tmp2; out2 = out6 ^ in4; out7 = tmp0 ^ out2; out0 = out3 ^ out7 ^ in5; out5 = out0 ^ out2 ^ in7; out1 = tmp2 ^ out0; out4 = out1 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_3C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3; tmp1 = in2 ^ in7; tmp2 = in1 ^ in6 ^ in7; out2 = tmp0 ^ in4; out3 = tmp0 ^ tmp2; out4 = tmp1 ^ out3 ^ in5; out5 = tmp2 ^ out2 ^ in2; out1 = out4 ^ out5 ^ in6; out0 = out1 ^ in3; out7 = tmp1 ^ out0; out6 = tmp2 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_3D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in2; tmp1 = tmp0 ^ in3; out2 = tmp1 ^ in4; tmp2 = out2 ^ in5; out4 = tmp2 ^ in1 ^ in6; out5 = out4 ^ in7; out6 = out5 ^ in0; out7 = out6 ^ in1; out0 = tmp0 ^ out7; out1 = tmp1 ^ out5; out3 = tmp2 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_3E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in5; tmp1 = tmp0 ^ in4; out0 = tmp1 ^ in6; out7 = tmp1 ^ in2; out6 = out7 ^ in1 ^ in5 ^ in7; out2 = out6 ^ in0 ^ in2; out4 = out0 ^ out6 ^ in0; out5 = tmp0 ^ out4; out3 = out5 ^ in7; out1 = out3 ^ out6 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_3F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; out3 = tmp0 ^ in2 ^ in6; tmp1 = out3 ^ in5 ^ in7; out4 = tmp1 ^ in4; out5 = tmp1 ^ in3; out1 = out4 ^ in2; out7 = out1 ^ out3 ^ in3; out2 = tmp0 ^ out7 ^ in5; tmp2 = out2 ^ in0; out6 = tmp2 ^ in6; out0 = tmp1 ^ tmp2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_40(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in3 ^ in7; tmp0 = in3 ^ in4; tmp1 = in6 ^ in7; out4 = tmp0 ^ in2; out5 = tmp0 ^ in5; out0 = tmp1 ^ in2; out7 = tmp1 ^ in1 ^ in5; out2 = out0 ^ in4; out3 = out2 ^ out5 ^ in7; out6 = out3 ^ out4 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_41(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in2 ^ in3; tmp0 = in5 ^ in6; tmp1 = in6 ^ in7; out5 = in3 ^ in4; out1 = in1 ^ in3 ^ in7; out6 = in0 ^ in4 ^ in5; out3 = tmp0 ^ in2; out7 = tmp0 ^ in1; out2 = tmp1 ^ in4; out0 = tmp1 ^ in0 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_42(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in2 ^ in6; out5 = in3 ^ in5; out1 = in0 ^ in3 ^ in7; out7 = in1 ^ in5 ^ in7; out4 = in2 ^ in4 ^ in7; out6 = in0 ^ in4 ^ in6; out2 = out0 ^ in1 ^ in4; out3 = out5 ^ in6 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_43(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out5 = in3; out7 = in1 ^ in5; out4 = in2 ^ in7; out6 = in0 ^ in4; out0 = in0 ^ in2 ^ in6; out3 = in5 ^ in6 ^ in7; out2 = in1 ^ in4 ^ in6; out1 = in0 ^ in1 ^ in3 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_44(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in3; out0 = in2 ^ in7; tmp0 = in4 ^ in7; out7 = in1 ^ in6 ^ in7; out6 = in0 ^ in5 ^ in6; out4 = tmp0 ^ in3 ^ in6; out3 = out0 ^ in1 ^ in3 ^ in5; out2 = out0 ^ in0 ^ in4; out5 = tmp0 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_45(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in1 ^ in3; out7 = in1 ^ in6; out5 = in4 ^ in7; out6 = in0 ^ in5; out0 = in0 ^ in2 ^ in7; out4 = in3 ^ in6 ^ in7; out2 = out5 ^ in0; out3 = out0 ^ out6 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_46(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in2; out1 = in0 ^ in3; out7 = in1 ^ in7; out4 = in4 ^ in6; out5 = in5 ^ in7; out6 = in0 ^ in6; out3 = in1 ^ in3 ^ in5; out2 = out4 ^ out6 ^ in1 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_47(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in6; out7 = in1; out5 = in7; out6 = in0; tmp0 = in0 ^ in1; out3 = in1 ^ in5; out0 = in0 ^ in2; out1 = tmp0 ^ in3; out2 = tmp0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_48(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in3; out1 = in3 ^ in6 ^ in7; out3 = tmp0 ^ in0; out0 = tmp0 ^ out1 ^ in5; tmp1 = out0 ^ in4; out2 = tmp1 ^ in7; out5 = tmp1 ^ in3; out4 = out5 ^ in1; out7 = tmp0 ^ out4; out6 = tmp1 ^ out3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_49(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in0 ^ in2; tmp0 = in2 ^ in5; out2 = in4 ^ in5 ^ in6; tmp1 = tmp0 ^ out2 ^ in3; out7 = out2 ^ in1; out5 = tmp1 ^ in7; out4 = out5 ^ out7 ^ in6; out1 = tmp0 ^ out4; out6 = out1 ^ out7 ^ in0; out0 = tmp1 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_4A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in6; tmp1 = in3 ^ in7; out0 = tmp0 ^ in5; out3 = tmp1 ^ in0; out5 = tmp1 ^ out0; out4 = out0 ^ in1 ^ in4; out1 = out3 ^ in6; out2 = out4 ^ in7; out6 = out1 ^ in4; out7 = tmp0 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_4B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in0 ^ in7; tmp0 = in1 ^ in5; tmp1 = in2 ^ in6; tmp2 = out3 ^ in3; out7 = tmp0 ^ in4; out4 = tmp0 ^ tmp1; tmp3 = tmp1 ^ in0; out6 = tmp2 ^ in4; out5 = tmp2 ^ tmp3; out1 = tmp2 ^ in1 ^ in6; out2 = out7 ^ in6 ^ in7; out0 = tmp3 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_4C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in3 ^ in6; tmp0 = in2 ^ in5; tmp1 = out1 ^ in5 ^ in7; out0 = tmp0 ^ in7; tmp2 = tmp0 ^ in4; out6 = tmp1 ^ in0; out2 = tmp2 ^ in0; out5 = tmp2 ^ in6; out3 = tmp0 ^ out6 ^ in1; out7 = out0 ^ out5 ^ in1; out4 = tmp1 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_4D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in5; tmp1 = in1 ^ in6; out4 = in1 ^ in3 ^ in5; tmp2 = tmp0 ^ in7; out2 = tmp0 ^ in4; out1 = tmp1 ^ in3; out7 = tmp1 ^ in4; out0 = tmp2 ^ in2; out6 = tmp2 ^ in3; out5 = out7 ^ in1 ^ in2; out3 = tmp1 ^ out0 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_4E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in2 ^ in5; out7 = in1 ^ in4 ^ in7; out1 = in0 ^ in3 ^ in6; out5 = out0 ^ in6; out4 = out7 ^ in5; out3 = out1 ^ in1; out6 = out1 ^ in7; out2 = out4 ^ in0 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_4F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out5 = in2 ^ in6; out7 = in1 ^ in4; out3 = in0 ^ in1 ^ in6; out4 = in1 ^ in5 ^ in7; out0 = in0 ^ in2 ^ in5; out6 = in0 ^ in3 ^ in7; out1 = out3 ^ in3; out2 = out4 ^ in0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_50(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in2 ^ in7; tmp0 = in3 ^ in5; out0 = out2 ^ in4 ^ in6; out1 = tmp0 ^ in7; tmp1 = tmp0 ^ in6; out3 = out0 ^ in3; out7 = tmp1 ^ in1; tmp2 = tmp1 ^ in0; out5 = out3 ^ in1 ^ in2; out4 = tmp2 ^ in2; out6 = tmp2 ^ out3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_51(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in7; out3 = in2 ^ in4 ^ in6 ^ in7; out0 = out3 ^ in0; out6 = out0 ^ in5; out4 = out6 ^ in3 ^ in7; out1 = out0 ^ out4 ^ in1; out7 = out1 ^ in6; out5 = out7 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_52(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in1 ^ in2; tmp0 = in2 ^ in4; tmp1 = in3 ^ in5; tmp2 = in3 ^ in6; tmp3 = in0 ^ in7; out0 = tmp0 ^ in6; out6 = tmp0 ^ tmp3; out7 = tmp1 ^ in1; out1 = tmp1 ^ tmp3; out3 = tmp2 ^ in4; out5 = tmp2 ^ in1 ^ in7; out4 = tmp2 ^ out1 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_53(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in1; out3 = in4 ^ in6; out0 = out3 ^ in0 ^ in2; out6 = out0 ^ in7; out4 = out6 ^ in5; out7 = out0 ^ out4 ^ in1 ^ in3; out1 = out7 ^ in0; out5 = out7 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_54(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in3 ^ in5; tmp0 = in1 ^ in3; tmp1 = in2 ^ in4; tmp2 = in0 ^ in7; out5 = in1 ^ in4 ^ in6; out4 = tmp2 ^ out1; out7 = tmp0 ^ in6; out3 = tmp0 ^ tmp1; out0 = tmp1 ^ in7; tmp3 = tmp2 ^ in2; out2 = tmp3 ^ in6; out6 = tmp3 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_55(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in3; tmp1 = in1 ^ in4; tmp2 = in6 ^ in7; out7 = tmp0 ^ tmp2; out1 = tmp0 ^ in5; out3 = tmp1 ^ in2; out5 = tmp1 ^ in5 ^ in6; out2 = tmp2 ^ in0; out4 = out5 ^ out7 ^ in0; out6 = out2 ^ in2 ^ in5; out0 = out5 ^ out6 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_56(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in2 ^ in4; tmp0 = in0 ^ in2; out4 = in0 ^ in5; out7 = in1 ^ in3; out5 = in1 ^ in6; out6 = tmp0 ^ in7; out2 = tmp0 ^ out5; out1 = out4 ^ in3; out3 = out7 ^ in4 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_57(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in5; tmp1 = in1 ^ in7; out0 = in0 ^ in2 ^ in4; out5 = in1 ^ in5 ^ in6; out4 = tmp0 ^ in4; out1 = tmp0 ^ in1 ^ in3; out2 = tmp0 ^ out5; out3 = tmp1 ^ in4; out7 = tmp1 ^ in3; out6 = tmp1 ^ out2 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_58(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in2 ^ in5; tmp0 = in2 ^ in3 ^ in4; out5 = tmp0 ^ in1; out6 = tmp0 ^ in0 ^ in5; out3 = out6 ^ in7; tmp1 = out2 ^ out5; out7 = tmp1 ^ in6; out4 = tmp1 ^ out3 ^ in3; out0 = out4 ^ out7 ^ in0; out1 = tmp0 ^ out0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_59(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in5; tmp0 = in0 ^ in5 ^ in7; out3 = tmp0 ^ in2 ^ in4; out0 = out3 ^ in6; tmp1 = out0 ^ in7; out6 = tmp1 ^ in3; out5 = out6 ^ in0 ^ in1 ^ in6; out4 = tmp0 ^ out5; out1 = tmp1 ^ out4; out7 = out1 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_5A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in2; tmp1 = in2 ^ in5; out5 = tmp0 ^ in3; out4 = tmp0 ^ in0; tmp2 = tmp1 ^ in4; out2 = tmp1 ^ in1 ^ in7; out7 = tmp2 ^ out5; out6 = out4 ^ out7 ^ in5; out0 = tmp2 ^ in6; out1 = out0 ^ out6 ^ in7; out3 = tmp1 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_5B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in3; tmp1 = in0 ^ in4; tmp2 = in1 ^ in5; out5 = tmp0 ^ tmp2; tmp3 = tmp1 ^ in6; out3 = tmp1 ^ in5; out2 = tmp2 ^ in7; tmp4 = out3 ^ in2; out7 = out2 ^ in3 ^ in4; out0 = tmp4 ^ in6; out6 = tmp0 ^ tmp3; out4 = tmp2 ^ tmp4; out1 = tmp3 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_5C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in6; tmp1 = in0 ^ in2 ^ in5; out1 = tmp0 ^ in5; tmp2 = tmp0 ^ in1; out2 = tmp1 ^ in6; out6 = tmp1 ^ in3; out4 = tmp2 ^ in0; out7 = tmp2 ^ in4; out3 = tmp1 ^ out7; out0 = out3 ^ out4 ^ in7; out5 = out0 ^ in1 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_5D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; tmp1 = in0 ^ in6; out2 = tmp1 ^ in5; tmp2 = out2 ^ in3; out6 = tmp2 ^ in2; out1 = tmp0 ^ tmp2; tmp3 = out1 ^ in4 ^ in5; out4 = tmp3 ^ in0; out7 = tmp3 ^ in7; tmp4 = out4 ^ out6; out5 = tmp4 ^ in7; out0 = tmp0 ^ out5; out3 = tmp1 ^ tmp4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_5E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in5; tmp1 = in3 ^ in5; tmp2 = in1 ^ in7; out7 = in1 ^ in3 ^ in4; out0 = tmp0 ^ in4; tmp3 = tmp1 ^ in0; out5 = tmp2 ^ in2; out1 = tmp3 ^ in6; out6 = tmp0 ^ tmp3; tmp4 = tmp2 ^ out1; out3 = tmp4 ^ in4; out4 = tmp1 ^ tmp4; out2 = tmp0 ^ out4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_5F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in5; tmp1 = in0 ^ in6; tmp2 = tmp0 ^ in7; tmp3 = tmp1 ^ in3; out2 = tmp1 ^ tmp2; out5 = tmp2 ^ in2; out6 = tmp3 ^ in2; out3 = out2 ^ in4; out4 = out3 ^ in5; out1 = tmp0 ^ tmp3; out7 = tmp3 ^ out4; out0 = out4 ^ out5 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_60(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in2 ^ in5; tmp0 = in3 ^ in6; out1 = in3 ^ in4 ^ in7; out7 = out4 ^ in1; tmp1 = out4 ^ in4; out0 = tmp0 ^ in2; out5 = tmp0 ^ in0; out2 = tmp0 ^ tmp1; out3 = tmp1 ^ in7; out6 = out3 ^ out7 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_61(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in5; out4 = tmp0 ^ in4; tmp1 = out4 ^ in3; out3 = tmp1 ^ in7; out2 = tmp1 ^ in2 ^ in6; out1 = tmp0 ^ out3 ^ in1; out0 = out2 ^ out4 ^ in0; out7 = tmp1 ^ out1; out6 = out0 ^ out1 ^ in2; out5 = tmp0 ^ out0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_62(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in4 ^ in5; tmp0 = in0 ^ in3 ^ in4; out1 = tmp0 ^ in7; out5 = tmp0 ^ in6; tmp1 = out1 ^ in0; tmp2 = tmp1 ^ out3; out4 = tmp2 ^ in2; tmp3 = tmp2 ^ in1; out0 = out4 ^ in5 ^ in6; out7 = tmp3 ^ out0; out6 = tmp0 ^ tmp3; out2 = tmp1 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_63(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in4; tmp1 = in1 ^ in7; out3 = tmp0 ^ in5; tmp2 = out3 ^ in6; out4 = out3 ^ in2 ^ in7; out5 = tmp2 ^ in0; tmp3 = out5 ^ in3; out0 = tmp3 ^ out4; out2 = tmp1 ^ tmp2; out6 = tmp1 ^ tmp3; tmp4 = tmp0 ^ out2; out1 = tmp4 ^ out5; out7 = tmp4 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_64(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in2 ^ in3; out1 = in3 ^ in4; out7 = in1 ^ in2; tmp0 = in4 ^ in5; tmp1 = in0 ^ in7; out4 = in5 ^ in6 ^ in7; out2 = tmp0 ^ out0 ^ in0; out3 = tmp0 ^ out7 ^ in6; out5 = tmp1 ^ in6; out6 = tmp1 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_65(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3; tmp1 = in4 ^ in5; tmp2 = in6 ^ in7; out7 = in1 ^ in2 ^ in7; out1 = in1 ^ in3 ^ in4; out0 = tmp0 ^ in2; out2 = tmp0 ^ tmp1; out4 = tmp1 ^ tmp2; tmp3 = tmp2 ^ in0; out3 = out4 ^ out7 ^ in3; out5 = tmp3 ^ in5; out6 = tmp3 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_66(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in2; tmp1 = in2 ^ in3; tmp2 = in0 ^ in4; out7 = tmp0 ^ in6; out0 = tmp1 ^ in7; out1 = tmp2 ^ in3; tmp3 = tmp2 ^ in6; tmp4 = out1 ^ in5; out5 = tmp3 ^ in7; out4 = tmp3 ^ tmp4; out2 = tmp0 ^ tmp4 ^ in7; out6 = tmp1 ^ out2 ^ in4; out3 = tmp3 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_67(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3; tmp1 = tmp0 ^ in1; tmp2 = tmp0 ^ in7; out1 = tmp1 ^ in4; out0 = tmp2 ^ in2; tmp3 = out1 ^ in7; out2 = tmp3 ^ in5; out3 = out2 ^ in0 ^ in6; out7 = tmp1 ^ out0 ^ in6; out5 = tmp1 ^ out3; out4 = tmp2 ^ out5; out6 = tmp3 ^ out4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_68(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in4; tmp1 = in2 ^ in3 ^ in5; tmp2 = tmp0 ^ in1; tmp3 = tmp0 ^ in6; out0 = tmp1 ^ in6; out6 = tmp2 ^ in0; out7 = tmp1 ^ tmp2; out1 = tmp3 ^ in7; out2 = out1 ^ in2; out4 = tmp2 ^ out2; out3 = out4 ^ out6 ^ in3; out5 = tmp3 ^ out3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_69(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in6 ^ in7; out2 = tmp0 ^ in3 ^ in4; out1 = out2 ^ in1; out3 = out2 ^ in0 ^ in2; out4 = out1 ^ in2 ^ in3; out6 = out1 ^ in0 ^ in7; out7 = out4 ^ in5 ^ in6; out5 = out4 ^ out6 ^ in5; out0 = tmp0 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_6A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in6; out3 = in0 ^ in4 ^ in6; tmp1 = tmp0 ^ in3; out4 = tmp1 ^ in1; tmp2 = tmp1 ^ in7; out2 = out4 ^ in4; out0 = tmp2 ^ in5; out5 = tmp2 ^ out3; out7 = out2 ^ in3 ^ in5; out1 = tmp0 ^ out5; out6 = tmp1 ^ out7 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_6B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in4 ^ in6; out2 = tmp0 ^ in1 ^ in3; out4 = out2 ^ in2; tmp1 = out2 ^ in0; out7 = out4 ^ in3 ^ in5 ^ in7; out1 = tmp1 ^ in7; out3 = tmp1 ^ in1; out6 = tmp1 ^ in5; out0 = tmp1 ^ out7 ^ in6; out5 = tmp0 ^ out0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_6C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in1; tmp0 = in2 ^ in3; out5 = in0 ^ in2; out1 = in3 ^ in4 ^ in6; tmp1 = out5 ^ in1; out0 = tmp0 ^ in5; out6 = tmp0 ^ tmp1; out3 = tmp1 ^ in4; out7 = out3 ^ in0; out2 = out6 ^ out7 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_6D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in1 ^ in4; tmp0 = in0 ^ in2; tmp1 = out4 ^ in3; out7 = out4 ^ in2 ^ in7; out5 = tmp0 ^ in5; out3 = tmp0 ^ tmp1; out1 = tmp1 ^ in6; out0 = out5 ^ in3; out2 = out3 ^ out7 ^ in4; out6 = out1 ^ in0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_6E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in3; tmp1 = in0 ^ in4; out4 = tmp0 ^ in7; out6 = tmp0 ^ in0 ^ in5; out5 = tmp1 ^ in2; tmp2 = tmp1 ^ in3; out3 = tmp2 ^ out4; out1 = tmp2 ^ in6; out2 = tmp0 ^ out5; out0 = out2 ^ out3 ^ in5; out7 = out1 ^ out2 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_6F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in7; tmp1 = tmp0 ^ in4; tmp2 = tmp0 ^ in0 ^ in2; out4 = tmp1 ^ in1; out0 = tmp2 ^ in5; out3 = out4 ^ in0; out2 = out3 ^ in7; out1 = out2 ^ in6; out6 = out1 ^ in4 ^ in5; out7 = tmp2 ^ out1; out5 = tmp1 ^ out0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_70(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in2; tmp0 = in2 ^ in4; out2 = in2 ^ in3 ^ in5; tmp1 = tmp0 ^ in6; tmp2 = out2 ^ in7; out0 = tmp1 ^ in3; out4 = tmp1 ^ in0; out7 = tmp2 ^ in1; out6 = out4 ^ in1; out5 = out7 ^ in0 ^ in2; out1 = tmp0 ^ tmp2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_71(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in3 ^ in5; out3 = in2 ^ in3; tmp0 = in0 ^ in2; tmp1 = out2 ^ in1; out4 = tmp0 ^ in6; tmp2 = tmp0 ^ in1; out7 = tmp1 ^ in2; out1 = tmp1 ^ in4 ^ in7; out0 = out4 ^ in3 ^ in4; out6 = tmp2 ^ in4; out5 = tmp2 ^ out3 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_72(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in7; tmp0 = in0 ^ in4; tmp1 = tmp0 ^ in3 ^ in7; out1 = tmp1 ^ in5; out5 = out1 ^ in1; tmp2 = tmp0 ^ out5; out2 = tmp2 ^ in2; out7 = out2 ^ in6; out6 = tmp1 ^ out7; out4 = tmp2 ^ out6; out0 = out4 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_73(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in3 ^ in7; out2 = out3 ^ in1 ^ in5; out1 = out2 ^ in0 ^ in4; out5 = out1 ^ in5; out6 = out1 ^ out3 ^ in2; out0 = out2 ^ out6 ^ in6; out7 = out0 ^ out1 ^ in3; out4 = out0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_74(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in4; tmp1 = in1 ^ in2 ^ in6; out4 = in0 ^ in4 ^ in7; out5 = in0 ^ in1 ^ in5; out0 = tmp0 ^ in2; out1 = tmp0 ^ in5; out3 = tmp1 ^ in7; out6 = tmp1 ^ in0; out2 = tmp1 ^ out5 ^ in3; out7 = out3 ^ in3 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_75(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in0 ^ in7; tmp0 = in1 ^ in3; out5 = in0 ^ in1; out7 = tmp0 ^ in2; tmp1 = tmp0 ^ in4; out6 = out5 ^ in2; tmp2 = out7 ^ in6; out1 = tmp1 ^ in5; out0 = tmp1 ^ out6; out3 = tmp2 ^ in7; out2 = tmp2 ^ out6 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_76(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in1 ^ in6; tmp0 = in0 ^ in5; tmp1 = in3 ^ in7; tmp2 = tmp0 ^ in4; tmp3 = tmp1 ^ in2; out5 = tmp2 ^ in1; out1 = tmp2 ^ in3; out0 = tmp3 ^ in4; out4 = out1 ^ in5; out7 = tmp3 ^ out3; out2 = tmp0 ^ out7; out6 = tmp1 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_77(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in0 ^ in3; tmp0 = in1 ^ in4; tmp1 = in1 ^ in6; tmp2 = out4 ^ in5; out5 = tmp0 ^ in0; out1 = tmp0 ^ tmp2; out3 = tmp1 ^ in3; out2 = tmp1 ^ tmp2 ^ in7; out7 = out3 ^ in2; tmp3 = out7 ^ in6; out6 = tmp2 ^ tmp3; out0 = tmp3 ^ out5 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_78(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3; tmp1 = in2 ^ in7; tmp2 = in0 ^ in5 ^ in6; out2 = tmp1 ^ in3; out3 = tmp2 ^ in2; out5 = out3 ^ in1 ^ in3; out0 = tmp0 ^ out3 ^ in4; out1 = tmp1 ^ out0; out4 = out1 ^ out5 ^ in5; out7 = tmp0 ^ out4; out6 = tmp2 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_79(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in3 ^ in7; tmp0 = in3 ^ in4; tmp1 = in1 ^ in5; tmp2 = tmp1 ^ in2; out4 = tmp2 ^ in0 ^ in7; tmp3 = out4 ^ in5; out5 = tmp3 ^ out2 ^ in6; out7 = tmp0 ^ tmp2; out6 = tmp0 ^ tmp3; out3 = tmp1 ^ out5; out0 = out3 ^ in4; out1 = tmp3 ^ out0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_7A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in2; out2 = tmp0 ^ in3; tmp1 = out2 ^ in4; out4 = tmp1 ^ in0 ^ in5; out5 = out4 ^ in6; out6 = out5 ^ in7; out7 = out6 ^ in0; out0 = out7 ^ in1; out1 = tmp0 ^ out6; out3 = tmp1 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_7B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in1 ^ in3; tmp0 = in0 ^ in5; out4 = tmp0 ^ out2 ^ in2; tmp1 = out4 ^ in4; out6 = tmp1 ^ in7; out5 = tmp1 ^ in5 ^ in6; out0 = out6 ^ in1 ^ in6; tmp2 = out0 ^ in2; out1 = tmp2 ^ in1; out3 = tmp2 ^ in4; out7 = tmp0 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_7C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in5; tmp1 = tmp0 ^ in4; out0 = tmp1 ^ in2; out1 = tmp1 ^ in6; out7 = out0 ^ in1 ^ in5 ^ in7; out5 = out1 ^ out7 ^ in0; out3 = out5 ^ in6; out6 = tmp0 ^ out5; out2 = out6 ^ in1; out4 = out2 ^ out7 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_7D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in2; tmp1 = tmp0 ^ in3; tmp2 = tmp0 ^ in6; out7 = tmp1 ^ in4; tmp3 = tmp2 ^ in0; out5 = tmp3 ^ in7; out4 = tmp3 ^ in2 ^ in5; out2 = tmp1 ^ out5; out6 = tmp2 ^ out2; out0 = out4 ^ out7 ^ in6; out1 = tmp3 ^ out0; out3 = out6 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_7E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in4; tmp1 = in0 ^ in5; out1 = tmp0 ^ tmp1 ^ in6; out3 = tmp1 ^ in1; out4 = out1 ^ in1 ^ in7; tmp2 = out4 ^ in3; out5 = tmp2 ^ in2; out6 = tmp0 ^ out5; out7 = tmp1 ^ out4 ^ in2; out2 = out6 ^ in5 ^ in7; out0 = tmp2 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_7F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in7; tmp1 = tmp0 ^ in3 ^ in5; tmp2 = tmp1 ^ in0; out0 = tmp2 ^ in4; out6 = tmp2 ^ in1; out3 = tmp0 ^ out6; tmp3 = out3 ^ in6; out1 = tmp3 ^ in4; out2 = tmp3 ^ in5; out4 = tmp3 ^ in7; out5 = tmp1 ^ out1; out7 = out0 ^ out4 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_80(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in3; tmp1 = in4 ^ in5; out1 = in2 ^ in6 ^ in7; out5 = tmp0 ^ in4; tmp2 = tmp0 ^ in1; out6 = tmp1 ^ in3; out7 = tmp1 ^ in0 ^ in6; out4 = tmp2 ^ in7; out3 = tmp2 ^ out6; out2 = out3 ^ out5 ^ in6; out0 = out2 ^ in3 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_81(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in4 ^ in6; tmp1 = tmp0 ^ in3; out6 = tmp1 ^ in5; out5 = out6 ^ in2 ^ in6; out3 = out5 ^ in1; out2 = tmp0 ^ out3; out1 = out3 ^ out6 ^ in7; out4 = tmp1 ^ out1; out7 = out2 ^ out4 ^ in0; out0 = out7 ^ in1 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_82(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in1 ^ in2; tmp0 = in6 ^ in7; out5 = in2 ^ in3; out6 = in3 ^ in4; out7 = in0 ^ in4 ^ in5; out0 = in1 ^ in5 ^ in6; out1 = tmp0 ^ in0 ^ in2; out2 = tmp0 ^ in3 ^ in5; out3 = tmp0 ^ out0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_83(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; tmp1 = in2 ^ in5; tmp2 = in3 ^ in6; out4 = in1 ^ in2 ^ in4; out0 = tmp0 ^ in5 ^ in6; out5 = tmp1 ^ in3; tmp3 = tmp1 ^ in7; out6 = tmp2 ^ in4; out2 = tmp2 ^ tmp3; tmp4 = tmp3 ^ out4; out1 = tmp3 ^ out0; out3 = tmp4 ^ in3; out7 = tmp0 ^ tmp4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_84(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in2 ^ in6; out6 = in3 ^ in5; out0 = in1 ^ in5 ^ in7; out7 = in0 ^ in4 ^ in6; out4 = in1 ^ in3 ^ in6; out5 = in2 ^ in4 ^ in7; out2 = out6 ^ in0 ^ in1; out3 = out5 ^ in5 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_85(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in6; tmp1 = in3 ^ in6; tmp2 = tmp0 ^ in4; out1 = tmp0 ^ in2; out6 = tmp1 ^ in5; out4 = tmp2 ^ in3; tmp3 = out1 ^ out6; out2 = tmp3 ^ in0; out3 = tmp2 ^ tmp3 ^ in7; out7 = out2 ^ out3 ^ in1; out5 = tmp1 ^ out3; out0 = tmp2 ^ out7 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_86(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out6 = in3; out7 = in0 ^ in4; out0 = in1 ^ in5; out5 = in2 ^ in7; out3 = in4 ^ in5 ^ in6; out1 = in0 ^ in2 ^ in6; out4 = in1 ^ in6 ^ in7; out2 = in0 ^ in3 ^ in5 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_87(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out6 = in3 ^ in6; tmp0 = in0 ^ in1; out7 = in0 ^ in4 ^ in7; out5 = in2 ^ in5 ^ in7; out3 = out6 ^ in4 ^ in5; out0 = tmp0 ^ in5; tmp1 = tmp0 ^ in6; out2 = out5 ^ in0 ^ in3; out1 = tmp1 ^ in2; out4 = tmp1 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_88(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in2 ^ in7; tmp0 = in5 ^ in6; out0 = in1 ^ in6 ^ in7; out6 = in4 ^ in5 ^ in7; out3 = out0 ^ out1 ^ in0 ^ in4; out7 = tmp0 ^ in0; tmp1 = tmp0 ^ in3; out2 = out0 ^ in3; out4 = tmp1 ^ in2; out5 = tmp1 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_89(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in7; tmp1 = in2 ^ in7; tmp2 = tmp0 ^ in6; out1 = tmp1 ^ in1; out7 = tmp2 ^ in5; out0 = tmp2 ^ in1; out2 = out1 ^ in3 ^ in6; out6 = out7 ^ in0 ^ in4; out5 = out6 ^ in3; out3 = tmp0 ^ out2 ^ in4; out4 = tmp1 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_8A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in1 ^ in6; out7 = in0 ^ in5; out2 = in3 ^ in6; out6 = in4 ^ in7; out1 = in0 ^ in2 ^ in7; out3 = out0 ^ out6 ^ in0; out4 = out1 ^ out7 ^ in6; out5 = out2 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_8B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; tmp1 = in3 ^ in6; tmp2 = in5 ^ in7; tmp3 = tmp0 ^ in7; out0 = tmp0 ^ in6; out2 = tmp1 ^ in2; out5 = tmp1 ^ tmp2; out7 = tmp2 ^ in0; tmp4 = tmp3 ^ in4; out1 = tmp3 ^ in2; out6 = tmp4 ^ out0; out4 = out6 ^ in2 ^ in5; out3 = tmp1 ^ tmp4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_8C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in2; out0 = in1 ^ in7; out7 = in0 ^ in6; out5 = in4 ^ in6; out6 = in5 ^ in7; out2 = out0 ^ in0 ^ in3; out3 = out5 ^ out7 ^ in2 ^ in7; out4 = out6 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_8D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in1 ^ in2; tmp0 = in6 ^ in7; out0 = in0 ^ in1 ^ in7; out5 = in4 ^ in5 ^ in6; out6 = tmp0 ^ in5; out7 = tmp0 ^ in0; out4 = tmp0 ^ out5 ^ in3; out2 = out0 ^ in2 ^ in3; out3 = out2 ^ in1 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_8E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in1; out4 = in5; out7 = in0; out5 = in6; out6 = in7; out3 = in0 ^ in4; out1 = in0 ^ in2; out2 = in0 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_8F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in0 ^ in1; tmp0 = in0 ^ in3; out4 = in4 ^ in5; out7 = in0 ^ in7; out5 = in5 ^ in6; out6 = in6 ^ in7; out1 = out0 ^ in2; out2 = tmp0 ^ in2; out3 = tmp0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_90(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in2; tmp1 = in2 ^ in6 ^ in7; out3 = tmp0 ^ in7; out1 = tmp1 ^ in5; tmp2 = out1 ^ in4; out6 = tmp2 ^ in3; out5 = out6 ^ in1; out4 = out5 ^ in0; out0 = tmp0 ^ tmp2; out7 = tmp0 ^ out4; out2 = tmp1 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_91(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in4; tmp1 = tmp0 ^ in3 ^ in5; out2 = tmp1 ^ in1; out6 = tmp1 ^ in7; tmp2 = out2 ^ in5 ^ in7; out3 = tmp2 ^ in4; out5 = tmp2 ^ in6; out1 = tmp1 ^ out5 ^ in2; tmp3 = out1 ^ in0; out4 = tmp3 ^ in3; out0 = tmp0 ^ tmp3; out7 = tmp2 ^ tmp3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_92(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in1; tmp0 = in4 ^ in5; tmp1 = tmp0 ^ in1; out2 = tmp0 ^ in3 ^ in7; out0 = tmp1 ^ in6; out7 = out2 ^ in0; out4 = out0 ^ in0 ^ in2; out5 = out4 ^ out7 ^ in5; out6 = tmp1 ^ out5; out1 = out6 ^ out7 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_93(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in1 ^ in3; tmp0 = in2 ^ in7; tmp1 = out3 ^ in6; tmp2 = tmp0 ^ in4; out5 = tmp0 ^ tmp1; out6 = tmp2 ^ in3; out2 = out6 ^ in5; out0 = out2 ^ out5 ^ in0; out7 = tmp1 ^ out0; out1 = tmp2 ^ out0; out4 = out1 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_94(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in2 ^ in6; tmp0 = in1 ^ in4 ^ in5; out1 = out3 ^ in5; out5 = tmp0 ^ out3; out0 = tmp0 ^ in7; out4 = tmp0 ^ in0 ^ in3; out6 = out1 ^ in3 ^ in7; out2 = out4 ^ in6; out7 = out0 ^ out2 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_95(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in3; out3 = tmp0 ^ in6; tmp1 = tmp0 ^ in7; tmp2 = out3 ^ in0; out6 = tmp1 ^ in5; tmp3 = tmp2 ^ in4; out7 = tmp3 ^ in2; tmp4 = tmp3 ^ in5; out2 = tmp4 ^ in1; tmp5 = out2 ^ in6; out0 = tmp1 ^ tmp5; out1 = tmp5 ^ out7; out4 = tmp2 ^ out1; out5 = tmp4 ^ out4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_96(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in6 ^ in7; tmp0 = in1 ^ in5; tmp1 = in5 ^ in6; out6 = out3 ^ in2 ^ in3; out0 = tmp0 ^ in4; tmp2 = tmp1 ^ in2; out4 = out0 ^ in0 ^ in7; out1 = tmp2 ^ in0; out5 = tmp2 ^ in1; out7 = tmp0 ^ out4 ^ in3; out2 = tmp1 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_97(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in4; tmp1 = in2 ^ in6; out3 = in3 ^ in6 ^ in7; out7 = tmp0 ^ in3; tmp2 = tmp0 ^ in5; out5 = tmp1 ^ in1; out6 = tmp1 ^ out3; out0 = tmp2 ^ in1; out2 = tmp2 ^ out3 ^ in2; tmp3 = out0 ^ in4; out4 = tmp3 ^ in7; out1 = tmp1 ^ tmp3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_98(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in5 ^ in7; tmp1 = in1 ^ in4 ^ in7; out1 = tmp0 ^ in2; out0 = tmp1 ^ in6; out2 = tmp1 ^ in3; out6 = out0 ^ out1 ^ in1; out5 = tmp0 ^ out2; out3 = tmp1 ^ out6 ^ in0; out7 = out0 ^ out5 ^ in0; out4 = out6 ^ out7 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_99(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3; out5 = in1 ^ in3 ^ in4; out6 = in2 ^ in4 ^ in5; out4 = tmp0 ^ in2; tmp1 = tmp0 ^ in6; tmp2 = out5 ^ in7; out7 = tmp1 ^ in5; out0 = tmp1 ^ tmp2; out2 = tmp2 ^ in2; out3 = out0 ^ out6 ^ in3; out1 = tmp1 ^ out3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_9A(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in3 ^ in4; tmp0 = in0 ^ in5; tmp1 = in1 ^ in6; out5 = in1 ^ in3 ^ in5; tmp2 = tmp0 ^ in7; out3 = tmp0 ^ tmp1; out0 = tmp1 ^ in4; out7 = tmp2 ^ in3; out1 = tmp2 ^ in2; out6 = out0 ^ in1 ^ in2; out4 = out1 ^ in4 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_9B(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out5 = in1 ^ in3; tmp0 = in3 ^ in5; out6 = in2 ^ in4; out4 = in0 ^ in2 ^ in7; out7 = tmp0 ^ in0; out2 = out6 ^ in3; out1 = out4 ^ in1 ^ in5; out3 = out7 ^ in1 ^ in6; out0 = tmp0 ^ out3 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_9C(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out1 = in2 ^ in5; tmp0 = in0 ^ in3 ^ in6; out3 = out1 ^ in0; out6 = out1 ^ in6; out7 = tmp0 ^ in7; out4 = out7 ^ in4; out2 = out4 ^ in1; out0 = tmp0 ^ out2; out5 = out0 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_9D(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out6 = in2 ^ in5; tmp0 = in0 ^ in3; out5 = in1 ^ in4 ^ in7; out1 = out6 ^ in1; out3 = tmp0 ^ out6; out7 = tmp0 ^ in6; out0 = out5 ^ in0; out4 = out7 ^ in7; out2 = out5 ^ out7 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_9E(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in1 ^ in4; tmp0 = in0 ^ in5; out6 = in2 ^ in6; out7 = in0 ^ in3 ^ in7; out4 = in0 ^ in4 ^ in6; out5 = in1 ^ in5 ^ in7; out1 = tmp0 ^ in2; out3 = tmp0 ^ in7; out2 = out4 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_9F(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out6 = in2; out7 = in0 ^ in3; tmp0 = in0 ^ in1; out4 = in0 ^ in6; out5 = in1 ^ in7; out1 = tmp0 ^ in2 ^ in5; out2 = out7 ^ in2 ^ in4 ^ in6; out3 = out7 ^ in5 ^ in7; out0 = tmp0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A0(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in6; out2 = tmp0 ^ in7; tmp1 = tmp0 ^ in5; out6 = out2 ^ in3 ^ in4; out0 = tmp1 ^ in3; tmp2 = out0 ^ in2; out3 = tmp2 ^ in7; tmp3 = tmp2 ^ in1; out5 = tmp3 ^ in0; out4 = tmp3 ^ out6; out7 = out5 ^ out6 ^ in1; out1 = tmp1 ^ out4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A1(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in5; tmp1 = tmp0 ^ in1; tmp2 = tmp0 ^ in4; out4 = tmp1 ^ in7; out7 = tmp2 ^ in0; out6 = tmp2 ^ out4 ^ in3; out3 = out4 ^ in6; out2 = out3 ^ in5; out1 = out2 ^ in4; out5 = out1 ^ out6 ^ in0; out0 = tmp1 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A2(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in6; tmp0 = in1 ^ in3 ^ in5; out3 = tmp0 ^ in6; out4 = tmp0 ^ in2 ^ in4; out0 = out3 ^ in7; out6 = out0 ^ in4; out1 = out0 ^ out4 ^ in0; out7 = out1 ^ in5; out5 = out7 ^ in3 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A3(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in2 ^ in6; out3 = in1 ^ in5 ^ in6; tmp0 = out2 ^ in0; out4 = out2 ^ out3 ^ in3; tmp1 = tmp0 ^ in4; out0 = tmp0 ^ out4 ^ in7; out5 = tmp1 ^ in3; out7 = tmp1 ^ in5; out1 = tmp1 ^ in1 ^ in7; out6 = tmp1 ^ out0 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A4(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in3; tmp1 = in2 ^ in4; tmp2 = in2 ^ in5; tmp3 = in0 ^ in7; out0 = tmp0 ^ in5; out6 = tmp0 ^ in6 ^ in7; out1 = tmp1 ^ in6; out7 = tmp1 ^ tmp3; out3 = tmp2 ^ in3; tmp4 = tmp2 ^ out1; out2 = tmp3 ^ in1; out5 = tmp4 ^ out7; out4 = tmp4 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A5(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in2 ^ in5; tmp0 = in1 ^ in6; tmp1 = in0 ^ in1; tmp2 = in2 ^ in4; out6 = in1 ^ in3 ^ in7; out4 = tmp0 ^ in5; out1 = tmp0 ^ tmp2; out0 = tmp1 ^ in3 ^ in5; out2 = tmp1 ^ in2 ^ in7; out7 = tmp2 ^ in0; out5 = tmp0 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A6(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in0; out3 = in3 ^ in5 ^ in7; out1 = in0 ^ in2 ^ in4 ^ in6; out0 = out3 ^ in1; out7 = out1 ^ in7; out6 = out0 ^ in6; out5 = out7 ^ in5; out4 = out6 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A7(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in0 ^ in2; out3 = in5 ^ in7; out7 = out2 ^ in4 ^ in6; out6 = out3 ^ in1 ^ in3; out1 = out7 ^ in1; out5 = out7 ^ in7; out0 = out6 ^ in0; out4 = out6 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A8(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in4; tmp1 = in1 ^ in6; tmp2 = in0 ^ in2 ^ in7; out1 = tmp0 ^ in7; out4 = tmp0 ^ in6; out0 = tmp1 ^ in3; out2 = tmp1 ^ in5; out6 = tmp1 ^ in4; out7 = tmp2 ^ in5; out3 = tmp2 ^ out0 ^ in6; out5 = out7 ^ in2 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_A9(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in2 ^ in6; out6 = in1 ^ in4; out7 = in0 ^ in2 ^ in5; out5 = in0 ^ in3 ^ in7; out2 = out4 ^ in1 ^ in5; out1 = out6 ^ in2 ^ in7; out0 = out2 ^ out7 ^ in3; out3 = out1 ^ in0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_AA(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in2; tmp1 = in1 ^ in3; tmp2 = in6 ^ in7; out1 = tmp0 ^ in4 ^ in7; out3 = tmp1 ^ in0; out0 = tmp1 ^ tmp2; out2 = tmp2 ^ in5; out7 = tmp0 ^ out2; out6 = out1 ^ out7 ^ in1; out5 = out0 ^ out6 ^ in0; out4 = out5 ^ out7 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_AB(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in0 ^ in1; tmp0 = in1 ^ in4; tmp1 = in0 ^ in7; out6 = tmp0 ^ in5; out1 = tmp0 ^ tmp1 ^ in2; out5 = tmp1 ^ in3 ^ in4; out0 = tmp0 ^ out5 ^ in6; out4 = out0 ^ out3 ^ in2; out2 = out4 ^ in3 ^ in5; out7 = tmp1 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_AC(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in1 ^ in3; out1 = in2 ^ in4; tmp0 = in0 ^ in2; out4 = in4 ^ in7; out5 = in0 ^ in5; out6 = in1 ^ in6; out7 = tmp0 ^ in7; out3 = tmp0 ^ in3 ^ in6; out2 = out5 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_AD(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in7; out5 = in0; out6 = in1; out7 = in0 ^ in2; out0 = in0 ^ in1 ^ in3; out2 = out7 ^ in1 ^ in5; out1 = in1 ^ in2 ^ in4; out3 = out7 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_AE(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in3 ^ in4; tmp0 = in0 ^ in4; tmp1 = in0 ^ in7; out0 = in1 ^ in3 ^ in7; out1 = tmp0 ^ in2; out5 = tmp0 ^ in5; tmp2 = tmp1 ^ in6; out2 = tmp1 ^ in5; out3 = tmp2 ^ in3; out7 = tmp2 ^ in2; out6 = tmp2 ^ out2 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_AF(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in3; tmp0 = in0 ^ in7; out5 = in0 ^ in4; out6 = in1 ^ in5; out7 = in0 ^ in2 ^ in6; out0 = tmp0 ^ in1 ^ in3; out3 = tmp0 ^ in6; out2 = tmp0 ^ in2 ^ in5; out1 = out5 ^ in1 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B0(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in4; tmp1 = in3 ^ in6; out2 = tmp0 ^ in7; tmp2 = tmp0 ^ tmp1; out0 = tmp2 ^ in5; out3 = tmp2 ^ in2; out6 = out3 ^ in6; tmp3 = out6 ^ in0 ^ in1; out7 = tmp3 ^ in5; out5 = tmp3 ^ out2; out1 = out0 ^ out5 ^ in0; out4 = tmp1 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B1(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in4; out2 = tmp0 ^ in2 ^ in7; tmp1 = out2 ^ in6; out1 = tmp1 ^ in5; out3 = tmp1 ^ in7; out4 = tmp1 ^ in0; out6 = out3 ^ in3; out0 = out6 ^ in0 ^ in2 ^ in5; out5 = tmp1 ^ out0 ^ in1; out7 = tmp0 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B2(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in4; tmp0 = in4 ^ in7; tmp1 = in1 ^ in3 ^ in6; out3 = tmp0 ^ tmp1; tmp2 = tmp1 ^ in0; out0 = out3 ^ in5; out4 = tmp2 ^ in2; tmp3 = out4 ^ in6; out5 = tmp0 ^ tmp3; out1 = tmp3 ^ out0; tmp4 = out1 ^ in7; out7 = tmp4 ^ in3; out6 = tmp2 ^ tmp4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B3(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in2 ^ in4; tmp0 = in0 ^ in5; tmp1 = in1 ^ in6; out3 = tmp1 ^ in4 ^ in7; tmp2 = tmp0 ^ out3; out0 = tmp2 ^ in3; out1 = tmp2 ^ in2; out5 = out0 ^ in2 ^ in6; out7 = tmp1 ^ out5; out4 = out7 ^ in1 ^ in5 ^ in7; out6 = tmp0 ^ out4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B4(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in0 ^ in1; out5 = out4 ^ in2; tmp0 = out4 ^ in4; out6 = out5 ^ in0 ^ in3; out7 = tmp0 ^ out6; out2 = tmp0 ^ in6 ^ in7; out3 = out7 ^ in0 ^ in7; out0 = out5 ^ out7 ^ in5; out1 = out0 ^ out6 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B5(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; tmp1 = in2 ^ in4; out4 = tmp0 ^ in4; out3 = tmp1 ^ in7; tmp2 = out4 ^ in5; out7 = out3 ^ in0 ^ in3; out0 = tmp2 ^ in3; out2 = tmp0 ^ out3 ^ in6; out5 = tmp1 ^ tmp2; out6 = out2 ^ out7 ^ in2; out1 = tmp0 ^ out0 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B6(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in3 ^ in4; tmp0 = in1 ^ in2; tmp1 = in0 ^ in4; tmp2 = in3 ^ in5; tmp3 = out3 ^ in1 ^ in7; out5 = tmp0 ^ tmp1; out6 = tmp0 ^ tmp2; out2 = tmp1 ^ in6; out4 = tmp1 ^ tmp3; out0 = tmp3 ^ in5; out1 = out2 ^ in2 ^ in5; out7 = tmp2 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B7(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in4; tmp0 = in0 ^ in4; out2 = tmp0 ^ in2 ^ in6; tmp1 = out2 ^ in7; out1 = out2 ^ in1 ^ in5; out7 = tmp1 ^ in3; out5 = out1 ^ in6; out6 = tmp0 ^ out1 ^ in3; out0 = tmp1 ^ out6; out4 = out0 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B8(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in4; tmp1 = in2 ^ in5; out2 = tmp0 ^ in5; out4 = tmp1 ^ in0; tmp2 = tmp1 ^ in7; out6 = tmp2 ^ out2; out7 = out4 ^ in3; out1 = tmp2 ^ in4; out3 = tmp0 ^ out7; out0 = out3 ^ out4 ^ in6; out5 = out0 ^ in0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_B9(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in2; tmp1 = in4 ^ in5; out4 = tmp0 ^ tmp1; tmp2 = tmp0 ^ in3 ^ in7; out3 = out4 ^ in1; out7 = tmp2 ^ in5; out2 = out3 ^ in0; out1 = out2 ^ in7; out6 = out1 ^ in5 ^ in6; out0 = tmp2 ^ out6; out5 = tmp1 ^ out0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_BA(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in5 ^ in7; out2 = tmp0 ^ in4; tmp1 = out2 ^ in2; out1 = tmp1 ^ in0; out6 = tmp1 ^ in1; out4 = out1 ^ in3 ^ in4; tmp2 = out4 ^ out6; out7 = out4 ^ in6 ^ in7; out5 = tmp2 ^ in6; out3 = tmp0 ^ tmp2; out0 = out6 ^ out7 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_BB(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in2 ^ in4 ^ in5 ^ in7; tmp0 = out2 ^ in1; out4 = out2 ^ in0 ^ in3; out1 = tmp0 ^ in0; out6 = tmp0 ^ in6; out3 = out1 ^ in2; tmp1 = out4 ^ out6 ^ in4; out0 = tmp1 ^ in7; out5 = tmp1 ^ in5; out7 = tmp0 ^ tmp1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_BC(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in2; tmp1 = in2 ^ in4; out0 = in1 ^ in3 ^ in4; out6 = in1 ^ in2 ^ in7; out7 = tmp0 ^ in3; out5 = tmp0 ^ out6 ^ in6; out1 = tmp1 ^ in5; tmp2 = out1 ^ out5 ^ in1; out3 = tmp2 ^ in3; out4 = tmp1 ^ tmp2; out2 = tmp2 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_BD(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3; tmp1 = in1 ^ in4; out0 = tmp0 ^ tmp1; out7 = tmp0 ^ in2 ^ in7; out1 = tmp1 ^ in2 ^ in5; tmp2 = out1 ^ in0; out2 = tmp2 ^ in6; out3 = out2 ^ in1 ^ in7; out4 = out3 ^ in2; out5 = tmp1 ^ out4; out6 = tmp2 ^ out4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_BE(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3 ^ in6; out4 = tmp0 ^ in5; out7 = tmp0 ^ in2; out3 = out4 ^ in4; out1 = out3 ^ out7 ^ in0; out2 = out3 ^ in3 ^ in7; out0 = out2 ^ out4 ^ in1; out5 = tmp0 ^ out0; out6 = out1 ^ out5 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_BF(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in4; out3 = tmp0 ^ in5 ^ in6; out4 = out3 ^ in3; tmp1 = out3 ^ in7; out2 = tmp1 ^ in2; out5 = tmp1 ^ in1; tmp2 = out2 ^ in5; out7 = tmp2 ^ in3 ^ in4; tmp3 = tmp0 ^ out5; out0 = tmp3 ^ out4; out1 = tmp2 ^ tmp3; out6 = tmp3 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C0(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out5 = in2 ^ in5; tmp0 = in1 ^ in4; tmp1 = in3 ^ in6; out0 = out5 ^ in1; out4 = tmp0 ^ in7; out3 = tmp0 ^ tmp1; out1 = tmp1 ^ in2; out6 = tmp1 ^ in0; out7 = out4 ^ in0; out2 = out4 ^ out5 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C1(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out5 = in2; tmp0 = in0 ^ in1; out4 = in1 ^ in7; out6 = in0 ^ in3; out3 = in1 ^ in4 ^ in6; tmp1 = tmp0 ^ in2; out7 = tmp0 ^ in4; out0 = tmp1 ^ in5; out1 = tmp1 ^ out6 ^ in6; out2 = out6 ^ out7 ^ in5 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C2(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in1 ^ in3 ^ in4; tmp0 = in0 ^ in3 ^ in6; out5 = in2 ^ in4 ^ in5; tmp1 = out4 ^ in7; out1 = tmp0 ^ in2; out6 = tmp0 ^ in5; out2 = out5 ^ in3; out7 = tmp0 ^ tmp1; out3 = tmp1 ^ in2 ^ in6; out0 = tmp1 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C3(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in1 ^ in3; tmp0 = in0 ^ in2; tmp1 = in3 ^ in5; out5 = in2 ^ in4; tmp2 = tmp0 ^ out4; out2 = tmp1 ^ in4; out6 = tmp1 ^ in0; out0 = tmp1 ^ tmp2 ^ in7; out1 = tmp2 ^ in6; out7 = out1 ^ out5 ^ in3; out3 = tmp0 ^ out7 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C4(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in7; out3 = tmp0 ^ in4; tmp1 = tmp0 ^ in2; out1 = tmp1 ^ in6; out5 = tmp1 ^ in5; out4 = out1 ^ out3 ^ in1; out0 = out4 ^ in4 ^ in5; out2 = out0 ^ out3 ^ in0; out7 = out1 ^ out2 ^ in7; out6 = tmp1 ^ out0 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C5(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in4 ^ in7; tmp0 = in3 ^ in7; out4 = in1 ^ in2 ^ in6; out6 = in0 ^ in3 ^ in4; out5 = tmp0 ^ in2; out1 = tmp0 ^ out4; out0 = out4 ^ in0 ^ in5; out2 = out0 ^ out5 ^ in4; out7 = tmp0 ^ out2 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C6(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in5 ^ in6; tmp1 = in1 ^ in7; tmp2 = tmp0 ^ in0; tmp3 = tmp0 ^ tmp1; tmp4 = tmp2 ^ in4; out0 = tmp3 ^ in2; out6 = tmp4 ^ in3; out2 = out6 ^ in2; out7 = tmp1 ^ tmp4; out3 = tmp2 ^ out2; tmp5 = out3 ^ in5; out5 = tmp5 ^ in7; out4 = tmp3 ^ tmp5; out1 = tmp4 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C7(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in2 ^ in4; tmp0 = in3 ^ in5; tmp1 = out3 ^ in7; out6 = tmp0 ^ in0 ^ in4; out5 = tmp1 ^ in3; out2 = out6 ^ in6; out7 = out2 ^ in1 ^ in3; out0 = tmp1 ^ out7; out1 = tmp0 ^ out0; out4 = out1 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C8(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out0 = in1 ^ in2; out1 = in2 ^ in3; tmp0 = in5 ^ in6; tmp1 = in0 ^ in7; out2 = out1 ^ in1 ^ in4; out4 = tmp0 ^ in4; out5 = tmp0 ^ in7; out6 = tmp1 ^ in6; out7 = tmp1 ^ in1; out3 = out2 ^ in0 ^ in2 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_C9(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in5 ^ in6; out7 = in0 ^ in1; tmp0 = in1 ^ in3; out5 = in6 ^ in7; out6 = in0 ^ in7; out0 = out7 ^ in2; out3 = out7 ^ in4 ^ in5; out1 = tmp0 ^ in2; out2 = tmp0 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_CA(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in7; tmp1 = in2 ^ in7; tmp2 = tmp0 ^ in6; out0 = tmp1 ^ in1; tmp3 = tmp1 ^ in3; out6 = tmp2 ^ in5; out7 = tmp2 ^ in1; out2 = tmp3 ^ in4; out5 = out6 ^ in0 ^ in4; out4 = out5 ^ in3; out1 = tmp0 ^ tmp3; out3 = tmp3 ^ out5 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_CB(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in4 ^ in7; tmp1 = in5 ^ in7; out7 = in0 ^ in1 ^ in6; out5 = tmp0 ^ in6; out2 = tmp0 ^ in3; out6 = tmp1 ^ in0; out4 = tmp1 ^ in3 ^ in6; tmp2 = out5 ^ out7 ^ in2; out1 = tmp2 ^ out2; out0 = tmp2 ^ in4; out3 = tmp2 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_CC(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in5; tmp1 = in1 ^ in6; out1 = in2 ^ in3 ^ in7; out5 = tmp0 ^ in6; out0 = tmp1 ^ in2; tmp2 = out5 ^ in0 ^ in7; out3 = tmp2 ^ in4; out6 = tmp0 ^ out3; out7 = tmp1 ^ tmp2 ^ in3; tmp3 = out1 ^ out6; out4 = tmp2 ^ tmp3; out2 = tmp3 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_CD(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out5 = in3 ^ in6; tmp0 = in0 ^ in1; tmp1 = in2 ^ in7; out6 = in0 ^ in4 ^ in7; out2 = tmp0 ^ out5 ^ in4; out7 = tmp0 ^ in5; out0 = tmp0 ^ in2 ^ in6; out4 = tmp1 ^ in5; out1 = tmp1 ^ in1 ^ in3; out3 = out6 ^ in5 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_CE(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in5; tmp1 = tmp0 ^ in3; out4 = tmp1 ^ in4; tmp2 = out4 ^ in6; out3 = tmp2 ^ in0; out5 = tmp2 ^ in2; out2 = out3 ^ in5 ^ in7; out6 = tmp1 ^ out2; out7 = out2 ^ out4 ^ in1; out1 = tmp2 ^ out6; out0 = tmp0 ^ out7 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_CF(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in6; tmp1 = in0 ^ in1 ^ in5; out4 = in2 ^ in3 ^ in5; out5 = tmp0 ^ in4; out7 = tmp1 ^ in6; out1 = tmp1 ^ out4 ^ in7; tmp2 = out5 ^ in0; out2 = tmp2 ^ in7; out3 = tmp2 ^ out4; out6 = tmp0 ^ out2 ^ in5; out0 = tmp0 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D0(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3; tmp1 = in1 ^ in4; tmp2 = in2 ^ in5; out7 = tmp0 ^ tmp1; out0 = tmp1 ^ tmp2; tmp3 = tmp2 ^ in3; out1 = tmp3 ^ in6; tmp4 = out1 ^ in1; out2 = tmp4 ^ in7; out3 = out2 ^ in2; out4 = tmp0 ^ out3; out5 = tmp3 ^ out3; out6 = tmp4 ^ out4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D1(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in5 ^ in6; tmp1 = tmp0 ^ in1; out1 = tmp1 ^ in2; out2 = tmp1 ^ in7; out3 = out2 ^ in3; out5 = out3 ^ in2; tmp2 = out3 ^ in0; out4 = tmp2 ^ in4; out7 = tmp0 ^ out4; out6 = tmp2 ^ out1 ^ in6; out0 = out2 ^ out6 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D2(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in5 ^ in6; out2 = tmp0 ^ in2 ^ in3; out1 = out2 ^ in0; out3 = out2 ^ in1; out4 = out1 ^ in1 ^ in2; out6 = out1 ^ in6 ^ in7; out7 = out4 ^ in4 ^ in5; out5 = out4 ^ out6 ^ in4; out0 = tmp0 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D3(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in3 ^ in5 ^ in6; tmp0 = out2 ^ in2; tmp1 = tmp0 ^ in1; out1 = tmp1 ^ in0; out3 = tmp1 ^ in3; out4 = out1 ^ in2 ^ in4; tmp2 = out4 ^ in5; out7 = tmp2 ^ in7; out0 = tmp0 ^ out7; tmp3 = out0 ^ in0; out5 = tmp3 ^ in6; out6 = tmp2 ^ tmp3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D4(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in3 ^ in5; tmp0 = in1 ^ in5; tmp1 = tmp0 ^ in2; out4 = tmp1 ^ in0; tmp2 = tmp1 ^ in6; out2 = out4 ^ in3 ^ in7; out0 = tmp2 ^ in4; out5 = tmp2 ^ out3; out1 = tmp0 ^ out5 ^ in7; out6 = tmp0 ^ out2 ^ in4; out7 = tmp1 ^ out6 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D5(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in5; tmp0 = in0 ^ in4; tmp1 = tmp0 ^ in1 ^ in5; out4 = tmp1 ^ in2; out0 = out4 ^ in6; tmp2 = tmp0 ^ out0; out5 = tmp2 ^ in3; out1 = out5 ^ in7; out6 = tmp1 ^ out1; out7 = tmp2 ^ out6; out2 = out7 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D6(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in2 ^ in4 ^ in6; out5 = tmp0 ^ in3; out0 = tmp0 ^ in5 ^ in7; out3 = out0 ^ out5 ^ in2; tmp1 = out3 ^ in0; out1 = tmp1 ^ in6; out2 = tmp1 ^ in7; out4 = tmp1 ^ in1; out6 = tmp1 ^ in4; out7 = tmp0 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D7(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in3; out3 = in2 ^ in5 ^ in7; out2 = tmp0 ^ in5; tmp1 = tmp0 ^ out3 ^ in1; out1 = tmp1 ^ in6; out4 = tmp1 ^ in4; tmp2 = out1 ^ in4; out6 = tmp2 ^ in1; out7 = tmp2 ^ in2; out0 = tmp2 ^ in3; out5 = tmp2 ^ in0 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D8(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in0; out5 = in1; tmp0 = in1 ^ in2; out6 = in0 ^ in2; out0 = tmp0 ^ in4; tmp1 = tmp0 ^ in3; out7 = tmp1 ^ out6; out2 = tmp1 ^ in6; out3 = out7 ^ in7; out1 = tmp1 ^ in1 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_D9(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in0 ^ in4; out5 = in1 ^ in5; out2 = in1 ^ in3 ^ in6; out3 = in0 ^ in1 ^ in7; out6 = in0 ^ in2 ^ in6; out0 = out4 ^ in1 ^ in2; out1 = out5 ^ in2 ^ in3; out7 = out3 ^ in3; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_DA(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out5 = in1 ^ in4; tmp0 = in2 ^ in7; tmp1 = in0 ^ in2 ^ in3; out0 = tmp0 ^ out5; out4 = tmp0 ^ tmp1; out2 = tmp0 ^ in3 ^ in6; out1 = tmp1 ^ in5; out3 = tmp1 ^ in1; out6 = out1 ^ in3; out7 = out3 ^ in2 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_DB(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; tmp1 = in1 ^ in5; tmp2 = in3 ^ in7; out3 = tmp0 ^ in2; out5 = tmp1 ^ in4; out6 = tmp1 ^ out3 ^ in6; out2 = tmp2 ^ in6; tmp3 = tmp2 ^ in4; tmp4 = out3 ^ in3; out4 = tmp3 ^ in0; out1 = tmp4 ^ in5; out0 = tmp3 ^ tmp4; out7 = tmp0 ^ out2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_DC(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in2; tmp1 = in0 ^ in3; out6 = tmp0 ^ in4; tmp2 = tmp0 ^ in7; out3 = tmp1 ^ in6; tmp3 = tmp1 ^ in1; out1 = tmp1 ^ tmp2 ^ in5; out4 = tmp2 ^ in6; out2 = tmp3 ^ in2; out7 = tmp3 ^ in5; out5 = tmp2 ^ out2; out0 = out2 ^ out3 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_DD(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in0 ^ in6; out2 = in0 ^ in1 ^ in3; out6 = out3 ^ in2 ^ in4; out7 = out2 ^ in5 ^ in7; out0 = out6 ^ in1; out4 = out6 ^ in7; out5 = out7 ^ in0; out1 = out5 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_DE(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in3 ^ in6; tmp1 = in3 ^ in4 ^ in7; out4 = tmp0 ^ in0; out5 = tmp1 ^ in1; out3 = out4 ^ in7; out2 = out3 ^ in6; out1 = out2 ^ in5; out6 = tmp1 ^ out1; out0 = tmp0 ^ out5; out7 = out0 ^ out1 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_DF(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in0 ^ in3 ^ in7; tmp0 = out2 ^ in1 ^ in5; out1 = tmp0 ^ in2; out7 = tmp0 ^ in6; out5 = tmp0 ^ in0 ^ in4; tmp1 = out1 ^ out5 ^ in6; out4 = tmp1 ^ in3; out6 = tmp1 ^ in5; tmp2 = tmp1 ^ in7; out0 = tmp2 ^ in1; out3 = tmp2 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E0(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in1 ^ in7; tmp0 = in2 ^ in4; out4 = out3 ^ in3 ^ in5; out2 = tmp0 ^ in1; tmp1 = tmp0 ^ in6; out0 = out4 ^ in2; out6 = out4 ^ in0; out1 = tmp1 ^ in3; out5 = tmp1 ^ in0; out7 = out5 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E1(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in1 ^ in4; tmp0 = in1 ^ in7; out3 = tmp0 ^ in3; tmp1 = out3 ^ in5; out4 = tmp1 ^ in4; tmp2 = tmp1 ^ in0; out0 = tmp2 ^ in2; out6 = tmp2 ^ in6; tmp3 = out0 ^ out4 ^ in6; out5 = tmp3 ^ in5; out7 = tmp0 ^ tmp3; out1 = tmp2 ^ out5 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E2(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in1 ^ in2; out4 = in1 ^ in5; out2 = in2 ^ in4 ^ in7; out5 = in0 ^ in2 ^ in6; out0 = out3 ^ in3 ^ in5; out7 = out3 ^ in0 ^ in4; out6 = out2 ^ out7 ^ in3; out1 = out5 ^ in3 ^ in4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E3(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in4 ^ in7; tmp0 = in1 ^ in3; out3 = tmp0 ^ in2; tmp1 = out3 ^ in0; out0 = tmp1 ^ in5; tmp2 = tmp1 ^ in4; out1 = tmp2 ^ in6; tmp3 = tmp2 ^ in3; out7 = tmp3 ^ in7; out6 = out1 ^ out2 ^ in2; tmp4 = tmp0 ^ out0; out5 = tmp4 ^ in6; out4 = tmp3 ^ tmp4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E4(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in6; tmp0 = in0 ^ in4; tmp1 = tmp0 ^ in2 ^ in6; out2 = tmp1 ^ in1; out7 = out2 ^ in5; tmp2 = tmp0 ^ out7; out4 = tmp2 ^ in3; out0 = out4 ^ in7; out6 = tmp1 ^ out0; out5 = tmp2 ^ out6; out1 = out5 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E5(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in3 ^ in6; tmp0 = in0 ^ in1; tmp1 = in5 ^ in7; out2 = tmp0 ^ in4 ^ in6; tmp2 = tmp1 ^ out2; out6 = tmp2 ^ in3; out7 = tmp2 ^ in2; out0 = out6 ^ in2 ^ in4; out5 = out6 ^ in1 ^ in2; out1 = tmp0 ^ out5 ^ in5; out4 = tmp1 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E6(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in2 ^ in6 ^ in7; out2 = out3 ^ in0 ^ in4; out4 = out3 ^ in1 ^ in5; out1 = out2 ^ in3; out7 = out2 ^ out4 ^ in2; out0 = out4 ^ in3 ^ in7; out5 = out1 ^ in4; out6 = out0 ^ out2 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E7(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in3; out3 = tmp0 ^ in6 ^ in7; tmp1 = out3 ^ in0; out5 = tmp1 ^ in5; tmp2 = tmp1 ^ in4; tmp3 = out5 ^ in7; out1 = tmp2 ^ in1; out0 = tmp3 ^ in1; out6 = out1 ^ in2; out2 = tmp0 ^ tmp2; tmp4 = tmp3 ^ out6; out4 = tmp4 ^ in6; out7 = tmp4 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E8(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in3 ^ in6; tmp0 = in4 ^ in7; out1 = in2 ^ in3 ^ in4; out5 = tmp0 ^ in0; tmp1 = tmp0 ^ in1; tmp2 = tmp1 ^ in5; out0 = tmp1 ^ out1; out2 = tmp2 ^ in2; out6 = tmp2 ^ out5; tmp3 = out6 ^ in6; out3 = tmp3 ^ in7; out7 = tmp3 ^ in2 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_E9(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; tmp1 = in3 ^ in6; tmp2 = tmp0 ^ in6; out4 = tmp1 ^ in4; out6 = tmp2 ^ in5; out7 = tmp2 ^ in2 ^ in7; out3 = out6 ^ in3 ^ in7; out0 = tmp1 ^ out7; out2 = out3 ^ out4 ^ in0; out5 = tmp0 ^ out2; out1 = out0 ^ out5 ^ in5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_EA(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in6 ^ in7; out5 = in0 ^ in7; out6 = in0 ^ in1; out0 = in1 ^ in2 ^ in3; out2 = in2 ^ in4 ^ in5; out7 = out6 ^ in2; out1 = out0 ^ out6 ^ in4; out3 = out7 ^ in5 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_EB(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in4 ^ in5; tmp0 = in0 ^ in1; out4 = in4 ^ in6 ^ in7; out5 = in0 ^ in5 ^ in7; out6 = tmp0 ^ in6; tmp1 = tmp0 ^ in2; out0 = tmp1 ^ in3; out7 = tmp1 ^ in7; out1 = out0 ^ in4; out3 = out0 ^ in5 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_EC(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out3 = in0 ^ in5; out4 = in2 ^ in3 ^ in7; out5 = in0 ^ in3 ^ in4; out6 = out3 ^ in1 ^ in4; out1 = out4 ^ in4; out0 = out4 ^ in1 ^ in6; out2 = out0 ^ out5 ^ in5; out7 = out2 ^ in4 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_ED(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in2 ^ in4; tmp1 = in3 ^ in5; out4 = tmp0 ^ in3 ^ in7; out3 = tmp1 ^ in0; out1 = out4 ^ in1; out5 = out3 ^ in4; out7 = out1 ^ out5 ^ in6; out2 = tmp0 ^ out7; out0 = tmp1 ^ out7; out6 = out2 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_EE(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in2; tmp0 = in0 ^ in1; out5 = in0 ^ in3; tmp1 = tmp0 ^ in2; out6 = tmp0 ^ in4; tmp2 = tmp1 ^ out5; out7 = tmp1 ^ in5; out1 = tmp2 ^ out6 ^ in7; out0 = tmp2 ^ in6; tmp3 = out7 ^ in1; out3 = tmp3 ^ in7; out2 = tmp3 ^ in4 ^ in6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_EF(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out4 = in2 ^ in4; tmp0 = in0 ^ in5; tmp1 = in4 ^ in6; out5 = tmp0 ^ in3; out2 = tmp0 ^ tmp1; out6 = tmp1 ^ in0 ^ in1; out3 = out5 ^ in2 ^ in7; out7 = out3 ^ in1 ^ in3; out0 = out4 ^ out6 ^ in3; out1 = tmp1 ^ out0 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F0(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in2; tmp1 = in4 ^ in5; out2 = tmp0 ^ in6; out3 = tmp1 ^ in1; tmp2 = tmp1 ^ in7; out1 = out2 ^ out3 ^ in3; tmp3 = tmp0 ^ tmp2; out0 = tmp3 ^ in3; out5 = tmp3 ^ in0; out4 = out1 ^ out5 ^ in4; out7 = out4 ^ in2; out6 = tmp2 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F1(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in1 ^ in6; tmp0 = in3 ^ in5; out3 = tmp0 ^ in1 ^ in4; tmp1 = out3 ^ in2; out1 = tmp1 ^ in6; tmp2 = tmp1 ^ in0; tmp3 = out1 ^ in5; out0 = tmp2 ^ in7; out6 = tmp2 ^ in4; out7 = tmp3 ^ in0; out5 = tmp0 ^ out0; out4 = tmp3 ^ out5 ^ in1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F2(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in4 ^ in5; out2 = in2 ^ in6 ^ in7; tmp1 = tmp0 ^ in1; tmp2 = tmp1 ^ in2; out0 = tmp2 ^ in3; out3 = tmp2 ^ in7; out5 = out3 ^ in0 ^ in4; tmp3 = tmp0 ^ out5; out7 = tmp3 ^ in3; out4 = tmp3 ^ out2; out1 = out0 ^ out4 ^ in4; out6 = tmp1 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F3(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in6 ^ in7; tmp0 = in0 ^ in1; out4 = tmp0 ^ in6; tmp1 = tmp0 ^ in2; out5 = tmp1 ^ in7; out6 = tmp1 ^ in3; out7 = out6 ^ in4; out0 = out7 ^ in5; out1 = out0 ^ in6; out3 = out0 ^ in0 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F4(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in0 ^ in1 ^ in2; tmp0 = out2 ^ in3; out4 = tmp0 ^ in4; out5 = out4 ^ in5; out6 = out5 ^ in6; out7 = out6 ^ in7; out0 = out7 ^ in0; out1 = out0 ^ in1; out3 = tmp0 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F5(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in0 ^ in1; tmp0 = out2 ^ in2; out4 = tmp0 ^ in3; out5 = out4 ^ in4; out6 = out5 ^ in5; out7 = out6 ^ in6; out0 = out7 ^ in7; out1 = out0 ^ in0; out3 = tmp0 ^ out0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F6(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in7; out2 = tmp0 ^ in2; out4 = out2 ^ in1 ^ in4; out7 = out4 ^ in3 ^ in5; out5 = out7 ^ in4 ^ in7; out0 = tmp0 ^ out7 ^ in6; tmp1 = out0 ^ in1; out6 = out0 ^ in0 ^ in5; out3 = tmp1 ^ in3; out1 = tmp0 ^ tmp1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F7(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in0 ^ in7; tmp0 = out2 ^ in1; out4 = tmp0 ^ in2; out5 = out4 ^ in3 ^ in7; out6 = out5 ^ in4; out7 = out6 ^ in5; out0 = out7 ^ in6; out1 = out0 ^ in7; out3 = tmp0 ^ out1; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F8(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in4; tmp1 = in3 ^ in5; tmp2 = tmp0 ^ in6; out4 = tmp0 ^ tmp1; out1 = tmp1 ^ in2 ^ in4; out3 = tmp2 ^ in1; out5 = out3 ^ in5; out7 = out1 ^ out5 ^ in7; out6 = tmp1 ^ out7; out0 = tmp2 ^ out7; out2 = out6 ^ in0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_F9(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in3 ^ in5; tmp1 = in0 ^ in6; out4 = tmp0 ^ in0; tmp2 = tmp1 ^ in4; tmp3 = tmp1 ^ in2; out5 = tmp2 ^ in1; out3 = out5 ^ in3; tmp4 = tmp3 ^ out3; out1 = tmp4 ^ in5; out0 = tmp4 ^ in0 ^ in7; out6 = tmp0 ^ out0 ^ in4; out7 = tmp2 ^ tmp4; out2 = tmp3 ^ out6; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_FA(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in1; tmp1 = tmp0 ^ in2; tmp2 = tmp0 ^ in5; tmp3 = tmp1 ^ in7; out5 = tmp2 ^ in6; out6 = tmp3 ^ in6; out7 = tmp3 ^ in3; out3 = out6 ^ in4; out2 = tmp1 ^ out5; out4 = out2 ^ out3 ^ in1; out0 = out4 ^ out7 ^ in5; out1 = tmp2 ^ out0; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_FB(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in5 ^ in6; tmp0 = in0 ^ in1; out4 = in0 ^ in5 ^ in7; out5 = tmp0 ^ in6; tmp1 = tmp0 ^ in2; out6 = tmp1 ^ in7; out7 = tmp1 ^ in3; out0 = out7 ^ in4; out1 = out0 ^ in5; out3 = out0 ^ in6 ^ in7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_FC(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in1 ^ in2; tmp1 = in0 ^ in7; out2 = tmp0 ^ tmp1 ^ in5; out3 = tmp1 ^ in4; tmp2 = out2 ^ in6; out6 = tmp2 ^ in4; out7 = tmp2 ^ in3; out4 = out6 ^ in1 ^ in3; tmp3 = out4 ^ in0; out1 = tmp3 ^ in6; out0 = tmp3 ^ in1 ^ in5; out5 = tmp0 ^ out4; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_FD(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in5; tmp1 = in1 ^ in7; out2 = tmp0 ^ tmp1; out6 = out2 ^ in2 ^ in4; tmp2 = out6 ^ in0; out1 = tmp2 ^ in3; out0 = tmp0 ^ out1 ^ in6; out5 = out0 ^ in2; tmp3 = out5 ^ in1; out3 = tmp3 ^ in6; out7 = tmp2 ^ tmp3; out4 = tmp1 ^ out7; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_FE(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3, tmp4; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; tmp0 = in0 ^ in2; out2 = tmp0 ^ in5; out3 = tmp0 ^ in4; tmp1 = out3 ^ in6; out4 = tmp1 ^ in5; tmp2 = tmp1 ^ in1; out6 = tmp2 ^ in7; tmp3 = tmp2 ^ in0; out0 = tmp3 ^ in3; tmp4 = out0 ^ out4 ^ in7; out5 = tmp4 ^ in6; out7 = tmp4 ^ in2; out1 = tmp3 ^ out5; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void gf8_muladd_FF(void *out, void *in) { unsigned int i; uint64_t *in_ptr = (uint64_t *)in; uint64_t *out_ptr = (uint64_t *)out; for (i = 0; i < WIDTH; i++) { uint64_t out0, out1, out2, out3, out4, out5, out6, out7; uint64_t tmp0, tmp1, tmp2, tmp3; uint64_t in0 = out_ptr[0]; uint64_t in1 = out_ptr[WIDTH]; uint64_t in2 = out_ptr[WIDTH * 2]; uint64_t in3 = out_ptr[WIDTH * 3]; uint64_t in4 = out_ptr[WIDTH * 4]; uint64_t in5 = out_ptr[WIDTH * 5]; uint64_t in6 = out_ptr[WIDTH * 6]; uint64_t in7 = out_ptr[WIDTH * 7]; out2 = in0 ^ in5; tmp0 = in4 ^ in7; tmp1 = out2 ^ in2; out4 = tmp1 ^ in6; out7 = tmp1 ^ in1 ^ in3; out1 = tmp0 ^ out7; tmp2 = out1 ^ in5; out6 = tmp2 ^ in3; tmp3 = tmp2 ^ in7; out0 = tmp3 ^ in6; out3 = tmp3 ^ in1; out5 = tmp0 ^ out0 ^ in2; out_ptr[0] = out0 ^ in_ptr[0]; out_ptr[WIDTH] = out1 ^ in_ptr[WIDTH]; out_ptr[WIDTH * 2] = out2 ^ in_ptr[WIDTH * 2]; out_ptr[WIDTH * 3] = out3 ^ in_ptr[WIDTH * 3]; out_ptr[WIDTH * 4] = out4 ^ in_ptr[WIDTH * 4]; out_ptr[WIDTH * 5] = out5 ^ in_ptr[WIDTH * 5]; out_ptr[WIDTH * 6] = out6 ^ in_ptr[WIDTH * 6]; out_ptr[WIDTH * 7] = out7 ^ in_ptr[WIDTH * 7]; in_ptr++; out_ptr++; } } static void (*gf8_muladd[])(void *out, void *in) = { gf8_muladd_00, gf8_muladd_01, gf8_muladd_02, gf8_muladd_03, gf8_muladd_04, gf8_muladd_05, gf8_muladd_06, gf8_muladd_07, gf8_muladd_08, gf8_muladd_09, gf8_muladd_0A, gf8_muladd_0B, gf8_muladd_0C, gf8_muladd_0D, gf8_muladd_0E, gf8_muladd_0F, gf8_muladd_10, gf8_muladd_11, gf8_muladd_12, gf8_muladd_13, gf8_muladd_14, gf8_muladd_15, gf8_muladd_16, gf8_muladd_17, gf8_muladd_18, gf8_muladd_19, gf8_muladd_1A, gf8_muladd_1B, gf8_muladd_1C, gf8_muladd_1D, gf8_muladd_1E, gf8_muladd_1F, gf8_muladd_20, gf8_muladd_21, gf8_muladd_22, gf8_muladd_23, gf8_muladd_24, gf8_muladd_25, gf8_muladd_26, gf8_muladd_27, gf8_muladd_28, gf8_muladd_29, gf8_muladd_2A, gf8_muladd_2B, gf8_muladd_2C, gf8_muladd_2D, gf8_muladd_2E, gf8_muladd_2F, gf8_muladd_30, gf8_muladd_31, gf8_muladd_32, gf8_muladd_33, gf8_muladd_34, gf8_muladd_35, gf8_muladd_36, gf8_muladd_37, gf8_muladd_38, gf8_muladd_39, gf8_muladd_3A, gf8_muladd_3B, gf8_muladd_3C, gf8_muladd_3D, gf8_muladd_3E, gf8_muladd_3F, gf8_muladd_40, gf8_muladd_41, gf8_muladd_42, gf8_muladd_43, gf8_muladd_44, gf8_muladd_45, gf8_muladd_46, gf8_muladd_47, gf8_muladd_48, gf8_muladd_49, gf8_muladd_4A, gf8_muladd_4B, gf8_muladd_4C, gf8_muladd_4D, gf8_muladd_4E, gf8_muladd_4F, gf8_muladd_50, gf8_muladd_51, gf8_muladd_52, gf8_muladd_53, gf8_muladd_54, gf8_muladd_55, gf8_muladd_56, gf8_muladd_57, gf8_muladd_58, gf8_muladd_59, gf8_muladd_5A, gf8_muladd_5B, gf8_muladd_5C, gf8_muladd_5D, gf8_muladd_5E, gf8_muladd_5F, gf8_muladd_60, gf8_muladd_61, gf8_muladd_62, gf8_muladd_63, gf8_muladd_64, gf8_muladd_65, gf8_muladd_66, gf8_muladd_67, gf8_muladd_68, gf8_muladd_69, gf8_muladd_6A, gf8_muladd_6B, gf8_muladd_6C, gf8_muladd_6D, gf8_muladd_6E, gf8_muladd_6F, gf8_muladd_70, gf8_muladd_71, gf8_muladd_72, gf8_muladd_73, gf8_muladd_74, gf8_muladd_75, gf8_muladd_76, gf8_muladd_77, gf8_muladd_78, gf8_muladd_79, gf8_muladd_7A, gf8_muladd_7B, gf8_muladd_7C, gf8_muladd_7D, gf8_muladd_7E, gf8_muladd_7F, gf8_muladd_80, gf8_muladd_81, gf8_muladd_82, gf8_muladd_83, gf8_muladd_84, gf8_muladd_85, gf8_muladd_86, gf8_muladd_87, gf8_muladd_88, gf8_muladd_89, gf8_muladd_8A, gf8_muladd_8B, gf8_muladd_8C, gf8_muladd_8D, gf8_muladd_8E, gf8_muladd_8F, gf8_muladd_90, gf8_muladd_91, gf8_muladd_92, gf8_muladd_93, gf8_muladd_94, gf8_muladd_95, gf8_muladd_96, gf8_muladd_97, gf8_muladd_98, gf8_muladd_99, gf8_muladd_9A, gf8_muladd_9B, gf8_muladd_9C, gf8_muladd_9D, gf8_muladd_9E, gf8_muladd_9F, gf8_muladd_A0, gf8_muladd_A1, gf8_muladd_A2, gf8_muladd_A3, gf8_muladd_A4, gf8_muladd_A5, gf8_muladd_A6, gf8_muladd_A7, gf8_muladd_A8, gf8_muladd_A9, gf8_muladd_AA, gf8_muladd_AB, gf8_muladd_AC, gf8_muladd_AD, gf8_muladd_AE, gf8_muladd_AF, gf8_muladd_B0, gf8_muladd_B1, gf8_muladd_B2, gf8_muladd_B3, gf8_muladd_B4, gf8_muladd_B5, gf8_muladd_B6, gf8_muladd_B7, gf8_muladd_B8, gf8_muladd_B9, gf8_muladd_BA, gf8_muladd_BB, gf8_muladd_BC, gf8_muladd_BD, gf8_muladd_BE, gf8_muladd_BF, gf8_muladd_C0, gf8_muladd_C1, gf8_muladd_C2, gf8_muladd_C3, gf8_muladd_C4, gf8_muladd_C5, gf8_muladd_C6, gf8_muladd_C7, gf8_muladd_C8, gf8_muladd_C9, gf8_muladd_CA, gf8_muladd_CB, gf8_muladd_CC, gf8_muladd_CD, gf8_muladd_CE, gf8_muladd_CF, gf8_muladd_D0, gf8_muladd_D1, gf8_muladd_D2, gf8_muladd_D3, gf8_muladd_D4, gf8_muladd_D5, gf8_muladd_D6, gf8_muladd_D7, gf8_muladd_D8, gf8_muladd_D9, gf8_muladd_DA, gf8_muladd_DB, gf8_muladd_DC, gf8_muladd_DD, gf8_muladd_DE, gf8_muladd_DF, gf8_muladd_E0, gf8_muladd_E1, gf8_muladd_E2, gf8_muladd_E3, gf8_muladd_E4, gf8_muladd_E5, gf8_muladd_E6, gf8_muladd_E7, gf8_muladd_E8, gf8_muladd_E9, gf8_muladd_EA, gf8_muladd_EB, gf8_muladd_EC, gf8_muladd_ED, gf8_muladd_EE, gf8_muladd_EF, gf8_muladd_F0, gf8_muladd_F1, gf8_muladd_F2, gf8_muladd_F3, gf8_muladd_F4, gf8_muladd_F5, gf8_muladd_F6, gf8_muladd_F7, gf8_muladd_F8, gf8_muladd_F9, gf8_muladd_FA, gf8_muladd_FB, gf8_muladd_FC, gf8_muladd_FD, gf8_muladd_FE, gf8_muladd_FF}; static uint64_t zero[EC_METHOD_WORD_SIZE * 8] = { 0, }; void ec_code_c_prepare(ec_gf_t *gf, uint32_t *values, uint32_t count) { uint32_t i, last, tmp; last = 1; for (i = count; i > 0; i--) { if (values[i - 1] != 0) { tmp = values[i - 1]; values[i - 1] = ec_gf_div(gf, tmp, last); last = tmp; } } } void ec_code_c_linear(void *dst, void *src, uint64_t offset, uint32_t *values, uint32_t count) { src += offset; gf8_muladd_00(dst, src); while (--count > 0) { src += EC_METHOD_CHUNK_SIZE; gf8_muladd[*values](dst, src); values++; } } void ec_code_c_interleaved(void *dst, void **src, uint64_t offset, uint32_t *values, uint32_t count) { uint32_t i, last, tmp; i = 0; while ((last = *values++) == 0) { i++; } gf8_muladd_00(dst, src[i++] + offset); while (i < count) { tmp = *values++; if (tmp != 0) { gf8_muladd[last](dst, src[i] + offset); last = tmp; } i++; } gf8_muladd[last](dst, zero); } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-data.c0000644000000000000000000000013214522202451022355 xustar000000000000000030 mtime=1699284265.635027335 30 atime=1699284265.635027335 30 ctime=1699284301.323134827 glusterfs-11.1/xlators/cluster/ec/src/ec-data.c0000664000175100017510000001543214522202451022641 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "ec-helpers.h" #include "ec-common.h" #include "ec-data.h" #include "ec-messages.h" ec_cbk_data_t * ec_cbk_data_allocate(call_frame_t *frame, xlator_t *this, ec_fop_data_t *fop, int32_t id, int32_t idx, int32_t op_ret, int32_t op_errno) { ec_cbk_data_t *cbk; ec_t *ec = this->private; if (fop->xl != this) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, EC_MSG_XLATOR_MISMATCH, "Mismatching xlators between request " "and answer (req=%s, ans=%s).", fop->xl->name, this->name); return NULL; } if (fop->frame != frame) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, EC_MSG_FRAME_MISMATCH, "Mismatching frames between request " "and answer (req=%p, ans=%p).", fop->frame, frame); return NULL; } if (fop->id != id) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, EC_MSG_FOP_MISMATCH, "Mismatching fops between request " "and answer (req=%d, ans=%d).", fop->id, id); return NULL; } cbk = mem_get0(ec->cbk_pool); if (cbk == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to allocate memory for an " "answer."); return NULL; } cbk->fop = fop; cbk->idx = idx; cbk->mask = 1ULL << idx; cbk->count = 1; cbk->op_ret = op_ret; cbk->op_errno = op_errno; INIT_LIST_HEAD(&cbk->entries.list); LOCK(&fop->lock); list_add_tail(&cbk->answer_list, &fop->answer_list); UNLOCK(&fop->lock); return cbk; } void ec_cbk_data_destroy(ec_cbk_data_t *cbk) { if (cbk->xdata != NULL) { dict_unref(cbk->xdata); } if (cbk->dict != NULL) { dict_unref(cbk->dict); } if (cbk->inode != NULL) { inode_unref(cbk->inode); } if (cbk->fd != NULL) { fd_unref(cbk->fd); } if (cbk->buffers != NULL) { iobref_unref(cbk->buffers); } GF_FREE(cbk->vector); gf_dirent_free(&cbk->entries); GF_FREE(cbk->str); mem_put(cbk); } ec_fop_data_t * ec_fop_data_allocate(call_frame_t *frame, xlator_t *this, int32_t id, uint32_t flags, uintptr_t target, uint32_t fop_flags, ec_wind_f wind, ec_handler_f handler, ec_cbk_t cbks, void *data) { ec_fop_data_t *fop, *parent; ec_t *ec = this->private; fop = mem_get0(ec->fop_pool); if (fop == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to allocate memory for a " "request."); return NULL; } INIT_LIST_HEAD(&fop->cbk_list); INIT_LIST_HEAD(&fop->healer); INIT_LIST_HEAD(&fop->answer_list); INIT_LIST_HEAD(&fop->pending_list); INIT_LIST_HEAD(&fop->locks[0].owner_list); INIT_LIST_HEAD(&fop->locks[0].wait_list); INIT_LIST_HEAD(&fop->locks[1].owner_list); INIT_LIST_HEAD(&fop->locks[1].wait_list); fop->xl = this; fop->req_frame = frame; /* fops need a private frame to be able to execute some postop operations * even if the original fop has completed and reported back to the upper * xlator and it has destroyed the base frame. * * TODO: minimize usage of private frames. Reuse req_frame as much as * possible. */ if (frame != NULL) { fop->frame = copy_frame(frame); } else { fop->frame = create_frame(this, this->ctx->pool); } if (fop->frame == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to create a private frame " "for a request"); mem_put(fop); return NULL; } fop->id = id; fop->refs = 1; fop->flags = flags; fop->minimum = EC_FOP_MINIMUM(fop_flags); fop->fop_flags = EC_FOP_FLAGS(fop_flags); fop->mask = target; fop->wind = wind; fop->handler = handler; fop->cbks = cbks; fop->data = data; fop->uid = fop->frame->root->uid; fop->gid = fop->frame->root->gid; LOCK_INIT(&fop->lock); fop->frame->local = fop; if (frame != NULL) { parent = frame->local; if (parent != NULL) { ec_sleep(parent); } fop->parent = parent; } LOCK(&ec->lock); list_add_tail(&fop->pending_list, &ec->pending_fops); UNLOCK(&ec->lock); return fop; } void ec_fop_data_acquire(ec_fop_data_t *fop) { LOCK(&fop->lock); ec_trace("ACQUIRE", fop, ""); fop->refs++; UNLOCK(&fop->lock); } static void ec_handle_last_pending_fop_completion(ec_fop_data_t *fop, gf_boolean_t *notify) { ec_t *ec = fop->xl->private; *notify = _gf_false; if (!list_empty(&fop->pending_list)) { LOCK(&ec->lock); { list_del_init(&fop->pending_list); *notify = __ec_is_last_fop(ec); } UNLOCK(&ec->lock); } } void ec_fop_cleanup(ec_fop_data_t *fop) { ec_cbk_data_t *cbk, *tmp; list_for_each_entry_safe(cbk, tmp, &fop->answer_list, answer_list) { list_del_init(&cbk->answer_list); ec_cbk_data_destroy(cbk); } INIT_LIST_HEAD(&fop->cbk_list); fop->answer = NULL; } void ec_fop_data_release(ec_fop_data_t *fop) { ec_t *ec = NULL; int32_t refs; gf_boolean_t notify = _gf_false; LOCK(&fop->lock); ec_trace("RELEASE", fop, ""); GF_ASSERT(fop->refs > 0); refs = --fop->refs; UNLOCK(&fop->lock); if (refs == 0) { fop->frame->local = NULL; STACK_DESTROY(fop->frame->root); if (fop->xdata != NULL) { dict_unref(fop->xdata); } if (fop->dict != NULL) { dict_unref(fop->dict); } if (fop->inode != NULL) { inode_unref(fop->inode); } if (fop->fd != NULL) { fd_unref(fop->fd); } if (fop->buffers != NULL) { iobref_unref(fop->buffers); } GF_FREE(fop->vector); GF_FREE(fop->str[0]); GF_FREE(fop->str[1]); loc_wipe(&fop->loc[0]); loc_wipe(&fop->loc[1]); GF_FREE(fop->errstr); ec_resume_parent(fop); ec_fop_cleanup(fop); ec = fop->xl->private; ec_handle_last_pending_fop_completion(fop, ¬ify); ec_handle_healers_done(fop); LOCK_DESTROY(&fop->lock); mem_put(fop); if (notify) { ec_pending_fops_completed(ec); } } } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-helpers.c0000644000000000000000000000013214522202451023106 xustar000000000000000030 mtime=1699284265.640027351 30 atime=1699284265.640027351 30 ctime=1699284301.325134833 glusterfs-11.1/xlators/cluster/ec/src/ec-helpers.c0000664000175100017510000004554614522202451023403 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "ec.h" #include "ec-mem-types.h" #include "ec-messages.h" #include "ec-fops.h" #include "ec-method.h" #include "ec-helpers.h" static const char *ec_fop_list[] = {[-EC_FOP_HEAL] = "HEAL"}; const char * ec_bin(char *str, size_t size, uint64_t value, int32_t digits) { str += size; if (size-- < 1) { goto failed; } *--str = 0; while ((value != 0) || (digits > 0)) { if (size-- < 1) { goto failed; } *--str = '0' + (value & 1); digits--; value >>= 1; } return str; failed: return ""; } const char * ec_fop_name(int32_t id) { if (id >= 0) { return gf_fop_list[id]; } return ec_fop_list[-id]; } void ec_trace(const char *event, ec_fop_data_t *fop, const char *fmt, ...) { char str1[32], str2[32], str3[32]; char *msg; ec_t *ec = fop->xl->private; va_list args; int32_t ret; va_start(args, fmt); ret = vasprintf(&msg, fmt, args); va_end(args); if (ret < 0) { msg = ""; } gf_msg_trace("ec", 0, "%s(%s) %p(%p) [refs=%d, winds=%d, jobs=%d] " "frame=%p/%p, min/exp=%d/%d, err=%d state=%d " "{%s:%s:%s} %s", event, ec_fop_name(fop->id), fop, fop->parent, fop->refs, fop->winds, fop->jobs, fop->req_frame, fop->frame, fop->minimum, fop->expected, fop->error, fop->state, ec_bin(str1, sizeof(str1), fop->mask, ec->nodes), ec_bin(str2, sizeof(str2), fop->remaining, ec->nodes), ec_bin(str3, sizeof(str3), fop->good, ec->nodes), msg); if (ret >= 0) { free(msg); } } size_t ec_iov_copy_to(void *dst, struct iovec *vector, int32_t count, off_t offset, size_t size) { int32_t i = 0; size_t total = 0, len = 0; while (i < count) { if (offset < vector[i].iov_len) { while ((i < count) && (size > 0)) { len = size; if (len > vector[i].iov_len - offset) { len = vector[i].iov_len - offset; } memcpy(dst, vector[i++].iov_base + offset, len); offset = 0; dst += len; total += len; size -= len; } break; } offset -= vector[i].iov_len; i++; } return total; } int32_t ec_buffer_alloc(xlator_t *xl, size_t size, struct iobref **piobref, void **ptr) { struct iobref *iobref = NULL; struct iobuf *iobuf = NULL; int32_t ret = -ENOMEM; iobuf = iobuf_get_page_aligned(xl->ctx->iobuf_pool, size, EC_METHOD_WORD_SIZE); if (iobuf == NULL) { goto out; } iobref = *piobref; if (iobref == NULL) { iobref = iobref_new(); if (iobref == NULL) { goto out; } } ret = iobref_add(iobref, iobuf); if (ret != 0) { if (iobref != *piobref) { iobref_unref(iobref); } iobref = NULL; goto out; } GF_ASSERT(EC_ALIGN_CHECK(iobuf->ptr, EC_METHOD_WORD_SIZE)); *ptr = iobuf->ptr; out: if (iobuf != NULL) { iobuf_unref(iobuf); } if (iobref != NULL) { *piobref = iobref; } return ret; } int32_t ec_dict_set_array(dict_t *dict, char *key, uint64_t value[], int32_t size) { int ret = -1; uint64_t *ptr = NULL; int32_t vindex; if (value == NULL) { return -EINVAL; } ptr = GF_MALLOC(sizeof(uint64_t) * size, gf_common_mt_char); if (ptr == NULL) { return -ENOMEM; } for (vindex = 0; vindex < size; vindex++) { ptr[vindex] = htobe64(value[vindex]); } ret = dict_set_bin(dict, key, ptr, sizeof(uint64_t) * size); if (ret) GF_FREE(ptr); return ret; } int32_t ec_dict_get_array(dict_t *dict, char *key, uint64_t value[], int32_t size) { void *ptr; int32_t len; int32_t vindex; int32_t old_size = 0; int32_t err; if (dict == NULL) { return -EINVAL; } err = dict_get_ptr_and_len(dict, key, &ptr, &len); if (err != 0) { return err; } if (len > (size * sizeof(uint64_t)) || (len % sizeof(uint64_t))) { return -EINVAL; } /* 3.6 version ec would have stored version in 64 bit. In that case treat * metadata versions same as data*/ old_size = min(size, len / sizeof(uint64_t)); for (vindex = 0; vindex < old_size; vindex++) { value[vindex] = be64toh(*((uint64_t *)ptr + vindex)); } if (old_size < size) { for (vindex = old_size; vindex < size; vindex++) { value[vindex] = value[old_size - 1]; } } return 0; } int32_t ec_dict_del_array(dict_t *dict, char *key, uint64_t value[], int32_t size) { int ret = 0; ret = ec_dict_get_array(dict, key, value, size); if (ret == 0) dict_del(dict, key); return ret; } int32_t ec_dict_set_number(dict_t *dict, char *key, uint64_t value) { int ret = -1; uint64_t *ptr; ptr = GF_MALLOC(sizeof(value), gf_common_mt_char); if (ptr == NULL) { return -ENOMEM; } *ptr = htobe64(value); ret = dict_set_bin(dict, key, ptr, sizeof(value)); if (ret) GF_FREE(ptr); return ret; } int32_t ec_dict_del_number(dict_t *dict, char *key, uint64_t *value) { void *ptr; int32_t len, err; if (dict == NULL) { return -EINVAL; } err = dict_get_ptr_and_len(dict, key, &ptr, &len); if (err != 0) { return err; } if (len != sizeof(uint64_t)) { return -EINVAL; } *value = be64toh(*(uint64_t *)ptr); dict_del(dict, key); return 0; } int32_t ec_dict_set_config(dict_t *dict, char *key, ec_config_t *config) { int ret = -1; uint64_t *ptr, data; if (config->version > EC_CONFIG_VERSION) { gf_msg("ec", GF_LOG_ERROR, EINVAL, EC_MSG_UNSUPPORTED_VERSION, "Trying to store an unsupported config " "version (%u)", config->version); return -EINVAL; } ptr = GF_MALLOC(sizeof(uint64_t), gf_common_mt_char); if (ptr == NULL) { return -ENOMEM; } data = ((uint64_t)config->version) << 56; data |= ((uint64_t)config->algorithm) << 48; data |= ((uint64_t)config->gf_word_size) << 40; data |= ((uint64_t)config->bricks) << 32; data |= ((uint64_t)config->redundancy) << 24; data |= config->chunk_size; *ptr = htobe64(data); ret = dict_set_bin(dict, key, ptr, sizeof(uint64_t)); if (ret) GF_FREE(ptr); return ret; } int32_t ec_dict_del_config(dict_t *dict, char *key, ec_config_t *config) { void *ptr; uint64_t data; int32_t len, err; if (dict == NULL) { return -EINVAL; } err = dict_get_ptr_and_len(dict, key, &ptr, &len); if (err != 0) { return err; } if (len != sizeof(uint64_t)) { return -EINVAL; } data = be64toh(*(uint64_t *)ptr); /* Currently we need to get the config xattr for entries of type IA_INVAL. * These entries can later become IA_DIR entries (after inode_link()), * which don't have a config xattr. However, since the xattr is requested * using an xattrop() fop, it will always return a config full of 0's * instead of saying that it doesn't exist. * * We need to filter out this case and consider that a config xattr == 0 is * the same as a non-existent xattr. Otherwise ec_config_check() will fail. */ if (data == 0) { return -ENODATA; } config->version = (data >> 56) & 0xff; if (config->version > EC_CONFIG_VERSION) { gf_msg("ec", GF_LOG_ERROR, EINVAL, EC_MSG_UNSUPPORTED_VERSION, "Found an unsupported config version (%u)", config->version); return -EINVAL; } config->algorithm = (data >> 48) & 0xff; config->gf_word_size = (data >> 40) & 0xff; config->bricks = (data >> 32) & 0xff; config->redundancy = (data >> 24) & 0xff; config->chunk_size = data & 0xffffff; dict_del(dict, key); return 0; } gf_boolean_t ec_loc_gfid_check(xlator_t *xl, uuid_t dst, uuid_t src) { if (gf_uuid_is_null(src)) { return _gf_true; } if (gf_uuid_is_null(dst)) { gf_uuid_copy(dst, src); return _gf_true; } if (gf_uuid_compare(dst, src) != 0) { gf_msg(xl->name, GF_LOG_WARNING, 0, EC_MSG_GFID_MISMATCH, "Mismatching GFID's in loc"); return _gf_false; } return _gf_true; } int32_t ec_loc_setup_inode(xlator_t *xl, inode_table_t *table, loc_t *loc) { int32_t ret = -EINVAL; if (loc->inode != NULL) { if (!ec_loc_gfid_check(xl, loc->gfid, loc->inode->gfid)) { goto out; } } else if (table != NULL) { if (!gf_uuid_is_null(loc->gfid)) { loc->inode = inode_find(table, loc->gfid); } else if (loc->path && strchr(loc->path, '/')) { loc->inode = inode_resolve(table, (char *)loc->path); } } ret = 0; out: return ret; } int32_t ec_loc_setup_parent(xlator_t *xl, inode_table_t *table, loc_t *loc) { char *path, *parent; int32_t ret = -EINVAL; if (loc->parent != NULL) { if (!ec_loc_gfid_check(xl, loc->pargfid, loc->parent->gfid)) { goto out; } } else if (table != NULL) { if (!gf_uuid_is_null(loc->pargfid)) { loc->parent = inode_find(table, loc->pargfid); } else if (loc->path && strchr(loc->path, '/')) { path = gf_strdup(loc->path); if (path == NULL) { gf_msg(xl->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Unable to duplicate path '%s'", loc->path); ret = -ENOMEM; goto out; } parent = dirname(path); loc->parent = inode_resolve(table, parent); if (loc->parent != NULL) { gf_uuid_copy(loc->pargfid, loc->parent->gfid); } GF_FREE(path); } } /* If 'pargfid' has not been determined, clear 'name' to avoid resolutions based on /name. */ if (gf_uuid_is_null(loc->pargfid)) { loc->name = NULL; } ret = 0; out: return ret; } int32_t ec_loc_setup_path(xlator_t *xl, loc_t *loc) { static uuid_t root = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; char *name; int32_t ret = -EINVAL; if (loc->path != NULL) { name = strrchr(loc->path, '/'); if (name == NULL) { /* Allow gfid paths: */ if (strncmp(loc->path, "path) { if (name[1] == 0) { if (!ec_loc_gfid_check(xl, loc->gfid, root)) { goto out; } } else { if (!ec_loc_gfid_check(xl, loc->pargfid, root)) { goto out; } } } name++; if (loc->name != NULL) { if (strcmp(loc->name, name) != 0) { gf_msg(xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_INVALID_LOC_NAME, "Invalid name '%s' in loc", loc->name); goto out; } } else { loc->name = name; } } ret = 0; out: return ret; } int32_t ec_loc_parent(xlator_t *xl, loc_t *loc, loc_t *parent) { inode_table_t *table = NULL; char *str = NULL; int32_t ret = -ENOMEM; memset(parent, 0, sizeof(loc_t)); if (loc->parent != NULL) { table = loc->parent->table; parent->inode = inode_ref(loc->parent); } else if (loc->inode != NULL) { table = loc->inode->table; } if (!gf_uuid_is_null(loc->pargfid)) { gf_uuid_copy(parent->gfid, loc->pargfid); } if (loc->path && strchr(loc->path, '/')) { str = gf_strdup(loc->path); if (str == NULL) { gf_msg(xl->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Unable to duplicate path '%s'", loc->path); goto out; } parent->path = gf_strdup(dirname(str)); if (parent->path == NULL) { gf_msg(xl->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Unable to duplicate path '%s'", dirname(str)); goto out; } } ret = ec_loc_setup_path(xl, parent); if (ret == 0) { ret = ec_loc_setup_inode(xl, table, parent); } if (ret == 0) { ret = ec_loc_setup_parent(xl, table, parent); } if (ret != 0) { goto out; } if ((parent->inode == NULL) && (parent->path == NULL) && gf_uuid_is_null(parent->gfid)) { gf_msg(xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_LOC_PARENT_INODE_MISSING, "Parent inode missing for loc_t"); ret = -EINVAL; goto out; } ret = 0; out: GF_FREE(str); if (ret != 0) { loc_wipe(parent); } return ret; } int32_t ec_loc_update(xlator_t *xl, loc_t *loc, inode_t *inode, struct iatt *iatt) { inode_table_t *table = NULL; int32_t ret = -EINVAL; if (inode != NULL) { table = inode->table; if (loc->inode != inode) { if (loc->inode != NULL) { inode_unref(loc->inode); } loc->inode = inode_ref(inode); gf_uuid_copy(loc->gfid, inode->gfid); } } else if (loc->inode != NULL) { table = loc->inode->table; } else if (loc->parent != NULL) { table = loc->parent->table; } if (iatt != NULL) { if (!ec_loc_gfid_check(xl, loc->gfid, iatt->ia_gfid)) { goto out; } } ret = ec_loc_setup_path(xl, loc); if (ret == 0) { ret = ec_loc_setup_inode(xl, table, loc); } if (ret == 0) { ret = ec_loc_setup_parent(xl, table, loc); } if (ret != 0) { goto out; } out: return ret; } int32_t ec_loc_from_fd(xlator_t *xl, loc_t *loc, fd_t *fd) { ec_fd_t *ctx; int32_t ret = -ENOMEM; memset(loc, 0, sizeof(*loc)); ctx = ec_fd_get(fd, xl); if (ctx != NULL) { if (loc_copy(loc, &ctx->loc) != 0) { goto out; } } ret = ec_loc_update(xl, loc, fd->inode, NULL); if (ret != 0) { goto out; } out: if (ret != 0) { loc_wipe(loc); } return ret; } int32_t ec_loc_from_loc(xlator_t *xl, loc_t *dst, loc_t *src) { int32_t ret = -ENOMEM; memset(dst, 0, sizeof(*dst)); if (loc_copy(dst, src) != 0) { goto out; } ret = ec_loc_update(xl, dst, NULL, NULL); if (ret != 0) { goto out; } out: if (ret != 0) { loc_wipe(dst); } return ret; } void ec_owner_set(call_frame_t *frame, void *owner) { set_lk_owner_from_ptr(&frame->root->lk_owner, owner); } void ec_owner_copy(call_frame_t *frame, gf_lkowner_t *owner) { lk_owner_copy(&frame->root->lk_owner, owner); } static void ec_stripe_cache_init(ec_t *ec, ec_inode_t *ctx) { ec_stripe_list_t *stripe_cache = NULL; stripe_cache = &(ctx->stripe_cache); if (stripe_cache->max == 0) { stripe_cache->max = ec->stripe_cache; } } ec_inode_t * __ec_inode_get(inode_t *inode, xlator_t *xl) { ec_inode_t *ctx = NULL; uint64_t value = 0; if ((__inode_ctx_get(inode, xl, &value) != 0) || (value == 0)) { ctx = GF_MALLOC(sizeof(*ctx), ec_mt_ec_inode_t); if (ctx != NULL) { memset(ctx, 0, sizeof(*ctx)); INIT_LIST_HEAD(&ctx->heal); INIT_LIST_HEAD(&ctx->stripe_cache.lru); ctx->heal_count = 0; value = (uint64_t)(uintptr_t)ctx; if (__inode_ctx_set(inode, xl, &value) != 0) { GF_FREE(ctx); return NULL; } } } else { ctx = (ec_inode_t *)(uintptr_t)value; } if (ctx) ec_stripe_cache_init(xl->private, ctx); return ctx; } ec_inode_t * ec_inode_get(inode_t *inode, xlator_t *xl) { ec_inode_t *ctx = NULL; LOCK(&inode->lock); ctx = __ec_inode_get(inode, xl); UNLOCK(&inode->lock); return ctx; } ec_fd_t * __ec_fd_get(fd_t *fd, xlator_t *xl) { int i = 0; ec_fd_t *ctx = NULL; ec_inode_t *ictx = NULL; uint64_t value = 0; ec_t *ec = xl->private; ctx = __fd_ctx_get_ptr(fd, xl); if (!ctx) { ctx = GF_MALLOC(sizeof(*ctx) + (sizeof(ec_fd_status_t) * ec->nodes), ec_mt_ec_fd_t); if (ctx != NULL) { memset(ctx, 0, sizeof(*ctx)); for (i = 0; i < ec->nodes; i++) { if (fd_is_anonymous(fd)) { ctx->fd_status[i] = EC_FD_OPENED; } else { ctx->fd_status[i] = EC_FD_NOT_OPENED; } } value = (uint64_t)(uintptr_t)ctx; if (__fd_ctx_set(fd, xl, value) != 0) { GF_FREE(ctx); return NULL; } /* Only refering bad-version so no need for lock * */ ictx = __ec_inode_get(fd->inode, xl); if (ictx) { ctx->bad_version = ictx->bad_version; } } } /* Treat anonymous fd specially */ if (fd->anonymous && ctx) { /* Mark the fd open for all subvolumes. */ ctx->open = -1; /* Try to populate ctx->loc with fd->inode information. */ ec_loc_update(xl, &ctx->loc, fd->inode, NULL); } return ctx; } ec_fd_t * ec_fd_get(fd_t *fd, xlator_t *xl) { ec_fd_t *ctx = NULL; LOCK(&fd->lock); ctx = __ec_fd_get(fd, xl); UNLOCK(&fd->lock); return ctx; } gf_boolean_t ec_is_internal_xattr(dict_t *dict, char *key, data_t *value, void *data) { if (key && (strncmp(key, EC_XATTR_PREFIX, SLEN(EC_XATTR_PREFIX)) == 0)) return _gf_true; return _gf_false; } void ec_filter_internal_xattrs(dict_t *xattr) { dict_foreach_match(xattr, ec_is_internal_xattr, NULL, dict_remove_foreach_fn, NULL); } /* gf_boolean_t ec_is_metadata_fop (int32_t lock_kind, glusterfs_fop_t fop) { if (lock_kind == EC_LOCK_ENTRY) { return _gf_false; } switch (fop) { case GF_FOP_SETATTR: case GF_FOP_FSETATTR: case GF_FOP_SETXATTR: case GF_FOP_FSETXATTR: case GF_FOP_REMOVEXATTR: case GF_FOP_FREMOVEXATTR: return _gf_true; default: return _gf_false; } return _gf_false; }*/ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-heal.c0000644000000000000000000000013214522202451022355 xustar000000000000000030 mtime=1699284265.640027351 30 atime=1699284265.639027347 30 ctime=1699284301.345134894 glusterfs-11.1/xlators/cluster/ec/src/ec-heal.c0000664000175100017510000030617114522202451022644 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "ec.h" #include "ec-types.h" #include "ec-messages.h" #include "ec-helpers.h" #include "ec-common.h" #include "ec-combine.h" #include "ec-method.h" #include "ec-fops.h" #include "ec-heald.h" #define EC_COUNT(array, max) \ ({ \ int __i; \ int __res = 0; \ for (__i = 0; __i < max; __i++) \ if (array[__i]) \ __res++; \ __res; \ }) #define EC_INTERSECT(dst, src1, src2, max) \ ({ \ int __i; \ for (__i = 0; __i < max; __i++) \ dst[__i] = src1[__i] && src2[__i]; \ }) #define IA_EQUAL(f, s, field) \ (memcmp(&(f.ia_##field), &(s.ia_##field), sizeof(s.ia_##field)) == 0) #define EC_REPLIES_ALLOC(replies, numsubvols) \ do { \ int __i = 0; \ replies = alloca0(numsubvols * sizeof(*replies)); \ for (__i = 0; __i < numsubvols; __i++) \ INIT_LIST_HEAD(&replies[__i].entries.list); \ } while (0) static int32_t ec_heal_inspect(call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *locked_on, gf_boolean_t self_locked, gf_boolean_t thorough, ec_heal_need_t *need_heal); struct ec_name_data { call_frame_t *frame; unsigned char *participants; unsigned char *failed_on; unsigned char *gfidless; unsigned char *enoent; unsigned char *same; char *name; inode_t *parent; default_args_cbk_t *replies; uint32_t heal_pending; }; static char *ec_ignore_xattrs[] = {GF_SELINUX_XATTR_KEY, QUOTA_SIZE_KEY, SQUOTA_SIZE_KEY, SQUOTA_LIMIT_KEY, NULL}; static gf_boolean_t ec_ignorable_key_match(dict_t *dict, char *key, data_t *val, void *mdata) { int i = 0; if (!key) goto out; if (strncmp(key, EC_XATTR_PREFIX, SLEN(EC_XATTR_PREFIX)) == 0) return _gf_true; for (i = 0; ec_ignore_xattrs[i]; i++) { if (!strcmp(key, ec_ignore_xattrs[i])) return _gf_true; } out: return _gf_false; } static gf_boolean_t ec_sh_key_match(dict_t *dict, char *key, data_t *val, void *mdata) { return !ec_ignorable_key_match(dict, key, val, mdata); } /* FOP: heal */ static void ec_set_entry_healing(ec_fop_data_t *fop) { ec_inode_t *ctx = NULL; loc_t *loc = NULL; if (!fop) return; loc = &fop->loc[0]; LOCK(&loc->inode->lock); { ctx = __ec_inode_get(loc->inode, fop->xl); if (ctx) { ctx->heal_count += 1; } } UNLOCK(&loc->inode->lock); } static void ec_reset_entry_healing(ec_fop_data_t *fop) { ec_inode_t *ctx = NULL; loc_t *loc = NULL; int32_t heal_count = 0; if (!fop) return; loc = &fop->loc[0]; LOCK(&loc->inode->lock); { ctx = __ec_inode_get(loc->inode, fop->xl); if (ctx) { ctx->heal_count += -1; heal_count = ctx->heal_count; } } UNLOCK(&loc->inode->lock); GF_ASSERT(heal_count >= 0); } static uintptr_t ec_heal_check(ec_fop_data_t *fop, uintptr_t *pgood) { ec_cbk_data_t *cbk; uintptr_t mask[2] = {0, 0}; list_for_each_entry(cbk, &fop->cbk_list, list) { mask[cbk->op_ret >= 0] |= cbk->mask; } if (pgood != NULL) { *pgood = mask[1]; } return mask[0]; } static void ec_heal_update(ec_fop_data_t *fop, int32_t is_open) { ec_heal_t *heal = fop->data; uintptr_t good, bad; bad = ec_heal_check(fop, &good); LOCK(&heal->lock); heal->bad &= ~bad; if (is_open) { heal->open |= good; } UNLOCK(&heal->lock); fop->error = 0; } static void ec_heal_avoid(ec_fop_data_t *fop) { ec_heal_t *heal = fop->data; uintptr_t bad; bad = ec_heal_check(fop, NULL); LOCK(&heal->lock); heal->good &= ~bad; UNLOCK(&heal->lock); } static int32_t ec_heal_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = cookie; ec_heal_t *heal = fop->data; if (op_ret >= 0) { GF_ASSERT( ec_set_inode_size(heal->fop, heal->fd->inode, heal->total_size)); } return 0; } static void ec_heal_lock(ec_heal_t *heal, int32_t type, fd_t *fd, loc_t *loc, off_t offset, size_t size) { struct gf_flock flock; fop_inodelk_cbk_t cbk = NULL; flock.l_type = type; flock.l_whence = SEEK_SET; flock.l_start = offset; flock.l_len = size; flock.l_pid = 0; flock.l_owner.len = 0; if (type == F_UNLCK) { /* Remove inode size information before unlocking it. */ if (fd == NULL) { ec_clear_inode_info(heal->fop, heal->loc.inode); } else { ec_clear_inode_info(heal->fop, heal->fd->inode); } cbk = ec_lock_unlocked; } else { /* Otherwise use the callback to update size information. */ cbk = ec_heal_lock_cbk; } if (fd != NULL) { ec_finodelk(heal->fop->frame, heal->xl, &heal->fop->frame->root->lk_owner, heal->fop->mask, EC_MINIMUM_ALL, cbk, heal, heal->xl->name, fd, F_SETLKW, &flock, NULL); } else { ec_inodelk(heal->fop->frame, heal->xl, &heal->fop->frame->root->lk_owner, heal->fop->mask, EC_MINIMUM_ALL, cbk, heal, heal->xl->name, loc, F_SETLKW, &flock, NULL); } } void ec_heal_inodelk(ec_heal_t *heal, int32_t type, int32_t use_fd, off_t offset, size_t size) { ec_heal_lock(heal, type, use_fd ? heal->fd : NULL, &heal->loc, offset, size); } int32_t ec_heal_xattr_clean(dict_t *dict, char *key, data_t *data, void *arg) { dict_t *base = arg; if (ec_ignorable_key_match(NULL, key, NULL, NULL)) { dict_del(dict, key); return 0; } if (dict_get(base, key) != NULL) dict_del(dict, key); return 0; } /******************************************************************** * ec_wind_xattrop_parallel: * Helper function to update the extended attributes * in parallel. * *******************************************************************/ void ec_wind_xattrop_parallel(call_frame_t *frame, xlator_t *subvol, int child_index, loc_t *loc, gf_xattrop_flags_t flags, dict_t **dict, dict_t *xdata) { gf_msg_debug("EC", 0, "WIND: on child %d ", child_index); STACK_WIND_COOKIE( frame, cluster_xattrop_cbk, (void *)(uintptr_t)child_index, subvol, subvol->fops->xattrop, loc, flags, dict[child_index], xdata); } int32_t ec_heal_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { ec_fop_data_t *fop = cookie; ec_heal_t *heal = fop->data; ec_trace("WRITE_CBK", cookie, "ret=%d, errno=%d", op_ret, op_errno); gf_msg_debug(fop->xl->name, op_errno, "%s: write op_ret %d at %" PRIu64, uuid_utoa(heal->fd->inode->gfid), op_ret, heal->offset); ec_heal_update(cookie, 0); return 0; } int32_t ec_heal_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { ec_fop_data_t *fop = cookie; ec_heal_t *heal = fop->data; ec_trace("READ_CBK", fop, "ret=%d, errno=%d", op_ret, op_errno); ec_heal_avoid(fop); if (op_ret > 0) { gf_msg_debug(fop->xl->name, 0, "%s: read succeeded, proceeding " "to write at %" PRIu64, uuid_utoa(heal->fd->inode->gfid), heal->offset); ec_writev(heal->fop->frame, heal->xl, heal->bad, EC_MINIMUM_ONE, ec_heal_writev_cbk, heal, heal->fd, vector, count, heal->offset, 0, iobref, NULL); } else { if (op_ret < 0) { gf_msg_debug(fop->xl->name, op_errno, "%s: read failed, failing " "to heal block at %" PRIu64, uuid_utoa(heal->fd->inode->gfid), heal->offset); heal->bad = 0; } heal->done = _gf_true; } return 0; } void ec_heal_data_block(ec_heal_t *heal) { ec_trace("DATA", heal->fop, "good=%lX, bad=%lX", heal->good, heal->bad); if ((heal->good != 0) && (heal->bad != 0) && (heal->ia_type == IA_IFREG)) { ec_readv(heal->fop->frame, heal->xl, heal->good, EC_MINIMUM_MIN, ec_heal_readv_cbk, heal, heal->fd, heal->size, heal->offset, 0, NULL); } } /* FOP: fheal */ void ec_fheal(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fheal_cbk_t func, void *data, fd_t *fd, int32_t partial, dict_t *xdata) { ec_fd_t *ctx = ec_fd_get(fd, this); if (ctx != NULL) { gf_msg_trace("ec", 0, "FHEAL ctx: flags=%X, open=%" PRIXPTR, ctx->flags, ctx->open); ec_heal(frame, this, target, fop_flags, func, data, &ctx->loc, partial, xdata); } } /* Common heal code */ void ec_mask_to_char_array(uintptr_t mask, unsigned char *array, int numsubvols) { int i = 0; for (i = 0; i < numsubvols; i++) array[i] = ((mask >> i) & 1); } uintptr_t ec_char_array_to_mask(unsigned char *array, int numsubvols) { int i = 0; uintptr_t mask = 0; if (array == NULL) goto out; for (i = 0; i < numsubvols; i++) if (array[i]) mask |= (1ULL << i); out: return mask; } int ec_heal_entry_find_direction(ec_t *ec, default_args_cbk_t *replies, uint64_t *versions, uint64_t *dirty, unsigned char *sources, unsigned char *healed_sinks) { uint64_t xattr[EC_VERSION_SIZE] = {0}; int source = -1; uint64_t max_version = 0; int ret = 0; int i = 0; for (i = 0; i < ec->nodes; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret == -1) continue; if (source == -1) source = i; ret = ec_dict_get_array(replies[i].xdata, EC_XATTR_VERSION, xattr, EC_VERSION_SIZE); if (ret == 0) { versions[i] = xattr[EC_DATA_TXN]; if (max_version < versions[i]) { max_version = versions[i]; source = i; } } memset(xattr, 0, sizeof(xattr)); ret = ec_dict_get_array(replies[i].xdata, EC_XATTR_DIRTY, xattr, EC_VERSION_SIZE); if (ret == 0) { dirty[i] = xattr[EC_DATA_TXN]; } } if (source < 0) goto out; for (i = 0; i < ec->nodes; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret == -1) continue; if (versions[i] == versions[source]) sources[i] = 1; else healed_sinks[i] = 1; } out: return source; } int ec_adjust_versions(call_frame_t *frame, ec_t *ec, ec_txn_t type, inode_t *inode, int source, unsigned char *sources, unsigned char *healed_sinks, uint64_t *versions, uint64_t *dirty) { int i = 0; int ret = 0; int call_count = 0; dict_t **xattr = NULL; int op_ret = 0; loc_t loc = {0}; gf_boolean_t erase_dirty = _gf_false; uint64_t *versions_xattr = NULL; uint64_t *dirty_xattr = NULL; uint64_t allzero[2] = {0}; unsigned char *on = NULL; unsigned char *output = NULL; default_args_cbk_t *replies = NULL; /* Allocate the required memory */ loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); on = alloca0(ec->nodes); output = alloca0(ec->nodes); EC_REPLIES_ALLOC(replies, ec->nodes); xattr = GF_CALLOC(ec->nodes, sizeof(*xattr), gf_common_mt_pointer); if (!xattr) { op_ret = -ENOMEM; goto out; } for (i = 0; i < ec->nodes; i++) { xattr[i] = dict_new(); if (!xattr[i]) { op_ret = -ENOMEM; goto out; } } /* dirty xattr represents if the file/dir needs heal. Unless all the * copies are healed, don't erase it */ if (EC_COUNT(sources, ec->nodes) + EC_COUNT(healed_sinks, ec->nodes) == ec->nodes) erase_dirty = _gf_true; else op_ret = -ENOTCONN; /* Populate the xattr array */ for (i = 0; i < ec->nodes; i++) { if (!sources[i] && !healed_sinks[i]) continue; versions_xattr = GF_CALLOC(EC_VERSION_SIZE, sizeof(*versions_xattr), gf_common_mt_pointer); if (!versions_xattr) { op_ret = -ENOMEM; continue; } versions_xattr[type] = htobe64(versions[source] - versions[i]); ret = dict_set_bin(xattr[i], EC_XATTR_VERSION, versions_xattr, (sizeof(*versions_xattr) * EC_VERSION_SIZE)); if (ret < 0) { op_ret = -ENOMEM; continue; } if (erase_dirty) { dirty_xattr = GF_CALLOC(EC_VERSION_SIZE, sizeof(*dirty_xattr), gf_common_mt_pointer); if (!dirty_xattr) { op_ret = -ENOMEM; continue; } dirty_xattr[type] = htobe64(-dirty[i]); ret = dict_set_bin(xattr[i], EC_XATTR_DIRTY, dirty_xattr, (sizeof(*dirty_xattr) * EC_VERSION_SIZE)); if (ret < 0) { op_ret = -ENOMEM; continue; } } if (memcmp(versions_xattr, allzero, (sizeof(*versions_xattr) * EC_VERSION_SIZE)) == 0) { if (!erase_dirty) { continue; } if (memcmp(dirty_xattr, allzero, (sizeof(*dirty_xattr) * EC_VERSION_SIZE)) == 0) { continue; } } on[i] = 1; call_count++; } /* Update the bricks with xattr */ if (call_count) { PARALLEL_FOP_ONLIST(ec->xl_list, on, ec->nodes, replies, frame, ec_wind_xattrop_parallel, &loc, GF_XATTROP_ADD_ARRAY64, xattr, NULL); ret = cluster_fop_success_fill(replies, ec->nodes, output); } if (ret < call_count) { op_ret = -ENOTCONN; goto out; } out: /* Cleanup */ if (xattr) { for (i = 0; i < ec->nodes; i++) { if (xattr[i]) dict_unref(xattr[i]); } GF_FREE(xattr); } cluster_replies_wipe(replies, ec->nodes); loc_wipe(&loc); return op_ret; } int ec_heal_metadata_find_direction(ec_t *ec, default_args_cbk_t *replies, uint64_t *versions, uint64_t *dirty, unsigned char *sources, unsigned char *healed_sinks) { uint64_t xattr[EC_VERSION_SIZE] = {0}; uint64_t max_version = 0; int same_count = 0; int max_same_count = 0; int same_source = -1; int ret = 0; int i = 0; int j = 0; int *groups = NULL; struct iatt source_ia = {0}; struct iatt child_ia = {0}; groups = alloca0(ec->nodes * sizeof(*groups)); for (i = 0; i < ec->nodes; i++) groups[i] = -1; for (i = 0; i < ec->nodes; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret < 0) continue; ret = ec_dict_get_array(replies[i].xdata, EC_XATTR_VERSION, xattr, EC_VERSION_SIZE); if (ret == 0) { versions[i] = xattr[EC_METADATA_TXN]; } memset(xattr, 0, sizeof(xattr)); ret = ec_dict_get_array(replies[i].xdata, EC_XATTR_DIRTY, xattr, EC_VERSION_SIZE); if (ret == 0) { dirty[i] = xattr[EC_METADATA_TXN]; } if (groups[i] >= 0) /*Already part of group*/ continue; groups[i] = i; same_count = 1; source_ia = replies[i].stat; for (j = i + 1; j < ec->nodes; j++) { if (!replies[j].valid || replies[j].op_ret < 0) continue; child_ia = replies[j].stat; if (!IA_EQUAL(source_ia, child_ia, gfid) || !IA_EQUAL(source_ia, child_ia, type) || !IA_EQUAL(source_ia, child_ia, prot) || !IA_EQUAL(source_ia, child_ia, uid) || !IA_EQUAL(source_ia, child_ia, gid)) continue; if (!are_dicts_equal(replies[i].xdata, replies[j].xdata, ec_sh_key_match, NULL, NULL)) continue; groups[j] = i; same_count++; } if (max_same_count < same_count) { max_same_count = same_count; same_source = i; } } if (max_same_count < ec->fragments) { ret = -EIO; goto out; } for (i = 0; i < ec->nodes; i++) { if (groups[i] == groups[same_source]) sources[i] = 1; else if (replies[i].valid && replies[i].op_ret >= 0) healed_sinks[i] = 1; } for (i = 0; i < ec->nodes; i++) { if (sources[i] && (versions[i] > max_version)) { same_source = i; max_version = versions[i]; } } ret = same_source; out: return ret; } int __ec_heal_metadata_prepare(call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *locked_on, default_args_cbk_t *replies, uint64_t *versions, uint64_t *dirty, unsigned char *sources, unsigned char *healed_sinks) { loc_t loc = {0}; unsigned char *output = NULL; unsigned char *lookup_on = NULL; int ret = 0; int source = 0; default_args_cbk_t *greplies = NULL; int i = 0; EC_REPLIES_ALLOC(greplies, ec->nodes); loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); output = alloca0(ec->nodes); lookup_on = alloca0(ec->nodes); ret = cluster_lookup(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, &loc, NULL); if (ret <= ec->fragments) { ret = -ENOTCONN; goto out; } memcpy(lookup_on, output, ec->nodes); /*Use getxattr to get the filtered xattrs which filter internal xattrs*/ ret = cluster_getxattr(ec->xl_list, lookup_on, ec->nodes, greplies, output, frame, ec->xl, &loc, NULL, NULL); for (i = 0; i < ec->nodes; i++) { if (lookup_on[i] && !output[i]) { replies[i].valid = 0; continue; } if (replies[i].xdata) { dict_unref(replies[i].xdata); replies[i].xdata = NULL; if (greplies[i].xattr) replies[i].xdata = dict_ref(greplies[i].xattr); } } source = ec_heal_metadata_find_direction(ec, replies, versions, dirty, sources, healed_sinks); if (source < 0) { ret = -EIO; goto out; } ret = source; out: cluster_replies_wipe(greplies, ec->nodes); loc_wipe(&loc); return ret; } /* Metadata heal */ int __ec_removexattr_sinks(call_frame_t *frame, ec_t *ec, inode_t *inode, int source, unsigned char *sources, unsigned char *healed_sinks, default_args_cbk_t *replies) { int i = 0; int ret = 0; loc_t loc = {0}; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); for (i = 0; i < ec->nodes; i++) { if (i == source) continue; if (!sources[i] && !healed_sinks[i]) continue; ret = dict_foreach(replies[i].xdata, ec_heal_xattr_clean, replies[source].xdata); if (ret < 0) { sources[i] = 0; healed_sinks[i] = 0; continue; } if (replies[i].xdata->count == 0) { continue; } else if (sources[i]) { /* This can happen if setxattr/removexattr succeeds on * the bricks but fails to update the version. This * will make sure that the xattrs are made equal after * heal*/ sources[i] = 0; healed_sinks[i] = 1; } ret = syncop_removexattr(ec->xl_list[i], &loc, "", replies[i].xdata, NULL); if (ret < 0) healed_sinks[i] = 0; } loc_wipe(&loc); if (EC_COUNT(healed_sinks, ec->nodes) == 0) return -ENOTCONN; return 0; } int __ec_heal_metadata(call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *healed_sinks) { loc_t loc = {0}; int ret = 0; int source = 0; default_args_cbk_t *replies = NULL; default_args_cbk_t *sreplies = NULL; uint64_t *versions = NULL; uint64_t *dirty = NULL; unsigned char *output = NULL; dict_t *source_dict = NULL; struct iatt source_buf = {0}; EC_REPLIES_ALLOC(replies, ec->nodes); EC_REPLIES_ALLOC(sreplies, ec->nodes); loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); output = alloca0(ec->nodes); versions = alloca0(ec->nodes * sizeof(*versions)); dirty = alloca0(ec->nodes * sizeof(*dirty)); source = __ec_heal_metadata_prepare(frame, ec, inode, locked_on, replies, versions, dirty, sources, healed_sinks); if (source < 0) { ret = -EIO; goto out; } if ((EC_COUNT(sources, ec->nodes) == ec->nodes) || (EC_COUNT(healed_sinks, ec->nodes) == 0)) { ret = 0; goto erase_dirty; } source_buf = replies[source].stat; ret = cluster_setattr(ec->xl_list, healed_sinks, ec->nodes, sreplies, output, frame, ec->xl, &loc, &source_buf, GF_SET_ATTR_MODE | GF_SET_ATTR_UID | GF_SET_ATTR_GID, NULL); /*In case the operation fails on some of the subvols*/ memcpy(healed_sinks, output, ec->nodes); if (EC_COUNT(healed_sinks, ec->nodes) == 0) { ret = -ENOTCONN; goto out; } ret = __ec_removexattr_sinks(frame, ec, inode, source, sources, healed_sinks, replies); if (ret < 0) goto out; source_dict = dict_ref(replies[source].xdata); if (dict_foreach_match(source_dict, ec_ignorable_key_match, NULL, dict_remove_foreach_fn, NULL) == -1) { ret = -ENOMEM; goto out; } ret = cluster_setxattr(ec->xl_list, healed_sinks, ec->nodes, replies, output, frame, ec->xl, &loc, source_dict, 0, NULL); EC_INTERSECT(healed_sinks, healed_sinks, output, ec->nodes); if (EC_COUNT(healed_sinks, ec->nodes) == 0) { ret = -ENOTCONN; goto out; } erase_dirty: ret = ec_adjust_versions(frame, ec, EC_METADATA_TXN, inode, source, sources, healed_sinks, versions, dirty); out: if (source_dict) dict_unref(source_dict); loc_wipe(&loc); cluster_replies_wipe(replies, ec->nodes); cluster_replies_wipe(sreplies, ec->nodes); return ret; } int ec_heal_metadata(call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *sources, unsigned char *healed_sinks) { unsigned char *locked_on = NULL; unsigned char *up_subvols = NULL; unsigned char *output = NULL; int ret = 0; default_args_cbk_t *replies = NULL; EC_REPLIES_ALLOC(replies, ec->nodes); locked_on = alloca0(ec->nodes); output = alloca0(ec->nodes); up_subvols = alloca0(ec->nodes); ec_mask_to_char_array(ec->xl_up, up_subvols, ec->nodes); ret = cluster_inodelk(ec->xl_list, up_subvols, ec->nodes, replies, locked_on, frame, ec->xl, ec->xl->name, inode, 0, 0); { if (ret <= ec->fragments) { gf_msg_debug(ec->xl->name, 0, "%s: Skipping heal " "as only %d number of subvolumes could " "be locked", uuid_utoa(inode->gfid), ret); ret = -ENOTCONN; goto unlock; } ret = __ec_heal_metadata(frame, ec, inode, locked_on, sources, healed_sinks); } unlock: cluster_uninodelk(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, ec->xl->name, inode, 0, 0); cluster_replies_wipe(replies, ec->nodes); return ret; } /*entry heal*/ int __ec_heal_entry_prepare(call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *locked_on, uint64_t *versions, uint64_t *dirty, unsigned char *sources, unsigned char *healed_sinks) { loc_t loc = {0}; int source = 0; int ret = 0; default_args_cbk_t *replies = NULL; unsigned char *output = NULL; dict_t *xdata = NULL; EC_REPLIES_ALLOC(replies, ec->nodes); loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); xdata = dict_new(); if (!xdata) { ret = -ENOMEM; goto out; } if (dict_set_uint64(xdata, EC_XATTR_VERSION, 0) || dict_set_uint64(xdata, EC_XATTR_DIRTY, 0)) { ret = -ENOMEM; goto out; } output = alloca0(ec->nodes); ret = cluster_lookup(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, &loc, xdata); if (ret <= ec->fragments) { ret = -ENOTCONN; goto out; } source = ec_heal_entry_find_direction(ec, replies, versions, dirty, sources, healed_sinks); if (source < 0) { ret = -EIO; goto out; } ret = source; out: if (xdata) dict_unref(xdata); loc_wipe(&loc); cluster_replies_wipe(replies, ec->nodes); return ret; } int32_t ec_set_new_entry_dirty(ec_t *ec, loc_t *loc, struct iatt *ia, call_frame_t *frame, xlator_t *this, unsigned char *on) { dict_t *xattr = NULL; int32_t ret = -1; default_args_cbk_t *replies = NULL; unsigned char *output = NULL; uint64_t dirty[EC_VERSION_SIZE] = {1, 1}; loc_t newloc = {0}; /*Symlinks don't have any data to be healed*/ if (ia->ia_type == IA_IFLNK) dirty[EC_DATA_TXN] = 0; newloc.inode = inode_ref(loc->inode); gf_uuid_copy(newloc.gfid, ia->ia_gfid); EC_REPLIES_ALLOC(replies, ec->nodes); output = alloca0(ec->nodes); xattr = dict_new(); if (!xattr) { ret = -ENOMEM; goto out; } ret = ec_dict_set_array(xattr, EC_XATTR_DIRTY, dirty, EC_VERSION_SIZE); if (ret) goto out; ret = cluster_xattrop(ec->xl_list, on, ec->nodes, replies, output, frame, ec->xl, &newloc, GF_XATTROP_ADD_ARRAY64, xattr, NULL); if (ret < ec->fragments) { ret = -ENOTCONN; goto out; } out: if (xattr) dict_unref(xattr); cluster_replies_wipe(replies, ec->nodes); loc_wipe(&newloc); return ret; } /*Name heal*/ int ec_delete_stale_name(dict_t *gfid_db, char *key, data_t *d, void *data) { struct ec_name_data *name_data = data; struct iatt *ia = NULL; ec_t *ec = NULL; loc_t loc = {0}; unsigned char *same = data_to_bin(d); default_args_cbk_t *replies = NULL; unsigned char *output = NULL; int ret = 0; int estale_count = 0; int i = 0; call_frame_t *frame = name_data->frame; uuid_t gfid; ec = name_data->frame->this->private; EC_REPLIES_ALLOC(replies, ec->nodes); if (EC_COUNT(same, ec->nodes) >= ec->fragments) { ret = 0; goto out; } loc.parent = inode_ref(name_data->parent); loc.inode = inode_new(name_data->parent->table); if (!loc.inode) { ret = -ENOMEM; goto out; } gf_uuid_parse(key, gfid); gf_uuid_copy(loc.pargfid, name_data->parent->gfid); loc.name = name_data->name; output = alloca0(ec->nodes); ret = cluster_lookup(ec->xl_list, name_data->participants, ec->nodes, replies, output, name_data->frame, ec->xl, &loc, NULL); for (i = 0; i < ec->nodes; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret == -1) { if (replies[i].op_errno == ESTALE || replies[i].op_errno == ENOENT) estale_count++; else name_data->participants[i] = 0; } else if (gf_uuid_compare(gfid, replies[i].stat.ia_gfid)) { estale_count++; gf_msg_debug(ec->xl->name, 0, "%s/%s: different gfid as %s", uuid_utoa(name_data->parent->gfid), name_data->name, key); } } if (estale_count <= ec->redundancy) { /* We have at least ec->fragments number of fragments, so the * file is recoverable, so don't delete it*/ /* Please note that the lookup call above could fail with * ENOTCONN on all subvoumes and still this branch will be * true, but in those cases conservatively we decide to not * delete the file until we are sure*/ ret = 0; goto out; } /*Noway to recover, delete the name*/ loc_wipe(&loc); loc.parent = inode_ref(name_data->parent); gf_uuid_copy(loc.pargfid, loc.parent->gfid); loc.name = name_data->name; for (i = 0; i < ec->nodes; i++) { if (same[i] && replies[i].valid && (replies[i].op_ret == 0)) { ia = &replies[i].stat; break; } } if (!ia) { ret = -ENOTCONN; goto out; } if (IA_ISDIR(ia->ia_type)) { ret = cluster_rmdir(ec->xl_list, same, ec->nodes, replies, output, frame, ec->xl, &loc, 1, NULL); gf_msg_debug(ec->xl->name, 0, "cluster rmdir succeeded on %d " "nodes", ret); } else { ret = cluster_unlink(ec->xl_list, same, ec->nodes, replies, output, frame, ec->xl, &loc, 0, NULL); gf_msg_debug(ec->xl->name, 0, "cluster unlink succeeded on %d " "nodes", ret); } for (i = 0; i < ec->nodes; i++) { if (output[i]) { same[i] = 0; name_data->enoent[i] = 1; } else { /*op failed*/ if (same[i]) name_data->participants[i] = 0; } } ret = 0; /*This will help in making decisions about creating names*/ dict_del(gfid_db, key); out: if (ret < 0) { gf_msg_debug(ec->xl->name, -ret, "%s/%s: heal failed", uuid_utoa(name_data->parent->gfid), name_data->name); } cluster_replies_wipe(replies, ec->nodes); loc_wipe(&loc); return ret; } int ec_delete_stale_names(call_frame_t *frame, ec_t *ec, inode_t *parent, char *name, default_args_cbk_t *replies, dict_t *gfid_db, unsigned char *enoent, unsigned char *gfidless, unsigned char *participants) { struct ec_name_data name_data = {0}; name_data.enoent = enoent; name_data.gfidless = gfidless; name_data.participants = participants; name_data.name = name; name_data.parent = parent; name_data.frame = frame; name_data.replies = replies; return dict_foreach(gfid_db, ec_delete_stale_name, &name_data); } int _assign_same(dict_t *dict, char *key, data_t *value, void *data) { struct ec_name_data *name_data = data; name_data->same = data_to_bin(value); return 0; } int ec_create_name(call_frame_t *frame, ec_t *ec, inode_t *parent, char *name, default_args_cbk_t *lookup_replies, dict_t *gfid_db, unsigned char *enoent, unsigned char *participants) { int ret = 0; int i = 0; struct ec_name_data name_data = {0}; struct iatt *ia = NULL; unsigned char *output = 0; unsigned char *output1 = 0; unsigned char *on = NULL; default_args_cbk_t *replies = NULL; loc_t loc = {0}; loc_t srcloc = {0}; unsigned char *link = NULL; unsigned char *create = NULL; dict_t *xdata = NULL; char *linkname = NULL; ec_config_t config; /* There should be just one gfid key */ EC_REPLIES_ALLOC(replies, ec->nodes); if (gfid_db->count != 1) { ret = -EINVAL; goto out; } ret = dict_foreach(gfid_db, _assign_same, &name_data); if (ret < 0) goto out; /*There should at least be one valid success reply with gfid*/ for (i = 0; i < ec->nodes; i++) if (name_data.same[i]) break; if (i == ec->nodes) { ret = -EINVAL; goto out; } ia = &lookup_replies[i].stat; xdata = dict_new(); loc.parent = inode_ref(parent); gf_uuid_copy(loc.pargfid, parent->gfid); loc.inode = inode_new(parent->table); if (loc.inode) srcloc.inode = inode_ref(loc.inode); gf_uuid_copy(srcloc.gfid, ia->ia_gfid); if (!loc.inode || !xdata || dict_set_static_bin(xdata, "gfid-req", ia->ia_gfid, sizeof(ia->ia_gfid))) { ret = -ENOMEM; goto out; } loc.name = name; link = alloca0(ec->nodes); create = alloca0(ec->nodes); on = alloca0(ec->nodes); output = alloca0(ec->nodes); output1 = alloca0(ec->nodes); for (i = 0; i < ec->nodes; i++) { if (!lookup_replies[i].valid) continue; if (lookup_replies[i].op_ret) continue; on[i] = 1; } switch (ia->ia_type) { case IA_IFDIR: ec_set_new_entry_dirty(ec, &loc, ia, frame, ec->xl, on); (void)cluster_mkdir( ec->xl_list, enoent, ec->nodes, replies, output, frame, ec->xl, &loc, st_mode_from_ia(ia->ia_prot, ia->ia_type), 0, xdata); break; case IA_IFLNK: /*Check for hard links and create/link*/ ret = cluster_lookup(ec->xl_list, enoent, ec->nodes, replies, output, frame, ec->xl, &srcloc, NULL); for (i = 0; i < ec->nodes; i++) { if (output[i]) { link[i] = 1; } else { if (replies[i].op_errno == ENOENT || replies[i].op_errno == ESTALE) { create[i] = 1; } } } if (EC_COUNT(link, ec->nodes)) { cluster_link(ec->xl_list, link, ec->nodes, replies, output1, frame, ec->xl, &srcloc, &loc, NULL); } if (EC_COUNT(create, ec->nodes)) { cluster_readlink(ec->xl_list, name_data.same, ec->nodes, replies, output, frame, ec->xl, &srcloc, 4096, NULL); if (EC_COUNT(output, ec->nodes) == 0) { ret = -ENOTCONN; goto out; } for (i = 0; i < ec->nodes; i++) { if (output[i]) break; } linkname = alloca0(strlen(replies[i].buf) + 1); strcpy(linkname, replies[i].buf); ec_set_new_entry_dirty(ec, &loc, ia, frame, ec->xl, on); cluster_symlink(ec->xl_list, create, ec->nodes, replies, output, frame, ec->xl, linkname, &loc, 0, xdata); } for (i = 0; i < ec->nodes; i++) if (output1[i]) output[i] = 1; break; case IA_IFREG: ec_set_new_entry_dirty(ec, &loc, ia, frame, ec->xl, on); config.version = EC_CONFIG_VERSION; config.algorithm = EC_CONFIG_ALGORITHM; config.gf_word_size = EC_GF_BITS; config.bricks = ec->nodes; config.redundancy = ec->redundancy; config.chunk_size = EC_METHOD_CHUNK_SIZE; ret = ec_dict_set_config(xdata, EC_XATTR_CONFIG, &config); if (ret != 0) { goto out; } /* Fall through */ default: ret = dict_set_int32(xdata, GLUSTERFS_INTERNAL_FOP_KEY, 1); if (ret) goto out; ret = cluster_mknod( ec->xl_list, enoent, ec->nodes, replies, output, frame, ec->xl, &loc, st_mode_from_ia(ia->ia_prot, ia->ia_type), makedev(ia_major(ia->ia_rdev), ia_minor(ia->ia_rdev)), 0, xdata); break; } for (i = 0; i < ec->nodes; i++) { if (enoent[i] && !output[i]) participants[i] = 0; } ret = 0; out: if (ret < 0) gf_msg_debug(ec->xl->name, -ret, "%s/%s: heal failed", uuid_utoa(parent->gfid), name); cluster_replies_wipe(replies, ec->nodes); loc_wipe(&loc); loc_wipe(&srcloc); if (xdata) dict_unref(xdata); return ret; } int __ec_heal_name(call_frame_t *frame, ec_t *ec, inode_t *parent, char *name, unsigned char *participants) { unsigned char *output = NULL; unsigned char *enoent = NULL; default_args_cbk_t *replies = NULL; dict_t *xdata = NULL; dict_t *gfid_db = NULL; int ret = 0; loc_t loc = {0}; int i = 0; struct iatt *ia = NULL; char gfid[64] = {0}; unsigned char *same = NULL; unsigned char *gfidless = NULL; EC_REPLIES_ALLOC(replies, ec->nodes); loc.parent = inode_ref(parent); loc.inode = inode_new(parent->table); gf_uuid_copy(loc.pargfid, parent->gfid); loc.name = name; xdata = dict_new(); gfid_db = dict_new(); if (!xdata || !gfid_db || !loc.inode) { ret = -ENOMEM; goto out; } ret = dict_set_int32(xdata, GF_GFIDLESS_LOOKUP, 1); if (ret) { ret = -ENOMEM; goto out; } output = alloca0(ec->nodes); gfidless = alloca0(ec->nodes); enoent = alloca0(ec->nodes); ret = cluster_lookup(ec->xl_list, participants, ec->nodes, replies, output, frame, ec->xl, &loc, NULL); for (i = 0; i < ec->nodes; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret == -1) { /*If ESTALE comes here, that means parent dir is not * present, nothing to do there, so reset participants * for that brick*/ if (replies[i].op_errno == ENOENT) enoent[i] = 1; else participants[i] = 0; continue; } ia = &replies[i].stat; if (gf_uuid_is_null(ia->ia_gfid)) { if (IA_ISDIR(ia->ia_type) || ia->ia_size == 0) gfidless[i] = 1; else participants[i] = 0; } else { uuid_utoa_r(ia->ia_gfid, gfid); ret = dict_get_bin(gfid_db, gfid, (void **)&same); if (ret < 0) { same = alloca0(ec->nodes); } same[i] = 1; if (ret < 0) { ret = dict_set_static_bin(gfid_db, gfid, same, ec->nodes); } if (ret < 0) goto out; } } ret = ec_delete_stale_names(frame, ec, parent, name, replies, gfid_db, enoent, gfidless, participants); if (gfid_db->count == 0) { /* All entries seem to be stale entries and deleted, * nothing more to do.*/ goto out; } if (gfid_db->count > 1) { gf_msg(ec->xl->name, GF_LOG_INFO, 0, EC_MSG_HEAL_FAIL, "%s/%s: Not able to heal", uuid_utoa(parent->gfid), name); memset(participants, 0, ec->nodes); goto out; } EC_INTERSECT(enoent, enoent, participants, ec->nodes); if (EC_COUNT(enoent, ec->nodes) == 0) { ret = 0; goto out; } ret = ec_create_name(frame, ec, parent, name, replies, gfid_db, enoent, participants); if (ret >= 0) { /* If ec_create_name() succeeded we return 1 to indicate that a new * file has been created and it will need to be healed. */ ret = 1; } out: cluster_replies_wipe(replies, ec->nodes); loc_wipe(&loc); if (xdata) dict_unref(xdata); if (gfid_db) dict_unref(gfid_db); return ret; } int ec_heal_name(call_frame_t *frame, ec_t *ec, inode_t *parent, char *name, unsigned char *participants) { int ret = 0; default_args_cbk_t *replies = NULL; unsigned char *output = NULL; unsigned char *locked_on = NULL; loc_t loc = {0}; loc.parent = inode_ref(parent); loc.name = name; loc.inode = inode_new(parent->table); if (!loc.inode) { ret = -ENOMEM; goto out; } EC_REPLIES_ALLOC(replies, ec->nodes); output = alloca0(ec->nodes); locked_on = alloca0(ec->nodes); ret = cluster_inodelk(ec->xl_list, participants, ec->nodes, replies, locked_on, frame, ec->xl, ec->xl->name, parent, 0, 0); { if (ret <= ec->fragments) { gf_msg_debug(ec->xl->name, 0, "%s/%s: Skipping " "heal as only %d number of subvolumes could " "be locked", uuid_utoa(parent->gfid), name, ret); ret = -ENOTCONN; goto unlock; } EC_INTERSECT(participants, participants, locked_on, ec->nodes); ret = __ec_heal_name(frame, ec, parent, name, participants); } unlock: cluster_uninodelk(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, ec->xl->name, parent, 0, 0); out: cluster_replies_wipe(replies, ec->nodes); loc_wipe(&loc); return ret; } int ec_name_heal_handler(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { struct ec_name_data *name_data = data; xlator_t *this = THIS; ec_t *ec = this->private; unsigned char *name_on = alloca0(ec->nodes); int i = 0; int ret = 0; if (ec->shutdown) { gf_msg_debug(this->name, 0, "Cancelling directory heal " "because EC is stopping."); return -ENOTCONN; } memcpy(name_on, name_data->participants, ec->nodes); ret = ec_heal_name(name_data->frame, ec, parent->inode, entry->d_name, name_on); if (ret < 0) { memset(name_on, 0, ec->nodes); } else { name_data->heal_pending += ret; } for (i = 0; i < ec->nodes; i++) if (name_data->participants[i] && !name_on[i]) name_data->failed_on[i] = 1; return 0; } int ec_heal_names(call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *participants, uint32_t *pending) { int i = 0; int j = 0; loc_t loc = {0}; struct ec_name_data name_data = {0}; int ret = 0; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); name_data.frame = frame; name_data.participants = participants; name_data.failed_on = alloca0(ec->nodes); name_data.heal_pending = 0; for (i = 0; i < ec->nodes; i++) { if (!participants[i]) continue; ret = syncop_dir_scan(ec->xl_list[i], &loc, GF_CLIENT_PID_SELF_HEALD, &name_data, ec_name_heal_handler); if (ret < 0) { break; } for (j = 0; j < ec->nodes; j++) if (name_data.failed_on[j]) participants[j] = 0; if (EC_COUNT(participants, ec->nodes) <= ec->fragments) { ret = -ENOTCONN; break; } } *pending += name_data.heal_pending; loc_wipe(&loc); return ret; } int __ec_heal_entry(call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *heal_on, unsigned char *sources, unsigned char *healed_sinks, uint32_t *pending) { unsigned char *locked_on = NULL; unsigned char *output = NULL; uint64_t *versions = NULL; uint64_t *dirty = NULL; unsigned char *participants = NULL; default_args_cbk_t *replies = NULL; int ret = 0; int source = 0; int i = 0; locked_on = alloca0(ec->nodes); output = alloca0(ec->nodes); versions = alloca0(ec->nodes * sizeof(*versions)); dirty = alloca0(ec->nodes * sizeof(*dirty)); EC_REPLIES_ALLOC(replies, ec->nodes); ret = cluster_inodelk(ec->xl_list, heal_on, ec->nodes, replies, locked_on, frame, ec->xl, ec->xl->name, inode, 0, 0); { if (ret <= ec->fragments) { gf_msg_debug(ec->xl->name, 0, "%s: Skipping heal " "as only %d number of subvolumes could " "be locked", uuid_utoa(inode->gfid), ret); ret = -ENOTCONN; goto unlock; } ret = __ec_heal_entry_prepare(frame, ec, inode, locked_on, versions, dirty, sources, healed_sinks); source = ret; } unlock: cluster_uninodelk(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, ec->xl->name, inode, 0, 0); if (ret < 0) goto out; participants = alloca0(ec->nodes); for (i = 0; i < ec->nodes; i++) { if (sources[i] || healed_sinks[i]) participants[i] = 1; } ret = ec_heal_names(frame, ec, inode, participants, pending); if (EC_COUNT(participants, ec->nodes) <= ec->fragments) goto out; for (i = 0; i < ec->nodes; i++) { if (!participants[i]) { sources[i] = 0; healed_sinks[i] = 0; } } ec_adjust_versions(frame, ec, EC_DATA_TXN, inode, source, sources, healed_sinks, versions, dirty); out: cluster_replies_wipe(replies, ec->nodes); return ret; } int ec_heal_entry(call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *sources, unsigned char *healed_sinks, uint32_t *pending) { unsigned char *locked_on = NULL; unsigned char *up_subvols = NULL; unsigned char *output = NULL; char selfheal_domain[1024] = {0}; int ret = 0; default_args_cbk_t *replies = NULL; EC_REPLIES_ALLOC(replies, ec->nodes); locked_on = alloca0(ec->nodes); output = alloca0(ec->nodes); up_subvols = alloca0(ec->nodes); sprintf(selfheal_domain, "%s:self-heal", ec->xl->name); ec_mask_to_char_array(ec->xl_up, up_subvols, ec->nodes); /*If other processes are already doing the heal, don't block*/ ret = cluster_tiebreaker_inodelk(ec->xl_list, up_subvols, ec->nodes, replies, locked_on, frame, ec->xl, selfheal_domain, inode, 0, 0); { if (ret <= ec->fragments) { gf_msg_debug(ec->xl->name, 0, "%s: Skipping heal " "as only %d number of subvolumes could " "be locked", uuid_utoa(inode->gfid), ret); ret = -ENOTCONN; goto unlock; } ret = __ec_heal_entry(frame, ec, inode, locked_on, sources, healed_sinks, pending); } unlock: cluster_uninodelk(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, selfheal_domain, inode, 0, 0); cluster_replies_wipe(replies, ec->nodes); return ret; } /*Find direction for data heal and heal info*/ int ec_heal_data_find_direction(ec_t *ec, default_args_cbk_t *replies, uint64_t *data_versions, uint64_t *dirty, uint64_t *size, unsigned char *sources, unsigned char *healed_sinks, gf_boolean_t check_ondisksize, int which) { uint64_t xattr[EC_VERSION_SIZE] = {0}; char version_size[128] = {0}; dict_t *version_size_db = NULL; unsigned char *same = NULL; int max_same_count = 0; int source = 0; int i = 0; int ret = 0; dict_t *dict = NULL; uint64_t source_size = 0; version_size_db = dict_new(); if (!version_size_db) { ret = -ENOMEM; goto out; } for (i = 0; i < ec->nodes; i++) { if (!replies[i].valid) continue; if (replies[i].op_ret < 0) continue; dict = (which == EC_COMBINE_XDATA) ? replies[i].xdata : replies[i].xattr; ret = ec_dict_get_array(dict, EC_XATTR_VERSION, xattr, EC_VERSION_SIZE); if (ret == 0) { data_versions[i] = xattr[EC_DATA_TXN]; } memset(xattr, 0, sizeof(xattr)); ret = ec_dict_get_array(dict, EC_XATTR_DIRTY, xattr, EC_VERSION_SIZE); if (ret == 0) { dirty[i] = xattr[EC_DATA_TXN]; } ret = ec_dict_del_number(dict, EC_XATTR_SIZE, &size[i]); /*Build a db of same metadata and data version and size*/ snprintf(version_size, sizeof(version_size), "%" PRIu64 "-%" PRIu64, data_versions[i], size[i]); ret = dict_get_bin(version_size_db, version_size, (void **)&same); if (ret < 0) { same = alloca0(ec->nodes); } same[i] = 1; if (max_same_count < EC_COUNT(same, ec->nodes)) { max_same_count = EC_COUNT(same, ec->nodes); source = i; } if (ret < 0) { ret = dict_set_static_bin(version_size_db, version_size, same, ec->nodes); } if (ret < 0) { ret = -ENOMEM; goto out; } } /* If we don't have ec->fragments number of same version,size it is not * recoverable*/ if (max_same_count < ec->fragments) { ret = -EIO; goto out; } else { snprintf(version_size, sizeof(version_size), "%" PRIu64 "-%" PRIu64, data_versions[source], size[source]); ret = dict_get_bin(version_size_db, version_size, (void **)&same); if (ret < 0) goto out; memcpy(sources, same, ec->nodes); for (i = 0; i < ec->nodes; i++) { if (replies[i].valid && (replies[i].op_ret == 0) && !sources[i]) healed_sinks[i] = 1; } } /* There could be files with versions, size same but on disk ia_size * could be different because of disk crashes, mark them as sinks as * well*/ if (check_ondisksize) { source_size = size[source]; ec_adjust_size_up(ec, &source_size, _gf_true); for (i = 0; i < ec->nodes; i++) { if (sources[i]) { if (replies[i].stat.ia_size != source_size) { sources[i] = 0; healed_sinks[i] = 1; max_same_count--; } else { source = i; } } } if (max_same_count < ec->fragments) { ret = -EIO; goto out; } } ret = source; out: if (version_size_db) dict_unref(version_size_db); return ret; } int __ec_heal_data_prepare(call_frame_t *frame, ec_t *ec, fd_t *fd, unsigned char *locked_on, uint64_t *versions, uint64_t *dirty, uint64_t *size, unsigned char *sources, unsigned char *healed_sinks, unsigned char *trim, struct iatt *stbuf) { default_args_cbk_t *replies = NULL; default_args_cbk_t *fstat_replies = NULL; unsigned char *output = NULL; unsigned char *fstat_output = NULL; dict_t *xattrs = NULL; uint64_t zero_array[2] = {0}; int source = 0; int ret = 0; uint64_t zero_value = 0; int i = 0; EC_REPLIES_ALLOC(replies, ec->nodes); EC_REPLIES_ALLOC(fstat_replies, ec->nodes); output = alloca0(ec->nodes); fstat_output = alloca0(ec->nodes); xattrs = dict_new(); if (!xattrs || dict_set_static_bin(xattrs, EC_XATTR_VERSION, zero_array, sizeof(zero_array)) || dict_set_static_bin(xattrs, EC_XATTR_DIRTY, zero_array, sizeof(zero_array)) || dict_set_static_bin(xattrs, EC_XATTR_SIZE, &zero_value, sizeof(zero_value))) { ret = -ENOMEM; goto out; } ret = cluster_fxattrop(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, fd, GF_XATTROP_ADD_ARRAY64, xattrs, NULL); ret = cluster_fstat(ec->xl_list, locked_on, ec->nodes, fstat_replies, fstat_output, frame, ec->xl, fd, NULL); for (i = 0; i < ec->nodes; i++) { output[i] = output[i] && fstat_output[i]; replies[i].valid = output[i]; if (output[i]) replies[i].stat = fstat_replies[i].stat; } if (EC_COUNT(output, ec->nodes) <= ec->fragments) { ret = -ENOTCONN; goto out; } source = ec_heal_data_find_direction(ec, replies, versions, dirty, size, sources, healed_sinks, _gf_true, EC_COMBINE_DICT); ret = source; if (ret < 0) goto out; if (stbuf) *stbuf = replies[source].stat; for (i = 0; i < ec->nodes; i++) { if (healed_sinks[i]) { if (replies[i].stat.ia_size) trim[i] = 1; } } if (EC_COUNT(sources, ec->nodes) < ec->fragments) { ret = -ENOTCONN; goto out; } ret = source; out: if (xattrs) dict_unref(xattrs); cluster_replies_wipe(replies, ec->nodes); cluster_replies_wipe(fstat_replies, ec->nodes); if (ret < 0) { gf_msg_debug(ec->xl->name, -ret, "%s: heal failed", uuid_utoa(fd->inode->gfid)); } else { gf_msg_debug(ec->xl->name, 0, "%s: sources: %d, sinks: " "%d", uuid_utoa(fd->inode->gfid), EC_COUNT(sources, ec->nodes), EC_COUNT(healed_sinks, ec->nodes)); } return ret; } int __ec_heal_mark_sinks(call_frame_t *frame, ec_t *ec, fd_t *fd, uint64_t *versions, unsigned char *healed_sinks) { int i = 0; int ret = 0; unsigned char *mark = NULL; dict_t *xattrs = NULL; default_args_cbk_t *replies = NULL; unsigned char *output = NULL; uint64_t versions_xattr[2] = {0}; EC_REPLIES_ALLOC(replies, ec->nodes); xattrs = dict_new(); if (!xattrs) { ret = -ENOMEM; goto out; } mark = alloca0(ec->nodes); for (i = 0; i < ec->nodes; i++) { if (!healed_sinks[i]) continue; if ((versions[i] >> EC_SELFHEAL_BIT) & 1) continue; mark[i] = 1; } if (EC_COUNT(mark, ec->nodes) == 0) return 0; versions_xattr[EC_DATA_TXN] = htobe64(1ULL << EC_SELFHEAL_BIT); if (dict_set_static_bin(xattrs, EC_XATTR_VERSION, versions_xattr, sizeof(versions_xattr))) { ret = -ENOMEM; goto out; } output = alloca0(ec->nodes); ret = cluster_fxattrop(ec->xl_list, mark, ec->nodes, replies, output, frame, ec->xl, fd, GF_XATTROP_ADD_ARRAY64, xattrs, NULL); for (i = 0; i < ec->nodes; i++) { if (!output[i]) { if (mark[i]) healed_sinks[i] = 0; continue; } versions[i] |= (1ULL << EC_SELFHEAL_BIT); } if (EC_COUNT(healed_sinks, ec->nodes) == 0) { ret = -ENOTCONN; goto out; } ret = 0; out: cluster_replies_wipe(replies, ec->nodes); if (xattrs) dict_unref(xattrs); if (ret < 0) gf_msg_debug(ec->xl->name, -ret, "%s: heal failed", uuid_utoa(fd->inode->gfid)); return ret; } int32_t ec_manager_heal_block(ec_fop_data_t *fop, int32_t state) { ec_heal_t *heal = fop->data; heal->fop = fop; switch (state) { case EC_STATE_INIT: ec_owner_set(fop->frame, fop->frame->root); ec_heal_inodelk(heal, F_WRLCK, 1, 0, 0); return EC_STATE_HEAL_DATA_COPY; case EC_STATE_HEAL_DATA_COPY: gf_msg_debug(fop->xl->name, 0, "%s: read/write starting", uuid_utoa(heal->fd->inode->gfid)); ec_heal_data_block(heal); return EC_STATE_HEAL_DATA_UNLOCK; case -EC_STATE_HEAL_DATA_COPY: case -EC_STATE_HEAL_DATA_UNLOCK: case EC_STATE_HEAL_DATA_UNLOCK: ec_heal_inodelk(heal, F_UNLCK, 1, 0, 0); return EC_STATE_REPORT; case EC_STATE_REPORT: if (fop->cbks.heal) { fop->cbks.heal(fop->req_frame, fop->data, fop->xl, 0, 0, (heal->good | heal->bad), heal->good, heal->bad, 0, NULL); } return EC_STATE_END; case -EC_STATE_REPORT: if (fop->cbks.heal) { fop->cbks.heal(fop->req_frame, fop->data, fop->xl, -1, fop->error, 0, 0, 0, 0, NULL); } return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, 0, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } /*Takes lock */ void ec_heal_block(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_heal_cbk_t func, ec_heal_t *heal) { ec_cbk_t callback = {.heal = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(HEAL) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, EC_FOP_HEAL, 0, target, fop_flags, NULL, ec_manager_heal_block, callback, heal); if (fop == NULL) goto out; error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, heal, this, -1, error, 0, 0, 0, 0, NULL); } } int32_t ec_heal_block_done(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, uintptr_t mask, uintptr_t good, uintptr_t bad, uint32_t pending, dict_t *xdata) { ec_heal_t *heal = cookie; if (heal->fop) { heal->fop->heal = NULL; } heal->fop = NULL; heal->error = op_ret < 0 ? op_errno : 0; syncbarrier_wake(&heal->barrier); return 0; } int ec_sync_heal_block(call_frame_t *frame, xlator_t *this, ec_heal_t *heal) { ec_heal_block(frame, this, heal->bad | heal->good, EC_MINIMUM_ONE, ec_heal_block_done, heal); syncbarrier_wait(&heal->barrier, 1); if (heal->error != 0) { return -heal->error; } if (heal->bad == 0) return -ENOTCONN; return 0; } int ec_rebuild_data(call_frame_t *frame, ec_t *ec, fd_t *fd, uint64_t size, unsigned char *sources, unsigned char *healed_sinks) { ec_heal_t obj, *heal = &obj; int ret = 0; memset(&obj, 0, sizeof(obj)); if (syncbarrier_init(&heal->barrier)) return -ENOMEM; heal->fd = fd_ref(fd); heal->xl = ec->xl; ec_adjust_size_up(ec, &size, _gf_false); heal->total_size = size; heal->size = (128 * GF_UNIT_KB * (ec->self_heal_window_size)); /* We need to adjust the size to a multiple of the stripe size of the * volume. Otherwise writes would need to fill gaps (head and/or tail) * with existent data from the bad bricks. This could be garbage on a * damaged file or it could fail if there aren't enough bricks. */ heal->size -= heal->size % ec->stripe_size; heal->bad = ec_char_array_to_mask(healed_sinks, ec->nodes); heal->good = ec_char_array_to_mask(sources, ec->nodes); heal->ia_type = IA_IFREG; LOCK_INIT(&heal->lock); for (heal->offset = 0; (heal->offset < size) && !heal->done; heal->offset += heal->size) { /* We immediately abort any heal if a shutdown request has been * received to avoid delays. The healing of this file will be * restarted by another SHD or other client that accesses the * file. */ if (ec->shutdown) { gf_msg_debug(ec->xl->name, 0, "Cancelling heal because " "EC is stopping."); ret = -ENOTCONN; break; } gf_msg_debug(ec->xl->name, 0, "%s: sources: %d, sinks: " "%d, offset: %" PRIu64 " bsize: %" PRIu64, uuid_utoa(fd->inode->gfid), EC_COUNT(sources, ec->nodes), EC_COUNT(healed_sinks, ec->nodes), heal->offset, heal->size); ret = ec_sync_heal_block(frame, ec->xl, heal); if (ret < 0) break; } memset(healed_sinks, 0, ec->nodes); ec_mask_to_char_array(heal->bad, healed_sinks, ec->nodes); fd_unref(heal->fd); LOCK_DESTROY(&heal->lock); syncbarrier_destroy(&heal->barrier); if (ret < 0) gf_msg_debug(ec->xl->name, -ret, "%s: heal failed", uuid_utoa(fd->inode->gfid)); return ret; } int __ec_heal_trim_sinks(call_frame_t *frame, ec_t *ec, fd_t *fd, unsigned char *healed_sinks, unsigned char *trim, uint64_t size) { default_args_cbk_t *replies = NULL; unsigned char *output = NULL; int ret = 0; int i = 0; off_t trim_offset = 0; EC_REPLIES_ALLOC(replies, ec->nodes); output = alloca0(ec->nodes); if (EC_COUNT(trim, ec->nodes) == 0) { ret = 0; goto out; } trim_offset = size; ec_adjust_offset_up(ec, &trim_offset, _gf_true); ret = cluster_ftruncate(ec->xl_list, trim, ec->nodes, replies, output, frame, ec->xl, fd, trim_offset, NULL); for (i = 0; i < ec->nodes; i++) { if (!output[i] && trim[i]) healed_sinks[i] = 0; } if (EC_COUNT(healed_sinks, ec->nodes) == 0) { ret = -ENOTCONN; goto out; } out: cluster_replies_wipe(replies, ec->nodes); if (ret < 0) gf_msg_debug(ec->xl->name, -ret, "%s: heal failed", uuid_utoa(fd->inode->gfid)); return ret; } int ec_data_undo_pending(call_frame_t *frame, ec_t *ec, fd_t *fd, dict_t *xattr, uint64_t *versions, uint64_t *dirty, uint64_t *size, int source, gf_boolean_t erase_dirty, int idx) { uint64_t versions_xattr[2] = {0}; uint64_t dirty_xattr[2] = {0}; uint64_t allzero[2] = {0}; uint64_t size_xattr = 0; int ret = 0; versions_xattr[EC_DATA_TXN] = htobe64(versions[source] - versions[idx]); ret = dict_set_static_bin(xattr, EC_XATTR_VERSION, versions_xattr, sizeof(versions_xattr)); if (ret < 0) goto out; size_xattr = htobe64(size[source] - size[idx]); ret = dict_set_static_bin(xattr, EC_XATTR_SIZE, &size_xattr, sizeof(size_xattr)); if (ret < 0) goto out; if (erase_dirty) { dirty_xattr[EC_DATA_TXN] = htobe64(-dirty[idx]); ret = dict_set_static_bin(xattr, EC_XATTR_DIRTY, dirty_xattr, sizeof(dirty_xattr)); if (ret < 0) goto out; } if ((memcmp(versions_xattr, allzero, sizeof(allzero)) == 0) && (memcmp(dirty_xattr, allzero, sizeof(allzero)) == 0) && (size_xattr == 0)) { ret = 0; goto out; } ret = syncop_fxattrop(ec->xl_list[idx], fd, GF_XATTROP_ADD_ARRAY64, xattr, NULL, NULL, NULL); out: return ret; } int __ec_fd_data_adjust_versions(call_frame_t *frame, ec_t *ec, fd_t *fd, unsigned char *sources, unsigned char *healed_sinks, uint64_t *versions, uint64_t *dirty, uint64_t *size) { dict_t *xattr = NULL; int i = 0; int ret = 0; int op_ret = 0; int source = -1; gf_boolean_t erase_dirty = _gf_false; xattr = dict_new(); if (!xattr) { op_ret = -ENOMEM; goto out; } /* dirty xattr represents if the file needs heal. Unless all the * copies are healed, don't erase it */ if (EC_COUNT(sources, ec->nodes) + EC_COUNT(healed_sinks, ec->nodes) == ec->nodes) erase_dirty = _gf_true; for (i = 0; i < ec->nodes; i++) { if (sources[i]) { source = i; break; } } if (source == -1) { op_ret = -ENOTCONN; goto out; } for (i = 0; i < ec->nodes; i++) { if (healed_sinks[i]) { ret = ec_data_undo_pending(frame, ec, fd, xattr, versions, dirty, size, source, erase_dirty, i); if (ret < 0) goto out; } } if (!erase_dirty) goto out; for (i = 0; i < ec->nodes; i++) { if (sources[i]) { ret = ec_data_undo_pending(frame, ec, fd, xattr, versions, dirty, size, source, erase_dirty, i); if (ret < 0) continue; } } out: if (xattr) dict_unref(xattr); return op_ret; } int ec_restore_time_and_adjust_versions(call_frame_t *frame, ec_t *ec, fd_t *fd, unsigned char *sources, unsigned char *healed_sinks, uint64_t *versions, uint64_t *dirty, uint64_t *size) { unsigned char *locked_on = NULL; unsigned char *participants = NULL; unsigned char *output = NULL; default_args_cbk_t *replies = NULL; unsigned char *postsh_sources = NULL; unsigned char *postsh_healed_sinks = NULL; unsigned char *postsh_trim = NULL; uint64_t *postsh_versions = NULL; uint64_t *postsh_dirty = NULL; uint64_t *postsh_size = NULL; int ret = 0; int i = 0; struct iatt source_buf = {0}; loc_t loc = {0}; locked_on = alloca0(ec->nodes); output = alloca0(ec->nodes); participants = alloca0(ec->nodes); postsh_sources = alloca0(ec->nodes); postsh_healed_sinks = alloca0(ec->nodes); postsh_trim = alloca0(ec->nodes); postsh_versions = alloca0(ec->nodes * sizeof(*postsh_versions)); postsh_dirty = alloca0(ec->nodes * sizeof(*postsh_dirty)); postsh_size = alloca0(ec->nodes * sizeof(*postsh_size)); for (i = 0; i < ec->nodes; i++) { if (healed_sinks[i] || sources[i]) participants[i] = 1; } EC_REPLIES_ALLOC(replies, ec->nodes); ret = cluster_inodelk(ec->xl_list, participants, ec->nodes, replies, locked_on, frame, ec->xl, ec->xl->name, fd->inode, 0, 0); { if (ret <= ec->fragments) { gf_msg_debug(ec->xl->name, 0, "%s: Skipping heal " "as only %d number of subvolumes could " "be locked", uuid_utoa(fd->inode->gfid), ret); ret = -ENOTCONN; goto unlock; } ret = __ec_heal_data_prepare(frame, ec, fd, locked_on, postsh_versions, postsh_dirty, postsh_size, postsh_sources, postsh_healed_sinks, postsh_trim, &source_buf); if (ret < 0) goto unlock; loc.inode = inode_ref(fd->inode); gf_uuid_copy(loc.gfid, fd->inode->gfid); ret = cluster_setattr( ec->xl_list, healed_sinks, ec->nodes, replies, output, frame, ec->xl, &loc, &source_buf, GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME | GF_SET_ATTR_CTIME, NULL); EC_INTERSECT(healed_sinks, healed_sinks, output, ec->nodes); if (EC_COUNT(healed_sinks, ec->nodes) == 0) { ret = -ENOTCONN; goto unlock; } ret = __ec_fd_data_adjust_versions(frame, ec, fd, sources, healed_sinks, versions, dirty, size); } unlock: cluster_uninodelk(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, ec->xl->name, fd->inode, 0, 0); cluster_replies_wipe(replies, ec->nodes); loc_wipe(&loc); return ret; } int __ec_heal_data(call_frame_t *frame, ec_t *ec, fd_t *fd, unsigned char *heal_on, unsigned char *sources, unsigned char *healed_sinks) { unsigned char *locked_on = NULL; unsigned char *output = NULL; uint64_t *versions = NULL; uint64_t *dirty = NULL; uint64_t *size = NULL; unsigned char *trim = NULL; default_args_cbk_t *replies = NULL; int ret = 0; int source = 0; locked_on = alloca0(ec->nodes); output = alloca0(ec->nodes); trim = alloca0(ec->nodes); versions = alloca0(ec->nodes * sizeof(*versions)); dirty = alloca0(ec->nodes * sizeof(*dirty)); size = alloca0(ec->nodes * sizeof(*size)); EC_REPLIES_ALLOC(replies, ec->nodes); ret = cluster_inodelk(ec->xl_list, heal_on, ec->nodes, replies, locked_on, frame, ec->xl, ec->xl->name, fd->inode, 0, 0); { if (ret <= ec->fragments) { gf_msg_debug(ec->xl->name, 0, "%s: Skipping heal " "as only %d number of subvolumes could " "be locked", uuid_utoa(fd->inode->gfid), ret); ret = -ENOTCONN; goto unlock; } ret = __ec_heal_data_prepare(frame, ec, fd, locked_on, versions, dirty, size, sources, healed_sinks, trim, NULL); if (ret < 0) goto unlock; if (EC_COUNT(healed_sinks, ec->nodes) == 0) { ret = __ec_fd_data_adjust_versions( frame, ec, fd, sources, healed_sinks, versions, dirty, size); goto unlock; } source = ret; ret = __ec_heal_mark_sinks(frame, ec, fd, versions, healed_sinks); if (ret < 0) goto unlock; ret = __ec_heal_trim_sinks(frame, ec, fd, healed_sinks, trim, size[source]); } unlock: cluster_uninodelk(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, ec->xl->name, fd->inode, 0, 0); if (ret < 0) goto out; if (EC_COUNT(healed_sinks, ec->nodes) == 0) goto out; gf_msg_debug(ec->xl->name, 0, "%s: sources: %d, sinks: " "%d", uuid_utoa(fd->inode->gfid), EC_COUNT(sources, ec->nodes), EC_COUNT(healed_sinks, ec->nodes)); ret = ec_rebuild_data(frame, ec, fd, size[source], sources, healed_sinks); if (ret < 0) goto out; ret = ec_restore_time_and_adjust_versions( frame, ec, fd, sources, healed_sinks, versions, dirty, size); out: cluster_replies_wipe(replies, ec->nodes); return ret; } int ec_heal_data(call_frame_t *frame, ec_t *ec, gf_boolean_t block, inode_t *inode, unsigned char *sources, unsigned char *healed_sinks) { unsigned char *locked_on = NULL; unsigned char *up_subvols = NULL; unsigned char *output = NULL; default_args_cbk_t *replies = NULL; fd_t *fd = NULL; loc_t loc = {0}; char selfheal_domain[1024] = {0}; int ret = 0; EC_REPLIES_ALLOC(replies, ec->nodes); locked_on = alloca0(ec->nodes); output = alloca0(ec->nodes); up_subvols = alloca0(ec->nodes); loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); fd = fd_create(inode, 0); if (!fd) { ret = -ENOMEM; goto out; } ec_mask_to_char_array(ec->xl_up, up_subvols, ec->nodes); ret = cluster_open(ec->xl_list, up_subvols, ec->nodes, replies, output, frame, ec->xl, &loc, O_RDWR | O_LARGEFILE, fd, NULL); if (ret <= ec->fragments) { ret = -ENOTCONN; goto out; } fd_bind(fd); sprintf(selfheal_domain, "%s:self-heal", ec->xl->name); /*If other processes are already doing the heal, don't block*/ if (block) { ret = cluster_inodelk(ec->xl_list, output, ec->nodes, replies, locked_on, frame, ec->xl, selfheal_domain, inode, 0, 0); } else { ret = cluster_tiebreaker_inodelk(ec->xl_list, output, ec->nodes, replies, locked_on, frame, ec->xl, selfheal_domain, inode, 0, 0); } { if (ret <= ec->fragments) { gf_msg_debug(ec->xl->name, 0, "%s: Skipping heal " "as only %d number of subvolumes could " "be locked", uuid_utoa(inode->gfid), ret); ret = -ENOTCONN; goto unlock; } ret = __ec_heal_data(frame, ec, fd, locked_on, sources, healed_sinks); } unlock: cluster_uninodelk(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, selfheal_domain, inode, 0, 0); out: if (fd) fd_unref(fd); loc_wipe(&loc); cluster_replies_wipe(replies, ec->nodes); return ret; } int ec_heal_purge_stale_index(call_frame_t *frame, ec_t *ec, inode_t *inode) { int i = 0; int ret = 0; dict_t **xattr = NULL; loc_t loc = {0}; uint64_t dirty_xattr[EC_VERSION_SIZE] = {0}; unsigned char *on = NULL; default_args_cbk_t *replies = NULL; dict_t *dict = NULL; /* Allocate the required memory */ loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); on = alloca0(ec->nodes); EC_REPLIES_ALLOC(replies, ec->nodes); xattr = GF_CALLOC(ec->nodes, sizeof(*xattr), gf_common_mt_pointer); if (!xattr) { ret = -ENOMEM; goto out; } dict = dict_new(); if (!dict) { ret = -ENOMEM; goto out; } for (i = 0; i < ec->nodes; i++) { xattr[i] = dict; on[i] = 1; } ret = dict_set_static_bin(dict, EC_XATTR_DIRTY, dirty_xattr, (sizeof(*dirty_xattr) * EC_VERSION_SIZE)); if (ret < 0) { ret = -ENOMEM; goto out; } PARALLEL_FOP_ONLIST(ec->xl_list, on, ec->nodes, replies, frame, ec_wind_xattrop_parallel, &loc, GF_XATTROP_ADD_ARRAY64, xattr, NULL); out: if (dict) { dict_unref(dict); } if (xattr) { GF_FREE(xattr); } cluster_replies_wipe(replies, ec->nodes); loc_wipe(&loc); return ret; } void ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial) { call_frame_t *frame = NULL; unsigned char *participants = NULL; unsigned char *msources = NULL; unsigned char *mhealed_sinks = NULL; unsigned char *sources = NULL; unsigned char *healed_sinks = NULL; ec_t *ec = NULL; int ret = 0; int op_ret = 0; int op_errno = 0; intptr_t mgood = 0; intptr_t mbad = 0; intptr_t good = 0; intptr_t bad = 0; uint32_t pending = 0; ec_fop_data_t *fop = data; gf_boolean_t blocking = _gf_false; ec_heal_need_t need_heal = EC_HEAL_NONEED; unsigned char *up_subvols = NULL; char up_bricks[32]; ec = this->private; /* If it is heal request from getxattr, complete the heal and then * unwind, if it is ec_heal with NULL as frame then no need to block * the heal as the caller doesn't care about its completion. In case * of heald whichever gets tiebreaking inodelk will take care of the * heal, so no need to block*/ if (fop->req_frame && !ec->shd.iamshd) blocking = _gf_true; frame = create_frame(this, this->ctx->pool); if (!frame) goto out; ec_owner_set(frame, frame->root); /*Do heal as root*/ frame->root->uid = 0; frame->root->gid = 0; /*Mark the fops as internal*/ frame->root->pid = GF_CLIENT_PID_SELF_HEALD; participants = alloca0(ec->nodes); ec_mask_to_char_array(ec->xl_up, participants, ec->nodes); up_subvols = alloca0(ec->nodes); ec_mask_to_char_array(ec->xl_up, up_subvols, ec->nodes); if (loc->name && strlen(loc->name)) { ret = ec_heal_name(frame, ec, loc->parent, (char *)loc->name, participants); if (ret >= 0) { gf_msg_debug(this->name, 0, "%s: name heal " "successful on %" PRIXPTR, loc->path, ec_char_array_to_mask(participants, ec->nodes)); } else { gf_msg_debug( this->name, 0, "%s: name heal " "failed. ret = %d, subvolumes up = %s", loc->path, ret, ec_bin(up_bricks, sizeof(up_bricks), ec->xl_up, ec->nodes)); } } /* Mount triggers heal only when it detects that it must need heal, shd * triggers heals periodically which need not be thorough*/ if (ec->shd.iamshd && (ret <= 0)) { ec_heal_inspect(frame, ec, loc->inode, up_subvols, _gf_false, _gf_false, &need_heal); if (need_heal == EC_HEAL_PURGE_INDEX) { gf_msg(ec->xl->name, GF_LOG_INFO, 0, EC_MSG_HEAL_FAIL, "Index entry needs to be purged for: %s ", uuid_utoa(loc->gfid)); /* We need to send zero-xattrop so that stale index entry could be * removed. We need not take lock on this entry to do so as * xattrop on a brick is atomic. */ ec_heal_purge_stale_index(frame, ec, loc->inode); goto out; } else if (need_heal == EC_HEAL_NONEED) { gf_msg(ec->xl->name, GF_LOG_DEBUG, 0, EC_MSG_HEAL_FAIL, "Heal is not required for : %s ", uuid_utoa(loc->gfid)); goto out; } } sources = alloca0(ec->nodes); healed_sinks = alloca0(ec->nodes); if (IA_ISREG(loc->inode->ia_type)) { ret = ec_heal_data(frame, ec, blocking, loc->inode, sources, healed_sinks); } else if (IA_ISDIR(loc->inode->ia_type) && !partial) { ret = ec_heal_entry(frame, ec, loc->inode, sources, healed_sinks, &pending); } else { ret = 0; memcpy(sources, participants, ec->nodes); memcpy(healed_sinks, participants, ec->nodes); } if (ret == 0) { good = ec_char_array_to_mask(sources, ec->nodes); bad = ec_char_array_to_mask(healed_sinks, ec->nodes); } else { op_ret = -1; op_errno = -ret; } msources = alloca0(ec->nodes); mhealed_sinks = alloca0(ec->nodes); ret = ec_heal_metadata(frame, ec, loc->inode, msources, mhealed_sinks); if (ret == 0) { mgood = ec_char_array_to_mask(msources, ec->nodes); mbad = ec_char_array_to_mask(mhealed_sinks, ec->nodes); } else { op_ret = -1; op_errno = -ret; } out: ec_reset_entry_healing(fop); if (fop->cbks.heal) { fop->cbks.heal(fop->req_frame, fop->data, fop->xl, op_ret, op_errno, ec_char_array_to_mask(participants, ec->nodes), mgood & good, mbad & bad, pending, NULL); } if (frame) STACK_DESTROY(frame->root); return; } int ec_synctask_heal_wrap(void *opaque) { ec_fop_data_t *fop = opaque; ec_heal_do(fop->xl, fop, &fop->loc[0], fop->int32); return 0; } int ec_heal_done(int ret, call_frame_t *heal, void *opaque) { if (opaque) ec_fop_data_release(opaque); if (heal) STACK_DESTROY(heal->root); return 0; } ec_fop_data_t * __ec_dequeue_heals(ec_t *ec) { ec_fop_data_t *fop = NULL; if (list_empty(&ec->heal_waiting)) goto none; if ((ec->background_heals > 0) && (ec->healers >= ec->background_heals)) goto none; fop = list_entry(ec->heal_waiting.next, ec_fop_data_t, healer); ec->heal_waiters--; list_del_init(&fop->healer); list_add(&fop->healer, &ec->healing); ec->healers++; return fop; none: gf_msg_debug(ec->xl->name, 0, "Num healers: %d, Num Waiters: %d", ec->healers, ec->heal_waiters); return NULL; } void ec_heal_fail(ec_t *ec, ec_fop_data_t *fop) { if (fop->cbks.heal) { fop->cbks.heal(fop->req_frame, fop->data, ec->xl, -1, fop->error, 0, 0, 0, 0, NULL); } ec_fop_data_release(fop); } void ec_launch_heal(ec_t *ec, ec_fop_data_t *fop) { int ret = 0; call_frame_t *frame = NULL; frame = create_frame(ec->xl, ec->xl->ctx->pool); if (!frame) { ret = -1; goto out; } ec_owner_set(frame, frame->root); /*Do heal as root*/ frame->root->uid = 0; frame->root->gid = 0; /*Mark the fops as internal*/ frame->root->pid = GF_CLIENT_PID_SELF_HEALD; ret = synctask_new(ec->xl->ctx->env, ec_synctask_heal_wrap, ec_heal_done, frame, fop); out: if (ret < 0) { ec_fop_set_error(fop, ENOMEM); ec_heal_fail(ec, fop); if (frame) STACK_DESTROY(frame->root); } } void ec_handle_healers_done(ec_fop_data_t *fop) { ec_t *ec = fop->xl->private; ec_fop_data_t *heal_fop = NULL; if (list_empty(&fop->healer)) return; LOCK(&ec->lock); list_del_init(&fop->healer); do { ec->healers--; heal_fop = __ec_dequeue_heals(ec); if ((heal_fop != NULL) && ec->shutdown) { /* This will prevent ec_handle_healers_done() to be * called recursively. That would be problematic if * the queue is too big. */ list_del_init(&heal_fop->healer); UNLOCK(&ec->lock); ec_fop_set_error(fop, ENOTCONN); ec_heal_fail(ec, heal_fop); LOCK(&ec->lock); } } while ((heal_fop != NULL) && ec->shutdown); UNLOCK(&ec->lock); if (heal_fop) ec_launch_heal(ec, heal_fop); } static gf_boolean_t ec_is_entry_healing(ec_fop_data_t *fop) { ec_inode_t *ctx = NULL; int32_t heal_count = 0; loc_t *loc = NULL; loc = &fop->loc[0]; LOCK(&loc->inode->lock); { ctx = __ec_inode_get(loc->inode, fop->xl); if (ctx) { heal_count = ctx->heal_count; } } UNLOCK(&loc->inode->lock); GF_ASSERT(heal_count >= 0); return heal_count; } static void ec_heal_throttle(xlator_t *this, ec_fop_data_t *fop) { gf_boolean_t can_heal = _gf_true; ec_t *ec = this->private; ec_fop_data_t *fop_rel = NULL; if (fop->req_frame == NULL) { LOCK(&ec->lock); { if ((ec->background_heals > 0) && (ec->heal_wait_qlen + ec->background_heals) > (ec->heal_waiters + ec->healers)) { if (!ec_is_entry_healing(fop)) { list_add_tail(&fop->healer, &ec->heal_waiting); ec->heal_waiters++; ec_set_entry_healing(fop); } else { fop_rel = fop; } fop = __ec_dequeue_heals(ec); } else { can_heal = _gf_false; } } UNLOCK(&ec->lock); } if (can_heal) { if (fop) { if (fop->req_frame != NULL) { ec_set_entry_healing(fop); } ec_launch_heal(ec, fop); } } else { gf_msg_debug(this->name, 0, "Max number of heals are " "pending, background self-heal rejected"); ec_fop_set_error(fop, EBUSY); ec_heal_fail(ec, fop); } if (fop_rel) { ec_heal_done(0, NULL, fop_rel); } } void ec_heal(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_heal_cbk_t func, void *data, loc_t *loc, int32_t partial, dict_t *xdata) { ec_cbk_t callback = {.heal = func}; ec_fop_data_t *fop = NULL; int32_t err = EINVAL; gf_msg_trace("ec", 0, "EC(HEAL) %p", frame); VALIDATE_OR_GOTO(this, fail); GF_VALIDATE_OR_GOTO(this->name, this->private, fail); if (!loc || !loc->inode || gf_uuid_is_null(loc->inode->gfid)) goto fail; if (frame && frame->local) goto fail; fop = ec_fop_data_allocate(frame, this, EC_FOP_HEAL, 0, target, fop_flags, NULL, NULL, callback, data); err = ENOMEM; if (fop == NULL) goto fail; fop->int32 = partial; if (loc) { if (loc_copy(&fop->loc[0], loc) != 0) goto fail; } if (xdata) fop->xdata = dict_ref(xdata); ec_heal_throttle(this, fop); return; fail: if (fop) ec_fop_data_release(fop); if (func) func(frame, data, this, -1, err, 0, 0, 0, 0, NULL); } static int ec_replace_heal_done(int ret, call_frame_t *heal, void *opaque) { ec_t *ec = opaque; gf_boolean_t last_fop = _gf_false; if (GF_ATOMIC_DEC(ec->async_fop_count) == 0) { LOCK(&ec->lock); { last_fop = __ec_is_last_fop(ec); } UNLOCK(&ec->lock); } gf_msg_debug(ec->xl->name, 0, "getxattr on bricks is done ret %d", ret); if (last_fop) ec_pending_fops_completed(ec); return 0; } static int32_t ec_replace_heal(ec_t *ec, inode_t *inode) { loc_t loc = {0}; int ret = 0; loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); ret = syncop_getxattr(ec->xl, &loc, NULL, EC_XATTR_HEAL, NULL, NULL); if (ret < 0) gf_msg_debug(ec->xl->name, 0, "Heal failed for replace brick ret = %d", ret); /* Once the root inode has been checked, it might have triggered a * self-heal on it after a replace brick command or for some other * reason. It can also happen that the volume already had damaged * files in the index, even if the heal on the root directory failed. * In both cases we need to wake all index healers to continue * healing remaining entries that are marked as dirty. */ ec_shd_index_healer_wake(ec); loc_wipe(&loc); return ret; } static int32_t ec_replace_brick_heal_wrap(void *opaque) { ec_t *ec = opaque; inode_table_t *itable = NULL; int32_t ret = -1; if (ec->xl->itable) itable = ec->xl->itable; else goto out; if (xlator_is_cleanup_starting(ec->xl)) goto out; ret = ec_replace_heal(ec, itable->root); out: return ret; } int32_t ec_launch_replace_heal(ec_t *ec) { int ret = -1; ret = synctask_new(ec->xl->ctx->env, ec_replace_brick_heal_wrap, ec_replace_heal_done, NULL, ec); if (ret < 0) { gf_msg_debug(ec->xl->name, 0, "Heal failed for replace brick ret = %d", ret); ec_replace_heal_done(-1, NULL, ec); } return ret; } static int32_t ec_set_heal_info(dict_t **dict_rsp, char *status) { dict_t *dict = NULL; int ret = 0; dict = dict_new(); if (!dict) { ret = -ENOMEM; goto out; } ret = dict_set_str(dict, "heal-info", status); if (ret) { gf_msg(THIS->name, GF_LOG_WARNING, -ret, EC_MSG_HEAL_FAIL, "Failed to set heal-info key to " "%s", status); dict_unref(dict); dict = NULL; } *dict_rsp = dict; out: return ret; } static int32_t _need_heal_calculate(ec_t *ec, uint64_t *dirty, unsigned char *sources, gf_boolean_t self_locked, int32_t lock_count, ec_heal_need_t *need_heal, uint64_t *versions) { int i = 0; int source_count = 0; source_count = EC_COUNT(sources, ec->nodes); if (source_count == ec->nodes) { *need_heal = EC_HEAL_NONEED; if (self_locked || lock_count == 0) { for (i = 0; i < ec->nodes; i++) { if (dirty[i] || (versions[i] != versions[0])) { *need_heal = EC_HEAL_MUST; goto out; } } /* If lock count is 0, all dirty flags are 0 and all the * versions are macthing then why are we here. It looks * like something went wrong while removing the index entries * after completing a successful heal or fop. In this case * we need to remove this index entry to avoid triggering heal * in a loop and causing lookups again and again*/ *need_heal = EC_HEAL_PURGE_INDEX; } else { for (i = 0; i < ec->nodes; i++) { /* Since each lock can only increment the dirty * count once, if dirty is > 1 it means that * another operation has left the dirty count * set and this indicates a problem in the * inode.*/ if (dirty[i] > 1) { *need_heal = EC_HEAL_MUST; goto out; } if (dirty[i] != dirty[0] || (versions[i] != versions[0])) { *need_heal = EC_HEAL_MAYBE; } } } } else { *need_heal = EC_HEAL_MUST; } out: return source_count; } static int32_t ec_need_metadata_heal(ec_t *ec, inode_t *inode, default_args_cbk_t *replies, int32_t lock_count, gf_boolean_t self_locked, gf_boolean_t thorough, ec_heal_need_t *need_heal) { uint64_t *dirty = NULL; unsigned char *sources = NULL; unsigned char *healed_sinks = NULL; uint64_t *meta_versions = NULL; int ret = 0; sources = alloca0(ec->nodes); healed_sinks = alloca0(ec->nodes); dirty = alloca0(ec->nodes * sizeof(*dirty)); meta_versions = alloca0(ec->nodes * sizeof(*meta_versions)); ret = ec_heal_metadata_find_direction(ec, replies, meta_versions, dirty, sources, healed_sinks); if (ret < 0 && ret != -EIO) { goto out; } ret = _need_heal_calculate(ec, dirty, sources, self_locked, lock_count, need_heal, meta_versions); out: return ret; } static int32_t ec_need_data_heal(ec_t *ec, inode_t *inode, default_args_cbk_t *replies, int32_t lock_count, gf_boolean_t self_locked, gf_boolean_t thorough, ec_heal_need_t *need_heal) { uint64_t *dirty = NULL; unsigned char *sources = NULL; unsigned char *healed_sinks = NULL; uint64_t *data_versions = NULL; uint64_t *size = NULL; int ret = 0; sources = alloca0(ec->nodes); healed_sinks = alloca0(ec->nodes); dirty = alloca0(ec->nodes * sizeof(*dirty)); data_versions = alloca0(ec->nodes * sizeof(*data_versions)); size = alloca0(ec->nodes * sizeof(*size)); /* When dd is going on and heal info is called there is a very good * chance for on disk sizes to mismatch even though nothing is wrong * we don't need ondisk size check there. But if the file is either * self-locked or the caller wants a thorough check then make sure to * perform on disk check also. */ ret = ec_heal_data_find_direction( ec, replies, data_versions, dirty, size, sources, healed_sinks, self_locked || thorough, EC_COMBINE_XDATA); if (ret < 0 && ret != -EIO) { goto out; } ret = _need_heal_calculate(ec, dirty, sources, self_locked, lock_count, need_heal, data_versions); out: return ret; } static int32_t ec_need_entry_heal(ec_t *ec, inode_t *inode, default_args_cbk_t *replies, int32_t lock_count, gf_boolean_t self_locked, gf_boolean_t thorough, ec_heal_need_t *need_heal) { uint64_t *dirty = NULL; unsigned char *sources = NULL; unsigned char *healed_sinks = NULL; uint64_t *data_versions = NULL; int ret = 0; sources = alloca0(ec->nodes); healed_sinks = alloca0(ec->nodes); dirty = alloca0(ec->nodes * sizeof(*dirty)); data_versions = alloca0(ec->nodes * sizeof(*data_versions)); ret = ec_heal_entry_find_direction(ec, replies, data_versions, dirty, sources, healed_sinks); if (ret < 0 && ret != -EIO) { goto out; } ret = _need_heal_calculate(ec, dirty, sources, self_locked, lock_count, need_heal, data_versions); out: return ret; } static int32_t ec_need_heal(ec_t *ec, inode_t *inode, default_args_cbk_t *replies, int32_t lock_count, gf_boolean_t self_locked, gf_boolean_t thorough, ec_heal_need_t *need_heal) { int ret = 0; ret = ec_need_metadata_heal(ec, inode, replies, lock_count, self_locked, thorough, need_heal); if (ret < 0) goto out; if (*need_heal == EC_HEAL_MUST) goto out; if (inode->ia_type == IA_IFREG) { ret = ec_need_data_heal(ec, inode, replies, lock_count, self_locked, thorough, need_heal); } else if (inode->ia_type == IA_IFDIR) { ret = ec_need_entry_heal(ec, inode, replies, lock_count, self_locked, thorough, need_heal); } out: return ret; } static int32_t ec_heal_inspect(call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *locked_on, gf_boolean_t self_locked, gf_boolean_t thorough, ec_heal_need_t *need_heal) { loc_t loc = {0}; int i = 0; int ret = 0; dict_t *xdata = NULL; uint64_t zero_array[2] = {0}; uint64_t zero_value = 0; unsigned char *output = NULL; default_args_cbk_t *replies = NULL; int32_t lock_count = 0; EC_REPLIES_ALLOC(replies, ec->nodes); output = alloca0(ec->nodes); loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); xdata = dict_new(); if (!xdata || dict_set_static_bin(xdata, EC_XATTR_VERSION, zero_array, sizeof(zero_array)) || dict_set_static_bin(xdata, EC_XATTR_DIRTY, zero_array, sizeof(zero_array)) || dict_set_static_bin(xdata, EC_XATTR_SIZE, &zero_value, sizeof(zero_value))) { ret = -ENOMEM; goto out; } if (!self_locked) { ret = dict_set_str(xdata, GLUSTERFS_INODELK_DOM_COUNT, ec->xl->name); if (ret) { ret = -ENOMEM; goto out; } } ret = cluster_lookup(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, &loc, xdata); if (ret != ec->nodes) { ret = ec->nodes; *need_heal = EC_HEAL_MUST; goto out; } if (self_locked) goto need_heal; for (i = 0; i < ec->nodes; i++) { if (!output[i] || !replies[i].xdata) { continue; } if ((dict_get_int32(replies[i].xdata, GLUSTERFS_INODELK_COUNT, &lock_count) == 0) && lock_count > 0) { break; } } need_heal: ret = ec_need_heal(ec, inode, replies, lock_count, self_locked, thorough, need_heal); out: cluster_replies_wipe(replies, ec->nodes); loc_wipe(&loc); if (xdata) { dict_unref(xdata); } return ret; } int32_t ec_heal_locked_inspect(call_frame_t *frame, ec_t *ec, inode_t *inode, ec_heal_need_t *need_heal) { unsigned char *locked_on = NULL; unsigned char *up_subvols = NULL; unsigned char *output = NULL; default_args_cbk_t *replies = NULL; int ret = 0; EC_REPLIES_ALLOC(replies, ec->nodes); locked_on = alloca0(ec->nodes); output = alloca0(ec->nodes); up_subvols = alloca0(ec->nodes); ec_mask_to_char_array(ec->xl_up, up_subvols, ec->nodes); ret = cluster_inodelk(ec->xl_list, up_subvols, ec->nodes, replies, locked_on, frame, ec->xl, ec->xl->name, inode, 0, 0); if (ret != ec->nodes) { *need_heal = EC_HEAL_MUST; goto unlock; } ret = ec_heal_inspect(frame, ec, inode, locked_on, _gf_true, _gf_true, need_heal); unlock: cluster_uninodelk(ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, ec->xl->name, inode, 0, 0); cluster_replies_wipe(replies, ec->nodes); return ret; } int32_t ec_get_heal_info(xlator_t *this, loc_t *entry_loc, dict_t **dict_rsp) { int ret = -ENOMEM; ec_heal_need_t need_heal = EC_HEAL_NONEED; call_frame_t *frame = NULL; ec_t *ec = NULL; unsigned char *up_subvols = NULL; loc_t loc = { 0, }; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, entry_loc, out); ec = this->private; up_subvols = alloca0(ec->nodes); ec_mask_to_char_array(ec->xl_up, up_subvols, ec->nodes); if (EC_COUNT(up_subvols, ec->nodes) != ec->nodes) { need_heal = EC_HEAL_MUST; goto set_heal; } frame = create_frame(this, this->ctx->pool); if (!frame) { goto out; } ec_owner_set(frame, frame->root); frame->root->uid = 0; frame->root->gid = 0; frame->root->pid = GF_CLIENT_PID_SELF_HEALD; if (loc_copy(&loc, entry_loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } if (!loc.inode) { ret = syncop_inode_find(this, this, loc.gfid, &loc.inode, NULL, NULL); if (ret < 0) goto out; } ret = ec_heal_inspect(frame, ec, loc.inode, up_subvols, _gf_false, _gf_false, &need_heal); if (ret == ec->nodes && need_heal != EC_HEAL_MAYBE) { goto set_heal; } need_heal = EC_HEAL_NONEED; ret = ec_heal_locked_inspect(frame, ec, loc.inode, &need_heal); if (ret < 0) goto out; set_heal: if (need_heal == EC_HEAL_MUST) { ret = ec_set_heal_info(dict_rsp, "heal"); } else { ret = ec_set_heal_info(dict_rsp, "no-heal"); } out: if (frame) { STACK_DESTROY(frame->root); } loc_wipe(&loc); return ret; } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-types.h0000644000000000000000000000013214522202451022615 xustar000000000000000030 mtime=1699284265.643027359 30 atime=1699284265.642027356 30 ctime=1699284301.373134978 glusterfs-11.1/xlators/cluster/ec/src/ec-types.h0000664000175100017510000004461714522202451023110 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_TYPES_H__ #define __EC_TYPES_H__ #include #include #include "libxlator.h" #include #define EC_GF_MAX_REGS 16 enum _ec_heal_need; typedef enum _ec_heal_need ec_heal_need_t; enum _ec_stripe_part; typedef enum _ec_stripe_part ec_stripe_part_t; enum _ec_read_policy; typedef enum _ec_read_policy ec_read_policy_t; struct _ec_config; typedef struct _ec_config ec_config_t; struct _ec_fd; typedef struct _ec_fd ec_fd_t; struct _ec_fragment_range; typedef struct _ec_fragment_range ec_fragment_range_t; struct _ec_inode; typedef struct _ec_inode ec_inode_t; union _ec_cbk; typedef union _ec_cbk ec_cbk_t; struct _ec_lock; typedef struct _ec_lock ec_lock_t; struct _ec_lock_link; typedef struct _ec_lock_link ec_lock_link_t; struct _ec_fop_data; typedef struct _ec_fop_data ec_fop_data_t; struct _ec_cbk_data; typedef struct _ec_cbk_data ec_cbk_data_t; enum _ec_gf_opcode; typedef enum _ec_gf_opcode ec_gf_opcode_t; struct _ec_gf_op; typedef struct _ec_gf_op ec_gf_op_t; struct _ec_gf_mul; typedef struct _ec_gf_mul ec_gf_mul_t; struct _ec_gf; typedef struct _ec_gf ec_gf_t; struct _ec_code_gen; typedef struct _ec_code_gen ec_code_gen_t; struct _ec_code; typedef struct _ec_code ec_code_t; struct _ec_code_arg; typedef struct _ec_code_arg ec_code_arg_t; struct _ec_code_op; typedef struct _ec_code_op ec_code_op_t; struct _ec_code_builder; typedef struct _ec_code_builder ec_code_builder_t; struct _ec_code_chunk; typedef struct _ec_code_chunk ec_code_chunk_t; struct _ec_stripe; typedef struct _ec_stripe ec_stripe_t; struct _ec_stripe_list; typedef struct _ec_stripe_list ec_stripe_list_t; struct _ec_code_space; typedef struct _ec_code_space ec_code_space_t; typedef void (*ec_code_func_linear_t)(void *dst, void *src, uint64_t offset, uint32_t *values, uint32_t count); typedef void (*ec_code_func_interleaved_t)(void *dst, void **src, uint64_t offset, uint32_t *values, uint32_t count); union _ec_code_func; typedef union _ec_code_func ec_code_func_t; struct _ec_matrix_row; typedef struct _ec_matrix_row ec_matrix_row_t; struct _ec_matrix; typedef struct _ec_matrix ec_matrix_t; struct _ec_matrix_list; typedef struct _ec_matrix_list ec_matrix_list_t; struct _ec_heal; typedef struct _ec_heal ec_heal_t; struct _ec_self_heald; typedef struct _ec_self_heald ec_self_heald_t; struct _ec_statistics; typedef struct _ec_statistics ec_statistics_t; struct _ec; typedef struct _ec ec_t; typedef void (*ec_wind_f)(ec_t *, ec_fop_data_t *, int32_t); typedef int32_t (*ec_handler_f)(ec_fop_data_t *, int32_t); typedef void (*ec_resume_f)(ec_fop_data_t *, int32_t); enum _ec_read_policy { EC_ROUND_ROBIN, EC_GFID_HASH, EC_READ_POLICY_MAX }; enum _ec_heal_need { EC_HEAL_NONEED, EC_HEAL_MAYBE, EC_HEAL_MUST, EC_HEAL_PURGE_INDEX }; enum _ec_stripe_part { EC_STRIPE_HEAD, EC_STRIPE_TAIL }; /* Enumartions to indicate FD status. */ typedef enum { EC_FD_NOT_OPENED, EC_FD_OPENED, EC_FD_OPENING } ec_fd_status_t; struct _ec_config { uint32_t version; uint8_t algorithm; uint8_t gf_word_size; uint8_t bricks; uint8_t redundancy; uint32_t chunk_size; }; struct _ec_fd { loc_t loc; uintptr_t open; int32_t flags; uint64_t bad_version; ec_fd_status_t fd_status[0]; }; struct _ec_stripe { struct list_head lru; /* LRU list member */ uint64_t frag_offset; /* Fragment offset of this stripe */ char data[]; /* Contents of the stripe */ }; struct _ec_stripe_list { struct list_head lru; uint32_t count; uint32_t max; }; struct _ec_inode { ec_lock_t *inode_lock; gf_boolean_t have_info; gf_boolean_t have_config; gf_boolean_t have_version; gf_boolean_t have_size; int32_t heal_count; ec_config_t config; uint64_t pre_version[2]; uint64_t post_version[2]; uint64_t pre_size; uint64_t post_size; uint64_t dirty[2]; struct list_head heal; ec_stripe_list_t stripe_cache; uint64_t bad_version; }; typedef int32_t (*fop_heal_cbk_t)(call_frame_t *, void *, xlator_t *, int32_t, int32_t, uintptr_t, uintptr_t, uintptr_t, uint32_t, dict_t *); typedef int32_t (*fop_fheal_cbk_t)(call_frame_t *, void *, xlator_t *, int32_t, int32_t, uintptr_t, uintptr_t, uintptr_t, uint32_t, dict_t *); union _ec_cbk { fop_access_cbk_t access; fop_create_cbk_t create; fop_discard_cbk_t discard; fop_entrylk_cbk_t entrylk; fop_fentrylk_cbk_t fentrylk; fop_fallocate_cbk_t fallocate; fop_flush_cbk_t flush; fop_fsync_cbk_t fsync; fop_fsyncdir_cbk_t fsyncdir; fop_getxattr_cbk_t getxattr; fop_fgetxattr_cbk_t fgetxattr; fop_heal_cbk_t heal; fop_fheal_cbk_t fheal; fop_inodelk_cbk_t inodelk; fop_finodelk_cbk_t finodelk; fop_link_cbk_t link; fop_lk_cbk_t lk; fop_lookup_cbk_t lookup; fop_mkdir_cbk_t mkdir; fop_mknod_cbk_t mknod; fop_open_cbk_t open; fop_opendir_cbk_t opendir; fop_readdir_cbk_t readdir; fop_readdirp_cbk_t readdirp; fop_readlink_cbk_t readlink; fop_readv_cbk_t readv; fop_removexattr_cbk_t removexattr; fop_fremovexattr_cbk_t fremovexattr; fop_rename_cbk_t rename; fop_rmdir_cbk_t rmdir; fop_setattr_cbk_t setattr; fop_fsetattr_cbk_t fsetattr; fop_setxattr_cbk_t setxattr; fop_fsetxattr_cbk_t fsetxattr; fop_stat_cbk_t stat; fop_fstat_cbk_t fstat; fop_statfs_cbk_t statfs; fop_symlink_cbk_t symlink; fop_truncate_cbk_t truncate; fop_ftruncate_cbk_t ftruncate; fop_unlink_cbk_t unlink; fop_writev_cbk_t writev; fop_xattrop_cbk_t xattrop; fop_fxattrop_cbk_t fxattrop; fop_zerofill_cbk_t zerofill; fop_seek_cbk_t seek; fop_ipc_cbk_t ipc; }; struct _ec_lock { ec_inode_t *ctx; gf_timer_t *timer; /* List of owners of this lock. All fops added to this list are running * concurrently. */ struct list_head owners; /* List of fops waiting to be an owner of the lock. Fops are added to this * list when the current owner has an incompatible access (conflicting lock) * or the lock is not acquired yet. */ struct list_head waiting; /* List of fops that will wait until the next unlock/lock cycle. This * happens when the currently acquired lock is decided to be released as * soon as possible. In this case, all frozen fops will be continued only * after the lock is reacquired. */ struct list_head frozen; uintptr_t mask; uintptr_t good_mask; uintptr_t healing; uint32_t refs_owners; /* Refs for fops owning the lock */ uint32_t refs_pending; /* Refs assigned to fops being prepared */ uint32_t waiting_flags; /*Track xattrop/dirty marking*/ gf_boolean_t acquired; gf_boolean_t contention; gf_boolean_t unlock_now; gf_boolean_t release; gf_boolean_t query; fd_t *fd; loc_t loc; union { entrylk_type type; struct gf_flock flock; }; }; struct _ec_lock_link { ec_lock_t *lock; ec_fop_data_t *fop; struct list_head owner_list; struct list_head wait_list; gf_boolean_t update[2]; gf_boolean_t dirty[2]; gf_boolean_t optimistic_changelog; loc_t *base; uint64_t size; uint32_t waiting_flags; off_t fl_start; off_t fl_end; }; /* This structure keeps a range of fragment offsets affected by a fop. Since * real file offsets can be difficult to handle correctly because of overflows, * we use the 'scaled' offset, which corresponds to the offset of the fragment * seen by the bricks, which is always smaller and cannot overflow. */ struct _ec_fragment_range { uint64_t first; /* Address of the first affected fragment as seen by the bricks (offset on brick) */ uint64_t last; /* Address of the first non affected fragment as seen by the bricks (offset on brick) */ }; /* EC xlator data structure to collect all the data required to perform * the file operation.*/ struct _ec_fop_data { int32_t id; /* ID of the file operation */ int32_t refs; int32_t state; uint32_t minimum; /* Minimum number of successful operation required to conclude a fop as successful */ int32_t expected; int32_t winds; int32_t jobs; int32_t error; ec_fop_data_t *parent; xlator_t *xl; /* points to EC xlator */ call_frame_t *req_frame; /* frame of the calling xlator */ call_frame_t *frame; /* frame used by this fop */ struct list_head cbk_list; /* sorted list of groups of answers */ struct list_head answer_list; /* list of answers */ struct list_head pending_list; /* member of ec_t.pending_fops */ ec_cbk_data_t *answer; /* accepted answer */ int32_t lock_count; int32_t locked; gf_lock_t lock; ec_lock_link_t locks[2]; int32_t first_lock; uint32_t fop_flags; /* Flags passed by the caller. */ uint32_t flags; /* Internal flags. */ uint32_t first; uintptr_t mask; uintptr_t healing; /*Dispatch is done but call is successful only if fop->minimum number of subvolumes succeed which are not healing*/ uintptr_t remaining; uintptr_t received; /* Mask of responses */ uintptr_t good; uid_t uid; gid_t gid; ec_wind_f wind; /* Function to wind to */ ec_handler_f handler; /* FOP manager function */ ec_resume_f resume; ec_cbk_t cbks; /* Callback function for this FOP */ void *data; ec_heal_t *heal; struct list_head healer; uint64_t user_size; uint32_t head; int32_t use_fd; /* Indicates whether this FOP uses FD or not */ dict_t *xdata; dict_t *dict; int32_t int32; uint32_t uint32; uint64_t size; off_t offset; mode_t mode[2]; entrylk_cmd entrylk_cmd; entrylk_type entrylk_type; gf_xattrop_flags_t xattrop_flags; dev_t dev; inode_t *inode; fd_t *fd; /* FD of the file on which FOP is being carried upon */ struct iatt iatt; char *str[2]; loc_t loc[2]; /* Holds the location details for the file */ struct gf_flock flock; struct iovec *vector; struct iobref *buffers; gf_seek_what_t seek; ec_fragment_range_t frag_range; /* This will hold the range of stripes affected by the fop. */ char *errstr; /*String of fop name, path and gfid to be used in gf_msg. */ }; struct _ec_cbk_data { struct list_head list; /* item in the sorted list of groups */ struct list_head answer_list; /* item in the list of answers */ ec_fop_data_t *fop; ec_cbk_data_t *next; /* next answer in the same group */ uint32_t idx; int32_t op_ret; int32_t op_errno; int32_t count; uintptr_t mask; dict_t *xdata; dict_t *dict; int32_t int32; uintptr_t uintptr[3]; uint64_t size; uint64_t version[2]; inode_t *inode; fd_t *fd; struct statvfs statvfs; struct iatt iatt[5]; struct gf_flock flock; struct iovec *vector; struct iobref *buffers; char *str; gf_dirent_t entries; off_t offset; gf_seek_what_t what; }; enum _ec_gf_opcode { EC_GF_OP_LOAD, EC_GF_OP_STORE, EC_GF_OP_COPY, EC_GF_OP_XOR2, EC_GF_OP_XOR3, EC_GF_OP_XORM, EC_GF_OP_END }; struct _ec_gf_op { ec_gf_opcode_t op; uint32_t arg1; uint32_t arg2; uint32_t arg3; }; struct _ec_gf_mul { uint32_t regs; uint32_t map[EC_GF_MAX_REGS]; ec_gf_op_t *ops; }; struct _ec_gf { uint32_t bits; uint32_t size; uint32_t mod; uint32_t min_ops; uint32_t max_ops; uint32_t avg_ops; uint32_t *log; uint32_t *pow; ec_gf_mul_t **table; }; struct _ec_code_gen { char *name; char **flags; uint32_t width; void (*prolog)(ec_code_builder_t *builder); void (*epilog)(ec_code_builder_t *builder); void (*load)(ec_code_builder_t *builder, uint32_t reg, uint32_t offset, uint32_t bit); void (*store)(ec_code_builder_t *builder, uint32_t reg, uint32_t bit); void (*copy)(ec_code_builder_t *builder, uint32_t dst, uint32_t src); void (*xor2)(ec_code_builder_t *builder, uint32_t dst, uint32_t src); void (*xor3)(ec_code_builder_t *builder, uint32_t dst, uint32_t src1, uint32_t src2); void (*xorm)(ec_code_builder_t *builder, uint32_t dst, uint32_t offset, uint32_t bit); }; struct _ec_code { gf_lock_t lock; struct list_head spaces; ec_gf_t *gf; ec_code_gen_t *gen; }; struct _ec_code_arg { uint32_t value; }; struct _ec_code_op { ec_gf_opcode_t op; ec_code_arg_t arg1; ec_code_arg_t arg2; ec_code_arg_t arg3; }; struct _ec_code_builder { ec_code_t *code; uint64_t address; uint8_t *data; uint32_t size; int32_t error; uint32_t regs; uint32_t bits; uint32_t width; uint32_t count; uint32_t base; uint32_t map[EC_GF_MAX_REGS]; gf_boolean_t linear; uint64_t loop; ec_code_op_t ops[0]; }; struct _ec_code_chunk { struct list_head list; size_t size; ec_code_space_t *space; }; struct _ec_code_space { struct list_head list; struct list_head chunks; ec_code_t *code; void *exec; size_t size; }; union _ec_code_func { ec_code_func_linear_t linear; ec_code_func_interleaved_t interleaved; }; struct _ec_matrix_row { ec_code_func_t func; uint32_t *values; }; struct _ec_matrix { struct list_head lru; uint32_t refs; uint32_t columns; uint32_t rows; uintptr_t mask; ec_code_t *code; uint32_t *values; ec_matrix_row_t row_data[0]; }; struct _ec_matrix_list { struct list_head lru; gf_lock_t lock; uint32_t columns; uint32_t rows; uint32_t max; uint32_t count; uint32_t stripe; struct mem_pool *pool; ec_gf_t *gf; ec_code_t *code; ec_matrix_t *encode; ec_matrix_t **objects; }; struct _ec_heal { gf_lock_t lock; xlator_t *xl; ec_fop_data_t *fop; syncbarrier_t barrier; loc_t loc; ia_type_t ia_type; fd_t *fd; gf_boolean_t done; int32_t error; uintptr_t good; uintptr_t bad; uintptr_t open; uint64_t offset; uint64_t size; uint64_t total_size; }; struct subvol_healer { xlator_t *this; int subvol; gf_boolean_t running; gf_boolean_t rerun; pthread_mutex_t mutex; pthread_cond_t cond; pthread_t thread; }; struct _ec_self_heald { gf_boolean_t iamshd; gf_boolean_t enabled; time_t timeout; uint32_t max_threads; uint32_t wait_qlength; struct subvol_healer *index_healers; struct subvol_healer *full_healers; }; struct _ec_statistics { struct { gf_atomic_t hits; /* Cache hits. */ gf_atomic_t misses; /* Cache misses. */ gf_atomic_t updates; /* Number of times an existing stripe has been updated with new content. */ gf_atomic_t invals; /* Number of times an existing stripe has been invalidated because of truncates or discards. */ gf_atomic_t evicts; /* Number of times that an existing entry has been evicted to make room for newer entries. */ gf_atomic_t allocs; /* Number of memory allocations made to store stripes. */ gf_atomic_t errors; /* Number of errors that have caused extra requests. (Basically memory allocation errors). */ } stripe_cache; struct { gf_atomic_t attempted; /*Number of heals attempted on files/directories*/ gf_atomic_t completed; /*Number of heals complted on files/directories*/ } shd; }; struct _ec { xlator_t *xl; int32_t healers; int32_t heal_waiters; int32_t nodes; /* Total number of bricks(n) */ int32_t bits_for_nodes; int32_t fragments; /* Data bricks(k) */ int32_t redundancy; /* Redundant bricks(m) */ uint32_t fragment_size; /* Size of fragment/chunk on a brick. */ uint32_t stripe_size; /* (fragment_size * fragments) maximum size of user data stored in one stripe. */ int32_t up; /* Represents whether EC volume is up or not. */ uint32_t idx; uint32_t xl_up_count; /* Number of UP bricks. */ uintptr_t xl_up; /* Bit flag representing UP bricks */ uint32_t xl_notify_count; /* Number of notifications. */ uintptr_t xl_notify; /* Bit flag representing notification for bricks. */ uintptr_t node_mask; uintptr_t read_mask; /*Stores user defined read-mask*/ gf_atomic_t async_fop_count; /* Number of on going asynchronous fops. */ xlator_t **xl_list; gf_lock_t lock; gf_timer_t *timer; gf_boolean_t shutdown; gf_boolean_t eager_lock; gf_boolean_t other_eager_lock; gf_boolean_t optimistic_changelog; gf_boolean_t parallel_writes; uint32_t stripe_cache; uint32_t quorum_count; uint32_t background_heals; uint32_t heal_wait_qlen; uint32_t self_heal_window_size; /* max size of read/writes */ time_t eager_lock_timeout; time_t other_eager_lock_timeout; struct list_head pending_fops; struct list_head heal_waiting; struct list_head healing; struct mem_pool *fop_pool; struct mem_pool *cbk_pool; struct mem_pool *lock_pool; ec_self_heald_t shd; char vol_uuid[GF_UUID_BUF_SIZE]; dict_t *leaf_to_subvolid; ec_read_policy_t read_policy; ec_matrix_list_t matrix; ec_statistics_t stats; }; #endif /* __EC_TYPES_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-helpers.h0000644000000000000000000000013114522202451023112 xustar000000000000000030 mtime=1699284265.640027351 30 atime=1699284265.640027351 29 ctime=1699284301.35713493 glusterfs-11.1/xlators/cluster/ec/src/ec-helpers.h0000664000175100017510000001234414522202451023376 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_HELPERS_H__ #define __EC_HELPERS_H__ #include "ec-types.h" #define EC_ERR(_x) ((void *)-(intptr_t)(_x)) #define EC_IS_ERR(_x) (((uintptr_t)(_x) & ~0xfffULL) == ~0xfffULL) #define EC_GET_ERR(_x) ((int32_t)(intptr_t)(_x)) #define EC_ALIGN_CHECK(_ptr, _align) ((((uintptr_t)(_ptr)) & ((_align)-1)) == 0) const char * ec_bin(char *str, size_t size, uint64_t value, int32_t digits); const char * ec_fop_name(int32_t id); void ec_trace(const char *event, ec_fop_data_t *fop, const char *fmt, ...); size_t ec_iov_copy_to(void *dst, struct iovec *vector, int32_t count, off_t offset, size_t size); int32_t ec_buffer_alloc(xlator_t *xl, size_t size, struct iobref **piobref, void **ptr); int32_t ec_dict_set_array(dict_t *dict, char *key, uint64_t *value, int32_t size); int32_t ec_dict_get_array(dict_t *dict, char *key, uint64_t value[], int32_t size); int32_t ec_dict_del_array(dict_t *dict, char *key, uint64_t *value, int32_t size); int32_t ec_dict_set_number(dict_t *dict, char *key, uint64_t value); int32_t ec_dict_del_number(dict_t *dict, char *key, uint64_t *value); int32_t ec_dict_set_config(dict_t *dict, char *key, ec_config_t *config); int32_t ec_dict_del_config(dict_t *dict, char *key, ec_config_t *config); int32_t ec_loc_parent(xlator_t *xl, loc_t *loc, loc_t *parent); int32_t ec_loc_update(xlator_t *xl, loc_t *loc, inode_t *inode, struct iatt *iatt); int32_t ec_loc_from_fd(xlator_t *xl, loc_t *loc, fd_t *fd); int32_t ec_loc_from_loc(xlator_t *xl, loc_t *dst, loc_t *src); void ec_owner_set(call_frame_t *frame, void *owner); void ec_owner_copy(call_frame_t *frame, gf_lkowner_t *owner); ec_inode_t * __ec_inode_get(inode_t *inode, xlator_t *xl); ec_inode_t * ec_inode_get(inode_t *inode, xlator_t *xl); ec_fd_t * __ec_fd_get(fd_t *fd, xlator_t *xl); ec_fd_t * ec_fd_get(fd_t *fd, xlator_t *xl); static inline uint32_t ec_adjust_size_down(ec_t *ec, uint64_t *value, gf_boolean_t scale) { uint64_t head, tmp; tmp = *value; head = tmp % ec->stripe_size; tmp -= head; if (scale) { tmp /= ec->fragments; } *value = tmp; return (uint32_t)head; } /* This function can cause an overflow if the passed value is too near to the * uint64_t limit. If this happens, it returns the tail in negative form and * the value is set to UINT64_MAX. */ static inline int32_t ec_adjust_size_up(ec_t *ec, uint64_t *value, gf_boolean_t scale) { uint64_t tmp; int32_t tail; tmp = *value; /* We first adjust the value down. This never causes overflow. */ tail = ec_adjust_size_down(ec, &tmp, scale); /* If the value was already aligned, tail will be 0 and nothing else * needs to be done. */ if (tail != 0) { /* Otherwise, we need to compute the real tail and adjust the * returned value to the next stripe. */ tail = ec->stripe_size - tail; if (scale) { tmp += ec->fragment_size; } else { tmp += ec->stripe_size; /* If no scaling is requested there's a possibility of * overflow. */ if (tmp < ec->stripe_size) { tmp = UINT64_MAX; tail = -tail; } } } *value = tmp; return tail; } /* This function is equivalent to ec_adjust_size_down() but with a potentially * different parameter size (off_t vs uint64_t). */ static inline uint32_t ec_adjust_offset_down(ec_t *ec, off_t *value, gf_boolean_t scale) { off_t head, tmp; tmp = *value; head = tmp % ec->stripe_size; tmp -= head; if (scale) { tmp /= ec->fragments; } *value = tmp; return (uint32_t)head; } /* This function is equivalent to ec_adjust_size_up() but with a potentially * different parameter size (off_t vs uint64_t). */ static inline int32_t ec_adjust_offset_up(ec_t *ec, off_t *value, gf_boolean_t scale) { uint64_t tail, tmp; /* An offset is a signed type that can only have positive values, so * we take advantage of this to avoid overflows. We simply convert it * to an unsigned integer and operate normally. This won't cause an * overflow. Overflow is only checked when converting back to an * off_t. */ tmp = *value; tail = ec->stripe_size; tail -= (tmp + tail - 1) % tail + 1; tmp += tail; if (scale) { /* If we are scaling, we'll never get an overflow. */ tmp /= ec->fragments; } else { /* Check if there has been an overflow. */ if ((off_t)tmp < 0) { tmp = GF_OFF_MAX; tail = -tail; } } *value = (off_t)tmp; return (int32_t)tail; } static inline int32_t ec_is_power_of_2(uint32_t value) { return (value != 0) && ((value & (value - 1)) == 0); } gf_boolean_t ec_is_internal_xattr(dict_t *dict, char *key, data_t *value, void *data); void ec_filter_internal_xattrs(dict_t *xattr); int32_t ec_launch_replace_heal(ec_t *ec); #endif /* __EC_HELPERS_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-heald.c0000644000000000000000000000013014522202451022517 xustar000000000000000030 mtime=1699284265.640027351 30 atime=1699284265.640027351 28 ctime=1699284301.3471349 glusterfs-11.1/xlators/cluster/ec/src/ec-heald.c0000664000175100017510000003764614522202451023020 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "ec.h" #include "ec-messages.h" #include "ec-heald.h" #include "ec-mem-types.h" #include #include #include "protocol-common.h" #define NTH_INDEX_HEALER(this, n) \ (&((((ec_t *)this->private))->shd.index_healers[n])) #define NTH_FULL_HEALER(this, n) \ (&((((ec_t *)this->private))->shd.full_healers[n])) gf_boolean_t ec_shd_is_subvol_local(xlator_t *this, int subvol) { ec_t *ec = NULL; gf_boolean_t is_local = _gf_false; loc_t loc = { 0, }; ec = this->private; loc.inode = this->itable->root; syncop_is_subvol_local(ec->xl_list[subvol], &loc, &is_local); return is_local; } char * ec_subvol_name(xlator_t *this, int subvol) { ec_t *ec = NULL; ec = this->private; if (subvol < 0 || subvol > ec->nodes) return NULL; return ec->xl_list[subvol]->name; } int __ec_shd_healer_wait(struct subvol_healer *healer) { ec_t *ec = NULL; struct timespec wait_till = { 0, }; int ret = 0; ec = healer->this->private; disabled_loop: wait_till.tv_sec = gf_time() + ec->shd.timeout; while (!healer->rerun) { ret = pthread_cond_timedwait(&healer->cond, &healer->mutex, &wait_till); if (ret == ETIMEDOUT) break; } if (ec->shutdown) { healer->running = _gf_false; return -1; } ret = healer->rerun; healer->rerun = 0; if (!ec->shd.enabled || !ec->up) goto disabled_loop; return ret; } int ec_shd_healer_wait(struct subvol_healer *healer) { int ret = 0; pthread_mutex_lock(&healer->mutex); { ret = __ec_shd_healer_wait(healer); } pthread_mutex_unlock(&healer->mutex); return ret; } int ec_shd_index_inode(xlator_t *this, xlator_t *subvol, inode_t **inode) { loc_t rootloc = { 0, }; int ret = 0; dict_t *xattr = NULL; void *index_gfid = NULL; *inode = NULL; rootloc.inode = inode_ref(this->itable->root); gf_uuid_copy(rootloc.gfid, rootloc.inode->gfid); ret = syncop_getxattr(subvol, &rootloc, &xattr, GF_XATTROP_INDEX_GFID, NULL, NULL); if (ret < 0) goto out; if (!xattr) { ret = -EINVAL; goto out; } ret = dict_get_ptr(xattr, GF_XATTROP_INDEX_GFID, &index_gfid); if (ret) goto out; gf_msg_debug(this->name, 0, "index-dir gfid for %s: %s", subvol->name, uuid_utoa(index_gfid)); ret = syncop_inode_find(this, subvol, index_gfid, inode, NULL, NULL); out: loc_wipe(&rootloc); if (xattr) dict_unref(xattr); return ret; } int ec_shd_index_purge(xlator_t *subvol, inode_t *inode, char *name) { loc_t loc = { 0, }; int ret = 0; loc.parent = inode_ref(inode); loc.name = name; ret = syncop_unlink(subvol, &loc, NULL, NULL); loc_wipe(&loc); return ret; } static gf_boolean_t ec_is_heal_completed(char *status) { char *bad_pos = NULL; char *zero_pos = NULL; if (!status) { return _gf_false; } /*Logic: * Status will be of the form Good: , Bad: * If heal completes, if we do strchr for '0' it should be present after * 'Bad:' i.e. strRchr for ':' * */ zero_pos = strchr(status, '0'); bad_pos = strrchr(status, ':'); if (!zero_pos || !bad_pos) { /*malformed status*/ return _gf_false; } if (zero_pos > bad_pos) { return _gf_true; } return _gf_false; } int ec_shd_selfheal(struct subvol_healer *healer, int child, loc_t *loc, gf_boolean_t full) { dict_t *xdata = NULL; dict_t *dict = NULL; uint32_t count; int32_t ret; char *heal_status = NULL; ec_t *ec = healer->this->private; GF_ATOMIC_INC(ec->stats.shd.attempted); ret = syncop_getxattr(healer->this, loc, &dict, EC_XATTR_HEAL, NULL, &xdata); if (ret == 0) { if (dict && (dict_get_str(dict, EC_XATTR_HEAL, &heal_status) == 0)) { if (ec_is_heal_completed(heal_status)) { GF_ATOMIC_INC(ec->stats.shd.completed); } } } if (!full && (loc->inode->ia_type == IA_IFDIR)) { /* If we have just healed a directory, it's possible that * other index entries have appeared to be healed. */ if ((xdata != NULL) && (dict_get_uint32(xdata, EC_XATTR_HEAL_NEW, &count) == 0) && (count > 0)) { /* Force a rerun of the index healer. */ gf_msg_debug(healer->this->name, 0, "%d more entries to heal", count); healer->rerun = _gf_true; } } if (xdata != NULL) { dict_unref(xdata); } if (dict) { dict_unref(dict); } return ret; } int ec_shd_index_heal(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { struct subvol_healer *healer = data; ec_t *ec = NULL; loc_t loc = {0}; int ret = 0; ec = healer->this->private; if (ec->xl_up_count <= ec->fragments) { return -ENOTCONN; } if (!ec->shd.enabled) return -EBUSY; gf_msg_debug(healer->this->name, 0, "got entry: %s", entry->d_name); ret = gf_uuid_parse(entry->d_name, loc.gfid); if (ret) return 0; /* If this fails with ENOENT/ESTALE index is stale */ ret = syncop_gfid_to_path(healer->this->itable, subvol, loc.gfid, (char **)&loc.path); if (ret < 0) goto out; ret = syncop_inode_find(healer->this, healer->this, loc.gfid, &loc.inode, NULL, NULL); if (ret < 0) goto out; ec_shd_selfheal(healer, healer->subvol, &loc, _gf_false); out: if (ret == -ENOENT || ret == -ESTALE) { gf_msg(healer->this->name, GF_LOG_DEBUG, 0, EC_MSG_HEAL_FAIL, "Purging index for gfid %s:", uuid_utoa(loc.gfid)); ec_shd_index_purge(subvol, parent->inode, entry->d_name); } loc_wipe(&loc); return 0; } int ec_shd_index_sweep(struct subvol_healer *healer) { loc_t loc = {0}; ec_t *ec = NULL; int ret = 0; xlator_t *subvol = NULL; dict_t *xdata = NULL; ec = healer->this->private; subvol = ec->xl_list[healer->subvol]; ret = ec_shd_index_inode(healer->this, subvol, &loc.inode); if (ret < 0) { gf_msg(healer->this->name, GF_LOG_WARNING, errno, EC_MSG_INDEX_DIR_GET_FAIL, "unable to get index-dir on %s", subvol->name); goto out; } xdata = dict_new(); if (!xdata || dict_set_int32(xdata, "get-gfid-type", 1)) { ret = -ENOMEM; goto out; } _mask_cancellation(); ret = syncop_mt_dir_scan(NULL, subvol, &loc, GF_CLIENT_PID_SELF_HEALD, healer, ec_shd_index_heal, xdata, ec->shd.max_threads, ec->shd.wait_qlength); _unmask_cancellation(); out: if (xdata) dict_unref(xdata); loc_wipe(&loc); return ret; } int ec_shd_full_heal(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { struct subvol_healer *healer = data; xlator_t *this = healer->this; ec_t *ec = NULL; loc_t loc = {0}; int ret = 0; ec = this->private; if (this->cleanup_starting) { return -ENOTCONN; } if (ec->xl_up_count <= ec->fragments) { return -ENOTCONN; } if (!ec->shd.enabled) return -EBUSY; if (gf_uuid_is_null(entry->d_stat.ia_gfid)) { /* It's possible that an entry has been removed just after * being seen in a directory but before getting its stat info. * In this case we'll receive a NULL gfid here. Since the file * doesn't exist anymore, we can safely ignore it. */ return 0; } loc.parent = inode_ref(parent->inode); loc.name = entry->d_name; gf_uuid_copy(loc.gfid, entry->d_stat.ia_gfid); /* If this fails with ENOENT/ESTALE index is stale */ ret = syncop_gfid_to_path(this->itable, subvol, loc.gfid, (char **)&loc.path); if (ret < 0) goto out; ret = syncop_inode_find(this, this, loc.gfid, &loc.inode, NULL, NULL); if (ret < 0) goto out; ec_shd_selfheal(healer, healer->subvol, &loc, _gf_true); ret = 0; out: loc_wipe(&loc); return ret; } int ec_shd_full_sweep(struct subvol_healer *healer, inode_t *inode) { ec_t *ec = NULL; loc_t loc = {0}; int ret = -1; ec = healer->this->private; loc.inode = inode; _mask_cancellation(); ret = syncop_ftw(ec->xl_list[healer->subvol], &loc, GF_CLIENT_PID_SELF_HEALD, healer, ec_shd_full_heal); _unmask_cancellation(); return ret; } void * ec_shd_index_healer(void *data) { struct subvol_healer *healer = NULL; xlator_t *this = NULL; int run = 0; healer = data; THIS = this = healer->this; ec_t *ec = this->private; for (;;) { run = ec_shd_healer_wait(healer); if (run == -1) break; if (ec->xl_up_count > ec->fragments) { gf_msg_debug(this->name, 0, "starting index sweep on subvol %s", ec_subvol_name(this, healer->subvol)); ec_shd_index_sweep(healer); } gf_msg_debug(this->name, 0, "finished index sweep on subvol %s", ec_subvol_name(this, healer->subvol)); } return NULL; } void * ec_shd_full_healer(void *data) { struct subvol_healer *healer = NULL; xlator_t *this = NULL; loc_t rootloc = {0}; int run = 0; healer = data; THIS = this = healer->this; ec_t *ec = this->private; rootloc.inode = this->itable->root; for (;;) { run = ec_shd_healer_wait(healer); if (run < 0) { break; } else if (run == 0) { continue; } if (ec->xl_up_count > ec->fragments) { gf_msg(this->name, GF_LOG_INFO, 0, EC_MSG_FULL_SWEEP_START, "starting full sweep on subvol %s", ec_subvol_name(this, healer->subvol)); ec_shd_selfheal(healer, healer->subvol, &rootloc, _gf_true); ec_shd_full_sweep(healer, this->itable->root); } gf_msg(this->name, GF_LOG_INFO, 0, EC_MSG_FULL_SWEEP_STOP, "finished full sweep on subvol %s", ec_subvol_name(this, healer->subvol)); } return NULL; } int ec_shd_healer_init(xlator_t *this, struct subvol_healer *healer) { int ret = 0; ret = pthread_mutex_init(&healer->mutex, NULL); if (ret) goto out; ret = pthread_cond_init(&healer->cond, NULL); if (ret) goto out; healer->this = this; healer->running = _gf_false; healer->rerun = _gf_false; out: return ret; } int ec_shd_healer_spawn(xlator_t *this, struct subvol_healer *healer, void *(threadfn)(void *)) { int ret = 0; pthread_mutex_lock(&healer->mutex); { if (healer->running) { pthread_cond_signal(&healer->cond); } else { ret = gf_thread_create(&healer->thread, NULL, threadfn, healer, "ecshd"); if (ret) goto unlock; healer->running = 1; } healer->rerun = 1; } unlock: pthread_mutex_unlock(&healer->mutex); return ret; } int ec_shd_full_healer_spawn(xlator_t *this, int subvol) { if (xlator_is_cleanup_starting(this)) return -1; return ec_shd_healer_spawn(this, NTH_FULL_HEALER(this, subvol), ec_shd_full_healer); } int ec_shd_index_healer_spawn(xlator_t *this, int subvol) { if (xlator_is_cleanup_starting(this)) return -1; return ec_shd_healer_spawn(this, NTH_INDEX_HEALER(this, subvol), ec_shd_index_healer); } void ec_shd_index_healer_wake(ec_t *ec) { int32_t i; for (i = 0; i < ec->nodes; i++) { if (((ec->xl_up >> i) & 1) != 0) { ec_shd_index_healer_spawn(ec->xl, i); } } } int ec_selfheal_daemon_init(xlator_t *this) { ec_t *ec = NULL; ec_self_heald_t *shd = NULL; int ret = -1; int i = 0; ec = this->private; shd = &ec->shd; shd->index_healers = GF_CALLOC(sizeof(*shd->index_healers), ec->nodes, ec_mt_subvol_healer_t); if (!shd->index_healers) goto out; for (i = 0; i < ec->nodes; i++) { shd->index_healers[i].subvol = i; ret = ec_shd_healer_init(this, &shd->index_healers[i]); if (ret) goto out; } shd->full_healers = GF_CALLOC(sizeof(*shd->full_healers), ec->nodes, ec_mt_subvol_healer_t); if (!shd->full_healers) goto out; for (i = 0; i < ec->nodes; i++) { shd->full_healers[i].subvol = i; ret = ec_shd_healer_init(this, &shd->full_healers[i]); if (ret) goto out; } ret = 0; out: return ret; } int ec_heal_op(xlator_t *this, dict_t *output, gf_xl_afr_op_t op, int xl_id) { char key[64] = {0}; int op_ret = 0; ec_t *ec = NULL; int i = 0; GF_UNUSED int ret = 0; ec = this->private; op_ret = -1; for (i = 0; i < ec->nodes; i++) { snprintf(key, sizeof(key), "%d-%d-status", xl_id, i); if (((ec->xl_up >> i) & 1) == 0) { ret = dict_set_str(output, key, "Brick is not connected"); } else if (!ec->up) { ret = dict_set_str(output, key, "Disperse subvolume is not up"); } else if (!ec_shd_is_subvol_local(this, i)) { ret = dict_set_str(output, key, "Brick is remote"); } else { ret = dict_set_str(output, key, "Started self-heal"); if (op == GF_SHD_OP_HEAL_FULL) { ec_shd_full_healer_spawn(this, i); } else if (op == GF_SHD_OP_HEAL_INDEX) { ec_shd_index_healer_spawn(this, i); } op_ret = 0; } } return op_ret; } int ec_xl_op(xlator_t *this, dict_t *input, dict_t *output) { gf_xl_afr_op_t op = GF_SHD_OP_INVALID; int ret = 0; int xl_id = 0; ret = dict_get_int32(input, "xl-op", (int32_t *)&op); if (ret) goto out; ret = dict_get_int32(input, this->name, &xl_id); if (ret) goto out; ret = dict_set_int32(output, this->name, xl_id); if (ret) goto out; switch (op) { case GF_SHD_OP_HEAL_FULL: ret = ec_heal_op(this, output, op, xl_id); break; case GF_SHD_OP_HEAL_INDEX: ret = ec_heal_op(this, output, op, xl_id); break; default: ret = -1; break; } out: dict_del(output, this->name); return ret; } void ec_destroy_healer_object(xlator_t *this, struct subvol_healer *healer) { if (!healer) return; pthread_cond_destroy(&healer->cond); pthread_mutex_destroy(&healer->mutex); } void ec_selfheal_daemon_fini(xlator_t *this) { struct subvol_healer *healer = NULL; ec_self_heald_t *shd = NULL; ec_t *priv = NULL; int i = 0; priv = this->private; if (!priv) return; shd = &priv->shd; if (!shd->iamshd) return; for (i = 0; i < priv->nodes; i++) { healer = &shd->index_healers[i]; ec_destroy_healer_object(this, healer); healer = &shd->full_healers[i]; ec_destroy_healer_object(this, healer); } GF_FREE(shd->index_healers); GF_FREE(shd->full_healers); } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-gf8.h0000644000000000000000000000013214522202451022135 xustar000000000000000030 mtime=1699284265.639027347 30 atime=1699284265.639027347 30 ctime=1699284301.369134966 glusterfs-11.1/xlators/cluster/ec/src/ec-gf8.h0000664000175100017510000000075114522202451022417 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_GF8_H__ #define __EC_GF8_H__ #include "ec-galois.h" extern ec_gf_mul_t *ec_gf8_mul[]; #endif /* __EC_GF8_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-intel.c0000644000000000000000000000013214522202451023467 xustar000000000000000030 mtime=1699284265.633027329 30 atime=1699284265.633027329 30 ctime=1699284301.348134903 glusterfs-11.1/xlators/cluster/ec/src/ec-code-intel.c0000664000175100017510000004007114522202451023750 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "ec-code-intel.h" static void ec_code_intel_init(ec_code_intel_t *intel) { memset(intel, 0, sizeof(ec_code_intel_t)); } static void ec_code_intel_prefix(ec_code_intel_t *intel, uint8_t prefix) { intel->prefix.data[intel->prefix.bytes++] = prefix; } static void ec_code_intel_rex(ec_code_intel_t *intel, gf_boolean_t w) { gf_boolean_t present = _gf_false; if (w) { intel->rex.w = 1; present = _gf_true; } if (intel->modrm.present) { if (intel->modrm.reg > 7) { intel->modrm.reg &= 7; intel->rex.r = 1; present = _gf_true; } if (intel->sib.present) { if (intel->sib.index > 7) { intel->sib.index &= 7; intel->rex.x = 1; present = _gf_true; } if (intel->sib.base > 7) { intel->sib.base &= 7; intel->rex.b = 1; present = _gf_true; } } else if (intel->modrm.rm > 7) { intel->modrm.rm &= 7; intel->rex.b = 1; present = _gf_true; } } else if (intel->reg > 7) { intel->reg &= 7; intel->rex.b = 1; present = _gf_true; } intel->rex.present = present; } static void ec_code_intel_vex(ec_code_intel_t *intel, gf_boolean_t w, gf_boolean_t l, ec_code_vex_opcode_t opcode, ec_code_vex_prefix_t prefix, uint32_t reg) { ec_code_intel_rex(intel, w); if (((intel->rex.w == 1) || (intel->rex.x == 0) || (intel->rex.b == 0)) || ((opcode != VEX_OPCODE_NONE) && (opcode != VEX_OPCODE_0F))) { intel->rex.present = _gf_false; intel->vex.bytes = 3; intel->vex.data[0] = 0xC4; intel->vex.data[1] = ((intel->rex.r << 7) | (intel->rex.x << 6) | (intel->rex.b << 5) | opcode) ^ 0xE0; intel->vex.data[2] = (intel->rex.w << 7) | ((~reg & 0x0F) << 3) | (l ? 0x04 : 0x00) | prefix; } else { intel->vex.bytes = 2; intel->vex.data[0] = 0xC5; intel->vex.data[1] = (intel->rex.r << 7) | ((~reg & 0x0F) << 3) | (l ? 0x04 : 0x00) | prefix; } } static void ec_code_intel_modrm_reg(ec_code_intel_t *intel, uint32_t rm, uint32_t reg) { intel->modrm.present = _gf_true; intel->modrm.mod = 3; intel->modrm.rm = rm; intel->modrm.reg = reg; } static void ec_code_intel_modrm_mem(ec_code_intel_t *intel, uint32_t reg, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset) { if (index == REG_SP) { intel->invalid = _gf_true; return; } if ((index != REG_NULL) && (scale != 1) && (scale != 2) && (scale != 4) && (scale != 8)) { intel->invalid = _gf_true; return; } scale >>= 1; if (scale == 4) { scale = 3; } intel->modrm.present = _gf_true; intel->modrm.reg = reg; intel->offset.value = offset; if ((offset == 0) && (base != REG_BP)) { intel->modrm.mod = 0; intel->offset.bytes = 0; } else if ((offset >= -128) && (offset <= 127)) { intel->modrm.mod = 1; intel->offset.bytes = 1; } else { intel->modrm.mod = 2; intel->offset.bytes = 4; } intel->modrm.rm = base; if ((index != REG_NULL) || (base == REG_SP)) { intel->modrm.rm = 4; intel->sib.present = _gf_true; intel->sib.index = index; if (index == REG_NULL) { intel->sib.index = 4; } intel->sib.scale = scale; intel->sib.base = base; if (base == REG_NULL) { intel->sib.base = 5; intel->modrm.mod = 0; intel->offset.bytes = 4; } } else if (base == REG_NULL) { intel->modrm.mod = 0; intel->modrm.rm = 5; intel->offset.bytes = 4; } } static void ec_code_intel_op_1(ec_code_intel_t *intel, uint8_t opcode, uint32_t reg) { intel->reg = reg; intel->opcode.bytes = 1; intel->opcode.data[0] = opcode; } static void ec_code_intel_op_2(ec_code_intel_t *intel, uint8_t opcode1, uint8_t opcode2, uint32_t reg) { intel->reg = reg; intel->opcode.bytes = 2; intel->opcode.data[0] = opcode1; intel->opcode.data[1] = opcode2; } static void ec_code_intel_immediate_1(ec_code_intel_t *intel, uint32_t value) { intel->immediate.bytes = 1; intel->immediate.value = value; } static void ec_code_intel_immediate_2(ec_code_intel_t *intel, uint32_t value) { intel->immediate.bytes = 2; intel->immediate.value = value; } static void ec_code_intel_immediate_4(ec_code_intel_t *intel, uint32_t value) { intel->immediate.bytes = 4; intel->immediate.value = value; } static void ec_code_intel_emit(ec_code_builder_t *builder, ec_code_intel_t *intel) { uint8_t insn[15]; uint32_t i, count; if (intel->invalid) { ec_code_error(builder, EINVAL); return; } count = 0; for (i = 0; i < intel->prefix.bytes; i++) { insn[count++] = intel->prefix.data[i]; } for (i = 0; i < intel->vex.bytes; i++) { insn[count++] = intel->vex.data[i]; } if (intel->rex.present) { insn[count++] = 0x40 | (intel->rex.w << 3) | (intel->rex.r << 2) | (intel->rex.x << 1) | (intel->rex.b << 0); } for (i = 0; i < intel->opcode.bytes; i++) { insn[count++] = intel->opcode.data[i]; } if (intel->modrm.present) { insn[count++] = (intel->modrm.mod << 6) | (intel->modrm.reg << 3) | (intel->modrm.rm << 0); if (intel->sib.present) { insn[count++] = (intel->sib.scale << 6) | (intel->sib.index << 3) | (intel->sib.base << 0); } } for (i = 0; i < intel->offset.bytes; i++) { insn[count++] = intel->offset.data[i]; } for (i = 0; i < intel->immediate.bytes; i++) { insn[count++] = intel->immediate.data[i]; } ec_code_emit(builder, insn, count); } void ec_code_intel_op_push_r(ec_code_builder_t *builder, ec_code_intel_reg_t reg) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_op_1(&intel, 0x50 | (reg & 7), reg); ec_code_intel_rex(&intel, _gf_false); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_pop_r(ec_code_builder_t *builder, ec_code_intel_reg_t reg) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_op_1(&intel, 0x58 | (reg & 7), reg); ec_code_intel_rex(&intel, _gf_false); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_ret(ec_code_builder_t *builder, uint32_t size) { ec_code_intel_t intel; ec_code_intel_init(&intel); if (size == 0) { ec_code_intel_op_1(&intel, 0xC3, 0); } else { ec_code_intel_immediate_2(&intel, size); ec_code_intel_op_1(&intel, 0xC2, 0); } ec_code_intel_rex(&intel, _gf_false); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_mov_r2r(ec_code_builder_t *builder, ec_code_intel_reg_t src, ec_code_intel_reg_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_reg(&intel, dst, src); ec_code_intel_op_1(&intel, 0x89, 0); ec_code_intel_rex(&intel, _gf_true); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_mov_r2m(ec_code_builder_t *builder, ec_code_intel_reg_t src, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_mem(&intel, src, base, index, scale, offset); ec_code_intel_op_1(&intel, 0x89, 0); ec_code_intel_rex(&intel, _gf_true); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_mov_m2r(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, ec_code_intel_reg_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_mem(&intel, dst, base, index, scale, offset); ec_code_intel_op_1(&intel, 0x8B, 0); ec_code_intel_rex(&intel, _gf_true); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_xor_r2r(ec_code_builder_t *builder, ec_code_intel_reg_t src, ec_code_intel_reg_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_reg(&intel, dst, src); ec_code_intel_op_1(&intel, 0x31, 0); ec_code_intel_rex(&intel, _gf_true); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_xor_m2r(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, ec_code_intel_reg_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_mem(&intel, dst, base, index, scale, offset); ec_code_intel_op_1(&intel, 0x33, 0); ec_code_intel_rex(&intel, _gf_true); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_add_i2r(ec_code_builder_t *builder, int32_t value, ec_code_intel_reg_t reg) { ec_code_intel_t intel; ec_code_intel_init(&intel); if ((value >= -128) && (value < 128)) { ec_code_intel_modrm_reg(&intel, reg, 0); ec_code_intel_op_1(&intel, 0x83, 0); ec_code_intel_immediate_1(&intel, value); } else { if (reg == REG_AX) { ec_code_intel_op_1(&intel, 0x05, reg); } else { ec_code_intel_modrm_reg(&intel, reg, 0); ec_code_intel_op_1(&intel, 0x81, 0); } ec_code_intel_immediate_4(&intel, value); } ec_code_intel_rex(&intel, _gf_true); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_test_i2r(ec_code_builder_t *builder, uint32_t value, ec_code_intel_reg_t reg) { ec_code_intel_t intel; ec_code_intel_init(&intel); if (reg == REG_AX) { ec_code_intel_op_1(&intel, 0xA9, reg); } else { ec_code_intel_modrm_reg(&intel, reg, 0); ec_code_intel_op_1(&intel, 0xF7, 0); } ec_code_intel_immediate_4(&intel, value); ec_code_intel_rex(&intel, _gf_true); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_jne(ec_code_builder_t *builder, uint32_t address) { ec_code_intel_t intel; int32_t rel; ec_code_intel_init(&intel); rel = address - builder->address - 2; if ((rel >= -128) && (rel < 128)) { ec_code_intel_op_1(&intel, 0x75, 0); ec_code_intel_immediate_1(&intel, rel); } else { rel -= 4; ec_code_intel_op_2(&intel, 0x0F, 0x85, 0); ec_code_intel_immediate_4(&intel, rel); } ec_code_intel_rex(&intel, _gf_false); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_mov_sse2sse(ec_code_builder_t *builder, uint32_t src, uint32_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_prefix(&intel, 0x66); ec_code_intel_modrm_reg(&intel, src, dst); ec_code_intel_op_2(&intel, 0x0F, 0x6F, 0); ec_code_intel_rex(&intel, _gf_false); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_mov_sse2m(ec_code_builder_t *builder, uint32_t src, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_prefix(&intel, 0x66); ec_code_intel_modrm_mem(&intel, src, base, index, scale, offset); ec_code_intel_op_2(&intel, 0x0F, 0x7F, 0); ec_code_intel_rex(&intel, _gf_false); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_mov_m2sse(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, uint32_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_prefix(&intel, 0x66); ec_code_intel_modrm_mem(&intel, dst, base, index, scale, offset); ec_code_intel_op_2(&intel, 0x0F, 0x6F, 0); ec_code_intel_rex(&intel, _gf_false); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_xor_sse2sse(ec_code_builder_t *builder, uint32_t src, uint32_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_prefix(&intel, 0x66); ec_code_intel_modrm_reg(&intel, src, dst); ec_code_intel_op_2(&intel, 0x0F, 0xEF, 0); ec_code_intel_rex(&intel, _gf_false); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_xor_m2sse(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, uint32_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_prefix(&intel, 0x66); ec_code_intel_modrm_mem(&intel, dst, base, index, scale, offset); ec_code_intel_op_2(&intel, 0x0F, 0xEF, 0); ec_code_intel_rex(&intel, _gf_false); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_mov_avx2avx(ec_code_builder_t *builder, uint32_t src, uint32_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_reg(&intel, src, dst); ec_code_intel_op_1(&intel, 0x6F, 0); ec_code_intel_vex(&intel, _gf_false, _gf_true, VEX_OPCODE_0F, VEX_PREFIX_66, VEX_REG_NONE); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_mov_avx2m(ec_code_builder_t *builder, uint32_t src, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_mem(&intel, src, base, index, scale, offset); ec_code_intel_op_1(&intel, 0x7F, 0); ec_code_intel_vex(&intel, _gf_false, _gf_true, VEX_OPCODE_0F, VEX_PREFIX_66, VEX_REG_NONE); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_mov_m2avx(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, uint32_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_mem(&intel, dst, base, index, scale, offset); ec_code_intel_op_1(&intel, 0x6F, 0); ec_code_intel_vex(&intel, _gf_false, _gf_true, VEX_OPCODE_0F, VEX_PREFIX_66, VEX_REG_NONE); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_xor_avx2avx(ec_code_builder_t *builder, uint32_t src, uint32_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_reg(&intel, src, dst); ec_code_intel_op_1(&intel, 0xEF, 0); ec_code_intel_vex(&intel, _gf_false, _gf_true, VEX_OPCODE_0F, VEX_PREFIX_66, dst); ec_code_intel_emit(builder, &intel); } void ec_code_intel_op_xor_m2avx(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, uint32_t dst) { ec_code_intel_t intel; ec_code_intel_init(&intel); ec_code_intel_modrm_mem(&intel, dst, base, index, scale, offset); ec_code_intel_op_1(&intel, 0xEF, 0); ec_code_intel_vex(&intel, _gf_false, _gf_true, VEX_OPCODE_0F, VEX_PREFIX_66, dst); ec_code_intel_emit(builder, &intel); } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-heald.h0000644000000000000000000000013214522202451022526 xustar000000000000000030 mtime=1699284265.640027351 30 atime=1699284265.640027351 30 ctime=1699284301.370134969 glusterfs-11.1/xlators/cluster/ec/src/ec-heald.h0000664000175100017510000000140414522202451023004 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_HEALD_H__ #define __EC_HEALD_H__ #include "ec-types.h" // for ec_t #include "glusterfs/dict.h" // for dict_t #include "glusterfs/globals.h" // for xlator_t int ec_xl_op(xlator_t *this, dict_t *input, dict_t *output); int ec_selfheal_daemon_init(xlator_t *this); void ec_shd_index_healer_wake(ec_t *ec); void ec_selfheal_daemon_fini(xlator_t *this); #endif /* __EC_HEALD_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-messages.h0000644000000000000000000000013214522202451023260 xustar000000000000000030 mtime=1699284265.642027356 30 atime=1699284265.642027356 30 ctime=1699284301.371134972 glusterfs-11.1/xlators/cluster/ec/src/ec-messages.h0000664000175100017510000000605514522202451023545 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _EC_MESSAGES_H_ #define _EC_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(EC, EC_MSG_INVALID_CONFIG, EC_MSG_HEAL_FAIL, EC_MSG_DICT_COMBINE_FAIL, EC_MSG_STIME_COMBINE_FAIL, EC_MSG_INVALID_DICT_NUMS, EC_MSG_IATT_COMBINE_FAIL, EC_MSG_INVALID_FORMAT, EC_MSG_DICT_GET_FAILED, EC_MSG_UNHANDLED_STATE, EC_MSG_FILE_DESC_REF_FAIL, EC_MSG_LOC_COPY_FAIL, EC_MSG_BUF_REF_FAIL, EC_MSG_DICT_REF_FAIL, EC_MSG_LK_UNLOCK_FAILED, EC_MSG_UNLOCK_FAILED, EC_MSG_LOC_PARENT_INODE_MISSING, EC_MSG_INVALID_LOC_NAME, EC_MSG_NO_MEMORY, EC_MSG_GFID_MISMATCH, EC_MSG_UNSUPPORTED_VERSION, EC_MSG_FD_CREATE_FAIL, EC_MSG_READDIRP_REQ_PREP_FAIL, EC_MSG_LOOKUP_REQ_PREP_FAIL, EC_MSG_INODE_REF_FAIL, EC_MSG_LOOKUP_READAHEAD_FAIL, EC_MSG_FRAME_MISMATCH, EC_MSG_XLATOR_MISMATCH, EC_MSG_VECTOR_MISMATCH, EC_MSG_IATT_MISMATCH, EC_MSG_FD_MISMATCH, EC_MSG_DICT_MISMATCH, EC_MSG_INDEX_DIR_GET_FAIL, EC_MSG_PREOP_LOCK_FAILED, EC_MSG_CHILDS_INSUFFICIENT, EC_MSG_OP_EXEC_UNAVAIL, EC_MSG_UNLOCK_DELAY_FAILED, EC_MSG_SIZE_VERS_UPDATE_FAIL, EC_MSG_INVALID_REQUEST, EC_MSG_INVALID_LOCK_TYPE, EC_MSG_SIZE_VERS_GET_FAIL, EC_MSG_FILE_SIZE_GET_FAIL, EC_MSG_FOP_MISMATCH, EC_MSG_SUBVOL_ID_DICT_SET_FAIL, EC_MSG_SUBVOL_BUILD_FAIL, EC_MSG_XLATOR_INIT_FAIL, EC_MSG_NO_PARENTS, EC_MSG_TIMER_CREATE_FAIL, EC_MSG_TOO_MANY_SUBVOLS, EC_MSG_DATA_UNAVAILABLE, EC_MSG_INODE_REMOVE_FAIL, EC_MSG_INVALID_REDUNDANCY, EC_MSG_XLATOR_PARSE_OPT_FAIL, EC_MSG_OP_FAIL_ON_SUBVOLS, EC_MSG_INVALID_INODE, EC_MSG_LOCK_MISMATCH, EC_MSG_XDATA_MISMATCH, EC_MSG_HEALING_INFO, EC_MSG_HEAL_SUCCESS, EC_MSG_FULL_SWEEP_START, EC_MSG_FULL_SWEEP_STOP, EC_MSG_INVALID_FOP, EC_MSG_EC_UP, EC_MSG_EC_DOWN, EC_MSG_SIZE_XATTR_GET_FAIL, EC_MSG_VER_XATTR_GET_FAIL, EC_MSG_CONFIG_XATTR_GET_FAIL, EC_MSG_CONFIG_XATTR_INVALID, EC_MSG_EXTENSION, EC_MSG_EXTENSION_NONE, EC_MSG_EXTENSION_UNKNOWN, EC_MSG_EXTENSION_UNSUPPORTED, EC_MSG_EXTENSION_FAILED, EC_MSG_NO_GF, EC_MSG_MATRIX_FAILED, EC_MSG_DYN_CREATE_FAILED, EC_MSG_DYN_CODEGEN_FAILED, EC_MSG_THREAD_CLEANUP_FAILED, EC_MSG_FD_BAD); #endif /* !_EC_MESSAGES_H_ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-locks.c0000644000000000000000000000013214522202451022557 xustar000000000000000030 mtime=1699284265.642027356 30 atime=1699284265.642027356 30 ctime=1699284301.329134845 glusterfs-11.1/xlators/cluster/ec/src/ec-locks.c0000664000175100017510000010015714522202451023042 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "ec-helpers.h" #include "ec-common.h" #include "ec-combine.h" #include "ec-fops.h" #include "ec-messages.h" #define EC_LOCK_MODE_NONE 0 #define EC_LOCK_MODE_INC 1 #define EC_LOCK_MODE_ALL 2 int32_t ec_lock_check(ec_fop_data_t *fop, uintptr_t *mask) { ec_t *ec = fop->xl->private; ec_cbk_data_t *ans = NULL; ec_cbk_data_t *cbk = NULL; uintptr_t locked = 0; int32_t good = 0; int32_t eagain = 0; int32_t estale = 0; int32_t error = -1; /* There are some errors that we'll handle in an special way while trying * to acquire a lock. * * EAGAIN: If it's found during a parallel non-blocking lock request, we * consider that there's contention on the inode, so we consider * the acquisition a failure and try again with a sequential * blocking lock request. This will ensure that we get a lock on * as many bricks as possible (ignoring EAGAIN here would cause * unnecessary triggers of self-healing). * * If it's found during a sequential blocking lock request, it's * considered an error. Lock will only succeed if there are * enough other bricks locked. * * ESTALE: This can appear during parallel or sequential lock request if * the inode has just been unlinked. We consider this error is * not recoverable, but we also don't consider it as fatal. So, * if it happens during parallel lock, we won't attempt a * sequential one unless there are EAGAIN errors on other * bricks (and are enough to form a quorum), but if we reach * quorum counting the ESTALE bricks, we consider the whole * result of the operation is ESTALE instead of EIO. */ list_for_each_entry(ans, &fop->cbk_list, list) { if (ans->op_ret >= 0) { if (locked != 0) { error = EIO; } locked |= ans->mask; good = ans->count; cbk = ans; } else if (ans->op_errno == ESTALE) { estale += ans->count; } else if ((ans->op_errno == EAGAIN) && (fop->uint32 != EC_LOCK_MODE_INC)) { eagain += ans->count; } } if (error == -1) { /* If we have enough quorum with succeeded and EAGAIN answers, we * ignore for now any ESTALE answer. If there are EAGAIN answers, * we retry with a sequential blocking lock request if needed. * Otherwise we succeed. */ if ((good + eagain) >= ec->fragments) { if (eagain == 0) { if (fop->answer == NULL) { fop->answer = cbk; } ec_update_good(fop, locked); error = 0; } else { switch (fop->uint32) { case EC_LOCK_MODE_NONE: error = EAGAIN; break; case EC_LOCK_MODE_ALL: fop->uint32 = EC_LOCK_MODE_INC; break; default: /* This shouldn't happen because eagain cannot be > 0 * when fop->uint32 is EC_LOCK_MODE_INC. */ error = EIO; break; } } } else { /* We have been unable to find enough candidates that will be able * to take the lock. If we have quorum on some answer, we return * it. Otherwise we check if ESTALE answers allow us to reach * quorum. If so, we return ESTALE. */ if (fop->answer && fop->answer->op_ret < 0) { error = fop->answer->op_errno; } else if ((good + eagain + estale) >= ec->fragments) { error = ESTALE; } else { error = EIO; } } } *mask = locked; return error; } int32_t ec_lock_unlocked(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { if (op_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, op_errno, EC_MSG_UNLOCK_FAILED, "Failed to unlock an entry/inode"); } return 0; } int32_t ec_lock_lk_unlocked(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *flock, dict_t *xdata) { if (op_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, op_errno, EC_MSG_LK_UNLOCK_FAILED, "Failed to unlock an lk"); } return 0; } /* FOP: entrylk */ int32_t ec_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_ENTRYLK, idx, op_ret, op_errno); if (cbk != NULL) { if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_entrylk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_entrylk_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->entrylk, fop->str[0], &fop->loc[0], fop->str[1], fop->entrylk_cmd, fop->entrylk_type, fop->xdata); } int32_t ec_manager_entrylk(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: if (fop->entrylk_cmd == ENTRYLK_LOCK) { fop->uint32 = EC_LOCK_MODE_ALL; fop->entrylk_cmd = ENTRYLK_LOCK_NB; } /* Fall through */ case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: case -EC_STATE_PREPARE_ANSWER: if (fop->entrylk_cmd != ENTRYLK_UNLOCK) { uintptr_t mask; ec_fop_set_error(fop, ec_lock_check(fop, &mask)); if (fop->error != 0) { if (mask != 0) { if (fop->id == GF_FOP_ENTRYLK) { ec_entrylk( fop->frame, fop->xl, mask, 1, ec_lock_unlocked, NULL, fop->str[0], &fop->loc[0], fop->str[1], ENTRYLK_UNLOCK, fop->entrylk_type, fop->xdata); } else { ec_fentrylk(fop->frame, fop->xl, mask, 1, ec_lock_unlocked, NULL, fop->str[0], fop->fd, fop->str[1], ENTRYLK_UNLOCK, fop->entrylk_type, fop->xdata); } } if (fop->error < 0) { fop->error = 0; fop->entrylk_cmd = ENTRYLK_LOCK; ec_dispatch_inc(fop); return EC_STATE_PREPARE_ANSWER; } } } else { ec_fop_prepare_answer(fop, _gf_true); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->id == GF_FOP_ENTRYLK) { if (fop->cbks.entrylk != NULL) { fop->cbks.entrylk(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } } else { if (fop->cbks.fentrylk != NULL) { fop->cbks.fentrylk(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } } return EC_STATE_END; case -EC_STATE_INIT: case -EC_STATE_DISPATCH: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->id == GF_FOP_ENTRYLK) { if (fop->cbks.entrylk != NULL) { fop->cbks.entrylk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } } else { if (fop->cbks.fentrylk != NULL) { fop->cbks.fentrylk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } } return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_entrylk(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_entrylk_cbk_t func, void *data, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { ec_cbk_t callback = {.entrylk = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(ENTRYLK) %p", frame); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_ENTRYLK, 0, target, fop_flags, ec_wind_entrylk, ec_manager_entrylk, callback, data); if (fop == NULL) { goto out; } fop->entrylk_cmd = cmd; fop->entrylk_type = type; if (volume != NULL) { fop->str[0] = gf_strdup(volume); if (fop->str[0] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (basename != NULL) { fop->str[1] = gf_strdup(basename); if (fop->str[1] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: fentrylk */ int32_t ec_fentrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FENTRYLK, idx, op_ret, op_errno); if (cbk != NULL) { if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_fentrylk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_fentrylk_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fentrylk, fop->str[0], fop->fd, fop->str[1], fop->entrylk_cmd, fop->entrylk_type, fop->xdata); } void ec_fentrylk(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fentrylk_cbk_t func, void *data, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { ec_cbk_t callback = {.fentrylk = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FENTRYLK) %p", frame); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FENTRYLK, 0, target, fop_flags, ec_wind_fentrylk, ec_manager_entrylk, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->entrylk_cmd = cmd; fop->entrylk_type = type; if (volume != NULL) { fop->str[0] = gf_strdup(volume); if (fop->str[0] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (basename != NULL) { fop->str[1] = gf_strdup(basename); if (fop->str[1] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: inodelk */ int32_t ec_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_INODELK, idx, op_ret, op_errno); if (cbk != NULL) { if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_inodelk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_inodelk_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->inodelk, fop->str[0], &fop->loc[0], fop->int32, &fop->flock, fop->xdata); } int32_t ec_manager_inodelk(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: fop->flock.l_len += ec_adjust_offset_down( fop->xl->private, &fop->flock.l_start, _gf_true); ec_adjust_offset_up(fop->xl->private, &fop->flock.l_len, _gf_true); if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK)) { fop->uint32 = EC_LOCK_MODE_ALL; fop->int32 = F_SETLK; } /* Fall through */ case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: case -EC_STATE_PREPARE_ANSWER: if (fop->flock.l_type != F_UNLCK) { uintptr_t mask; ec_fop_set_error(fop, ec_lock_check(fop, &mask)); if (fop->error != 0) { if (mask != 0) { ec_t *ec = fop->xl->private; struct gf_flock flock; flock.l_type = F_UNLCK; flock.l_whence = fop->flock.l_whence; flock.l_start = fop->flock.l_start * ec->fragments; flock.l_len = fop->flock.l_len * ec->fragments; flock.l_pid = 0; flock.l_owner.len = 0; if (fop->id == GF_FOP_INODELK) { ec_inodelk(fop->frame, fop->xl, &fop->frame->root->lk_owner, mask, 1, ec_lock_unlocked, NULL, fop->str[0], &fop->loc[0], F_SETLK, &flock, fop->xdata); } else { ec_finodelk(fop->frame, fop->xl, &fop->frame->root->lk_owner, mask, 1, ec_lock_unlocked, NULL, fop->str[0], fop->fd, F_SETLK, &flock, fop->xdata); } } if (fop->error < 0) { fop->error = 0; fop->int32 = F_SETLKW; ec_dispatch_inc(fop); return EC_STATE_PREPARE_ANSWER; } } } else { ec_fop_prepare_answer(fop, _gf_true); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->id == GF_FOP_INODELK) { if (fop->cbks.inodelk != NULL) { fop->cbks.inodelk(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } } else { if (fop->cbks.finodelk != NULL) { fop->cbks.finodelk(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } } return EC_STATE_END; case -EC_STATE_INIT: case -EC_STATE_DISPATCH: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->id == GF_FOP_INODELK) { if (fop->cbks.inodelk != NULL) { fop->cbks.inodelk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } } else { if (fop->cbks.finodelk != NULL) { fop->cbks.finodelk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } } return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_inodelk(call_frame_t *frame, xlator_t *this, gf_lkowner_t *owner, uintptr_t target, uint32_t fop_flags, fop_inodelk_cbk_t func, void *data, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { ec_cbk_t callback = {.inodelk = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(INODELK) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_INODELK, 0, target, fop_flags, ec_wind_inodelk, ec_manager_inodelk, callback, data); if (fop == NULL) { goto out; } fop->int32 = cmd; ec_owner_copy(fop->frame, owner); if (volume != NULL) { fop->str[0] = gf_strdup(volume); if (fop->str[0] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (flock != NULL) gf_flock_copy(&fop->flock, flock); if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: finodelk */ int32_t ec_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FINODELK, idx, op_ret, op_errno); if (cbk != NULL) { if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_finodelk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_finodelk_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->finodelk, fop->str[0], fop->fd, fop->int32, &fop->flock, fop->xdata); } void ec_finodelk(call_frame_t *frame, xlator_t *this, gf_lkowner_t *owner, uintptr_t target, uint32_t fop_flags, fop_finodelk_cbk_t func, void *data, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { ec_cbk_t callback = {.finodelk = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FINODELK) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FINODELK, 0, target, fop_flags, ec_wind_finodelk, ec_manager_inodelk, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->int32 = cmd; ec_owner_copy(fop->frame, owner); if (volume != NULL) { fop->str[0] = gf_strdup(volume); if (fop->str[0] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (flock != NULL) gf_flock_copy(&fop->flock, flock); if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: lk */ int32_t ec_combine_lk(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_flock_compare(&dst->flock, &src->flock)) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_LOCK_MISMATCH, "Mismatching lock in " "answers of 'GF_FOP_LK'"); return 0; } return 1; } int32_t ec_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *flock, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_LK, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0 && flock != NULL) gf_flock_copy(&cbk->flock, flock); if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, ec_combine_lk); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_lk(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_lk_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->lk, fop->fd, fop->int32, &fop->flock, fop->xdata); } int32_t ec_manager_lk(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK)) { fop->uint32 = EC_LOCK_MODE_ALL; fop->int32 = F_SETLK; } /* Fall through */ case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: case -EC_STATE_PREPARE_ANSWER: if (fop->flock.l_type != F_UNLCK) { uintptr_t mask; ec_fop_set_error(fop, ec_lock_check(fop, &mask)); if (fop->error != 0) { if (mask != 0) { struct gf_flock flock = {0}; flock.l_type = F_UNLCK; flock.l_whence = fop->flock.l_whence; flock.l_start = fop->flock.l_start; flock.l_len = fop->flock.l_len; flock.l_pid = fop->flock.l_pid; lk_owner_copy(&flock.l_owner, &fop->flock.l_owner); ec_lk(fop->frame, fop->xl, mask, 1, ec_lock_lk_unlocked, NULL, fop->fd, F_SETLK, &flock, fop->xdata); } if (fop->error < 0) { fop->error = 0; fop->int32 = F_SETLKW; ec_dispatch_inc(fop); return EC_STATE_PREPARE_ANSWER; } } } else { ec_fop_prepare_answer(fop, _gf_true); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.lk != NULL) { fop->cbks.lk(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->flock, cbk->xdata); } return EC_STATE_END; case -EC_STATE_INIT: case -EC_STATE_DISPATCH: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.lk != NULL) { fop->cbks.lk(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_lk(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_lk_cbk_t func, void *data, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { ec_cbk_t callback = {.lk = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(LK) %p", frame); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_LK, 0, target, fop_flags, ec_wind_lk, ec_manager_lk, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->int32 = cmd; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (flock != NULL) gf_flock_copy(&fop->flock, flock); if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-avx.h0000644000000000000000000000013214522202451023157 xustar000000000000000030 mtime=1699284265.631027323 30 atime=1699284265.631027323 30 ctime=1699284301.378134993 glusterfs-11.1/xlators/cluster/ec/src/ec-code-avx.h0000664000175100017510000000077214522202451023444 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_CODE_AVX_H__ #define __EC_CODE_AVX_H__ #include "ec-code.h" extern ec_code_gen_t ec_code_gen_avx; #endif /* __EC_CODE_AVX_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-gf8.c0000644000000000000000000000013214522202451022130 xustar000000000000000030 mtime=1699284265.639027347 30 atime=1699284265.638027344 30 ctime=1699284301.344134891 glusterfs-11.1/xlators/cluster/ec/src/ec-gf8.c0000664000175100017510000075717514522202451022435 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "ec-gf8.h" static ec_gf_op_t ec_gf8_mul_00_ops[] = {{EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_00 = {0, { 0, }, ec_gf8_mul_00_ops}; static ec_gf_op_t ec_gf8_mul_01_ops[] = {{EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_01 = {8, { 0, 1, 2, 3, 4, 5, 6, 7, }, ec_gf8_mul_01_ops}; static ec_gf_op_t ec_gf8_mul_02_ops[] = {{EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_02 = {8, { 7, 0, 1, 2, 3, 4, 5, 6, }, ec_gf8_mul_02_ops}; static ec_gf_op_t ec_gf8_mul_03_ops[] = { {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_COPY, 8, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_03 = {9, { 0, 1, 2, 3, 4, 5, 6, 7, 8, }, ec_gf8_mul_03_ops}; static ec_gf_op_t ec_gf8_mul_04_ops[] = { {EC_GF_OP_XOR3, 8, 6, 7}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_04 = {9, { 6, 7, 0, 1, 2, 3, 4, 5, 8, }, ec_gf8_mul_04_ops}; static ec_gf_op_t ec_gf8_mul_05_ops[] = { {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_05 = {8, { 0, 1, 2, 6, 7, 3, 4, 5, }, ec_gf8_mul_05_ops}; static ec_gf_op_t ec_gf8_mul_06_ops[] = { {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_COPY, 8, 2, 0}, {EC_GF_OP_XOR2, 8, 3, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_06 = {9, { 7, 0, 1, 2, 8, 3, 4, 5, 6, }, ec_gf8_mul_06_ops}; static ec_gf_op_t ec_gf8_mul_07_ops[] = { {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_07 = {8, { 6, 0, 1, 3, 2, 4, 5, 7, }, ec_gf8_mul_07_ops}; static ec_gf_op_t ec_gf8_mul_08_ops[] = { {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR3, 8, 6, 7}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_08 = {9, { 5, 6, 7, 0, 1, 2, 3, 4, 8, }, ec_gf8_mul_08_ops}; static ec_gf_op_t ec_gf8_mul_09_ops[] = { {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_09 = {8, { 0, 1, 2, 3, 5, 6, 7, 4, }, ec_gf8_mul_09_ops}; static ec_gf_op_t ec_gf8_mul_0A_ops[] = { {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_0A = {8, { 5, 0, 1, 2, 6, 7, 3, 4, }, ec_gf8_mul_0A_ops}; static ec_gf_op_t ec_gf8_mul_0B_ops[] = { {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_COPY, 9, 3, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_COPY, 8, 5, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR3, 3, 8, 6}, {EC_GF_OP_XOR2, 1, 9, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_0B = {10, { 7, 1, 5, 2, 4, 3, 0, 6, 8, 9, }, ec_gf8_mul_0B_ops}; static ec_gf_op_t ec_gf8_mul_0C_ops[] = { {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_COPY, 8, 1, 0}, {EC_GF_OP_XOR2, 8, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_0C = {9, { 5, 7, 0, 1, 8, 2, 3, 4, 6, }, ec_gf8_mul_0C_ops}; static ec_gf_op_t ec_gf8_mul_0D_ops[] = { {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR3, 8, 2, 4}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR3, 2, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_0D = {9, { 5, 6, 7, 3, 1, 0, 2, 4, 8, }, ec_gf8_mul_0D_ops}; static ec_gf_op_t ec_gf8_mul_0E_ops[] = { {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_0E = {8, { 7, 0, 6, 1, 3, 2, 4, 5, }, ec_gf8_mul_0E_ops}; static ec_gf_op_t ec_gf8_mul_0F_ops[] = { {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_0F = {8, { 1, 0, 5, 6, 7, 2, 3, 4, }, ec_gf8_mul_0F_ops}; static ec_gf_op_t ec_gf8_mul_10_ops[] = { {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_10 = {8, { 4, 5, 6, 7, 0, 1, 2, 3, }, ec_gf8_mul_10_ops}; static ec_gf_op_t ec_gf8_mul_11_ops[] = { {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_11 = {8, { 4, 1, 2, 6, 0, 5, 7, 3, }, ec_gf8_mul_11_ops}; static ec_gf_op_t ec_gf8_mul_12_ops[] = { {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_12 = {8, { 7, 0, 1, 2, 3, 5, 6, 4, }, ec_gf8_mul_12_ops}; static ec_gf_op_t ec_gf8_mul_13_ops[] = { {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR3, 8, 3, 7}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_13 = {9, { 4, 5, 2, 6, 0, 1, 7, 3, 8, }, ec_gf8_mul_13_ops}; static ec_gf_op_t ec_gf8_mul_14_ops[] = { {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_14 = {8, { 6, 7, 0, 1, 2, 4, 5, 3, }, ec_gf8_mul_14_ops}; static ec_gf_op_t ec_gf8_mul_15_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR3, 5, 8, 7}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_15 = {9, { 0, 1, 2, 4, 7, 6, 5, 3, 8, }, ec_gf8_mul_15_ops}; static ec_gf_op_t ec_gf8_mul_16_ops[] = { {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_16 = {8, { 6, 7, 4, 1, 2, 3, 5, 0, }, ec_gf8_mul_16_ops}; static ec_gf_op_t ec_gf8_mul_17_ops[] = { {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_17 = {8, { 5, 7, 0, 1, 3, 2, 4, 6, }, ec_gf8_mul_17_ops}; static ec_gf_op_t ec_gf8_mul_18_ops[] = { {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_18 = {9, { 4, 5, 7, 6, 0, 1, 2, 3, 8, }, ec_gf8_mul_18_ops}; static ec_gf_op_t ec_gf8_mul_19_ops[] = { {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_19 = {8, { 0, 5, 2, 6, 7, 1, 3, 4, }, ec_gf8_mul_19_ops}; static ec_gf_op_t ec_gf8_mul_1A_ops[] = { {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_1A = {8, { 7, 0, 4, 5, 3, 1, 2, 6, }, ec_gf8_mul_1A_ops}; static ec_gf_op_t ec_gf8_mul_1B_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_1B = {8, { 7, 4, 5, 6, 3, 1, 2, 0, }, ec_gf8_mul_1B_ops}; static ec_gf_op_t ec_gf8_mul_1C_ops[] = { {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_1C = {8, { 5, 4, 3, 0, 1, 7, 2, 6, }, ec_gf8_mul_1C_ops}; static ec_gf_op_t ec_gf8_mul_1D_ops[] = { {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR3, 8, 4, 2}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_1D = {9, { 0, 7, 5, 8, 2, 3, 4, 1, 6, }, ec_gf8_mul_1D_ops}; static ec_gf_op_t ec_gf8_mul_1E_ops[] = { {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_1E = {8, { 4, 7, 5, 1, 6, 0, 2, 3, }, ec_gf8_mul_1E_ops}; static ec_gf_op_t ec_gf8_mul_1F_ops[] = { {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR3, 8, 3, 7}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_1F = {9, { 1, 4, 5, 6, 7, 0, 3, 2, 8, }, ec_gf8_mul_1F_ops}; static ec_gf_op_t ec_gf8_mul_20_ops[] = { {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_20 = {8, { 7, 4, 5, 6, 3, 0, 1, 2, }, ec_gf8_mul_20_ops}; static ec_gf_op_t ec_gf8_mul_21_ops[] = { {EC_GF_OP_COPY, 9, 0, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR3, 8, 7, 5}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 4, 9, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_21 = {10, { 0, 1, 2, 7, 5, 4, 3, 6, 8, 9, }, ec_gf8_mul_21_ops}; static ec_gf_op_t ec_gf8_mul_22_ops[] = { {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_22 = {8, { 3, 0, 5, 2, 6, 4, 1, 7, }, ec_gf8_mul_22_ops}; static ec_gf_op_t ec_gf8_mul_23_ops[] = { {EC_GF_OP_COPY, 8, 2, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_23 = {9, { 0, 4, 3, 2, 5, 6, 1, 8, 7, }, ec_gf8_mul_23_ops}; static ec_gf_op_t ec_gf8_mul_24_ops[] = { {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_24 = {8, { 6, 7, 0, 1, 2, 4, 5, 3, }, ec_gf8_mul_24_ops}; static ec_gf_op_t ec_gf8_mul_25_ops[] = { {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_25 = {8, { 2, 7, 0, 1, 3, 4, 5, 6, }, ec_gf8_mul_25_ops}; static ec_gf_op_t ec_gf8_mul_26_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_26 = {8, { 3, 4, 1, 2, 0, 5, 6, 7, }, ec_gf8_mul_26_ops}; static ec_gf_op_t ec_gf8_mul_27_ops[] = { {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_27 = {8, { 3, 0, 1, 2, 6, 7, 4, 5, }, ec_gf8_mul_27_ops}; static ec_gf_op_t ec_gf8_mul_28_ops[] = { {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_28 = {8, { 5, 6, 3, 0, 1, 2, 4, 7, }, ec_gf8_mul_28_ops}; static ec_gf_op_t ec_gf8_mul_29_ops[] = { {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_29 = {8, { 4, 6, 3, 5, 7, 0, 1, 2, }, ec_gf8_mul_29_ops}; static ec_gf_op_t ec_gf8_mul_2A_ops[] = { {EC_GF_OP_COPY, 8, 1, 0}, {EC_GF_OP_XOR2, 8, 0, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR3, 6, 8, 4}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_2A = {9, { 3, 4, 7, 2, 6, 5, 1, 0, 8, }, ec_gf8_mul_2A_ops}; static ec_gf_op_t ec_gf8_mul_2B_ops[] = { {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_2B = {8, { 3, 4, 7, 5, 6, 0, 1, 2, }, ec_gf8_mul_2B_ops}; static ec_gf_op_t ec_gf8_mul_2C_ops[] = { {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_2C = {8, { 5, 6, 7, 0, 2, 3, 4, 1, }, ec_gf8_mul_2C_ops}; static ec_gf_op_t ec_gf8_mul_2D_ops[] = { {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR3, 8, 4, 6}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_2D = {9, { 7, 0, 3, 5, 1, 4, 2, 6, 8, }, ec_gf8_mul_2D_ops}; static ec_gf_op_t ec_gf8_mul_2E_ops[] = { {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_COPY, 8, 4, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 8, 7, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_2E = {9, { 5, 0, 7, 3, 2, 6, 4, 1, 8, }, ec_gf8_mul_2E_ops}; static ec_gf_op_t ec_gf8_mul_2F_ops[] = { {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR3, 8, 7, 6}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_2F = {9, { 6, 3, 2, 5, 7, 0, 1, 4, 8, }, ec_gf8_mul_2F_ops}; static ec_gf_op_t ec_gf8_mul_30_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 8, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR3, 6, 8, 7}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_30 = {9, { 3, 4, 7, 5, 0, 6, 1, 2, 8, }, ec_gf8_mul_30_ops}; static ec_gf_op_t ec_gf8_mul_31_ops[] = { {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_31 = {8, { 7, 1, 4, 5, 6, 0, 2, 3, }, ec_gf8_mul_31_ops}; static ec_gf_op_t ec_gf8_mul_32_ops[] = { {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_32 = {8, { 3, 4, 6, 7, 5, 0, 1, 2, }, ec_gf8_mul_32_ops}; static ec_gf_op_t ec_gf8_mul_33_ops[] = { {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_33 = {8, { 5, 4, 3, 0, 2, 1, 6, 7, }, ec_gf8_mul_33_ops}; static ec_gf_op_t ec_gf8_mul_34_ops[] = { {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_34 = {8, { 7, 5, 3, 0, 2, 4, 1, 6, }, ec_gf8_mul_34_ops}; static ec_gf_op_t ec_gf8_mul_35_ops[] = { {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_35 = {8, { 6, 7, 5, 4, 2, 0, 1, 3, }, ec_gf8_mul_35_ops}; static ec_gf_op_t ec_gf8_mul_36_ops[] = { {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_36 = {8, { 6, 7, 4, 1, 2, 3, 0, 5, }, ec_gf8_mul_36_ops}; static ec_gf_op_t ec_gf8_mul_37_ops[] = { {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR3, 8, 0, 1}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_37 = {9, { 6, 7, 2, 1, 0, 3, 4, 5, 8, }, ec_gf8_mul_37_ops}; static ec_gf_op_t ec_gf8_mul_38_ops[] = { {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR3, 8, 6, 7}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_38 = {9, { 4, 5, 6, 3, 0, 1, 7, 2, 8, }, ec_gf8_mul_38_ops}; static ec_gf_op_t ec_gf8_mul_39_ops[] = { {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_39 = {8, { 1, 6, 3, 0, 5, 2, 4, 7, }, ec_gf8_mul_39_ops}; static ec_gf_op_t ec_gf8_mul_3A_ops[] = { {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_3A = {8, { 3, 4, 7, 0, 5, 6, 1, 2, }, ec_gf8_mul_3A_ops}; static ec_gf_op_t ec_gf8_mul_3B_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR3, 8, 7, 3}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_3B = {9, { 3, 0, 1, 7, 6, 2, 4, 8, 5, }, ec_gf8_mul_3B_ops}; static ec_gf_op_t ec_gf8_mul_3C_ops[] = { {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_3C = {8, { 3, 6, 4, 1, 7, 2, 0, 5, }, ec_gf8_mul_3C_ops}; static ec_gf_op_t ec_gf8_mul_3D_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_3D = {8, { 2, 3, 4, 5, 6, 7, 0, 1, }, ec_gf8_mul_3D_ops}; static ec_gf_op_t ec_gf8_mul_3E_ops[] = { {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_3E = {8, { 6, 1, 2, 7, 0, 3, 5, 4, }, ec_gf8_mul_3E_ops}; static ec_gf_op_t ec_gf8_mul_3F_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_COPY, 10, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_COPY, 9, 2, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR3, 4, 9, 7}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 3, 10, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_3F = {11, { 1, 7, 6, 2, 4, 3, 5, 0, 8, 9, 10, }, ec_gf8_mul_3F_ops}; static ec_gf_op_t ec_gf8_mul_40_ops[] = { {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR3, 8, 7, 6}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_40 = {9, { 5, 7, 4, 6, 2, 3, 0, 1, 8, }, ec_gf8_mul_40_ops}; static ec_gf_op_t ec_gf8_mul_41_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 8, 4, 0}, {EC_GF_OP_XOR2, 8, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_41 = {9, { 0, 7, 6, 5, 3, 4, 8, 1, 2, }, ec_gf8_mul_41_ops}; static ec_gf_op_t ec_gf8_mul_42_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 8, 3, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_42 = {9, { 2, 7, 1, 6, 4, 3, 0, 5, 8, }, ec_gf8_mul_42_ops}; static ec_gf_op_t ec_gf8_mul_43_ops[] = { {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_43 = {8, { 2, 6, 4, 1, 7, 3, 0, 5, }, ec_gf8_mul_43_ops}; static ec_gf_op_t ec_gf8_mul_44_ops[] = { {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_44 = {8, { 2, 3, 4, 1, 6, 5, 0, 7, }, ec_gf8_mul_44_ops}; static ec_gf_op_t ec_gf8_mul_45_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_45 = {8, { 2, 3, 0, 1, 7, 4, 5, 6, }, ec_gf8_mul_45_ops}; static ec_gf_op_t ec_gf8_mul_46_ops[] = { {EC_GF_OP_XOR3, 8, 2, 4}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 8, 0, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_46 = {9, { 2, 0, 1, 3, 4, 5, 6, 7, 8, }, ec_gf8_mul_46_ops}; static ec_gf_op_t ec_gf8_mul_47_ops[] = { {EC_GF_OP_XOR3, 8, 0, 1}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_47 = {9, { 2, 3, 4, 5, 6, 7, 0, 1, 8, }, ec_gf8_mul_47_ops}; static ec_gf_op_t ec_gf8_mul_48_ops[] = { {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_48 = {8, { 4, 5, 6, 0, 1, 3, 7, 2, }, ec_gf8_mul_48_ops}; static ec_gf_op_t ec_gf8_mul_49_ops[] = { {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR3, 8, 0, 6}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR3, 1, 8, 5}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_49 = {9, { 7, 2, 4, 0, 3, 5, 1, 6, 8, }, ec_gf8_mul_49_ops}; static ec_gf_op_t ec_gf8_mul_4A_ops[] = { {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_4A = {8, { 5, 6, 7, 0, 1, 3, 4, 2, }, ec_gf8_mul_4A_ops}; static ec_gf_op_t ec_gf8_mul_4B_ops[] = { {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR3, 8, 3, 7}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_4B = {9, { 5, 3, 6, 7, 0, 2, 4, 1, 8, }, ec_gf8_mul_4B_ops}; static ec_gf_op_t ec_gf8_mul_4C_ops[] = { {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_4C = {8, { 5, 3, 4, 7, 0, 6, 2, 1, }, ec_gf8_mul_4C_ops}; static ec_gf_op_t ec_gf8_mul_4D_ops[] = { {EC_GF_OP_COPY, 8, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR3, 9, 3, 1}, {EC_GF_OP_XOR2, 5, 9, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR3, 0, 8, 2}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_4D = {10, { 0, 9, 3, 5, 6, 4, 7, 1, 2, 8, }, ec_gf8_mul_4D_ops}; static ec_gf_op_t ec_gf8_mul_4E_ops[] = { {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_4E = {8, { 2, 3, 0, 1, 5, 6, 7, 4, }, ec_gf8_mul_4E_ops}; static ec_gf_op_t ec_gf8_mul_4F_ops[] = { {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_4F = {8, { 0, 3, 5, 6, 1, 2, 7, 4, }, ec_gf8_mul_4F_ops}; static ec_gf_op_t ec_gf8_mul_50_ops[] = { {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_50 = {8, { 4, 5, 7, 3, 0, 1, 2, 6, }, ec_gf8_mul_50_ops}; static ec_gf_op_t ec_gf8_mul_51_ops[] = { {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_51 = {8, { 0, 1, 7, 2, 3, 4, 5, 6, }, ec_gf8_mul_51_ops}; static ec_gf_op_t ec_gf8_mul_52_ops[] = { {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_COPY, 9, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR3, 3, 5, 8}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 2, 9, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_52 = {10, { 2, 3, 1, 4, 6, 7, 0, 5, 8, 9, }, ec_gf8_mul_52_ops}; static ec_gf_op_t ec_gf8_mul_53_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_53 = {8, { 2, 0, 1, 4, 5, 6, 7, 3, }, ec_gf8_mul_53_ops}; static ec_gf_op_t ec_gf8_mul_54_ops[] = { {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_54 = {8, { 7, 3, 0, 4, 2, 6, 5, 1, }, ec_gf8_mul_54_ops}; static ec_gf_op_t ec_gf8_mul_55_ops[] = { {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_55 = {8, { 1, 5, 6, 4, 3, 7, 2, 0, }, ec_gf8_mul_55_ops}; static ec_gf_op_t ec_gf8_mul_56_ops[] = { {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_56 = {8, { 2, 3, 0, 4, 5, 6, 7, 1, }, ec_gf8_mul_56_ops}; static ec_gf_op_t ec_gf8_mul_57_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_57 = {8, { 2, 3, 0, 1, 4, 5, 6, 7, }, ec_gf8_mul_57_ops}; static ec_gf_op_t ec_gf8_mul_58_ops[] = { {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_58 = {8, { 4, 3, 2, 7, 0, 1, 5, 6, }, ec_gf8_mul_58_ops}; static ec_gf_op_t ec_gf8_mul_59_ops[] = { {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_59 = {8, { 7, 3, 5, 6, 1, 2, 0, 4, }, ec_gf8_mul_59_ops}; static ec_gf_op_t ec_gf8_mul_5A_ops[] = { {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_5A = {8, { 6, 7, 0, 1, 2, 3, 5, 4, }, ec_gf8_mul_5A_ops}; static ec_gf_op_t ec_gf8_mul_5B_ops[] = { {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_5B = {8, { 6, 0, 7, 5, 2, 1, 3, 4, }, ec_gf8_mul_5B_ops}; static ec_gf_op_t ec_gf8_mul_5C_ops[] = { {EC_GF_OP_COPY, 8, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_5C = {9, { 7, 5, 2, 4, 1, 0, 6, 3, 8, }, ec_gf8_mul_5C_ops}; static ec_gf_op_t ec_gf8_mul_5D_ops[] = { {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_5D = {8, { 1, 3, 5, 4, 6, 7, 2, 0, }, ec_gf8_mul_5D_ops}; static ec_gf_op_t ec_gf8_mul_5E_ops[] = { {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_5E = {8, { 4, 3, 6, 2, 5, 7, 0, 1, }, ec_gf8_mul_5E_ops}; static ec_gf_op_t ec_gf8_mul_5F_ops[] = { {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_5F = {8, { 6, 1, 3, 4, 5, 7, 2, 0, }, ec_gf8_mul_5F_ops}; static ec_gf_op_t ec_gf8_mul_60_ops[] = { {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_60 = {8, { 2, 3, 4, 7, 5, 6, 0, 1, }, ec_gf8_mul_60_ops}; static ec_gf_op_t ec_gf8_mul_61_ops[] = { {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_61 = {8, { 0, 5, 6, 7, 4, 2, 1, 3, }, ec_gf8_mul_61_ops}; static ec_gf_op_t ec_gf8_mul_62_ops[] = { {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_62 = {8, { 2, 0, 3, 4, 5, 6, 7, 1, }, ec_gf8_mul_62_ops}; static ec_gf_op_t ec_gf8_mul_63_ops[] = { {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_63 = {8, { 3, 4, 6, 5, 7, 0, 1, 2, }, ec_gf8_mul_63_ops}; static ec_gf_op_t ec_gf8_mul_64_ops[] = { {EC_GF_OP_COPY, 8, 1, 0}, {EC_GF_OP_XOR2, 8, 0, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 8, 7, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_64 = {9, { 2, 3, 4, 6, 5, 7, 8, 1, 0, }, ec_gf8_mul_64_ops}; static ec_gf_op_t ec_gf8_mul_65_ops[] = { {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_65 = {8, { 2, 5, 1, 3, 4, 0, 6, 7, }, ec_gf8_mul_65_ops}; static ec_gf_op_t ec_gf8_mul_66_ops[] = { {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_66 = {8, { 2, 3, 1, 4, 5, 7, 0, 6, }, ec_gf8_mul_66_ops}; static ec_gf_op_t ec_gf8_mul_67_ops[] = { {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_67 = {8, { 2, 4, 5, 6, 7, 3, 1, 0, }, ec_gf8_mul_67_ops}; static ec_gf_op_t ec_gf8_mul_68_ops[] = { {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_68 = {8, { 5, 7, 2, 3, 0, 6, 4, 1, }, ec_gf8_mul_68_ops}; static ec_gf_op_t ec_gf8_mul_69_ops[] = { {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_69 = {8, { 0, 1, 3, 2, 4, 5, 7, 6, }, ec_gf8_mul_69_ops}; static ec_gf_op_t ec_gf8_mul_6A_ops[] = { {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_6A = {8, { 5, 7, 4, 6, 1, 2, 0, 3, }, ec_gf8_mul_6A_ops}; static ec_gf_op_t ec_gf8_mul_6B_ops[] = { {EC_GF_OP_COPY, 8, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_6B = {9, { 6, 7, 2, 0, 3, 1, 5, 4, 8, }, ec_gf8_mul_6B_ops}; static ec_gf_op_t ec_gf8_mul_6C_ops[] = { {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_6C = {8, { 5, 6, 7, 0, 1, 2, 3, 4, }, ec_gf8_mul_6C_ops}; static ec_gf_op_t ec_gf8_mul_6D_ops[] = { {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR3, 8, 3, 4}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_6D = {9, { 3, 6, 7, 0, 4, 5, 1, 2, 8, }, ec_gf8_mul_6D_ops}; static ec_gf_op_t ec_gf8_mul_6E_ops[] = { {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_6E = {8, { 5, 6, 3, 1, 7, 2, 0, 4, }, ec_gf8_mul_6E_ops}; static ec_gf_op_t ec_gf8_mul_6F_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR3, 0, 8, 7}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_6F = {9, { 2, 6, 3, 7, 0, 1, 4, 5, 8, }, ec_gf8_mul_6F_ops}; static ec_gf_op_t ec_gf8_mul_70_ops[] = { {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_70 = {8, { 3, 4, 5, 2, 6, 0, 1, 7, }, ec_gf8_mul_70_ops}; static ec_gf_op_t ec_gf8_mul_71_ops[] = { {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_71 = {8, { 4, 7, 5, 3, 6, 0, 2, 1, }, ec_gf8_mul_71_ops}; static ec_gf_op_t ec_gf8_mul_72_ops[] = { {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_72 = {8, { 0, 5, 2, 7, 4, 1, 3, 6, }, ec_gf8_mul_72_ops}; static ec_gf_op_t ec_gf8_mul_73_ops[] = { {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_73 = {8, { 6, 0, 1, 7, 4, 5, 2, 3, }, ec_gf8_mul_73_ops}; static ec_gf_op_t ec_gf8_mul_74_ops[] = { {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_74 = {8, { 3, 2, 1, 0, 4, 5, 6, 7, }, ec_gf8_mul_74_ops}; static ec_gf_op_t ec_gf8_mul_75_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_75 = {8, { 4, 5, 6, 7, 0, 1, 2, 3, }, ec_gf8_mul_75_ops}; static ec_gf_op_t ec_gf8_mul_76_ops[] = { {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR3, 8, 6, 2}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_76 = {9, { 2, 3, 0, 6, 5, 1, 7, 8, 4, }, ec_gf8_mul_76_ops}; static ec_gf_op_t ec_gf8_mul_77_ops[] = { {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_77 = {8, { 7, 4, 3, 6, 0, 1, 5, 2, }, ec_gf8_mul_77_ops}; static ec_gf_op_t ec_gf8_mul_78_ops[] = { {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR3, 8, 0, 2}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_78 = {9, { 4, 7, 3, 2, 5, 1, 6, 0, 8, }, ec_gf8_mul_78_ops}; static ec_gf_op_t ec_gf8_mul_79_ops[] = { {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR3, 8, 4, 7}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_79 = {9, { 4, 5, 7, 3, 1, 6, 2, 0, 8, }, ec_gf8_mul_79_ops}; static ec_gf_op_t ec_gf8_mul_7A_ops[] = { {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_7A = {8, { 1, 2, 3, 4, 5, 6, 7, 0, }, ec_gf8_mul_7A_ops}; static ec_gf_op_t ec_gf8_mul_7B_ops[] = { {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR3, 8, 5, 3}, {EC_GF_OP_XOR2, 8, 0, 0}, {EC_GF_OP_COPY, 9, 4, 0}, {EC_GF_OP_XOR2, 8, 2, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR3, 4, 1, 9}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_7B = {10, { 1, 2, 3, 4, 8, 5, 6, 0, 7, 9, }, ec_gf8_mul_7B_ops}; static ec_gf_op_t ec_gf8_mul_7C_ops[] = { {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_7C = {8, { 2, 4, 1, 6, 3, 5, 7, 0, }, ec_gf8_mul_7C_ops}; static ec_gf_op_t ec_gf8_mul_7D_ops[] = { {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_7D = {8, { 1, 0, 3, 5, 6, 7, 2, 4, }, ec_gf8_mul_7D_ops}; static ec_gf_op_t ec_gf8_mul_7E_ops[] = { {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR3, 6, 2, 7}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_7E = {9, { 5, 1, 2, 0, 7, 3, 4, 6, 8, }, ec_gf8_mul_7E_ops}; static ec_gf_op_t ec_gf8_mul_7F_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR3, 9, 7, 5}, {EC_GF_OP_XOR2, 2, 9, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 9, 0}, {EC_GF_OP_XOR3, 9, 6, 4}, {EC_GF_OP_XOR2, 7, 9, 0}, {EC_GF_OP_XOR2, 3, 9, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_7F = {10, { 4, 1, 0, 5, 6, 7, 2, 3, 8, 9, }, ec_gf8_mul_7F_ops}; static ec_gf_op_t ec_gf8_mul_80_ops[] = { {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_80 = {8, { 7, 5, 6, 4, 1, 2, 3, 0, }, ec_gf8_mul_80_ops}; static ec_gf_op_t ec_gf8_mul_81_ops[] = { {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_81 = {8, { 2, 7, 4, 1, 5, 6, 3, 0, }, ec_gf8_mul_81_ops}; static ec_gf_op_t ec_gf8_mul_82_ops[] = { {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_COPY, 8, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR3, 5, 8, 7}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_82 = {9, { 6, 2, 7, 5, 1, 3, 4, 0, 8, }, ec_gf8_mul_82_ops}; static ec_gf_op_t ec_gf8_mul_83_ops[] = { {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_83 = {8, { 3, 5, 6, 7, 1, 2, 4, 0, }, ec_gf8_mul_83_ops}; static ec_gf_op_t ec_gf8_mul_84_ops[] = { {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_84 = {8, { 7, 6, 0, 4, 1, 5, 3, 2, }, ec_gf8_mul_84_ops}; static ec_gf_op_t ec_gf8_mul_85_ops[] = { {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_85 = {8, { 7, 6, 0, 3, 2, 4, 5, 1, }, ec_gf8_mul_85_ops}; static ec_gf_op_t ec_gf8_mul_86_ops[] = { {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_86 = {8, { 1, 2, 6, 4, 5, 7, 3, 0, }, ec_gf8_mul_86_ops}; static ec_gf_op_t ec_gf8_mul_87_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_COPY, 8, 1, 0}, {EC_GF_OP_XOR2, 8, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR3, 5, 8, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_87 = {9, { 1, 2, 3, 4, 5, 7, 6, 0, 8, }, ec_gf8_mul_87_ops}; static ec_gf_op_t ec_gf8_mul_88_ops[] = { {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_88 = {8, { 6, 7, 3, 1, 2, 4, 5, 0, }, ec_gf8_mul_88_ops}; static ec_gf_op_t ec_gf8_mul_89_ops[] = { {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR3, 8, 5, 2}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_89 = {9, { 2, 1, 6, 5, 7, 3, 4, 0, 8, }, ec_gf8_mul_89_ops}; static ec_gf_op_t ec_gf8_mul_8A_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_8A = {8, { 1, 2, 3, 0, 6, 7, 4, 5, }, ec_gf8_mul_8A_ops}; static ec_gf_op_t ec_gf8_mul_8B_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_8B = {8, { 6, 1, 2, 3, 5, 7, 4, 0, }, ec_gf8_mul_8B_ops}; static ec_gf_op_t ec_gf8_mul_8C_ops[] = { {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_8C = {8, { 1, 2, 0, 7, 3, 4, 5, 6, }, ec_gf8_mul_8C_ops}; static ec_gf_op_t ec_gf8_mul_8D_ops[] = { {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_8D = {8, { 7, 1, 3, 2, 4, 5, 0, 6, }, ec_gf8_mul_8D_ops}; static ec_gf_op_t ec_gf8_mul_8E_ops[] = {{EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_8E = {8, { 1, 2, 3, 4, 5, 6, 7, 0, }, ec_gf8_mul_8E_ops}; static ec_gf_op_t ec_gf8_mul_8F_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_8F = {8, { 1, 2, 3, 4, 5, 6, 7, 0, }, ec_gf8_mul_8F_ops}; static ec_gf_op_t ec_gf8_mul_90_ops[] = { {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_90 = {8, { 4, 5, 6, 7, 0, 1, 3, 2, }, ec_gf8_mul_90_ops}; static ec_gf_op_t ec_gf8_mul_91_ops[] = { {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_COPY, 9, 1, 0}, {EC_GF_OP_COPY, 8, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 9, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR3, 5, 8, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_91 = {10, { 2, 3, 1, 4, 0, 6, 7, 5, 8, 9, }, ec_gf8_mul_91_ops}; static ec_gf_op_t ec_gf8_mul_92_ops[] = { {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_92 = {8, { 6, 7, 0, 1, 2, 3, 5, 4, }, ec_gf8_mul_92_ops}; static ec_gf_op_t ec_gf8_mul_93_ops[] = { {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_93 = {8, { 6, 4, 5, 1, 7, 2, 3, 0, }, ec_gf8_mul_93_ops}; static ec_gf_op_t ec_gf8_mul_94_ops[] = { {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_94 = {8, { 7, 5, 0, 2, 6, 1, 3, 4, }, ec_gf8_mul_94_ops}; static ec_gf_op_t ec_gf8_mul_95_ops[] = { {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_95 = {8, { 7, 6, 1, 3, 0, 4, 5, 2, }, ec_gf8_mul_95_ops}; static ec_gf_op_t ec_gf8_mul_96_ops[] = { {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR3, 8, 0, 4}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 8, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_96 = {9, { 4, 0, 1, 6, 7, 2, 3, 5, 8, }, ec_gf8_mul_96_ops}; static ec_gf_op_t ec_gf8_mul_97_ops[] = { {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_COPY, 8, 2, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 8, 6, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_97 = {9, { 4, 5, 3, 6, 7, 1, 2, 0, 8, }, ec_gf8_mul_97_ops}; static ec_gf_op_t ec_gf8_mul_98_ops[] = { {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_98 = {8, { 4, 2, 3, 6, 7, 5, 1, 0, }, ec_gf8_mul_98_ops}; static ec_gf_op_t ec_gf8_mul_99_ops[] = { {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_99 = {8, { 6, 5, 3, 7, 0, 1, 4, 2, }, ec_gf8_mul_99_ops}; static ec_gf_op_t ec_gf8_mul_9A_ops[] = { {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR3, 8, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_9A = {9, { 6, 3, 4, 0, 5, 1, 2, 7, 8, }, ec_gf8_mul_9A_ops}; static ec_gf_op_t ec_gf8_mul_9B_ops[] = { {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_COPY, 9, 5, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR3, 8, 3, 2}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 3, 9, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_9B = {10, { 4, 5, 8, 6, 7, 1, 2, 0, 3, 9, }, ec_gf8_mul_9B_ops}; static ec_gf_op_t ec_gf8_mul_9C_ops[] = { {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_9C = {8, { 3, 2, 1, 0, 4, 5, 6, 7, }, ec_gf8_mul_9C_ops}; static ec_gf_op_t ec_gf8_mul_9D_ops[] = { {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_9D = {8, { 0, 1, 2, 3, 7, 4, 5, 6, }, ec_gf8_mul_9D_ops}; static ec_gf_op_t ec_gf8_mul_9E_ops[] = { {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_COPY, 8, 7, 0}, {EC_GF_OP_XOR2, 8, 5, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_9E = {9, { 4, 5, 3, 8, 6, 0, 2, 7, 1, }, ec_gf8_mul_9E_ops}; static ec_gf_op_t ec_gf8_mul_9F_ops[] = { {EC_GF_OP_XOR3, 8, 1, 2}, {EC_GF_OP_XOR2, 8, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_9F = {9, { 4, 5, 6, 7, 0, 1, 2, 3, 8, }, ec_gf8_mul_9F_ops}; static ec_gf_op_t ec_gf8_mul_A0_ops[] = { {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A0 = {8, { 3, 1, 6, 7, 5, 2, 4, 0, }, ec_gf8_mul_A0_ops}; static ec_gf_op_t ec_gf8_mul_A1_ops[] = { {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR3, 8, 0, 6}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A1 = {9, { 7, 4, 1, 5, 6, 0, 2, 3, 8, }, ec_gf8_mul_A1_ops}; static ec_gf_op_t ec_gf8_mul_A2_ops[] = { {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A2 = {8, { 7, 0, 6, 3, 2, 1, 4, 5, }, ec_gf8_mul_A2_ops}; static ec_gf_op_t ec_gf8_mul_A3_ops[] = { {EC_GF_OP_COPY, 8, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A3 = {9, { 3, 7, 2, 6, 1, 4, 0, 5, 8, }, ec_gf8_mul_A3_ops}; static ec_gf_op_t ec_gf8_mul_A4_ops[] = { {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A4 = {8, { 5, 6, 7, 2, 4, 3, 0, 1, }, ec_gf8_mul_A4_ops}; static ec_gf_op_t ec_gf8_mul_A5_ops[] = { {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR3, 8, 5, 6}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A5 = {9, { 1, 4, 2, 5, 6, 7, 3, 0, 8, }, ec_gf8_mul_A5_ops}; static ec_gf_op_t ec_gf8_mul_A6_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A6 = {8, { 1, 2, 0, 3, 4, 5, 6, 7, }, ec_gf8_mul_A6_ops}; static ec_gf_op_t ec_gf8_mul_A7_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A7 = {8, { 0, 1, 2, 5, 6, 7, 3, 4, }, ec_gf8_mul_A7_ops}; static ec_gf_op_t ec_gf8_mul_A8_ops[] = { {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 8, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_COPY, 9, 4, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 8, 3, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 9, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A8 = {10, { 1, 7, 5, 8, 6, 3, 4, 0, 2, 9, }, ec_gf8_mul_A8_ops}; static ec_gf_op_t ec_gf8_mul_A9_ops[] = { {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_A9 = {8, { 3, 7, 6, 1, 2, 0, 4, 5, }, ec_gf8_mul_A9_ops}; static ec_gf_op_t ec_gf8_mul_AA_ops[] = { {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_AA = {8, { 0, 4, 5, 3, 6, 7, 1, 2, }, ec_gf8_mul_AA_ops}; static ec_gf_op_t ec_gf8_mul_AB_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_COPY, 9, 6, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 8, 7, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR3, 3, 9, 7}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_AB = {10, { 2, 3, 8, 0, 5, 6, 1, 4, 7, 9, }, ec_gf8_mul_AB_ops}; static ec_gf_op_t ec_gf8_mul_AC_ops[] = { {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_AC = {8, { 3, 2, 1, 0, 4, 5, 6, 7, }, ec_gf8_mul_AC_ops}; static ec_gf_op_t ec_gf8_mul_AD_ops[] = { {EC_GF_OP_XOR3, 8, 1, 2}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_AD = {9, { 3, 4, 5, 6, 7, 0, 1, 2, 8, }, ec_gf8_mul_AD_ops}; static ec_gf_op_t ec_gf8_mul_AE_ops[] = { {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_COPY, 8, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_AE = {9, { 7, 0, 5, 6, 3, 4, 1, 2, 8, }, ec_gf8_mul_AE_ops}; static ec_gf_op_t ec_gf8_mul_AF_ops[] = { {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_AF = {8, { 0, 1, 2, 7, 3, 4, 5, 6, }, ec_gf8_mul_AF_ops}; static ec_gf_op_t ec_gf8_mul_B0_ops[] = { {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B0 = {8, { 4, 0, 7, 2, 3, 1, 6, 5, }, ec_gf8_mul_B0_ops}; static ec_gf_op_t ec_gf8_mul_B1_ops[] = { {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_COPY, 8, 4, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR3, 5, 8, 1}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B1 = {9, { 2, 6, 4, 7, 0, 1, 3, 5, 8, }, ec_gf8_mul_B1_ops}; static ec_gf_op_t ec_gf8_mul_B2_ops[] = { {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR3, 8, 4, 5}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 8, 1, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B2 = {9, { 0, 7, 4, 5, 6, 1, 2, 3, 8, }, ec_gf8_mul_B2_ops}; static ec_gf_op_t ec_gf8_mul_B3_ops[] = { {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_COPY, 9, 5, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR3, 8, 6, 4}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 8, 5, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR3, 1, 9, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B3 = {10, { 2, 3, 4, 5, 1, 6, 0, 7, 8, 9, }, ec_gf8_mul_B3_ops}; static ec_gf_op_t ec_gf8_mul_B4_ops[] = { {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B4 = {8, { 5, 6, 7, 0, 1, 2, 3, 4, }, ec_gf8_mul_B4_ops}; static ec_gf_op_t ec_gf8_mul_B5_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_COPY, 8, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR3, 4, 8, 3}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B5 = {9, { 3, 4, 0, 7, 1, 5, 6, 2, 8, }, ec_gf8_mul_B5_ops}; static ec_gf_op_t ec_gf8_mul_B6_ops[] = { {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B6 = {8, { 5, 3, 6, 4, 7, 0, 1, 2, }, ec_gf8_mul_B6_ops}; static ec_gf_op_t ec_gf8_mul_B7_ops[] = { {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B7 = {8, { 5, 0, 1, 4, 2, 6, 7, 3, }, ec_gf8_mul_B7_ops}; static ec_gf_op_t ec_gf8_mul_B8_ops[] = { {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B8 = {8, { 6, 4, 5, 1, 2, 0, 7, 3, }, ec_gf8_mul_B8_ops}; static ec_gf_op_t ec_gf8_mul_B9_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR3, 0, 8, 2}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_B9 = {9, { 6, 7, 0, 2, 1, 4, 5, 3, 8, }, ec_gf8_mul_B9_ops}; static ec_gf_op_t ec_gf8_mul_BA_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_BA = {8, { 1, 2, 4, 3, 5, 6, 0, 7, }, ec_gf8_mul_BA_ops}; static ec_gf_op_t ec_gf8_mul_BB_ops[] = { {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_COPY, 8, 3, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 8, 5, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 8, 7, 0}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_BB = {9, { 7, 2, 1, 8, 3, 5, 6, 4, 0, }, ec_gf8_mul_BB_ops}; static ec_gf_op_t ec_gf8_mul_BC_ops[] = { {EC_GF_OP_COPY, 8, 1, 0}, {EC_GF_OP_XOR2, 8, 2, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR3, 2, 8, 4}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_BC = {9, { 2, 6, 3, 4, 5, 1, 7, 0, 8, }, ec_gf8_mul_BC_ops}; static ec_gf_op_t ec_gf8_mul_BD_ops[] = { {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_BD = {8, { 4, 5, 0, 2, 7, 1, 6, 3, }, ec_gf8_mul_BD_ops}; static ec_gf_op_t ec_gf8_mul_BE_ops[] = { {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_BE = {8, { 0, 6, 7, 4, 5, 1, 3, 2, }, ec_gf8_mul_BE_ops}; static ec_gf_op_t ec_gf8_mul_BF_ops[] = { {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_BF = {8, { 5, 6, 1, 7, 3, 0, 2, 4, }, ec_gf8_mul_BF_ops}; static ec_gf_op_t ec_gf8_mul_C0_ops[] = { {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C0 = {8, { 1, 2, 3, 4, 7, 5, 6, 0, }, ec_gf8_mul_C0_ops}; static ec_gf_op_t ec_gf8_mul_C1_ops[] = { {EC_GF_OP_XOR3, 8, 1, 2}, {EC_GF_OP_XOR2, 8, 3, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C1 = {9, { 5, 6, 7, 4, 1, 2, 3, 0, 8, }, ec_gf8_mul_C1_ops}; static ec_gf_op_t ec_gf8_mul_C2_ops[] = { {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C2 = {8, { 7, 6, 3, 0, 1, 4, 5, 2, }, ec_gf8_mul_C2_ops}; static ec_gf_op_t ec_gf8_mul_C3_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR3, 0, 2, 6}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR3, 9, 1, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 7, 9, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C3 = {10, { 5, 6, 4, 7, 1, 2, 3, 0, 8, 9, }, ec_gf8_mul_C3_ops}; static ec_gf_op_t ec_gf8_mul_C4_ops[] = { {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C4 = {8, { 0, 2, 1, 3, 4, 5, 6, 7, }, ec_gf8_mul_C4_ops}; static ec_gf_op_t ec_gf8_mul_C5_ops[] = { {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C5 = {8, { 4, 3, 5, 7, 6, 2, 0, 1, }, ec_gf8_mul_C5_ops}; static ec_gf_op_t ec_gf8_mul_C6_ops[] = { {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_COPY, 8, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR3, 9, 5, 4}, {EC_GF_OP_XOR2, 6, 9, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 7, 9, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C6 = {10, { 6, 3, 0, 4, 5, 7, 2, 1, 8, 9, }, ec_gf8_mul_C6_ops}; static ec_gf_op_t ec_gf8_mul_C7_ops[] = { {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C7 = {8, { 7, 0, 6, 2, 5, 3, 4, 1, }, ec_gf8_mul_C7_ops}; static ec_gf_op_t ec_gf8_mul_C8_ops[] = { {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C8 = {8, { 1, 3, 2, 4, 6, 7, 5, 0, }, ec_gf8_mul_C8_ops}; static ec_gf_op_t ec_gf8_mul_C9_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_C9 = {8, { 2, 3, 4, 5, 6, 7, 0, 1, }, ec_gf8_mul_C9_ops}; static ec_gf_op_t ec_gf8_mul_CA_ops[] = { {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_CA = {8, { 1, 2, 5, 7, 3, 4, 0, 6, }, ec_gf8_mul_CA_ops}; static ec_gf_op_t ec_gf8_mul_CB_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_CB = {8, { 2, 3, 4, 5, 7, 6, 0, 1, }, ec_gf8_mul_CB_ops}; static ec_gf_op_t ec_gf8_mul_CC_ops[] = { {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_CC = {8, { 2, 7, 1, 0, 5, 6, 3, 4, }, ec_gf8_mul_CC_ops}; static ec_gf_op_t ec_gf8_mul_CD_ops[] = { {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_CD = {8, { 0, 6, 1, 2, 7, 3, 4, 5, }, ec_gf8_mul_CD_ops}; static ec_gf_op_t ec_gf8_mul_CE_ops[] = { {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_COPY, 8, 7, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR3, 3, 6, 8}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR3, 8, 2, 3}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_CE = {9, { 5, 7, 3, 0, 2, 6, 4, 1, 8, }, ec_gf8_mul_CE_ops}; static ec_gf_op_t ec_gf8_mul_CF_ops[] = { {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_CF = {8, { 3, 6, 7, 0, 2, 4, 5, 1, }, ec_gf8_mul_CF_ops}; static ec_gf_op_t ec_gf8_mul_D0_ops[] = { {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D0 = {8, { 5, 6, 7, 2, 0, 3, 1, 4, }, ec_gf8_mul_D0_ops}; static ec_gf_op_t ec_gf8_mul_D1_ops[] = { {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR3, 8, 6, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D1 = {9, { 5, 6, 3, 2, 0, 7, 4, 1, 8, }, ec_gf8_mul_D1_ops}; static ec_gf_op_t ec_gf8_mul_D2_ops[] = { {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D2 = {8, { 7, 0, 2, 1, 3, 4, 6, 5, }, ec_gf8_mul_D2_ops}; static ec_gf_op_t ec_gf8_mul_D3_ops[] = { {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_COPY, 8, 4, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 8, 6, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D3 = {9, { 0, 3, 2, 8, 4, 6, 7, 1, 5, }, ec_gf8_mul_D3_ops}; static ec_gf_op_t ec_gf8_mul_D4_ops[] = { {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_COPY, 8, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR3, 1, 7, 8}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D4 = {9, { 4, 1, 7, 5, 0, 6, 3, 2, 8, }, ec_gf8_mul_D4_ops}; static ec_gf_op_t ec_gf8_mul_D5_ops[] = { {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D5 = {8, { 6, 7, 4, 5, 2, 3, 1, 0, }, ec_gf8_mul_D5_ops}; static ec_gf_op_t ec_gf8_mul_D6_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D6 = {9, { 0, 6, 2, 7, 1, 3, 4, 5, 8, }, ec_gf8_mul_D6_ops}; static ec_gf_op_t ec_gf8_mul_D7_ops[] = { {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR3, 8, 3, 5}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR3, 6, 7, 8}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D7 = {9, { 3, 4, 6, 5, 0, 7, 1, 2, 8, }, ec_gf8_mul_D7_ops}; static ec_gf_op_t ec_gf8_mul_D8_ops[] = { {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D8 = {8, { 4, 5, 6, 7, 0, 1, 2, 3, }, ec_gf8_mul_D8_ops}; static ec_gf_op_t ec_gf8_mul_D9_ops[] = { {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_D9 = {8, { 1, 2, 6, 7, 4, 5, 0, 3, }, ec_gf8_mul_D9_ops}; static ec_gf_op_t ec_gf8_mul_DA_ops[] = { {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR3, 8, 2, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_DA = {9, { 2, 5, 7, 1, 0, 4, 3, 6, 8, }, ec_gf8_mul_DA_ops}; static ec_gf_op_t ec_gf8_mul_DB_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 8, 4, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_DB = {9, { 7, 5, 6, 2, 3, 4, 1, 0, 8, }, ec_gf8_mul_DB_ops}; static ec_gf_op_t ec_gf8_mul_DC_ops[] = { {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_DC = {8, { 4, 5, 2, 6, 7, 1, 0, 3, }, ec_gf8_mul_DC_ops}; static ec_gf_op_t ec_gf8_mul_DD_ops[] = { {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_DD = {8, { 1, 2, 3, 6, 7, 0, 4, 5, }, ec_gf8_mul_DD_ops}; static ec_gf_op_t ec_gf8_mul_DE_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_DE = {8, { 0, 5, 2, 6, 7, 1, 3, 4, }, ec_gf8_mul_DE_ops}; static ec_gf_op_t ec_gf8_mul_DF_ops[] = { {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 8, 3, 0}, {EC_GF_OP_COPY, 9, 0, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 8, 7, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR3, 1, 9, 2}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_DF = {10, { 7, 2, 8, 4, 3, 1, 0, 6, 5, 9, }, ec_gf8_mul_DF_ops}; static ec_gf_op_t ec_gf8_mul_E0_ops[] = { {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E0 = {8, { 2, 3, 4, 7, 5, 6, 0, 1, }, ec_gf8_mul_E0_ops}; static ec_gf_op_t ec_gf8_mul_E1_ops[] = { {EC_GF_OP_COPY, 8, 1, 0}, {EC_GF_OP_XOR2, 8, 7, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR3, 9, 5, 3}, {EC_GF_OP_XOR2, 0, 9, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 4, 9, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E1 = {10, { 0, 7, 1, 3, 4, 5, 6, 2, 8, 9, }, ec_gf8_mul_E1_ops}; static ec_gf_op_t ec_gf8_mul_E2_ops[] = { {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E2 = {8, { 2, 3, 7, 1, 5, 6, 0, 4, }, ec_gf8_mul_E2_ops}; static ec_gf_op_t ec_gf8_mul_E3_ops[] = { {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR3, 8, 2, 7}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 0, 8, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR3, 6, 8, 4}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E3 = {9, { 5, 4, 7, 2, 1, 3, 6, 0, 8, }, ec_gf8_mul_E3_ops}; static ec_gf_op_t ec_gf8_mul_E4_ops[] = { {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 4, 5, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E4 = {8, { 7, 0, 1, 6, 3, 4, 2, 5, }, ec_gf8_mul_E4_ops}; static ec_gf_op_t ec_gf8_mul_E5_ops[] = { {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E5 = {9, { 4, 5, 3, 6, 7, 1, 0, 2, 8, }, ec_gf8_mul_E5_ops}; static ec_gf_op_t ec_gf8_mul_E6_ops[] = { {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E6 = {8, { 5, 4, 3, 6, 7, 0, 1, 2, }, ec_gf8_mul_E6_ops}; static ec_gf_op_t ec_gf8_mul_E7_ops[] = { {EC_GF_OP_COPY, 8, 6, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR3, 9, 0, 6}, {EC_GF_OP_XOR2, 4, 9, 0}, {EC_GF_OP_XOR2, 5, 9, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E7 = {10, { 1, 4, 3, 6, 7, 5, 2, 0, 8, 9, }, ec_gf8_mul_E7_ops}; static ec_gf_op_t ec_gf8_mul_E8_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 1, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E8 = {8, { 1, 4, 2, 7, 3, 0, 5, 6, }, ec_gf8_mul_E8_ops}; static ec_gf_op_t ec_gf8_mul_E9_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_COPY, 8, 1, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 6, 3, 0}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR3, 1, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_E9 = {9, { 6, 2, 0, 3, 4, 1, 5, 7, 8, }, ec_gf8_mul_E9_ops}; static ec_gf_op_t ec_gf8_mul_EA_ops[] = { {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_EA = {8, { 3, 4, 5, 6, 7, 0, 1, 2, }, ec_gf8_mul_EA_ops}; static ec_gf_op_t ec_gf8_mul_EB_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_EB = {8, { 3, 4, 5, 6, 7, 0, 1, 2, }, ec_gf8_mul_EB_ops}; static ec_gf_op_t ec_gf8_mul_EC_ops[] = { {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR3, 8, 4, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_EC = {9, { 7, 4, 3, 0, 2, 5, 1, 6, 8, }, ec_gf8_mul_EC_ops}; static ec_gf_op_t ec_gf8_mul_ED_ops[] = { {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_ED = {8, { 5, 6, 7, 0, 1, 4, 3, 2, }, ec_gf8_mul_ED_ops}; static ec_gf_op_t ec_gf8_mul_EE_ops[] = { {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR3, 8, 2, 3}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 8, 5, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_EE = {9, { 6, 4, 5, 7, 2, 3, 0, 1, 8, }, ec_gf8_mul_EE_ops}; static ec_gf_op_t ec_gf8_mul_EF_ops[] = { {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_COPY, 8, 0, 0}, {EC_GF_OP_XOR2, 8, 2, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 6, 8, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_EF = {9, { 6, 4, 5, 7, 2, 0, 3, 1, 8, }, ec_gf8_mul_EF_ops}; static ec_gf_op_t ec_gf8_mul_F0_ops[] = { {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR3, 8, 3, 6}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 8, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 1, 8, 0}, {EC_GF_OP_XOR2, 0, 2, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F0 = {9, { 3, 4, 6, 1, 2, 0, 5, 7, 8, }, ec_gf8_mul_F0_ops}; static ec_gf_op_t ec_gf8_mul_F1_ops[] = { {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_COPY, 8, 3, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_COPY, 9, 2, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 9, 0, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 5, 2, 0}, {EC_GF_OP_XOR2, 7, 9, 0}, {EC_GF_OP_XOR2, 4, 9, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR3, 9, 8, 7}, {EC_GF_OP_XOR2, 1, 9, 0}, {EC_GF_OP_XOR2, 5, 9, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F1 = {10, { 7, 2, 6, 3, 5, 1, 4, 0, 8, 9, }, ec_gf8_mul_F1_ops}; static ec_gf_op_t ec_gf8_mul_F2_ops[] = { {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 2, 3, 0}, {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_XOR3, 8, 6, 4}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 8, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F2 = {9, { 1, 0, 6, 7, 4, 5, 2, 3, 8, }, ec_gf8_mul_F2_ops}; static ec_gf_op_t ec_gf8_mul_F3_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F3 = {8, { 5, 6, 7, 0, 1, 2, 3, 4, }, ec_gf8_mul_F3_ops}; static ec_gf_op_t ec_gf8_mul_F4_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F4 = {8, { 0, 1, 2, 3, 4, 5, 6, 7, }, ec_gf8_mul_F4_ops}; static ec_gf_op_t ec_gf8_mul_F5_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F5 = {8, { 7, 0, 1, 2, 3, 4, 5, 6, }, ec_gf8_mul_F5_ops}; static ec_gf_op_t ec_gf8_mul_F6_ops[] = { {EC_GF_OP_XOR2, 3, 1, 0}, {EC_GF_OP_COPY, 8, 3, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_COPY, 9, 3, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 9, 4, 0}, {EC_GF_OP_XOR2, 4, 1, 0}, {EC_GF_OP_XOR2, 6, 9, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 5, 7, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR3, 7, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F6 = {10, { 0, 6, 2, 7, 4, 3, 5, 9, 1, 8, }, ec_gf8_mul_F6_ops}; static ec_gf_op_t ec_gf8_mul_F7_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F7 = {8, { 6, 7, 0, 1, 2, 3, 4, 5, }, ec_gf8_mul_F7_ops}; static ec_gf_op_t ec_gf8_mul_F8_ops[] = { {EC_GF_OP_XOR2, 4, 0, 0}, {EC_GF_OP_XOR2, 3, 5, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F8 = {8, { 6, 2, 0, 1, 4, 5, 3, 7, }, ec_gf8_mul_F8_ops}; static ec_gf_op_t ec_gf8_mul_F9_ops[] = { {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 6, 4, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR3, 8, 7, 1}, {EC_GF_OP_XOR2, 1, 3, 0}, {EC_GF_OP_XOR2, 4, 8, 0}, {EC_GF_OP_XOR2, 5, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_F9 = {9, { 4, 1, 7, 6, 0, 3, 5, 2, 8, }, ec_gf8_mul_F9_ops}; static ec_gf_op_t ec_gf8_mul_FA_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 7, 2, 0}, {EC_GF_OP_XOR2, 1, 5, 0}, {EC_GF_OP_XOR2, 3, 7, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 0, 3, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_FA = {8, { 0, 1, 2, 4, 5, 6, 7, 3, }, ec_gf8_mul_FA_ops}; static ec_gf_op_t ec_gf8_mul_FB_ops[] = { {EC_GF_OP_XOR2, 1, 0, 0}, {EC_GF_OP_XOR2, 2, 1, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 3, 2, 0}, {EC_GF_OP_XOR2, 0, 7, 0}, {EC_GF_OP_XOR2, 2, 7, 0}, {EC_GF_OP_XOR2, 1, 6, 0}, {EC_GF_OP_XOR2, 7, 6, 0}, {EC_GF_OP_XOR2, 4, 3, 0}, {EC_GF_OP_XOR2, 6, 5, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 5, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_FB = {8, { 4, 5, 6, 7, 0, 1, 2, 3, }, ec_gf8_mul_FB_ops}; static ec_gf_op_t ec_gf8_mul_FC_ops[] = { {EC_GF_OP_XOR2, 7, 0, 0}, {EC_GF_OP_XOR2, 7, 4, 0}, {EC_GF_OP_XOR2, 5, 1, 0}, {EC_GF_OP_COPY, 9, 3, 0}, {EC_GF_OP_XOR3, 8, 5, 7}, {EC_GF_OP_XOR2, 3, 6, 0}, {EC_GF_OP_XOR2, 8, 3, 0}, {EC_GF_OP_XOR2, 2, 8, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 3, 4, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 6, 0, 0}, {EC_GF_OP_XOR3, 0, 9, 2}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_FC = {10, { 5, 6, 3, 7, 1, 8, 0, 4, 2, 9, }, ec_gf8_mul_FC_ops}; static ec_gf_op_t ec_gf8_mul_FD_ops[] = { {EC_GF_OP_XOR2, 7, 1, 0}, {EC_GF_OP_COPY, 8, 7, 0}, {EC_GF_OP_XOR2, 5, 0, 0}, {EC_GF_OP_XOR2, 7, 5, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 2, 5, 0}, {EC_GF_OP_XOR2, 1, 2, 0}, {EC_GF_OP_XOR2, 0, 1, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR3, 1, 8, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_FD = {9, { 5, 3, 7, 6, 1, 2, 4, 0, 8, }, ec_gf8_mul_FD_ops}; static ec_gf_op_t ec_gf8_mul_FE_ops[] = { {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_COPY, 8, 2, 0}, {EC_GF_OP_XOR2, 2, 4, 0}, {EC_GF_OP_XOR2, 6, 2, 0}, {EC_GF_OP_XOR2, 8, 5, 0}, {EC_GF_OP_XOR2, 5, 6, 0}, {EC_GF_OP_XOR2, 6, 1, 0}, {EC_GF_OP_XOR2, 0, 6, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 7, 8, 0}, {EC_GF_OP_XOR2, 3, 0, 0}, {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR2, 0, 4, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_FE = {9, { 3, 4, 8, 2, 5, 0, 6, 1, 7, }, ec_gf8_mul_FE_ops}; static ec_gf_op_t ec_gf8_mul_FF_ops[] = { {EC_GF_OP_XOR2, 4, 7, 0}, {EC_GF_OP_COPY, 9, 0, 0}, {EC_GF_OP_COPY, 8, 4, 0}, {EC_GF_OP_XOR2, 9, 1, 0}, {EC_GF_OP_XOR2, 4, 2, 0}, {EC_GF_OP_XOR2, 9, 4, 0}, {EC_GF_OP_XOR2, 0, 5, 0}, {EC_GF_OP_XOR2, 2, 0, 0}, {EC_GF_OP_XOR2, 3, 9, 0}, {EC_GF_OP_XOR2, 7, 3, 0}, {EC_GF_OP_XOR2, 2, 6, 0}, {EC_GF_OP_XOR2, 5, 3, 0}, {EC_GF_OP_XOR2, 6, 7, 0}, {EC_GF_OP_XOR2, 1, 7, 0}, {EC_GF_OP_XOR3, 3, 8, 5}, {EC_GF_OP_XOR2, 4, 6, 0}, {EC_GF_OP_END, 0, 0, 0}}; static ec_gf_mul_t ec_gf8_mul_FF = {10, { 6, 5, 0, 1, 2, 4, 9, 3, 7, 8, }, ec_gf8_mul_FF_ops}; ec_gf_mul_t *ec_gf8_mul[] = { &ec_gf8_mul_00, &ec_gf8_mul_01, &ec_gf8_mul_02, &ec_gf8_mul_03, &ec_gf8_mul_04, &ec_gf8_mul_05, &ec_gf8_mul_06, &ec_gf8_mul_07, &ec_gf8_mul_08, &ec_gf8_mul_09, &ec_gf8_mul_0A, &ec_gf8_mul_0B, &ec_gf8_mul_0C, &ec_gf8_mul_0D, &ec_gf8_mul_0E, &ec_gf8_mul_0F, &ec_gf8_mul_10, &ec_gf8_mul_11, &ec_gf8_mul_12, &ec_gf8_mul_13, &ec_gf8_mul_14, &ec_gf8_mul_15, &ec_gf8_mul_16, &ec_gf8_mul_17, &ec_gf8_mul_18, &ec_gf8_mul_19, &ec_gf8_mul_1A, &ec_gf8_mul_1B, &ec_gf8_mul_1C, &ec_gf8_mul_1D, &ec_gf8_mul_1E, &ec_gf8_mul_1F, &ec_gf8_mul_20, &ec_gf8_mul_21, &ec_gf8_mul_22, &ec_gf8_mul_23, &ec_gf8_mul_24, &ec_gf8_mul_25, &ec_gf8_mul_26, &ec_gf8_mul_27, &ec_gf8_mul_28, &ec_gf8_mul_29, &ec_gf8_mul_2A, &ec_gf8_mul_2B, &ec_gf8_mul_2C, &ec_gf8_mul_2D, &ec_gf8_mul_2E, &ec_gf8_mul_2F, &ec_gf8_mul_30, &ec_gf8_mul_31, &ec_gf8_mul_32, &ec_gf8_mul_33, &ec_gf8_mul_34, &ec_gf8_mul_35, &ec_gf8_mul_36, &ec_gf8_mul_37, &ec_gf8_mul_38, &ec_gf8_mul_39, &ec_gf8_mul_3A, &ec_gf8_mul_3B, &ec_gf8_mul_3C, &ec_gf8_mul_3D, &ec_gf8_mul_3E, &ec_gf8_mul_3F, &ec_gf8_mul_40, &ec_gf8_mul_41, &ec_gf8_mul_42, &ec_gf8_mul_43, &ec_gf8_mul_44, &ec_gf8_mul_45, &ec_gf8_mul_46, &ec_gf8_mul_47, &ec_gf8_mul_48, &ec_gf8_mul_49, &ec_gf8_mul_4A, &ec_gf8_mul_4B, &ec_gf8_mul_4C, &ec_gf8_mul_4D, &ec_gf8_mul_4E, &ec_gf8_mul_4F, &ec_gf8_mul_50, &ec_gf8_mul_51, &ec_gf8_mul_52, &ec_gf8_mul_53, &ec_gf8_mul_54, &ec_gf8_mul_55, &ec_gf8_mul_56, &ec_gf8_mul_57, &ec_gf8_mul_58, &ec_gf8_mul_59, &ec_gf8_mul_5A, &ec_gf8_mul_5B, &ec_gf8_mul_5C, &ec_gf8_mul_5D, &ec_gf8_mul_5E, &ec_gf8_mul_5F, &ec_gf8_mul_60, &ec_gf8_mul_61, &ec_gf8_mul_62, &ec_gf8_mul_63, &ec_gf8_mul_64, &ec_gf8_mul_65, &ec_gf8_mul_66, &ec_gf8_mul_67, &ec_gf8_mul_68, &ec_gf8_mul_69, &ec_gf8_mul_6A, &ec_gf8_mul_6B, &ec_gf8_mul_6C, &ec_gf8_mul_6D, &ec_gf8_mul_6E, &ec_gf8_mul_6F, &ec_gf8_mul_70, &ec_gf8_mul_71, &ec_gf8_mul_72, &ec_gf8_mul_73, &ec_gf8_mul_74, &ec_gf8_mul_75, &ec_gf8_mul_76, &ec_gf8_mul_77, &ec_gf8_mul_78, &ec_gf8_mul_79, &ec_gf8_mul_7A, &ec_gf8_mul_7B, &ec_gf8_mul_7C, &ec_gf8_mul_7D, &ec_gf8_mul_7E, &ec_gf8_mul_7F, &ec_gf8_mul_80, &ec_gf8_mul_81, &ec_gf8_mul_82, &ec_gf8_mul_83, &ec_gf8_mul_84, &ec_gf8_mul_85, &ec_gf8_mul_86, &ec_gf8_mul_87, &ec_gf8_mul_88, &ec_gf8_mul_89, &ec_gf8_mul_8A, &ec_gf8_mul_8B, &ec_gf8_mul_8C, &ec_gf8_mul_8D, &ec_gf8_mul_8E, &ec_gf8_mul_8F, &ec_gf8_mul_90, &ec_gf8_mul_91, &ec_gf8_mul_92, &ec_gf8_mul_93, &ec_gf8_mul_94, &ec_gf8_mul_95, &ec_gf8_mul_96, &ec_gf8_mul_97, &ec_gf8_mul_98, &ec_gf8_mul_99, &ec_gf8_mul_9A, &ec_gf8_mul_9B, &ec_gf8_mul_9C, &ec_gf8_mul_9D, &ec_gf8_mul_9E, &ec_gf8_mul_9F, &ec_gf8_mul_A0, &ec_gf8_mul_A1, &ec_gf8_mul_A2, &ec_gf8_mul_A3, &ec_gf8_mul_A4, &ec_gf8_mul_A5, &ec_gf8_mul_A6, &ec_gf8_mul_A7, &ec_gf8_mul_A8, &ec_gf8_mul_A9, &ec_gf8_mul_AA, &ec_gf8_mul_AB, &ec_gf8_mul_AC, &ec_gf8_mul_AD, &ec_gf8_mul_AE, &ec_gf8_mul_AF, &ec_gf8_mul_B0, &ec_gf8_mul_B1, &ec_gf8_mul_B2, &ec_gf8_mul_B3, &ec_gf8_mul_B4, &ec_gf8_mul_B5, &ec_gf8_mul_B6, &ec_gf8_mul_B7, &ec_gf8_mul_B8, &ec_gf8_mul_B9, &ec_gf8_mul_BA, &ec_gf8_mul_BB, &ec_gf8_mul_BC, &ec_gf8_mul_BD, &ec_gf8_mul_BE, &ec_gf8_mul_BF, &ec_gf8_mul_C0, &ec_gf8_mul_C1, &ec_gf8_mul_C2, &ec_gf8_mul_C3, &ec_gf8_mul_C4, &ec_gf8_mul_C5, &ec_gf8_mul_C6, &ec_gf8_mul_C7, &ec_gf8_mul_C8, &ec_gf8_mul_C9, &ec_gf8_mul_CA, &ec_gf8_mul_CB, &ec_gf8_mul_CC, &ec_gf8_mul_CD, &ec_gf8_mul_CE, &ec_gf8_mul_CF, &ec_gf8_mul_D0, &ec_gf8_mul_D1, &ec_gf8_mul_D2, &ec_gf8_mul_D3, &ec_gf8_mul_D4, &ec_gf8_mul_D5, &ec_gf8_mul_D6, &ec_gf8_mul_D7, &ec_gf8_mul_D8, &ec_gf8_mul_D9, &ec_gf8_mul_DA, &ec_gf8_mul_DB, &ec_gf8_mul_DC, &ec_gf8_mul_DD, &ec_gf8_mul_DE, &ec_gf8_mul_DF, &ec_gf8_mul_E0, &ec_gf8_mul_E1, &ec_gf8_mul_E2, &ec_gf8_mul_E3, &ec_gf8_mul_E4, &ec_gf8_mul_E5, &ec_gf8_mul_E6, &ec_gf8_mul_E7, &ec_gf8_mul_E8, &ec_gf8_mul_E9, &ec_gf8_mul_EA, &ec_gf8_mul_EB, &ec_gf8_mul_EC, &ec_gf8_mul_ED, &ec_gf8_mul_EE, &ec_gf8_mul_EF, &ec_gf8_mul_F0, &ec_gf8_mul_F1, &ec_gf8_mul_F2, &ec_gf8_mul_F3, &ec_gf8_mul_F4, &ec_gf8_mul_F5, &ec_gf8_mul_F6, &ec_gf8_mul_F7, &ec_gf8_mul_F8, &ec_gf8_mul_F9, &ec_gf8_mul_FA, &ec_gf8_mul_FB, &ec_gf8_mul_FC, &ec_gf8_mul_FD, &ec_gf8_mul_FE, &ec_gf8_mul_FF}; glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-dir-read.c0000644000000000000000000000013214522202451023133 xustar000000000000000030 mtime=1699284265.636027338 30 atime=1699284265.635027335 30 ctime=1699284301.331134852 glusterfs-11.1/xlators/cluster/ec/src/ec-dir-read.c0000664000175100017510000004375614522202451023431 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "ec.h" #include "ec-messages.h" #include "ec-helpers.h" #include "ec-common.h" #include "ec-combine.h" #include "ec-fops.h" /**************************************************************** * * File Operation: opendir * ***************************************************************/ int32_t ec_combine_opendir(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (dst->fd != src->fd) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_FD_MISMATCH, "Mismatching fd in answers " "of 'GF_FOP_OPENDIR': %p <-> %p", dst->fd, src->fd); return 0; } return 1; } int32_t ec_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_OPENDIR, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { if (fd != NULL) { cbk->fd = fd_ref(fd); if (cbk->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, ec_combine_opendir); ec_update_fd_status(fd, this, idx, op_ret); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_opendir(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_opendir_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->opendir, &fop->loc[0], fop->fd, fop->xdata); } int32_t ec_manager_opendir(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; ec_fd_t *ctx; int32_t err; switch (state) { case EC_STATE_INIT: LOCK(&fop->fd->lock); ctx = __ec_fd_get(fop->fd, fop->xl); if (ctx == NULL) { UNLOCK(&fop->fd->lock); fop->error = ENOMEM; return EC_STATE_REPORT; } if (!ctx->loc.inode) { err = ec_loc_from_loc(fop->xl, &ctx->loc, &fop->loc[0]); if (err != 0) { UNLOCK(&fop->fd->lock); fop->error = -err; return EC_STATE_REPORT; } } UNLOCK(&fop->fd->lock); /* Fall through */ case EC_STATE_LOCK: ec_lock_prepare_inode(fop, &fop->loc[0], EC_QUERY_INFO, 0, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_true); if (cbk != NULL) { /* Save which subvolumes successfully opened the directory. * If ctx->open is 0, it means that readdir cannot be * processed in this directory. */ LOCK(&fop->fd->lock); ctx = __ec_fd_get(fop->fd, fop->xl); if (ctx != NULL) { ctx->open |= cbk->mask; } UNLOCK(&fop->fd->lock); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.opendir != NULL) { fop->cbks.opendir(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->fd, cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.opendir != NULL) { fop->cbks.opendir(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_opendir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_opendir_cbk_t func, void *data, loc_t *loc, fd_t *fd, dict_t *xdata) { ec_cbk_t callback = {.opendir = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(OPENDIR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_OPENDIR, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_opendir, ec_manager_opendir, callback, data); if (fop == NULL) { goto out; } if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } /* Returns -1 if client_id is invalid else index of child subvol in xl_list */ int ec_deitransform(xlator_t *this, off_t offset) { int idx = -1; int client_id = -1; ec_t *ec = this->private; char id[32] = {0}; int err; client_id = gf_deitransform(this, offset); sprintf(id, "%d", client_id); err = dict_get_int32(ec->leaf_to_subvolid, id, &idx); if (err < 0) { idx = err; goto out; } out: if (idx < 0) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, EC_MSG_INVALID_REQUEST, "Invalid index %d in readdirp request", client_id); idx = -EINVAL; } return idx; } /* FOP: readdir */ void ec_adjust_readdirp(ec_t *ec, int32_t idx, gf_dirent_t *entries) { gf_dirent_t *entry; list_for_each_entry(entry, &entries->list, list) { if (!entry->inode) continue; if (entry->d_stat.ia_type == IA_IFREG) { if ((entry->dict == NULL) || (ec_dict_del_number(entry->dict, EC_XATTR_SIZE, &entry->d_stat.ia_size) != 0)) { inode_unref(entry->inode); entry->inode = NULL; } else { ec_iatt_rebuild(ec, &entry->d_stat, 1, 1); } } } } int32_t ec_common_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, fop->id, idx, op_ret, op_errno); if (cbk) { if (xdata) cbk->xdata = dict_ref(xdata); if (cbk->op_ret >= 0) list_splice_init(&entries->list, &cbk->entries.list); ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_readdir(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_common_readdir_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->readdir, fop->fd, fop->size, fop->offset, fop->xdata); } int32_t ec_manager_readdir(ec_fop_data_t *fop, int32_t state) { ec_fd_t *ctx = NULL; ec_cbk_data_t *cbk = NULL; switch (state) { case EC_STATE_INIT: /* Return error if opendir has not been successfully called on * any subvolume. */ ctx = ec_fd_get(fop->fd, fop->xl); if (ctx == NULL) { fop->error = ENOMEM; } else if (ctx->open == 0) { fop->error = EBADFD; } if (fop->error) { gf_msg(fop->xl->name, GF_LOG_ERROR, fop->error, EC_MSG_INVALID_REQUEST, "EC is not winding readdir: %s", ec_msg_str(fop)); return EC_STATE_REPORT; } if (fop->id == GF_FOP_READDIRP) { int32_t err; if (fop->xdata == NULL) { fop->xdata = dict_new(); if (fop->xdata == NULL) { fop->error = ENOMEM; return EC_STATE_REPORT; } } err = dict_set_uint64(fop->xdata, EC_XATTR_SIZE, 0); if (err != 0) { fop->error = -err; return EC_STATE_REPORT; } } if (fop->offset != 0) { /* Non-zero offset is irrecoverable error as the offset may not * be valid on other bricks*/ int32_t idx = -1; idx = ec_deitransform(fop->xl, fop->offset); if (idx < 0) { fop->error = -idx; return EC_STATE_REPORT; } fop->mask &= 1ULL << idx; } else { ec_lock_prepare_fd(fop, fop->fd, EC_QUERY_INFO, 0, EC_RANGE_FULL); ec_lock(fop); } return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_one(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: if (ec_dispatch_one_retry(fop, &cbk)) { return EC_STATE_DISPATCH; } if ((cbk != NULL) && (cbk->op_ret > 0) && (fop->id == GF_FOP_READDIRP)) { ec_adjust_readdirp(fop->xl->private, cbk->idx, &cbk->entries); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk); if (fop->id == GF_FOP_READDIR) { if (fop->cbks.readdir != NULL) { fop->cbks.readdir(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->entries, cbk->xdata); } } else { if (fop->cbks.readdirp != NULL) { fop->cbks.readdirp(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->entries, cbk->xdata); } } if (fop->offset == 0) return EC_STATE_LOCK_REUSE; else return EC_STATE_END; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: if (fop->id == GF_FOP_READDIR) { if (fop->cbks.readdir != NULL) { fop->cbks.readdir(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } } else { if (fop->cbks.readdirp != NULL) { fop->cbks.readdirp(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } } if (fop->offset == 0) return EC_STATE_LOCK_REUSE; else return EC_STATE_END; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: GF_ASSERT(fop->offset == 0); ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: GF_ASSERT(fop->offset == 0); ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_readdir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_readdir_cbk_t func, void *data, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { ec_cbk_t callback = {.readdir = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(READDIR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_READDIR, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_readdir, ec_manager_readdir, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->size = size; fop->offset = offset; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } /* FOP: readdirp */ void ec_wind_readdirp(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_common_readdir_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->readdirp, fop->fd, fop->size, fop->offset, fop->xdata); } void ec_readdirp(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_readdirp_cbk_t func, void *data, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { ec_cbk_t callback = {.readdirp = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(READDIRP) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate( frame, this, GF_FOP_READDIRP, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_readdirp, ec_manager_readdir, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->size = size; fop->offset = offset; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-galois.c0000644000000000000000000000013214522202451022722 xustar000000000000000030 mtime=1699284265.637027341 30 atime=1699284265.637027341 30 ctime=1699284301.339134876 glusterfs-11.1/xlators/cluster/ec/src/ec-galois.c0000664000175100017510000000666714522202451023220 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "ec-mem-types.h" #include "ec-gf8.h" #include "ec-helpers.h" static ec_gf_t * ec_gf_alloc(uint32_t bits, uint32_t mod) { ec_gf_t *gf; gf = GF_MALLOC(sizeof(ec_gf_t), ec_mt_ec_gf_t); if (gf == NULL) { goto failed; } gf->bits = bits; gf->size = 1 << bits; gf->mod = mod; gf->log = GF_MALLOC(sizeof(uint32_t) * (gf->size * 2 - 1), gf_common_mt_int); if (gf->log == NULL) { goto failed_gf; } gf->pow = GF_MALLOC(sizeof(uint32_t) * (gf->size * 2 - 1), gf_common_mt_int); if (gf->pow == NULL) { goto failed_log; } return gf; failed_log: GF_FREE(gf->log); failed_gf: GF_FREE(gf); failed: return EC_ERR(ENOMEM); } static void ec_gf_init_tables(ec_gf_t *gf) { uint32_t i, tmp; memset(gf->log, -1, sizeof(uint32_t) * gf->size); gf->pow[0] = 1; gf->log[0] = gf->size; gf->log[1] = 0; for (i = 1; i < gf->size; i++) { tmp = gf->pow[i - 1] << 1; if (tmp >= gf->size) { tmp ^= gf->mod; } gf->pow[i + gf->size - 1] = gf->pow[i] = tmp; gf->log[tmp + gf->size - 1] = gf->log[tmp] = i; } } ec_gf_t * ec_gf_prepare(uint32_t bits, uint32_t mod) { ec_gf_mul_t **tbl; ec_gf_t *gf; uint32_t i, j; if (bits != 8) { return EC_ERR(EINVAL); } tbl = ec_gf8_mul; if (mod == 0) { mod = 0x11d; } gf = ec_gf_alloc(bits, mod); if (EC_IS_ERR(gf)) { return gf; } ec_gf_init_tables(gf); gf->table = tbl; gf->min_ops = bits * bits; gf->max_ops = 0; gf->avg_ops = 0; for (i = 1; i < gf->size; i++) { for (j = 0; tbl[i]->ops[j].op != EC_GF_OP_END; j++) { } if (gf->max_ops < j) { gf->max_ops = j; } if (gf->min_ops > j) { gf->min_ops = j; } gf->avg_ops += j; } gf->avg_ops /= gf->size; return gf; } void ec_gf_destroy(ec_gf_t *gf) { GF_FREE(gf->pow); GF_FREE(gf->log); GF_FREE(gf); } uint32_t ec_gf_add(ec_gf_t *gf, uint32_t a, uint32_t b) { if ((a >= gf->size) || (b >= gf->size)) { return gf->size; } return a ^ b; } uint32_t ec_gf_mul(ec_gf_t *gf, uint32_t a, uint32_t b) { if ((a >= gf->size) || (b >= gf->size)) { return gf->size; } if ((a != 0) && (b != 0)) { return gf->pow[gf->log[a] + gf->log[b]]; } return 0; } uint32_t ec_gf_div(ec_gf_t *gf, uint32_t a, uint32_t b) { if ((a >= gf->size) || (b >= gf->size)) { return gf->size; } if (b != 0) { if (a != 0) { return gf->pow[gf->size - 1 + gf->log[a] - gf->log[b]]; } return 0; } return gf->size; } uint32_t ec_gf_exp(ec_gf_t *gf, uint32_t a, uint32_t b) { uint32_t r; if ((a >= gf->size) || ((a == 0) && (b == 0))) { return gf->size; } r = 1; while (b != 0) { if ((b & 1) != 0) { r = ec_gf_mul(gf, r, a); } a = ec_gf_mul(gf, a, a); b >>= 1; } return r; } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-data.h0000644000000000000000000000013214522202451022362 xustar000000000000000030 mtime=1699284265.635027335 30 atime=1699284265.635027335 30 ctime=1699284301.358134933 glusterfs-11.1/xlators/cluster/ec/src/ec-data.h0000664000175100017510000000207314522202451022643 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_DATA_H__ #define __EC_DATA_H__ #include "ec-types.h" ec_cbk_data_t * ec_cbk_data_allocate(call_frame_t *frame, xlator_t *this, ec_fop_data_t *fop, int32_t id, int32_t idx, int32_t op_ret, int32_t op_errno); ec_fop_data_t * ec_fop_data_allocate(call_frame_t *frame, xlator_t *this, int32_t id, uint32_t flags, uintptr_t target, uint32_t fop_flags, ec_wind_f wind, ec_handler_f handler, ec_cbk_t cbks, void *data); void ec_fop_data_acquire(ec_fop_data_t *fop); void ec_fop_data_release(ec_fop_data_t *fop); void ec_fop_cleanup(ec_fop_data_t *fop); void ec_pending_fops_completed(ec_t *ec); #endif /* __EC_DATA_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec.c0000644000000000000000000000013214522202451021446 xustar000000000000000030 mtime=1699284265.643027359 30 atime=1699284265.643027359 30 ctime=1699284301.321134821 glusterfs-11.1/xlators/cluster/ec/src/ec.c0000664000175100017510000016120014522202451021725 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "ec.h" #include "ec-messages.h" #include "ec-mem-types.h" #include "ec-types.h" #include "ec-helpers.h" #include "ec-common.h" #include "ec-fops.h" #include "ec-method.h" #include "ec-code.h" #include "ec-heald.h" #include static char *ec_read_policies[EC_READ_POLICY_MAX + 1] = { [EC_ROUND_ROBIN] = "round-robin", [EC_GFID_HASH] = "gfid-hash", [EC_READ_POLICY_MAX] = NULL}; #define EC_INTERNAL_XATTR_OR_GOTO(name, xattr, op_errno, label) \ do { \ if (ec_is_internal_xattr(NULL, (char *)name, NULL, NULL)) { \ op_errno = EPERM; \ goto label; \ } \ if (name && (strlen(name) == 0) && xattr) { \ /* Bulk [f]removexattr/[f]setxattr */ \ GF_IF_INTERNAL_XATTR_GOTO(EC_XATTR_PREFIX "*", xattr, op_errno, \ label); \ } \ } while (0) int32_t ec_parse_options(xlator_t *this) { ec_t *ec = this->private; int32_t error = EINVAL; uintptr_t mask; GF_OPTION_INIT("redundancy", ec->redundancy, int32, out); ec->fragments = ec->nodes - ec->redundancy; if ((ec->redundancy < 1) || (ec->redundancy >= ec->fragments) || (ec->fragments > EC_MAX_FRAGMENTS)) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, EC_MSG_INVALID_REDUNDANCY, "Invalid redundancy (must be between " "1 and %d)", (ec->nodes - 1) / 2); goto out; } ec->bits_for_nodes = 1; mask = 2; while (ec->nodes > mask) { ec->bits_for_nodes++; mask <<= 1; } ec->node_mask = (1ULL << ec->nodes) - 1ULL; ec->fragment_size = EC_METHOD_CHUNK_SIZE; ec->stripe_size = ec->fragment_size * ec->fragments; gf_msg_debug("ec", 0, "Initialized with: nodes=%u, fragments=%u, " "stripe_size=%u, node_mask=%" PRIxFAST32, ec->nodes, ec->fragments, ec->stripe_size, ec->node_mask); error = 0; out: return error; } int32_t ec_prepare_childs(xlator_t *this) { ec_t *ec = this->private; xlator_list_t *child = NULL; int32_t count = 0; for (child = this->children; child != NULL; child = child->next) { count++; } if (count > EC_MAX_NODES) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, EC_MSG_TOO_MANY_SUBVOLS, "Too many subvolumes"); return EINVAL; } ec->nodes = count; ec->xl_list = GF_CALLOC(count, sizeof(ec->xl_list[0]), ec_mt_xlator_t); if (ec->xl_list == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Allocation of xlator list failed"); return ENOMEM; } ec->xl_up = 0; ec->xl_up_count = 0; count = 0; for (child = this->children; child != NULL; child = child->next) { ec->xl_list[count++] = child->xlator; } return 0; } /* This function transforms the subvol to subvol-id*/ static int _subvol_to_subvolid(dict_t *this, char *key, data_t *value, void *data) { ec_t *ec = data; xlator_t *subvol = NULL; int i = 0; int ret = -1; subvol = data_to_ptr(value); for (i = 0; i < ec->nodes; i++) { if (ec->xl_list[i] == subvol) { ret = dict_set_int32(this, key, i); /* -1 stops dict_foreach and returns -1*/ if (ret < 0) ret = -1; goto out; } } out: return ret; } int ec_subvol_to_subvol_id_transform(ec_t *ec, dict_t *leaf_to_subvolid) { return dict_foreach(leaf_to_subvolid, _subvol_to_subvolid, ec); } void __ec_destroy_private(xlator_t *this) { ec_t *ec = this->private; if (ec != NULL) { LOCK(&ec->lock); if (ec->timer != NULL) { gf_timer_call_cancel(this->ctx, ec->timer); ec->timer = NULL; } UNLOCK(&ec->lock); /* There is a race with timer because there is no way to know if * timer callback has really been cancelled or it has been scheduled * for execution. If it has been scheduled, it will crash if we * destroy ec too fast. * * Not sure how this can be solved without using global variables or * having support from gf_timer_call_cancel() */ sleep(2); this->private = NULL; if (ec->xl_list != NULL) { GF_FREE(ec->xl_list); ec->xl_list = NULL; } if (ec->fop_pool != NULL) { mem_pool_destroy(ec->fop_pool); } if (ec->cbk_pool != NULL) { mem_pool_destroy(ec->cbk_pool); } if (ec->lock_pool != NULL) { mem_pool_destroy(ec->lock_pool); } LOCK_DESTROY(&ec->lock); if (ec->leaf_to_subvolid) dict_unref(ec->leaf_to_subvolid); ec_method_fini(&ec->matrix); GF_FREE(ec); } } int32_t mem_acct_init(xlator_t *this) { if (xlator_mem_acct_init(this, ec_mt_end) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Memory accounting initialization " "failed."); return -1; } return 0; } void ec_configure_background_heal_opts(ec_t *ec, int background_heals, int heal_wait_qlen) { if (background_heals == 0) { ec->heal_wait_qlen = 0; } else { ec->heal_wait_qlen = heal_wait_qlen; } ec->background_heals = background_heals; } int ec_assign_read_policy(ec_t *ec, char *read_policy) { int read_policy_idx = -1; read_policy_idx = gf_get_index_by_elem(ec_read_policies, read_policy); if (read_policy_idx < 0 || read_policy_idx >= EC_READ_POLICY_MAX) return -1; ec->read_policy = read_policy_idx; return 0; } int32_t reconfigure(xlator_t *this, dict_t *options) { ec_t *ec = this->private; char *read_policy = NULL; char *extensions = NULL; uint32_t heal_wait_qlen = 0; uint32_t background_heals = 0; int32_t ret = -1; int32_t err; GF_OPTION_RECONF("cpu-extensions", extensions, options, str, failed); GF_OPTION_RECONF("self-heal-daemon", ec->shd.enabled, options, bool, failed); GF_OPTION_RECONF("iam-self-heal-daemon", ec->shd.iamshd, options, bool, failed); GF_OPTION_RECONF("eager-lock", ec->eager_lock, options, bool, failed); GF_OPTION_RECONF("other-eager-lock", ec->other_eager_lock, options, bool, failed); GF_OPTION_RECONF("eager-lock-timeout", ec->eager_lock_timeout, options, time, failed); GF_OPTION_RECONF("other-eager-lock-timeout", ec->other_eager_lock_timeout, options, time, failed); GF_OPTION_RECONF("background-heals", background_heals, options, uint32, failed); GF_OPTION_RECONF("heal-wait-qlength", heal_wait_qlen, options, uint32, failed); GF_OPTION_RECONF("self-heal-window-size", ec->self_heal_window_size, options, uint32, failed); GF_OPTION_RECONF("heal-timeout", ec->shd.timeout, options, time, failed); ec_configure_background_heal_opts(ec, background_heals, heal_wait_qlen); GF_OPTION_RECONF("shd-max-threads", ec->shd.max_threads, options, uint32, failed); GF_OPTION_RECONF("shd-wait-qlength", ec->shd.wait_qlength, options, uint32, failed); GF_OPTION_RECONF("read-policy", read_policy, options, str, failed); GF_OPTION_RECONF("optimistic-change-log", ec->optimistic_changelog, options, bool, failed); GF_OPTION_RECONF("parallel-writes", ec->parallel_writes, options, bool, failed); GF_OPTION_RECONF("stripe-cache", ec->stripe_cache, options, uint32, failed); GF_OPTION_RECONF("quorum-count", ec->quorum_count, options, uint32, failed); ret = 0; if (ec_assign_read_policy(ec, read_policy)) { ret = -1; } err = ec_method_update(this, &ec->matrix, extensions); if (err != 0) { ret = -1; } failed: return ret; } glusterfs_event_t ec_get_event_from_state(ec_t *ec) { int down_count = 0; if (ec->xl_up_count >= ec->fragments) { /* If ec is up but some subvolumes are yet to notify, give * grace time for other subvols to notify to prevent start of * I/O which may result in self-heals */ if (ec->xl_notify_count < ec->nodes) return GF_EVENT_MAXVAL; return GF_EVENT_CHILD_UP; } else { down_count = ec->xl_notify_count - ec->xl_up_count; if (down_count > ec->redundancy) return GF_EVENT_CHILD_DOWN; } return GF_EVENT_MAXVAL; } void ec_up(xlator_t *this, ec_t *ec) { char str1[32], str2[32]; if (ec->timer != NULL) { gf_timer_call_cancel(this->ctx, ec->timer); ec->timer = NULL; } ec->up = 1; gf_msg(this->name, GF_LOG_INFO, 0, EC_MSG_EC_UP, "Going UP : Child UP = %s Child Notify = %s", ec_bin(str1, sizeof(str1), ec->xl_up, ec->nodes), ec_bin(str2, sizeof(str2), ec->xl_notify, ec->nodes)); gf_event(EVENT_EC_MIN_BRICKS_UP, "subvol=%s", this->name); } void ec_down(xlator_t *this, ec_t *ec) { char str1[32], str2[32]; if (ec->timer != NULL) { gf_timer_call_cancel(this->ctx, ec->timer); ec->timer = NULL; } ec->up = 0; gf_msg(this->name, GF_LOG_INFO, 0, EC_MSG_EC_DOWN, "Going DOWN : Child UP = %s Child Notify = %s", ec_bin(str1, sizeof(str1), ec->xl_up, ec->nodes), ec_bin(str2, sizeof(str2), ec->xl_notify, ec->nodes)); gf_event(EVENT_EC_MIN_BRICKS_NOT_UP, "subvol=%s", this->name); } void ec_notify_cbk(void *data) { ec_t *ec = data; glusterfs_event_t event = GF_EVENT_MAXVAL; gf_boolean_t propagate = _gf_false; gf_boolean_t launch_heal = _gf_false; LOCK(&ec->lock); { if (!ec->timer) { /* * Either child_up/child_down is already sent to parent * This is a spurious wake up. */ goto unlock; } gf_timer_call_cancel(ec->xl->ctx, ec->timer); ec->timer = NULL; /* The timeout has expired, so any subvolume that has not * already reported its state, will be considered to be down. * We mark as if all bricks had reported. */ ec->xl_notify = (1ULL << ec->nodes) - 1ULL; ec->xl_notify_count = ec->nodes; /* Since we have marked all subvolumes as notified, it's * guaranteed that ec_get_event_from_state() will return * CHILD_UP or CHILD_DOWN, but not MAXVAL. */ event = ec_get_event_from_state(ec); if (event == GF_EVENT_CHILD_UP) { /* We are ready to bring the volume up. If there are * still bricks DOWN, they will be healed when they * come up. */ ec_up(ec->xl, ec); if (ec->shd.iamshd && !ec->shutdown) { launch_heal = _gf_true; GF_ATOMIC_INC(ec->async_fop_count); } } propagate = _gf_true; } unlock: UNLOCK(&ec->lock); if (launch_heal) { /* We have just brought the volume UP, so we trigger * a self-heal check on the root directory. */ ec_launch_replace_heal(ec); } if (propagate) { default_notify(ec->xl, event, NULL); } } void ec_launch_notify_timer(xlator_t *this, ec_t *ec) { struct timespec delay = { 0, }; gf_msg_debug(this->name, 0, "Initiating child-down timer"); delay.tv_sec = 10; delay.tv_nsec = 0; ec->timer = gf_timer_call_after(this->ctx, delay, ec_notify_cbk, ec); if (ec->timer == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_TIMER_CREATE_FAIL, "Cannot create timer " "for delayed initialization"); } } gf_boolean_t ec_disable_delays(ec_t *ec) { ec->shutdown = _gf_true; return __ec_is_last_fop(ec); } void ec_cleanup_healer_object(ec_t *ec) { struct subvol_healer *healer = NULL; ec_self_heald_t *shd = NULL; void *res = NULL; int i = 0; gf_boolean_t is_join = _gf_false; shd = &ec->shd; if (!shd->iamshd) return; for (i = 0; i < ec->nodes; i++) { healer = &shd->index_healers[i]; pthread_mutex_lock(&healer->mutex); { healer->rerun = 1; if (healer->running) { pthread_cond_signal(&healer->cond); is_join = _gf_true; } } pthread_mutex_unlock(&healer->mutex); if (is_join) { pthread_join(healer->thread, &res); is_join = _gf_false; } healer = &shd->full_healers[i]; pthread_mutex_lock(&healer->mutex); { healer->rerun = 1; if (healer->running) { pthread_cond_signal(&healer->cond); is_join = _gf_true; } } pthread_mutex_unlock(&healer->mutex); if (is_join) { pthread_join(healer->thread, &res); is_join = _gf_false; } } } void ec_pending_fops_completed(ec_t *ec) { if (ec->shutdown) { default_notify(ec->xl, GF_EVENT_PARENT_DOWN, NULL); } } static gf_boolean_t ec_set_up_state(ec_t *ec, uintptr_t index_mask, uintptr_t new_state) { uintptr_t current_state = 0; if (xlator_is_cleanup_starting(ec->xl)) return _gf_false; if ((ec->xl_notify & index_mask) == 0) { ec->xl_notify |= index_mask; ec->xl_notify_count++; } current_state = ec->xl_up & index_mask; if (current_state != new_state) { ec->xl_up ^= index_mask; ec->xl_up_count += (current_state ? -1 : 1); return _gf_true; } return _gf_false; } static gf_boolean_t ec_upcall(ec_t *ec, struct gf_upcall *upcall) { struct gf_upcall_cache_invalidation *ci = NULL; struct gf_upcall_inodelk_contention *lc = NULL; inode_t *inode; inode_table_t *table; switch (upcall->event_type) { case GF_UPCALL_CACHE_INVALIDATION: ci = upcall->data; ci->flags |= UP_INVAL_ATTR; return _gf_true; case GF_UPCALL_INODELK_CONTENTION: lc = upcall->data; if (strcmp(lc->domain, ec->xl->name) != 0) { /* The lock is not owned by EC, ignore it. */ return _gf_true; } table = ((xlator_t *)ec->xl->graph->top)->itable; if (table == NULL) { /* Self-heal daemon doesn't have an inode table on the top * xlator because it doesn't need it. In this case we should * use the inode table managed by EC itself where all inodes * being healed should be present. However self-heal doesn't * use eager-locking and inodelk's are already released as * soon as possible. In this case we can safely ignore these * notifications. */ return _gf_false; } inode = inode_find(table, upcall->gfid); /* If inode is not found, it means that it's already released, * so we can ignore it. Probably it has been released and * destroyed while the contention notification was being sent. */ if (inode != NULL) { ec_lock_release(ec, inode); inode_unref(inode); } return _gf_false; default: return _gf_true; } } int32_t ec_notify(xlator_t *this, int32_t event, void *data, void *data2) { ec_t *ec = this->private; int32_t idx = 0; int32_t error = 0; glusterfs_event_t old_event = GF_EVENT_MAXVAL; dict_t *input = NULL; dict_t *output = NULL; gf_boolean_t propagate = _gf_true; gf_boolean_t needs_shd_check = _gf_false; int32_t orig_event = event; uintptr_t mask = 0; gf_msg_trace(this->name, 0, "NOTIFY(%d): %p, %p", event, data, data2); if (event == GF_EVENT_UPCALL) { propagate = ec_upcall(ec, data); goto done; } if (event == GF_EVENT_TRANSLATOR_OP) { if (!ec->up) { error = -1; } else { input = data; output = data2; error = ec_xl_op(this, input, output); } goto out; } for (idx = 0; idx < ec->nodes; idx++) { if (ec->xl_list[idx] == data) { break; } } LOCK(&ec->lock); if (event == GF_EVENT_PARENT_UP) { /* * Start a timer which sends appropriate event to parent * xlator to prevent the 'mount' syscall from hanging. */ ec_launch_notify_timer(this, ec); goto unlock; } else if (event == GF_EVENT_PARENT_DOWN) { /* If there aren't pending fops running after we have waken up * them, we immediately propagate the notification. */ propagate = ec_disable_delays(ec); ec_cleanup_healer_object(ec); goto unlock; } if (idx < ec->nodes) { /* CHILD_* events */ old_event = ec_get_event_from_state(ec); mask = 1ULL << idx; if (event == GF_EVENT_CHILD_UP) { /* We need to trigger a selfheal if a brick changes * to UP state. */ if (ec_set_up_state(ec, mask, mask) && ec->shd.iamshd && !ec->shutdown) { needs_shd_check = _gf_true; } } else if (event == GF_EVENT_CHILD_DOWN) { ec_set_up_state(ec, mask, 0); } event = ec_get_event_from_state(ec); if (event == GF_EVENT_CHILD_UP) { if (!ec->up) { ec_up(this, ec); } } else { /* If the volume is not UP, it's irrelevant if one * brick has come up. We cannot heal anything. */ needs_shd_check = _gf_false; if ((event == GF_EVENT_CHILD_DOWN) && ec->up) { ec_down(this, ec); } } if (event != GF_EVENT_MAXVAL) { if (event == old_event) { if (orig_event == GF_EVENT_CHILD_UP) event = GF_EVENT_SOME_DESCENDENT_UP; else /* orig_event has to be GF_EVENT_CHILD_DOWN */ event = GF_EVENT_SOME_DESCENDENT_DOWN; } } else { propagate = _gf_false; needs_shd_check = _gf_false; } if (needs_shd_check) { GF_ATOMIC_INC(ec->async_fop_count); } } unlock: UNLOCK(&ec->lock); done: if (needs_shd_check) { ec_launch_replace_heal(ec); } if (propagate) { error = default_notify(this, event, data); } out: return error; } int32_t notify(xlator_t *this, int32_t event, void *data, ...) { int ret = -1; va_list ap; void *data2 = NULL; va_start(ap, data); data2 = va_arg(ap, dict_t *); va_end(ap); ret = ec_notify(this, event, data, data2); return ret; } static void ec_statistics_init(ec_t *ec) { GF_ATOMIC_INIT(ec->stats.stripe_cache.hits, 0); GF_ATOMIC_INIT(ec->stats.stripe_cache.misses, 0); GF_ATOMIC_INIT(ec->stats.stripe_cache.updates, 0); GF_ATOMIC_INIT(ec->stats.stripe_cache.invals, 0); GF_ATOMIC_INIT(ec->stats.stripe_cache.evicts, 0); GF_ATOMIC_INIT(ec->stats.stripe_cache.allocs, 0); GF_ATOMIC_INIT(ec->stats.stripe_cache.errors, 0); GF_ATOMIC_INIT(ec->stats.shd.attempted, 0); GF_ATOMIC_INIT(ec->stats.shd.completed, 0); } static int ec_assign_read_mask(ec_t *ec, char *read_mask_str) { char *mask = NULL; char *maskptr = NULL; char *saveptr = NULL; char *id_str = NULL; int id = 0; int ret = 0; uintptr_t read_mask = 0; if (!read_mask_str) { ec->read_mask = 0; ret = 0; goto out; } mask = gf_strdup(read_mask_str); if (!mask) { ret = -1; goto out; } maskptr = mask; for (;;) { id_str = strtok_r(maskptr, ":", &saveptr); if (id_str == NULL) break; if (gf_string2int(id_str, &id)) { gf_msg(ec->xl->name, GF_LOG_ERROR, 0, EC_MSG_XLATOR_INIT_FAIL, "In read-mask \"%s\" id %s is not a valid integer", read_mask_str, id_str); ret = -1; goto out; } if ((id < 0) || (id >= ec->nodes)) { gf_msg(ec->xl->name, GF_LOG_ERROR, 0, EC_MSG_XLATOR_INIT_FAIL, "In read-mask \"%s\" id %d is not in range [0 - %d]", read_mask_str, id, ec->nodes - 1); ret = -1; goto out; } read_mask |= (1UL << id); maskptr = NULL; } if (gf_bits_count(read_mask) < ec->fragments) { gf_msg(ec->xl->name, GF_LOG_ERROR, 0, EC_MSG_XLATOR_INIT_FAIL, "read-mask \"%s\" should contain at least %d ids", read_mask_str, ec->fragments); ret = -1; goto out; } ec->read_mask = read_mask; ret = 0; out: GF_FREE(mask); return ret; } int32_t init(xlator_t *this) { ec_t *ec = NULL; char *read_policy = NULL; char *extensions = NULL; int32_t err; char *read_mask_str = NULL; if (this->parents == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, EC_MSG_NO_PARENTS, "Volume does not have parents."); } ec = GF_MALLOC(sizeof(*ec), ec_mt_ec_t); if (ec == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to allocate private memory."); return -1; } memset(ec, 0, sizeof(*ec)); this->private = ec; ec->xl = this; LOCK_INIT(&ec->lock); GF_ATOMIC_INIT(ec->async_fop_count, 0); INIT_LIST_HEAD(&ec->pending_fops); INIT_LIST_HEAD(&ec->heal_waiting); INIT_LIST_HEAD(&ec->healing); ec->fop_pool = mem_pool_new(ec_fop_data_t, 1024); ec->cbk_pool = mem_pool_new(ec_cbk_data_t, 4096); ec->lock_pool = mem_pool_new(ec_lock_t, 1024); if ((ec->fop_pool == NULL) || (ec->cbk_pool == NULL) || (ec->lock_pool == NULL)) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to create memory pools."); goto failed; } if (ec_prepare_childs(this) != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_XLATOR_INIT_FAIL, "Failed to initialize xlator"); goto failed; } if (ec_parse_options(this) != 0) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, EC_MSG_XLATOR_PARSE_OPT_FAIL, "Failed to parse xlator options"); goto failed; } GF_OPTION_INIT("cpu-extensions", extensions, str, failed); err = ec_method_init(this, &ec->matrix, ec->fragments, ec->nodes, ec->nodes * 2, extensions); if (err != 0) { gf_msg(this->name, GF_LOG_ERROR, -err, EC_MSG_MATRIX_FAILED, "Failed to initialize matrix management"); goto failed; } GF_OPTION_INIT("self-heal-daemon", ec->shd.enabled, bool, failed); GF_OPTION_INIT("iam-self-heal-daemon", ec->shd.iamshd, bool, failed); GF_OPTION_INIT("eager-lock", ec->eager_lock, bool, failed); GF_OPTION_INIT("other-eager-lock", ec->other_eager_lock, bool, failed); GF_OPTION_INIT("eager-lock-timeout", ec->eager_lock_timeout, time, failed); GF_OPTION_INIT("other-eager-lock-timeout", ec->other_eager_lock_timeout, time, failed); GF_OPTION_INIT("background-heals", ec->background_heals, uint32, failed); GF_OPTION_INIT("heal-wait-qlength", ec->heal_wait_qlen, uint32, failed); GF_OPTION_INIT("self-heal-window-size", ec->self_heal_window_size, uint32, failed); ec_configure_background_heal_opts(ec, ec->background_heals, ec->heal_wait_qlen); GF_OPTION_INIT("read-policy", read_policy, str, failed); if (ec_assign_read_policy(ec, read_policy)) goto failed; GF_OPTION_INIT("heal-timeout", ec->shd.timeout, time, failed); GF_OPTION_INIT("shd-max-threads", ec->shd.max_threads, uint32, failed); GF_OPTION_INIT("shd-wait-qlength", ec->shd.wait_qlength, uint32, failed); GF_OPTION_INIT("optimistic-change-log", ec->optimistic_changelog, bool, failed); GF_OPTION_INIT("parallel-writes", ec->parallel_writes, bool, failed); GF_OPTION_INIT("stripe-cache", ec->stripe_cache, uint32, failed); GF_OPTION_INIT("quorum-count", ec->quorum_count, uint32, failed); GF_OPTION_INIT("ec-read-mask", read_mask_str, str, failed); if (ec_assign_read_mask(ec, read_mask_str)) goto failed; this->itable = inode_table_new(EC_SHD_INODE_LRU_LIMIT, this, 0, 0); if (!this->itable) goto failed; if (ec->shd.iamshd) ec_selfheal_daemon_init(this); gf_msg_debug(this->name, 0, "Disperse translator initialized."); ec->leaf_to_subvolid = dict_new(); if (!ec->leaf_to_subvolid) goto failed; if (glusterfs_reachable_leaves(this, ec->leaf_to_subvolid)) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_SUBVOL_BUILD_FAIL, "Failed to build subvol " "dictionary"); goto failed; } if (ec_subvol_to_subvol_id_transform(ec, ec->leaf_to_subvolid) < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_SUBVOL_ID_DICT_SET_FAIL, "Failed to build subvol-id " "dictionary"); goto failed; } ec_statistics_init(ec); return 0; failed: __ec_destroy_private(this); return -1; } void fini(xlator_t *this) { ec_selfheal_daemon_fini(this); __ec_destroy_private(this); } int32_t ec_gf_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { ec_access(frame, this, -1, EC_MINIMUM_ONE, default_access_cbk, NULL, loc, mask, xdata); return 0; } int32_t ec_gf_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { ec_create(frame, this, -1, EC_MINIMUM_MIN, default_create_cbk, NULL, loc, flags, mode, umask, fd, xdata); return 0; } int32_t ec_gf_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { ec_discard(frame, this, -1, EC_MINIMUM_MIN, default_discard_cbk, NULL, fd, offset, len, xdata); return 0; } int32_t ec_gf_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { uint32_t fop_flags = EC_MINIMUM_ALL; if (cmd == ENTRYLK_UNLOCK) fop_flags = EC_MINIMUM_ONE; ec_entrylk(frame, this, -1, fop_flags, default_entrylk_cbk, NULL, volume, loc, basename, cmd, type, xdata); return 0; } int32_t ec_gf_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { uint32_t fop_flags = EC_MINIMUM_ALL; if (cmd == ENTRYLK_UNLOCK) fop_flags = EC_MINIMUM_ONE; ec_fentrylk(frame, this, -1, fop_flags, default_fentrylk_cbk, NULL, volume, fd, basename, cmd, type, xdata); return 0; } int32_t ec_gf_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { ec_fallocate(frame, this, -1, EC_MINIMUM_MIN, default_fallocate_cbk, NULL, fd, mode, offset, len, xdata); return 0; } int32_t ec_gf_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { ec_flush(frame, this, -1, EC_MINIMUM_MIN, default_flush_cbk, NULL, fd, xdata); return 0; } int32_t ec_gf_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { ec_fsync(frame, this, -1, EC_MINIMUM_MIN, default_fsync_cbk, NULL, fd, datasync, xdata); return 0; } int32_t ec_gf_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { ec_fsyncdir(frame, this, -1, EC_MINIMUM_MIN, default_fsyncdir_cbk, NULL, fd, datasync, xdata); return 0; } int ec_marker_populate_args(call_frame_t *frame, int type, int *gauge, xlator_t **subvols) { xlator_t *this = frame->this; ec_t *ec = this->private; memcpy(subvols, ec->xl_list, sizeof(*subvols) * ec->nodes); if (type == MARKER_XTIME_TYPE) { /*Don't error out on ENOENT/ENOTCONN */ gauge[MCNT_NOTFOUND] = 0; gauge[MCNT_ENOTCONN] = 0; } return ec->nodes; } int32_t ec_handle_heal_commands(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { dict_t *dict_rsp = NULL; int op_ret = -1; int op_errno = ENOMEM; if (!name || strcmp(name, GF_HEAL_INFO)) return -1; op_errno = -ec_get_heal_info(this, loc, &dict_rsp); if (op_errno <= 0) { op_errno = op_ret = 0; } STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict_rsp, NULL); if (dict_rsp) dict_unref(dict_rsp); return 0; } int32_t ec_gf_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int error = 0; ec_t *ec = this->private; int32_t fop_flags = EC_MINIMUM_ONE; if (name && strcmp(name, EC_XATTR_HEAL) != 0) { EC_INTERNAL_XATTR_OR_GOTO(name, NULL, error, out); } if (ec_handle_heal_commands(frame, this, loc, name, xdata) == 0) return 0; if (cluster_handle_marker_getxattr(frame, loc, name, ec->vol_uuid, NULL, ec_marker_populate_args) == 0) return 0; if (name && ((fnmatch(GF_XATTR_STIME_PATTERN, name, 0) == 0) || XATTR_IS_NODE_UUID(name) || XATTR_IS_NODE_UUID_LIST(name))) { fop_flags = EC_MINIMUM_ALL; } ec_getxattr(frame, this, -1, fop_flags, default_getxattr_cbk, NULL, loc, name, xdata); return 0; out: error = ENODATA; STACK_UNWIND_STRICT(getxattr, frame, -1, error, NULL, NULL); return 0; } int32_t ec_gf_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int error = 0; EC_INTERNAL_XATTR_OR_GOTO(name, NULL, error, out); ec_fgetxattr(frame, this, -1, EC_MINIMUM_ONE, default_fgetxattr_cbk, NULL, fd, name, xdata); return 0; out: error = ENODATA; STACK_UNWIND_STRICT(fgetxattr, frame, -1, error, NULL, NULL); return 0; } int32_t ec_gf_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { int32_t fop_flags = EC_MINIMUM_ALL; if (flock->l_type == F_UNLCK) fop_flags = EC_MINIMUM_ONE; ec_inodelk(frame, this, &frame->root->lk_owner, -1, fop_flags, default_inodelk_cbk, NULL, volume, loc, cmd, flock, xdata); return 0; } int32_t ec_gf_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { int32_t fop_flags = EC_MINIMUM_ALL; if (flock->l_type == F_UNLCK) fop_flags = EC_MINIMUM_ONE; ec_finodelk(frame, this, &frame->root->lk_owner, -1, fop_flags, default_finodelk_cbk, NULL, volume, fd, cmd, flock, xdata); return 0; } int32_t ec_gf_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { ec_link(frame, this, -1, EC_MINIMUM_MIN, default_link_cbk, NULL, oldloc, newloc, xdata); return 0; } int32_t ec_gf_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { int32_t fop_flags = EC_MINIMUM_ALL; if (flock->l_type == F_UNLCK) fop_flags = EC_MINIMUM_ONE; ec_lk(frame, this, -1, fop_flags, default_lk_cbk, NULL, fd, cmd, flock, xdata); return 0; } int32_t ec_gf_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { ec_lookup(frame, this, -1, EC_MINIMUM_MIN, default_lookup_cbk, NULL, loc, xdata); return 0; } int32_t ec_gf_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { ec_mkdir(frame, this, -1, EC_MINIMUM_MIN, default_mkdir_cbk, NULL, loc, mode, umask, xdata); return 0; } int32_t ec_gf_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { ec_mknod(frame, this, -1, EC_MINIMUM_MIN, default_mknod_cbk, NULL, loc, mode, rdev, umask, xdata); return 0; } int32_t ec_gf_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { ec_open(frame, this, -1, EC_MINIMUM_MIN, default_open_cbk, NULL, loc, flags, fd, xdata); return 0; } int32_t ec_gf_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { ec_opendir(frame, this, -1, EC_MINIMUM_MIN, default_opendir_cbk, NULL, loc, fd, xdata); return 0; } int32_t ec_gf_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { ec_readdir(frame, this, -1, EC_MINIMUM_ONE, default_readdir_cbk, NULL, fd, size, offset, xdata); return 0; } int32_t ec_gf_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { ec_readdirp(frame, this, -1, EC_MINIMUM_ONE, default_readdirp_cbk, NULL, fd, size, offset, xdata); return 0; } int32_t ec_gf_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { ec_readlink(frame, this, -1, EC_MINIMUM_ONE, default_readlink_cbk, NULL, loc, size, xdata); return 0; } int32_t ec_gf_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { ec_readv(frame, this, -1, EC_MINIMUM_MIN, default_readv_cbk, NULL, fd, size, offset, flags, xdata); return 0; } int32_t ec_gf_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int error = 0; EC_INTERNAL_XATTR_OR_GOTO(name, xdata, error, out); ec_removexattr(frame, this, -1, EC_MINIMUM_MIN, default_removexattr_cbk, NULL, loc, name, xdata); return 0; out: STACK_UNWIND_STRICT(removexattr, frame, -1, error, NULL); return 0; } int32_t ec_gf_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int error = 0; EC_INTERNAL_XATTR_OR_GOTO(name, xdata, error, out); ec_fremovexattr(frame, this, -1, EC_MINIMUM_MIN, default_fremovexattr_cbk, NULL, fd, name, xdata); return 0; out: STACK_UNWIND_STRICT(fremovexattr, frame, -1, error, NULL); return 0; } int32_t ec_gf_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { ec_rename(frame, this, -1, EC_MINIMUM_MIN, default_rename_cbk, NULL, oldloc, newloc, xdata); return 0; } int32_t ec_gf_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { ec_rmdir(frame, this, -1, EC_MINIMUM_MIN, default_rmdir_cbk, NULL, loc, xflags, xdata); return 0; } int32_t ec_gf_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { ec_setattr(frame, this, -1, EC_MINIMUM_MIN, default_setattr_cbk, NULL, loc, stbuf, valid, xdata); return 0; } int32_t ec_gf_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { ec_fsetattr(frame, this, -1, EC_MINIMUM_MIN, default_fsetattr_cbk, NULL, fd, stbuf, valid, xdata); return 0; } int32_t ec_gf_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { int error = 0; EC_INTERNAL_XATTR_OR_GOTO("", dict, error, out); ec_setxattr(frame, this, -1, EC_MINIMUM_MIN, default_setxattr_cbk, NULL, loc, dict, flags, xdata); return 0; out: STACK_UNWIND_STRICT(setxattr, frame, -1, error, NULL); return 0; } int32_t ec_gf_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { int error = 0; EC_INTERNAL_XATTR_OR_GOTO("", dict, error, out); ec_fsetxattr(frame, this, -1, EC_MINIMUM_MIN, default_fsetxattr_cbk, NULL, fd, dict, flags, xdata); return 0; out: STACK_UNWIND_STRICT(fsetxattr, frame, -1, error, NULL); return 0; } int32_t ec_gf_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { ec_stat(frame, this, -1, EC_MINIMUM_MIN, default_stat_cbk, NULL, loc, xdata); return 0; } int32_t ec_gf_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { ec_fstat(frame, this, -1, EC_MINIMUM_MIN, default_fstat_cbk, NULL, fd, xdata); return 0; } int32_t ec_gf_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { ec_statfs(frame, this, -1, EC_MINIMUM_MIN, default_statfs_cbk, NULL, loc, xdata); return 0; } int32_t ec_gf_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { ec_symlink(frame, this, -1, EC_MINIMUM_MIN, default_symlink_cbk, NULL, linkname, loc, umask, xdata); return 0; } int32_t ec_gf_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { ec_truncate(frame, this, -1, EC_MINIMUM_MIN, default_truncate_cbk, NULL, loc, offset, xdata); return 0; } int32_t ec_gf_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { ec_ftruncate(frame, this, -1, EC_MINIMUM_MIN, default_ftruncate_cbk, NULL, fd, offset, xdata); return 0; } int32_t ec_gf_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { ec_unlink(frame, this, -1, EC_MINIMUM_MIN, default_unlink_cbk, NULL, loc, xflags, xdata); return 0; } int32_t ec_gf_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { ec_writev(frame, this, -1, EC_MINIMUM_MIN, default_writev_cbk, NULL, fd, vector, count, offset, flags, iobref, xdata); return 0; } int32_t ec_gf_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { ec_xattrop(frame, this, -1, EC_MINIMUM_MIN, default_xattrop_cbk, NULL, loc, optype, xattr, xdata); return 0; } int32_t ec_gf_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { ec_fxattrop(frame, this, -1, EC_MINIMUM_MIN, default_fxattrop_cbk, NULL, fd, optype, xattr, xdata); return 0; } int32_t ec_gf_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { default_zerofill_failure_cbk(frame, ENOTSUP); return 0; } int32_t ec_gf_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { ec_seek(frame, this, -1, EC_MINIMUM_ONE, default_seek_cbk, NULL, fd, offset, what, xdata); return 0; } int32_t ec_gf_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) { ec_ipc(frame, this, -1, EC_MINIMUM_MIN, default_ipc_cbk, NULL, op, xdata); return 0; } int32_t ec_gf_forget(xlator_t *this, inode_t *inode) { uint64_t value = 0; ec_inode_t *ctx = NULL; if ((inode_ctx_del(inode, this, &value) == 0) && (value != 0)) { ctx = (ec_inode_t *)(uintptr_t)value; /* We can only forget an inode if it has been unlocked, so the stripe * cache should also be empty. */ GF_ASSERT(list_empty(&ctx->stripe_cache.lru)); GF_FREE(ctx); } return 0; } void ec_gf_release_fd(xlator_t *this, fd_t *fd) { ec_fd_t *ctx = NULL; ctx = fd_ctx_del_ptr(fd, this); if (ctx) { loc_wipe(&ctx->loc); GF_FREE(ctx); } } int32_t ec_gf_release(xlator_t *this, fd_t *fd) { ec_gf_release_fd(this, fd); return 0; } int32_t ec_gf_releasedir(xlator_t *this, fd_t *fd) { ec_gf_release_fd(this, fd); return 0; } int32_t ec_dump_private(xlator_t *this) { ec_t *ec = NULL; char key_prefix[GF_DUMP_MAX_BUF_LEN]; char tmp[65]; GF_ASSERT(this); ec = this->private; GF_ASSERT(ec); snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type, this->name); gf_proc_dump_add_section("%s", key_prefix); gf_proc_dump_write("up", "%u", ec->up); gf_proc_dump_write("nodes", "%u", ec->nodes); gf_proc_dump_write("redundancy", "%u", ec->redundancy); gf_proc_dump_write("fragment_size", "%u", ec->fragment_size); gf_proc_dump_write("stripe_size", "%u", ec->stripe_size); gf_proc_dump_write("childs_up", "%u", ec->xl_up_count); gf_proc_dump_write("childs_up_mask", "%s", ec_bin(tmp, sizeof(tmp), ec->xl_up, ec->nodes)); if (ec->read_mask) { gf_proc_dump_write("read-mask", "%s", ec_bin(tmp, sizeof(tmp), ec->read_mask, ec->nodes)); } gf_proc_dump_write("background-heals", "%d", ec->background_heals); gf_proc_dump_write("heal-wait-qlength", "%d", ec->heal_wait_qlen); gf_proc_dump_write("self-heal-window-size", "%" PRIu32, ec->self_heal_window_size); gf_proc_dump_write("healers", "%d", ec->healers); gf_proc_dump_write("heal-waiters", "%d", ec->heal_waiters); gf_proc_dump_write("read-policy", "%s", ec_read_policies[ec->read_policy]); gf_proc_dump_write("parallel-writes", "%d", ec->parallel_writes); gf_proc_dump_write("quorum-count", "%u", ec->quorum_count); snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s.stats.stripe_cache", this->type, this->name); gf_proc_dump_add_section("%s", key_prefix); gf_proc_dump_write("hits", "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(ec->stats.stripe_cache.hits)); gf_proc_dump_write("misses", "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(ec->stats.stripe_cache.misses)); gf_proc_dump_write("updates", "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(ec->stats.stripe_cache.updates)); gf_proc_dump_write("invalidations", "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(ec->stats.stripe_cache.invals)); gf_proc_dump_write("evicts", "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(ec->stats.stripe_cache.evicts)); gf_proc_dump_write("allocations", "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(ec->stats.stripe_cache.allocs)); gf_proc_dump_write("errors", "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(ec->stats.stripe_cache.errors)); gf_proc_dump_write("heals-attempted", "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(ec->stats.shd.attempted)); gf_proc_dump_write("heals-completed", "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(ec->stats.shd.completed)); return 0; } struct xlator_fops fops = {.lookup = ec_gf_lookup, .stat = ec_gf_stat, .fstat = ec_gf_fstat, .truncate = ec_gf_truncate, .ftruncate = ec_gf_ftruncate, .access = ec_gf_access, .readlink = ec_gf_readlink, .mknod = ec_gf_mknod, .mkdir = ec_gf_mkdir, .unlink = ec_gf_unlink, .rmdir = ec_gf_rmdir, .symlink = ec_gf_symlink, .rename = ec_gf_rename, .link = ec_gf_link, .create = ec_gf_create, .open = ec_gf_open, .readv = ec_gf_readv, .writev = ec_gf_writev, .flush = ec_gf_flush, .fsync = ec_gf_fsync, .opendir = ec_gf_opendir, .readdir = ec_gf_readdir, .readdirp = ec_gf_readdirp, .fsyncdir = ec_gf_fsyncdir, .statfs = ec_gf_statfs, .setxattr = ec_gf_setxattr, .getxattr = ec_gf_getxattr, .fsetxattr = ec_gf_fsetxattr, .fgetxattr = ec_gf_fgetxattr, .removexattr = ec_gf_removexattr, .fremovexattr = ec_gf_fremovexattr, .lk = ec_gf_lk, .inodelk = ec_gf_inodelk, .finodelk = ec_gf_finodelk, .entrylk = ec_gf_entrylk, .fentrylk = ec_gf_fentrylk, .xattrop = ec_gf_xattrop, .fxattrop = ec_gf_fxattrop, .setattr = ec_gf_setattr, .fsetattr = ec_gf_fsetattr, .fallocate = ec_gf_fallocate, .discard = ec_gf_discard, .zerofill = ec_gf_zerofill, .seek = ec_gf_seek, .ipc = ec_gf_ipc}; struct xlator_cbks cbks = {.forget = ec_gf_forget, .release = ec_gf_release, .releasedir = ec_gf_releasedir}; struct xlator_dumpops dumpops = {.priv = ec_dump_private}; struct volume_options options[] = { {.key = {"redundancy"}, .type = GF_OPTION_TYPE_INT, .default_value = "{{ volume.redundancy }}", .description = "Maximum number of bricks that can fail " "simultaneously without losing data."}, { .key = {"self-heal-daemon"}, .type = GF_OPTION_TYPE_BOOL, .description = "self-heal daemon enable/disable", .default_value = "enable", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"disperse"}, }, {.key = {"iam-self-heal-daemon"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "This option differentiates if the disperse " "translator is running as part of self-heal-daemon " "or not."}, {.key = {"eager-lock"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {GD_OP_VERSION_3_7_10}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, .tags = {"disperse"}, .description = "Enable/Disable eager lock for regular files on a " "disperse volume. If a fop takes a lock and completes " "its operation, it waits for next 1 second before " "releasing the lock, to see if the lock can be reused " "for next fop from the same client. If ec finds any lock " "contention within 1 second it releases the lock " "immediately before time expires. This improves the " "performance of file operations. However, as it takes " "lock on first brick, for few operations like read, " "discovery of lock contention might take long time and " "can actually degrade the performance. If eager lock is " "disabled, lock will be released as soon as fop " "completes."}, {.key = {"other-eager-lock"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {GD_OP_VERSION_3_13_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, .tags = {"disperse"}, .description = "It's equivalent to the eager-lock option but for non " "regular files."}, {.key = {"eager-lock-timeout"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 60, .default_value = "1", .op_version = {GD_OP_VERSION_4_0_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"disperse", "locks", "timeout"}, .description = "Maximum time (in seconds) that a lock on an inode is " "kept held if no new operations on the inode are " "received."}, {.key = {"other-eager-lock-timeout"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 60, .default_value = "1", .op_version = {GD_OP_VERSION_4_0_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"disperse", "locks", "timeout"}, .description = "It's equivalent to eager-lock-timeout option but for " "non regular files."}, { .key = {"background-heals"}, .type = GF_OPTION_TYPE_INT, .min = 0, /*Disabling background heals*/ .max = 256, .default_value = "8", .op_version = {GD_OP_VERSION_3_7_3}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"disperse"}, .description = "This option can be used to control number of parallel" " background heals. Zero means disable them completely.", }, { .key = {"heal-wait-qlength"}, .type = GF_OPTION_TYPE_INT, .min = 0, .max = 65536, /*Around 100MB as of now with sizeof(ec_fop_data_t) at 1800*/ .default_value = "128", .op_version = {GD_OP_VERSION_3_7_3}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"disperse"}, .description = "This option can be used to control number of heals" " that can wait.", }, {.key = {"heal-timeout"}, .type = GF_OPTION_TYPE_INT, .min = 60, .max = INT_MAX, .default_value = "600", .op_version = {GD_OP_VERSION_3_7_3}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_RANGE, .tags = {"disperse"}, .description = "Time interval for checking the need to self-heal " "in self-heal-daemon."}, { .key = {"read-policy"}, .type = GF_OPTION_TYPE_STR, .value = {"round-robin", "gfid-hash"}, .default_value = "gfid-hash", .op_version = {GD_OP_VERSION_3_7_6}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, .tags = {"disperse"}, .description = "inode-read fops happen only on 'k' number of bricks in" " n=k+m disperse subvolume. 'round-robin' selects the read" " subvolume using round-robin algo. 'gfid-hash' selects read" " subvolume based on hash of the gfid of that file/directory.", }, {.key = {"shd-max-threads"}, .type = GF_OPTION_TYPE_INT, .min = SHD_MIN_THREADS, .max = SHD_MAX_THREADS, .default_value = TOSTRING(SHD_DEFAULT_THREADS), .op_version = {GD_OP_VERSION_3_9_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"disperse"}, .description = "Maximum number of parallel heals SHD can do per local " "brick. This can substantially lower heal times, but can " "also crush your bricks if you don't have the storage " "hardware to support this."}, {.key = {"shd-wait-qlength"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 65536, .default_value = "1024", .op_version = {GD_OP_VERSION_3_9_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"disperse"}, .description = "This option can be used to control number of heals" " that can wait in SHD per subvolume."}, {.key = {"cpu-extensions"}, .type = GF_OPTION_TYPE_STR, .value = {"none", "auto", "x64", "sse", "avx"}, .default_value = "auto", .op_version = {GD_OP_VERSION_3_9_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, .tags = {"disperse"}, .description = "force the cpu extensions to be used to accelerate the " "galois field computations."}, {.key = {"self-heal-window-size"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 1024, .default_value = "32", .op_version = {GD_OP_VERSION_3_11_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC | OPT_FLAG_RANGE, .tags = {"disperse"}, .description = "Maximum number blocks(128KB) per file for which " "self-heal process would be applied simultaneously."}, {.key = {"optimistic-change-log"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {GD_OP_VERSION_3_10_1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT, .tags = {"disperse"}, .description = "Set/Unset dirty flag for every update fop at the start" "of the fop. If OFF, this option impacts performance of" "entry operations or metadata operations as it will" "set dirty flag at the start and unset it at the end of" "ALL update fop. If ON and all the bricks are good," "dirty flag will be set at the start only for file fops" "For metadata and entry fops dirty flag will not be set" "at the start, if all the bricks are good. This does" "not impact performance for metadata operations and" "entry operation but has a very small window to miss" "marking entry as dirty in case it is required to be" "healed"}, {.key = {"parallel-writes"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "This controls if writes can be wound in parallel as long" "as it doesn't modify same stripes"}, {.key = {"stripe-cache"}, .type = GF_OPTION_TYPE_INT, .min = 0, /*Disabling stripe_cache*/ .max = EC_STRIPE_CACHE_MAX_SIZE, .default_value = "4", .description = "This option will keep the last stripe of write fop" "in memory. If next write falls in this stripe, we need" "not to read it again from backend and we can save READ" "fop going over the network. This will improve performance," "specially for sequential writes. However, this will also" "lead to extra memory consumption, maximum " "(cache size * stripe size) Bytes per open file."}, { .key = {"quorum-count"}, .type = GF_OPTION_TYPE_INT, .default_value = "0", .description = "This option can be used to define how many successes on" "the bricks constitute a success to the application. This" " count should be in the range" "[disperse-data-count, disperse-count] (inclusive)", }, { .key = {"ec-read-mask"}, .type = GF_OPTION_TYPE_STR, .default_value = NULL, .description = "This option can be used to choose which bricks can be" " used for reading data/metadata of a file/directory", }, { .key = {NULL}, }, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "disperse", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-dir-write.c0000644000000000000000000000013214522202451023352 xustar000000000000000030 mtime=1699284265.637027341 30 atime=1699284265.636027338 30 ctime=1699284301.332134854 glusterfs-11.1/xlators/cluster/ec/src/ec-dir-write.c0000664000175100017510000012443314522202451023640 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "ec.h" #include "ec-messages.h" #include "ec-helpers.h" #include "ec-common.h" #include "ec-combine.h" #include "ec-method.h" #include "ec-fops.h" int ec_dir_write_cbk(call_frame_t *frame, xlator_t *this, void *cookie, int op_ret, int op_errno, struct iatt *poststat, struct iatt *preparent, struct iatt *postparent, struct iatt *preparent2, struct iatt *postparent2, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int i = 0; int idx = 0; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; idx = (long)cookie; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, fop->id, idx, op_ret, op_errno); if (!cbk) goto out; if (xdata) cbk->xdata = dict_ref(xdata); if (op_ret < 0) goto out; if (poststat) cbk->iatt[i++] = *poststat; if (preparent) cbk->iatt[i++] = *preparent; if (postparent) cbk->iatt[i++] = *postparent; if (preparent2) cbk->iatt[i++] = *preparent2; if (postparent2) cbk->iatt[i++] = *postparent2; out: if (cbk) ec_combine(cbk, ec_combine_write); if (fop) ec_complete(fop); return 0; } /* FOP: create */ int32_t ec_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return ec_dir_write_cbk(frame, this, cookie, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } void ec_wind_create(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_create_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->create, &fop->loc[0], fop->int32, fop->mode[0], fop->mode[1], fop->fd, fop->xdata); } int32_t ec_manager_create(ec_fop_data_t *fop, int32_t state) { ec_config_t config; ec_t *ec; ec_cbk_data_t *cbk; ec_fd_t *ctx; uint64_t version[2] = {0, 0}; int32_t err; switch (state) { case EC_STATE_INIT: LOCK(&fop->fd->lock); ctx = __ec_fd_get(fop->fd, fop->xl); if (ctx == NULL) { UNLOCK(&fop->fd->lock); fop->error = ENOMEM; return EC_STATE_REPORT; } err = ec_loc_from_loc(fop->xl, &ctx->loc, &fop->loc[0]); if (err != 0) { UNLOCK(&fop->fd->lock); fop->error = -err; return EC_STATE_REPORT; } ctx->flags = fop->int32; UNLOCK(&fop->fd->lock); if (fop->xdata == NULL) { fop->xdata = dict_new(); if (fop->xdata == NULL) { fop->error = ENOMEM; return EC_STATE_REPORT; } } ec = fop->xl->private; config.version = EC_CONFIG_VERSION; config.algorithm = EC_CONFIG_ALGORITHM; config.gf_word_size = EC_GF_BITS; config.bricks = ec->nodes; config.redundancy = ec->redundancy; config.chunk_size = EC_METHOD_CHUNK_SIZE; err = ec_dict_set_config(fop->xdata, EC_XATTR_CONFIG, &config); if (err != 0) { fop->error = -err; return EC_STATE_REPORT; } err = ec_dict_set_array(fop->xdata, EC_XATTR_VERSION, version, EC_VERSION_SIZE); if (err != 0) { fop->error = -err; return EC_STATE_REPORT; } err = ec_dict_set_number(fop->xdata, EC_XATTR_SIZE, 0); if (err != 0) { fop->error = -err; return EC_STATE_REPORT; } /* We need to write to specific offsets on the bricks, so we * need to remove O_APPEND from flags (if present) */ fop->int32 &= ~O_APPEND; /* Fall through */ case EC_STATE_LOCK: ec_lock_prepare_parent_inode(fop, &fop->loc[0], NULL, EC_UPDATE_DATA | EC_UPDATE_META); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { int32_t err; ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3, cbk->count); err = ec_loc_update(fop->xl, &fop->loc[0], cbk->inode, &cbk->iatt[0]); if (!ec_cbk_set_error(cbk, -err, _gf_false)) { LOCK(&fop->fd->lock); ctx = __ec_fd_get(fop->fd, fop->xl); if (ctx != NULL) { ctx->open |= cbk->mask; } UNLOCK(&fop->fd->lock); } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.create != NULL) { QUORUM_CBK(fop->cbks.create, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, fop->fd, fop->loc[0].inode, &cbk->iatt[0], &cbk->iatt[1], &cbk->iatt[2], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(fop->error != 0); if (fop->cbks.create != NULL) { fop->cbks.create(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL, NULL, NULL, cbk == NULL ? NULL : cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_create(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_create_cbk_t func, void *data, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { ec_cbk_t callback = {.create = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(CREATE) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_CREATE, 0, target, fop_flags, ec_wind_create, ec_manager_create, callback, data); if (fop == NULL) { goto out; } fop->int32 = flags; fop->mode[0] = mode; fop->mode[1] = umask; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL, NULL, NULL, NULL); } } /* FOP: link */ int32_t ec_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return ec_dir_write_cbk(frame, this, cookie, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } void ec_wind_link(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_link_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->link, &fop->loc[0], &fop->loc[1], fop->xdata); } int32_t ec_manager_link(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_parent_inode( fop, &fop->loc[1], &fop->loc[0], EC_UPDATE_DATA | EC_UPDATE_META | EC_INODE_SIZE); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { int32_t err; ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3, cbk->count); if (cbk->iatt[0].ia_type == IA_IFREG) { cbk->iatt[0].ia_size = fop->locks[0].size; } err = ec_loc_update(fop->xl, &fop->loc[0], cbk->inode, &cbk->iatt[0]); ec_cbk_set_error(cbk, -err, _gf_false); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.link != NULL) { QUORUM_CBK(fop->cbks.link, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, fop->loc[0].inode, &cbk->iatt[0], &cbk->iatt[1], &cbk->iatt[2], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.link != NULL) { fop->cbks.link(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_link(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_link_cbk_t func, void *data, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { ec_cbk_t callback = {.link = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(LINK) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_LINK, 0, target, fop_flags, ec_wind_link, ec_manager_link, callback, data); if (fop == NULL) { goto out; } if (oldloc != NULL) { if (loc_copy(&fop->loc[0], oldloc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (newloc != NULL) { if (loc_copy(&fop->loc[1], newloc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL, NULL, NULL); } } /* FOP: mkdir */ int32_t ec_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return ec_dir_write_cbk(frame, this, cookie, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } void ec_wind_mkdir(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_mkdir_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->mkdir, &fop->loc[0], fop->mode[0], fop->mode[1], fop->xdata); } int32_t ec_manager_mkdir(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; uint64_t version[2] = {0, 0}; int32_t err; switch (state) { case EC_STATE_INIT: if (fop->xdata == NULL) { fop->xdata = dict_new(); if (fop->xdata == NULL) { fop->error = ENOMEM; return EC_STATE_REPORT; } } err = ec_dict_set_array(fop->xdata, EC_XATTR_VERSION, version, EC_VERSION_SIZE); if (err != 0) { fop->error = -err; return EC_STATE_REPORT; } /* Fall through */ case EC_STATE_LOCK: ec_lock_prepare_parent_inode(fop, &fop->loc[0], NULL, EC_UPDATE_DATA | EC_UPDATE_META); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { int32_t err; ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3, cbk->count); err = ec_loc_update(fop->xl, &fop->loc[0], cbk->inode, &cbk->iatt[0]); ec_cbk_set_error(cbk, -err, _gf_false); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.mkdir != NULL) { QUORUM_CBK(fop->cbks.mkdir, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, fop->loc[0].inode, &cbk->iatt[0], &cbk->iatt[1], &cbk->iatt[2], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(fop->error != 0); if (fop->cbks.mkdir != NULL) { fop->cbks.mkdir(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL, NULL, ((cbk) ? cbk->xdata : NULL)); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_mkdir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_mkdir_cbk_t func, void *data, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { ec_cbk_t callback = {.mkdir = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(MKDIR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_MKDIR, 0, target, fop_flags, ec_wind_mkdir, ec_manager_mkdir, callback, data); if (fop == NULL) { goto out; } fop->mode[0] = mode; fop->mode[1] = umask; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL, NULL, NULL); } } /* FOP: mknod */ int32_t ec_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return ec_dir_write_cbk(frame, this, cookie, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } void ec_wind_mknod(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_mknod_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->mknod, &fop->loc[0], fop->mode[0], fop->dev, fop->mode[1], fop->xdata); } int32_t ec_manager_mknod(ec_fop_data_t *fop, int32_t state) { ec_config_t config; ec_t *ec; ec_cbk_data_t *cbk; uint64_t version[2] = {0, 0}; switch (state) { case EC_STATE_INIT: if (S_ISREG(fop->mode[0])) { int32_t err; if (fop->xdata == NULL) { fop->xdata = dict_new(); if (fop->xdata == NULL) { fop->error = ENOMEM; return EC_STATE_REPORT; } } ec = fop->xl->private; config.version = EC_CONFIG_VERSION; config.algorithm = EC_CONFIG_ALGORITHM; config.gf_word_size = EC_GF_BITS; config.bricks = ec->nodes; config.redundancy = ec->redundancy; config.chunk_size = EC_METHOD_CHUNK_SIZE; err = ec_dict_set_config(fop->xdata, EC_XATTR_CONFIG, &config); if (err != 0) { fop->error = -err; return EC_STATE_REPORT; } err = ec_dict_set_array(fop->xdata, EC_XATTR_VERSION, version, EC_VERSION_SIZE); if (err != 0) { fop->error = -err; return EC_STATE_REPORT; } err = ec_dict_set_number(fop->xdata, EC_XATTR_SIZE, 0); if (err != 0) { fop->error = -err; return EC_STATE_REPORT; } } /* Fall through */ case EC_STATE_LOCK: ec_lock_prepare_parent_inode(fop, &fop->loc[0], NULL, EC_UPDATE_DATA | EC_UPDATE_META); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { int32_t err; ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3, cbk->count); err = ec_loc_update(fop->xl, &fop->loc[0], cbk->inode, &cbk->iatt[0]); ec_cbk_set_error(cbk, -err, _gf_false); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.mknod != NULL) { QUORUM_CBK(fop->cbks.mknod, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, fop->loc[0].inode, &cbk->iatt[0], &cbk->iatt[1], &cbk->iatt[2], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.mknod != NULL) { fop->cbks.mknod(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_mknod(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_mknod_cbk_t func, void *data, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { ec_cbk_t callback = {.mknod = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(MKNOD) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_MKNOD, 0, target, fop_flags, ec_wind_mknod, ec_manager_mknod, callback, data); if (fop == NULL) { goto out; } fop->mode[0] = mode; fop->dev = rdev; fop->mode[1] = umask; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL, NULL, NULL); } } /* FOP: rename */ int32_t ec_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { return ec_dir_write_cbk(frame, this, cookie, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); } void ec_wind_rename(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_rename_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->rename, &fop->loc[0], &fop->loc[1], fop->xdata); } int32_t ec_manager_rename(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_parent_inode( fop, &fop->loc[0], &fop->loc[0], EC_UPDATE_DATA | EC_UPDATE_META | EC_INODE_SIZE); ec_lock_prepare_parent_inode(fop, &fop->loc[1], NULL, EC_UPDATE_DATA | EC_UPDATE_META); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { ec_iatt_rebuild(fop->xl->private, cbk->iatt, 5, cbk->count); if (cbk->iatt[0].ia_type == IA_IFREG) { cbk->iatt[0].ia_size = fop->locks[0].size; } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.rename != NULL) { QUORUM_CBK(fop->cbks.rename, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], &cbk->iatt[2], &cbk->iatt[3], &cbk->iatt[4], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.rename != NULL) { fop->cbks.rename(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_rename(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_rename_cbk_t func, void *data, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { ec_cbk_t callback = {.rename = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(RENAME) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_RENAME, 0, target, fop_flags, ec_wind_rename, ec_manager_rename, callback, data); if (fop == NULL) { goto out; } if (oldloc != NULL) { if (loc_copy(&fop->loc[0], oldloc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (newloc != NULL) { if (loc_copy(&fop->loc[1], newloc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL, NULL, NULL, NULL); } } /* FOP: rmdir */ int32_t ec_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return ec_dir_write_cbk(frame, this, cookie, op_ret, op_errno, NULL, preparent, postparent, NULL, NULL, xdata); } void ec_wind_rmdir(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_rmdir_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->rmdir, &fop->loc[0], fop->int32, fop->xdata); } int32_t ec_manager_rmdir(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_parent_inode(fop, &fop->loc[0], NULL, EC_UPDATE_DATA | EC_UPDATE_META); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: ec_fop_prepare_answer(fop, _gf_false); return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.rmdir != NULL) { QUORUM_CBK(fop->cbks.rmdir, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.rmdir != NULL) { fop->cbks.rmdir(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_rmdir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_rmdir_cbk_t func, void *data, loc_t *loc, int xflags, dict_t *xdata) { ec_cbk_t callback = {.rmdir = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(RMDIR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_RMDIR, 0, target, fop_flags, ec_wind_rmdir, ec_manager_rmdir, callback, data); if (fop == NULL) { goto out; } fop->int32 = xflags; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } /* FOP: symlink */ int32_t ec_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return ec_dir_write_cbk(frame, this, cookie, op_ret, op_errno, buf, preparent, postparent, NULL, NULL, xdata); } void ec_wind_symlink(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_symlink_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->symlink, fop->str[0], &fop->loc[0], fop->mode[0], fop->xdata); } int32_t ec_manager_symlink(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_parent_inode(fop, &fop->loc[0], NULL, EC_UPDATE_DATA | EC_UPDATE_META); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { int32_t err; ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3, cbk->count); err = ec_loc_update(fop->xl, &fop->loc[0], cbk->inode, &cbk->iatt[0]); ec_cbk_set_error(cbk, -err, _gf_false); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.symlink != NULL) { QUORUM_CBK(fop->cbks.symlink, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, fop->loc[0].inode, &cbk->iatt[0], &cbk->iatt[1], &cbk->iatt[2], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.symlink != NULL) { fop->cbks.symlink(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_symlink(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_symlink_cbk_t func, void *data, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { ec_cbk_t callback = {.symlink = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(SYMLINK) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_SYMLINK, 0, target, fop_flags, ec_wind_symlink, ec_manager_symlink, callback, data); if (fop == NULL) { goto out; } fop->mode[0] = umask; if (linkname != NULL) { fop->str[0] = gf_strdup(linkname); if (fop->str[0] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL, NULL, NULL); } } /* FOP: unlink */ int32_t ec_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { return ec_dir_write_cbk(frame, this, cookie, op_ret, op_errno, NULL, preparent, postparent, NULL, NULL, xdata); } void ec_wind_unlink(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_unlink_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->unlink, &fop->loc[0], fop->int32, fop->xdata); } int32_t ec_manager_unlink(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_parent_inode(fop, &fop->loc[0], NULL, EC_UPDATE_DATA | EC_UPDATE_META); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: ec_fop_prepare_answer(fop, _gf_false); return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.unlink != NULL) { QUORUM_CBK(fop->cbks.unlink, fop, fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.unlink != NULL) { fop->cbks.unlink(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_unlink(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_unlink_cbk_t func, void *data, loc_t *loc, int xflags, dict_t *xdata) { ec_cbk_t callback = {.unlink = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(UNLINK) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_UNLINK, 0, target, fop_flags, ec_wind_unlink, ec_manager_unlink, callback, data); if (fop == NULL) { goto out; } fop->int32 = xflags; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-combine.c0000644000000000000000000000013214522202451023060 xustar000000000000000030 mtime=1699284265.634027332 30 atime=1699284265.634027332 30 ctime=1699284301.336134867 glusterfs-11.1/xlators/cluster/ec/src/ec-combine.c0000664000175100017510000006506514522202451023353 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "libxlator.h" #include "ec-types.h" #include "ec-helpers.h" #include "ec-common.h" #include "ec-combine.h" #include "ec-messages.h" #include #define EC_QUOTA_PREFIX "trusted.glusterfs.quota." #define EC_MISSING_DATA ((data_t *)1ULL) struct _ec_dict_info; typedef struct _ec_dict_info ec_dict_info_t; struct _ec_dict_combine; typedef struct _ec_dict_combine ec_dict_combine_t; struct _ec_dict_info { dict_t *dict; int32_t count; }; struct _ec_dict_combine { ec_cbk_data_t *cbk; int32_t which; }; int32_t ec_combine_write(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { int valid = 0; if (!fop || !dst || !src) return 0; switch (fop->id) { case GF_FOP_REMOVEXATTR: case GF_FOP_FREMOVEXATTR: case GF_FOP_SETXATTR: case GF_FOP_FSETXATTR: return 1; case GF_FOP_SYMLINK: case GF_FOP_LINK: case GF_FOP_CREATE: case GF_FOP_MKNOD: case GF_FOP_MKDIR: valid = 3; break; case GF_FOP_UNLINK: case GF_FOP_RMDIR: case GF_FOP_SETATTR: case GF_FOP_FSETATTR: case GF_FOP_TRUNCATE: case GF_FOP_FTRUNCATE: case GF_FOP_WRITE: case GF_FOP_FALLOCATE: case GF_FOP_DISCARD: case GF_FOP_ZEROFILL: valid = 2; break; case GF_FOP_RENAME: valid = 5; break; default: gf_msg_callingfn(fop->xl->name, GF_LOG_WARNING, EINVAL, EC_MSG_INVALID_FOP, "Invalid fop %d", fop->id); return 0; break; } if (!ec_iatt_combine(fop, dst->iatt, src->iatt, valid)) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_IATT_MISMATCH, "Mismatching iatt in " "answers of '%s'", gf_fop_list[fop->id]); return 0; } return 1; } void ec_iatt_time_merge(int64_t *dst_sec, uint32_t *dst_nsec, int64_t src_sec, uint32_t src_nsec) { if ((*dst_sec < src_sec) || ((*dst_sec == src_sec) && (*dst_nsec < src_nsec))) { *dst_sec = src_sec; *dst_nsec = src_nsec; } } static gf_boolean_t ec_iatt_is_trusted(ec_fop_data_t *fop, struct iatt *iatt) { uint64_t ino; int32_t i; /* Only the top level fop will have fop->locks filled. */ while (fop->parent != NULL) { fop = fop->parent; } /* Lookups are special requests always done without locks taken but they * require to be able to identify differences between bricks. Special * handling of these differences is already done in lookup specific code * so we shouldn't ignore any difference here and consider all iatt * structures as trusted. */ if (fop->id == GF_FOP_LOOKUP) { return _gf_true; } /* Check if the iatt references an inode locked by the current fop */ for (i = 0; i < fop->lock_count; i++) { ino = gfid_to_ino(fop->locks[i].lock->loc.inode->gfid); if (iatt->ia_ino == ino) { return _gf_true; } } return _gf_false; } int32_t ec_iatt_combine(ec_fop_data_t *fop, struct iatt *dst, struct iatt *src, int32_t count) { int32_t i; gf_boolean_t failed = _gf_false; for (i = 0; i < count; i++) { /* Check for basic fields. These fields must be equal always, even if * the inode is not locked because in these cases the parent inode * will be locked and differences in these fields require changes in * the parent directory. */ if ((dst[i].ia_ino != src[i].ia_ino) || (((dst[i].ia_type == IA_IFBLK) || (dst[i].ia_type == IA_IFCHR)) && (dst[i].ia_rdev != src[i].ia_rdev)) || (gf_uuid_compare(dst[i].ia_gfid, src[i].ia_gfid) != 0)) { failed = _gf_true; } /* Check for not so stable fields. These fields can change if the * inode is not locked. */ if (!failed && ((dst[i].ia_uid != src[i].ia_uid) || (dst[i].ia_gid != src[i].ia_gid) || (st_mode_from_ia(dst[i].ia_prot, dst[i].ia_type) != st_mode_from_ia(src[i].ia_prot, src[i].ia_type)))) { if (ec_iatt_is_trusted(fop, dst)) { /* If the iatt contains information from an inode that is * locked, these differences are real problems, so we need to * report them. Otherwise we ignore them and don't care which * data is returned. */ failed = _gf_true; } else { gf_msg_debug(fop->xl->name, 0, "Ignoring iatt differences because inode is not " "locked"); } } if (failed) { gf_msg(fop->xl->name, GF_LOG_WARNING, 0, EC_MSG_IATT_COMBINE_FAIL, "Failed to combine iatt (inode: %" PRIu64 "-%" PRIu64 ", " "links: %u-%u, uid: %u-%u, gid: %u-%u, " "rdev: %" PRIu64 "-%" PRIu64 ", size: %" PRIu64 "-%" PRIu64 ", " "mode: %o-%o), %s", dst[i].ia_ino, src[i].ia_ino, dst[i].ia_nlink, src[i].ia_nlink, dst[i].ia_uid, src[i].ia_uid, dst[i].ia_gid, src[i].ia_gid, dst[i].ia_rdev, src[i].ia_rdev, dst[i].ia_size, src[i].ia_size, st_mode_from_ia(dst[i].ia_prot, dst[i].ia_type), st_mode_from_ia(src[i].ia_prot, dst[i].ia_type), ec_msg_str(fop)); return 0; } } while (count-- > 0) { dst[count].ia_blocks += src[count].ia_blocks; if (dst[count].ia_blksize < src[count].ia_blksize) { dst[count].ia_blksize = src[count].ia_blksize; } ec_iatt_time_merge(&dst[count].ia_atime, &dst[count].ia_atime_nsec, src[count].ia_atime, src[count].ia_atime_nsec); ec_iatt_time_merge(&dst[count].ia_mtime, &dst[count].ia_mtime_nsec, src[count].ia_mtime, src[count].ia_mtime_nsec); ec_iatt_time_merge(&dst[count].ia_ctime, &dst[count].ia_ctime_nsec, src[count].ia_ctime, src[count].ia_ctime_nsec); } return 1; } void ec_iatt_rebuild(ec_t *ec, struct iatt *iatt, int32_t count, int32_t answers) { uint64_t blocks; while (count-- > 0) { blocks = iatt[count].ia_blocks * ec->fragments + answers - 1; blocks /= answers; iatt[count].ia_blocks = blocks; } } gf_boolean_t ec_xattr_match(dict_t *dict, char *key, data_t *value, void *arg) { if ((fnmatch(GF_XATTR_STIME_PATTERN, key, 0) == 0) || (strcmp(key, GET_LINK_COUNT) == 0) || (strcmp(key, GLUSTERFS_INODELK_COUNT) == 0) || (strcmp(key, GLUSTERFS_ENTRYLK_COUNT) == 0) || (strcmp(key, GLUSTERFS_OPEN_FD_COUNT) == 0)) { return _gf_false; } return _gf_true; } gf_boolean_t ec_value_ignore(char *key) { if ((strcmp(key, GF_CONTENT_KEY) == 0) || (strcmp(key, GF_XATTR_PATHINFO_KEY) == 0) || (strcmp(key, GF_XATTR_USER_PATHINFO_KEY) == 0) || (strcmp(key, GF_XATTR_LOCKINFO_KEY) == 0) || (strcmp(key, GLUSTERFS_OPEN_FD_COUNT) == 0) || (strcmp(key, GLUSTERFS_INODELK_COUNT) == 0) || (strcmp(key, GLUSTERFS_ENTRYLK_COUNT) == 0) || (strncmp(key, GF_XATTR_CLRLK_CMD, SLEN(GF_XATTR_CLRLK_CMD)) == 0) || (strcmp(key, DHT_IATT_IN_XDATA_KEY) == 0) || (strncmp(key, EC_QUOTA_PREFIX, SLEN(EC_QUOTA_PREFIX)) == 0) || (fnmatch(MARKER_XATTR_PREFIX ".*." XTIME, key, 0) == 0) || (fnmatch(GF_XATTR_MARKER_KEY ".*", key, 0) == 0) || (XATTR_IS_NODE_UUID(key))) { return _gf_true; } return _gf_false; } int32_t ec_dict_compare(dict_t *dict1, dict_t *dict2) { if (are_dicts_equal(dict1, dict2, ec_xattr_match, NULL, ec_value_ignore)) return 1; return 0; } static uint32_t ec_dict_list(data_t **list, ec_cbk_data_t *cbk, int32_t which, char *key, gf_boolean_t global) { ec_t *ec = cbk->fop->xl->private; ec_cbk_data_t *ans = NULL; dict_t *dict = NULL; data_t *data; uint32_t count; int32_t i; for (i = 0; i < ec->nodes; i++) { /* We initialize the list with EC_MISSING_DATA if we are * returning a global list or the current subvolume belongs * to the group of the accepted answer. Note that if some * subvolume is known to be down before issuing the request, * we won't have any answer from it, so we set here the * appropriate default value. */ if (global || ((cbk->mask & (1ULL << i)) != 0)) { list[i] = EC_MISSING_DATA; } else { list[i] = NULL; } } count = 0; list_for_each_entry(ans, &cbk->fop->answer_list, answer_list) { if (global || ((cbk->mask & ans->mask) != 0)) { dict = (which == EC_COMBINE_XDATA) ? ans->xdata : ans->dict; data = dict_get(dict, key); if (data != NULL) { list[ans->idx] = data; count++; } } } return count; } int32_t ec_concat_prepare(xlator_t *xl, char **str, char **sep, char **post, const char *fmt, va_list args) { char *tmp; int32_t len; len = gf_vasprintf(str, fmt, args); if (len < 0) { return -ENOMEM; } tmp = strchr(*str, '{'); if (tmp == NULL) { goto out; } *tmp++ = 0; *sep = tmp; tmp = strchr(tmp, '}'); if (tmp == NULL) { goto out; } *tmp++ = 0; *post = tmp; return 0; out: gf_msg(xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_INVALID_FORMAT, "Invalid concat format"); GF_FREE(*str); return -EINVAL; } static int32_t ec_dict_data_concat(ec_cbk_data_t *cbk, int32_t which, char *key, char *new_key, const char *def, gf_boolean_t global, const char *fmt, ...) { ec_t *ec = cbk->fop->xl->private; data_t *data[ec->nodes]; char *str = NULL, *pre = NULL, *sep, *post; dict_t *dict; va_list args; int32_t i, num, len, deflen, prelen, postlen, seplen, tmp; int32_t err; ec_dict_list(data, cbk, which, key, global); va_start(args, fmt); err = ec_concat_prepare(cbk->fop->xl, &pre, &sep, &post, fmt, args); va_end(args); if (err != 0) { return err; } prelen = strlen(pre); seplen = strlen(sep); postlen = strlen(post); deflen = 0; if (def != NULL) { deflen = strlen(def); } len = prelen + postlen + 1; num = -1; for (i = 0; i < ec->nodes; i++) { if (data[i] == NULL) { continue; } if (data[i] == EC_MISSING_DATA) { if (def == NULL) { continue; } len += deflen; } else { len += data[i]->len - 1; } if (num >= 0) { len += seplen; } num++; } err = -ENOMEM; str = GF_MALLOC(len, gf_common_mt_char); if (str == NULL) { goto out; } memcpy(str, pre, prelen); len = prelen; for (i = 0; i < ec->nodes; i++) { if (data[i] == NULL) { continue; } if (data[i] == EC_MISSING_DATA) { if (deflen == 0) { continue; } tmp = deflen; memcpy(str + len, def, tmp); } else { tmp = data[i]->len - 1; memcpy(str + len, data[i]->data, tmp); } len += tmp; if (i < num) { memcpy(str + len, sep, seplen); len += seplen; } } memcpy(str + len, post, postlen + 1); dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; if (new_key) { key = new_key; } err = dict_set_dynstr(dict, key, str); if (err != 0) { goto out; } str = NULL; out: GF_FREE(str); GF_FREE(pre); return err; } int32_t ec_dict_data_merge(ec_cbk_data_t *cbk, int32_t which, char *key) { ec_t *ec = cbk->fop->xl->private; data_t *data[ec->nodes]; dict_t *dict, *lockinfo, *tmp = NULL; char *ptr = NULL; int32_t i, len; int32_t err; ec_dict_list(data, cbk, which, key, _gf_false); lockinfo = dict_new(); if (lockinfo == NULL) { return -ENOMEM; } for (i = 0; i < ec->nodes; i++) { if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { continue; } tmp = dict_new(); if (tmp == NULL) { err = -ENOMEM; goto out; } err = dict_unserialize(data[i]->data, data[i]->len, &tmp); if (err != 0) { goto out; } if (dict_copy(tmp, lockinfo) == NULL) { err = -ENOMEM; goto out; } dict_unref(tmp); } tmp = NULL; err = dict_allocate_and_serialize(lockinfo, (char **)&ptr, (unsigned int *)&len); if (err != 0) { goto out; } dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; err = dict_set_dynptr(dict, key, ptr, len); if (err != 0) { goto out; } ptr = NULL; out: GF_FREE(ptr); dict_unref(lockinfo); if (tmp != NULL) { dict_unref(tmp); } return err; } int32_t ec_dict_data_uuid(ec_cbk_data_t *cbk, int32_t which, char *key) { ec_cbk_data_t *ans, *min; dict_t *src, *dst; data_t *data; min = cbk; for (ans = cbk->next; ans != NULL; ans = ans->next) { if (ans->idx < min->idx) { min = ans; } } if (min != cbk) { src = (which == EC_COMBINE_XDATA) ? min->xdata : min->dict; dst = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; data = dict_get(src, key); if (data == NULL) { return -ENOENT; } if (dict_set(dst, key, data) != 0) { return -ENOMEM; } } return 0; } int32_t ec_dict_data_iatt(ec_cbk_data_t *cbk, int32_t which, char *key) { ec_t *ec = cbk->fop->xl->private; data_t *data[ec->nodes]; dict_t *dict; struct iatt *stbuf, *tmp; int32_t i, ret; ec_dict_list(data, cbk, which, key, _gf_false); stbuf = NULL; for (i = 0; i < ec->nodes; i++) { if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { continue; } tmp = data_to_iatt(data[i], key); if (tmp == NULL) { ret = -EINVAL; goto out; } if (stbuf == NULL) { stbuf = GF_MALLOC(sizeof(struct iatt), gf_common_mt_char); if (stbuf == NULL) { ret = -ENOMEM; goto out; } *stbuf = *tmp; } else { if (!ec_iatt_combine(cbk->fop, stbuf, tmp, 1)) { ret = -EINVAL; goto out; } } } if ((stbuf != NULL) && (stbuf->ia_type == IA_IFREG)) { ec_iatt_rebuild(ec, stbuf, 1, cbk->count); /* TODO: not sure if an iatt could come in xdata from a fop that takes * no locks. */ if (!ec_get_inode_size(cbk->fop, cbk->fop->locks[0].lock->loc.inode, &stbuf->ia_size)) { ret = -EINVAL; goto out; } } dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; ret = dict_set_iatt(dict, key, stbuf, false); if (ret >= 0) { stbuf = NULL; } out: GF_FREE(stbuf); return ret; } int32_t ec_dict_data_max32(ec_cbk_data_t *cbk, int32_t which, char *key) { ec_t *ec = cbk->fop->xl->private; data_t *data[ec->nodes]; dict_t *dict; int32_t i; uint32_t max, tmp; ec_dict_list(data, cbk, which, key, _gf_false); max = 0; for (i = 0; i < ec->nodes; i++) { if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { continue; } tmp = data_to_uint32(data[i]); if (max < tmp) { max = tmp; } } dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; return dict_set_uint32(dict, key, max); } int32_t ec_dict_data_max64(ec_cbk_data_t *cbk, int32_t which, char *key) { ec_t *ec = cbk->fop->xl->private; data_t *data[ec->nodes]; dict_t *dict; int32_t i; uint64_t max, tmp; ec_dict_list(data, cbk, which, key, _gf_false); max = 0; for (i = 0; i < ec->nodes; i++) { if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { continue; } tmp = data_to_uint64(data[i]); if (max < tmp) { max = tmp; } } dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; return dict_set_uint64(dict, key, max); } int32_t ec_dict_data_quota(ec_cbk_data_t *cbk, int32_t which, char *key) { ec_t *ec = cbk->fop->xl->private; data_t *data[ec->nodes]; dict_t *dict = NULL; int32_t i = 0; quota_meta_t size = { 0, }; quota_meta_t max_size = { 0, }; if (ec_dict_list(data, cbk, which, key, _gf_false) == 0) { return 0; } /* Quota size xattr is managed outside of the control of the ec xlator. * This means that it might not be updated at the same time on all * bricks and we can receive slightly different values. If that's the * case, we take the maximum of all received values. */ for (i = 0; i < ec->nodes; i++) { if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA) || (quota_data_to_meta(data[i], &size) < 0)) { continue; } if (size.size > max_size.size) max_size.size = size.size; if (size.file_count > max_size.file_count) max_size.file_count = size.file_count; if (size.dir_count > max_size.dir_count) max_size.dir_count = size.dir_count; } max_size.size *= ec->fragments; dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; return quota_dict_set_meta(dict, key, &max_size, IA_IFDIR); } int32_t ec_dict_data_stime(ec_cbk_data_t *cbk, int32_t which, char *key) { ec_t *ec = cbk->fop->xl->private; data_t *data[ec->nodes]; dict_t *dict; int32_t i, err; ec_dict_list(data, cbk, which, key, _gf_false); dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; for (i = 0; i < ec->nodes; i++) { if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { continue; } err = gf_get_max_stime(cbk->fop->xl, dict, key, data[i]); if (err != 0) { gf_msg(cbk->fop->xl->name, GF_LOG_ERROR, -err, EC_MSG_STIME_COMBINE_FAIL, "STIME combination failed"); return err; } } return 0; } int32_t ec_dict_data_combine(dict_t *dict, char *key, data_t *value, void *arg) { ec_dict_combine_t *data = arg; if ((strcmp(key, GF_XATTR_PATHINFO_KEY) == 0) || (strcmp(key, GF_XATTR_USER_PATHINFO_KEY) == 0)) { return ec_dict_data_concat(data->cbk, data->which, key, NULL, NULL, _gf_false, _gf_false, "( { })", data->cbk->fop->xl->name); } if (strncmp(key, GF_XATTR_CLRLK_CMD, SLEN(GF_XATTR_CLRLK_CMD)) == 0) { return ec_dict_data_concat(data->cbk, data->which, key, NULL, NULL, _gf_false, "{\n}"); } if (strncmp(key, GF_XATTR_LOCKINFO_KEY, SLEN(GF_XATTR_LOCKINFO_KEY)) == 0) { return ec_dict_data_merge(data->cbk, data->which, key); } if (strcmp(key, GET_LINK_COUNT) == 0) { return ec_dict_data_max32(data->cbk, data->which, key); } if (strcmp(key, GLUSTERFS_OPEN_FD_COUNT) == 0) { return ec_dict_data_max32(data->cbk, data->which, key); } if ((strcmp(key, GLUSTERFS_INODELK_COUNT) == 0) || (strcmp(key, GLUSTERFS_ENTRYLK_COUNT) == 0)) { return ec_dict_data_max32(data->cbk, data->which, key); } if (strcmp(key, QUOTA_SIZE_KEY) == 0) { return ec_dict_data_quota(data->cbk, data->which, key); } /* Ignore all other quota attributes */ if (strncmp(key, EC_QUOTA_PREFIX, SLEN(EC_QUOTA_PREFIX)) == 0) { return 0; } if (XATTR_IS_NODE_UUID(key)) { if (data->cbk->fop->int32) { /* List of node uuid is requested */ return ec_dict_data_concat(data->cbk, data->which, key, GF_XATTR_LIST_NODE_UUIDS_KEY, UUID0_STR, _gf_true, "{ }"); } else { return ec_dict_data_uuid(data->cbk, data->which, key); } } if (fnmatch(GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0) { return ec_dict_data_stime(data->cbk, data->which, key); } if (fnmatch(MARKER_XATTR_PREFIX ".*." XTIME, key, FNM_NOESCAPE) == 0) { return ec_dict_data_max64(data->cbk, data->which, key); } if (strcmp(key, GF_PRESTAT) == 0 || strcmp(key, GF_POSTSTAT) == 0) { return ec_dict_data_iatt(data->cbk, data->which, key); } return 0; } int32_t ec_dict_combine(ec_cbk_data_t *cbk, int32_t which) { dict_t *dict = NULL; ec_dict_combine_t data; int32_t err = 0; data.cbk = cbk; data.which = which; dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; if (dict != NULL) { err = dict_foreach(dict, ec_dict_data_combine, &data); if (err != 0) { gf_msg(cbk->fop->xl->name, GF_LOG_ERROR, -err, EC_MSG_DICT_COMBINE_FAIL, "Dictionary combination failed"); return err; } } return 0; } int32_t ec_vector_compare(struct iovec *dst_vector, int32_t dst_count, struct iovec *src_vector, int32_t src_count) { int32_t dst_size = 0, src_size = 0; if (dst_count > 0) { dst_size = iov_length(dst_vector, dst_count); } if (src_count > 0) { src_size = iov_length(src_vector, src_count); } return (dst_size == src_size); } int32_t ec_flock_compare(struct gf_flock *dst, struct gf_flock *src) { if ((dst->l_type != src->l_type) || (dst->l_whence != src->l_whence) || (dst->l_start != src->l_start) || (dst->l_len != src->l_len) || (dst->l_pid != src->l_pid) || !is_same_lkowner(&dst->l_owner, &src->l_owner)) { return 0; } return 1; } void ec_statvfs_combine(struct statvfs *dst, struct statvfs *src) { if (dst->f_bsize < src->f_bsize) { dst->f_bsize = src->f_bsize; } if (dst->f_frsize < src->f_frsize) { dst->f_blocks *= dst->f_frsize; dst->f_blocks /= src->f_frsize; dst->f_bfree *= dst->f_frsize; dst->f_bfree /= src->f_frsize; dst->f_bavail *= dst->f_frsize; dst->f_bavail /= src->f_frsize; dst->f_frsize = src->f_frsize; } else if (dst->f_frsize > src->f_frsize) { src->f_blocks *= src->f_frsize; src->f_blocks /= dst->f_frsize; src->f_bfree *= src->f_frsize; src->f_bfree /= dst->f_frsize; src->f_bavail *= src->f_frsize; src->f_bavail /= dst->f_frsize; } if (dst->f_blocks > src->f_blocks) { dst->f_blocks = src->f_blocks; } if (dst->f_bfree > src->f_bfree) { dst->f_bfree = src->f_bfree; } if (dst->f_bavail > src->f_bavail) { dst->f_bavail = src->f_bavail; } if (dst->f_files < src->f_files) { dst->f_files = src->f_files; } if (dst->f_ffree > src->f_ffree) { dst->f_ffree = src->f_ffree; } if (dst->f_favail > src->f_favail) { dst->f_favail = src->f_favail; } if (dst->f_namemax > src->f_namemax) { dst->f_namemax = src->f_namemax; } if (dst->f_flag != src->f_flag) { gf_msg_debug(THIS->name, 0, "Mismatching file system flags " "(%lX, %lX)", dst->f_flag, src->f_flag); } dst->f_flag &= src->f_flag; } int32_t ec_combine_check(ec_cbk_data_t *dst, ec_cbk_data_t *src, ec_combine_f combine) { ec_fop_data_t *fop = dst->fop; if (dst->op_ret != src->op_ret) { gf_msg_debug(fop->xl->name, 0, "Mismatching return code in " "answers of '%s': %d <-> %d", ec_fop_name(fop->id), dst->op_ret, src->op_ret); return 0; } if (dst->op_ret < 0) { if (dst->op_errno != src->op_errno) { gf_msg_debug(fop->xl->name, 0, "Mismatching errno code in " "answers of '%s': %d <-> %d", ec_fop_name(fop->id), dst->op_errno, src->op_errno); return 0; } } if (!ec_dict_compare(dst->xdata, src->xdata)) { gf_msg(fop->xl->name, GF_LOG_DEBUG, 0, EC_MSG_XDATA_MISMATCH, "Mismatching xdata in answers " "of '%s'", ec_fop_name(fop->id)); return 0; } if ((dst->op_ret >= 0) && (combine != NULL)) { return combine(fop, dst, src); } return 1; } void ec_combine(ec_cbk_data_t *newcbk, ec_combine_f combine) { ec_fop_data_t *fop = newcbk->fop; ec_cbk_data_t *cbk = NULL, *tmp = NULL; struct list_head *item = NULL; int32_t needed = 0; char str[32]; LOCK(&fop->lock); fop->received |= newcbk->mask; item = fop->cbk_list.prev; list_for_each_entry(cbk, &fop->cbk_list, list) { if (ec_combine_check(newcbk, cbk, combine)) { newcbk->count += cbk->count; newcbk->mask |= cbk->mask; item = cbk->list.prev; while (item != &fop->cbk_list) { tmp = list_entry(item, ec_cbk_data_t, list); if (tmp->count >= newcbk->count) { break; } item = item->prev; } list_del(&cbk->list); newcbk->next = cbk; break; } } list_add(&newcbk->list, item); ec_trace("ANSWER", fop, "combine=%s[%d]", ec_bin(str, sizeof(str), newcbk->mask, 0), newcbk->count); cbk = list_entry(fop->cbk_list.next, ec_cbk_data_t, list); if ((fop->mask ^ fop->remaining) == fop->received) { needed = fop->minimum - cbk->count; } UNLOCK(&fop->lock); if (needed > 0) { ec_dispatch_next(fop, newcbk->idx); } } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202462022762 xustar000000000000000030 mtime=1699284274.640054459 30 atime=1699284289.133098112 30 ctime=1699284301.318134812 glusterfs-11.1/xlators/cluster/ec/src/Makefile.in0000664000175100017510000007217014522202462023250 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_EC_DYNAMIC_INTEL_TRUE@am__append_1 = ec-code-intel.c @ENABLE_EC_DYNAMIC_INTEL_TRUE@am__append_2 = ec-code-intel.h @ENABLE_EC_DYNAMIC_X64_TRUE@am__append_3 = ec-code-x64.c @ENABLE_EC_DYNAMIC_X64_TRUE@am__append_4 = ec-code-x64.h @ENABLE_EC_DYNAMIC_SSE_TRUE@am__append_5 = ec-code-sse.c @ENABLE_EC_DYNAMIC_SSE_TRUE@am__append_6 = ec-code-sse.h @ENABLE_EC_DYNAMIC_AVX_TRUE@am__append_7 = ec-code-avx.c @ENABLE_EC_DYNAMIC_AVX_TRUE@am__append_8 = ec-code-avx.h subdir = xlators/cluster/ec/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) ec_la_DEPENDENCIES = $(top_builddir)/libglusterfs/src/libglusterfs.la am__ec_la_SOURCES_DIST = ec.c ec-data.c ec-helpers.c ec-common.c \ ec-generic.c ec-locks.c ec-dir-read.c ec-dir-write.c \ ec-inode-read.c ec-inode-write.c ec-combine.c ec-method.c \ ec-galois.c ec-code.c ec-code-c.c ec-gf8.c ec-heal.c \ ec-heald.c ec-code-intel.c ec-code-x64.c ec-code-sse.c \ ec-code-avx.c ec.h ec-mem-types.h ec-helpers.h ec-data.h \ ec-fops.h ec-common.h ec-combine.h ec-method.h ec-galois.h \ ec-code.h ec-code-c.h ec-gf8.h ec-heald.h ec-messages.h \ ec-types.h ec-code-intel.h ec-code-x64.h ec-code-sse.h \ ec-code-avx.h $(top_builddir)/xlators/lib/src/libxlator.c \ $(top_builddir)/xlators/lib/src/libxlator.h @ENABLE_EC_DYNAMIC_INTEL_TRUE@am__objects_1 = ec-code-intel.lo @ENABLE_EC_DYNAMIC_X64_TRUE@am__objects_2 = ec-code-x64.lo @ENABLE_EC_DYNAMIC_SSE_TRUE@am__objects_3 = ec-code-sse.lo @ENABLE_EC_DYNAMIC_AVX_TRUE@am__objects_4 = ec-code-avx.lo am__objects_5 = ec.lo ec-data.lo ec-helpers.lo ec-common.lo \ ec-generic.lo ec-locks.lo ec-dir-read.lo ec-dir-write.lo \ ec-inode-read.lo ec-inode-write.lo ec-combine.lo ec-method.lo \ ec-galois.lo ec-code.lo ec-code-c.lo ec-gf8.lo ec-heal.lo \ ec-heald.lo $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) am__objects_6 = am__objects_7 = $(am__objects_6) $(am__objects_6) $(am__objects_6) \ $(am__objects_6) am__objects_8 = libxlator.lo am_ec_la_OBJECTS = $(am__objects_5) $(am__objects_7) $(am__objects_8) \ $(am__objects_6) ec_la_OBJECTS = $(am_ec_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = ec_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(ec_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(ec_la_SOURCES) DIST_SOURCES = $(am__ec_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = ec.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster ec_sources := ec.c ec-data.c ec-helpers.c ec-common.c ec-generic.c \ ec-locks.c ec-dir-read.c ec-dir-write.c ec-inode-read.c \ ec-inode-write.c ec-combine.c ec-method.c ec-galois.c \ ec-code.c ec-code-c.c ec-gf8.c ec-heal.c ec-heald.c \ $(am__append_1) $(am__append_3) $(am__append_5) \ $(am__append_7) ec_headers := ec.h ec-mem-types.h ec-helpers.h ec-data.h ec-fops.h \ ec-common.h ec-combine.h ec-method.h ec-galois.h ec-code.h \ ec-code-c.h ec-gf8.h ec-heald.h ec-messages.h ec-types.h \ $(am__append_2) $(am__append_4) $(am__append_6) \ $(am__append_8) ec_ext_sources = $(top_builddir)/xlators/lib/src/libxlator.c ec_ext_headers = $(top_builddir)/xlators/lib/src/libxlator.h ec_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) ec_la_SOURCES = $(ec_sources) $(ec_headers) $(ec_ext_sources) $(ec_ext_headers) ec_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/lib/src \ -I$(top_srcdir)/rpc/rpc-lib/src -I$(top_srcdir)/rpc/xdr/src \ -I$(top_builddir)/rpc/xdr/src \ -DGLUSTERFS_LIBEXECDIR=\"$(GLUSTERFS_LIBEXECDIR)\" AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/cluster/ec/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/cluster/ec/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } ec.la: $(ec_la_OBJECTS) $(ec_la_DEPENDENCIES) $(EXTRA_ec_la_DEPENDENCIES) $(AM_V_CCLD)$(ec_la_LINK) -rpath $(xlatordir) $(ec_la_OBJECTS) $(ec_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-code-avx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-code-c.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-code-intel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-code-sse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-code-x64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-code.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-combine.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-dir-read.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-dir-write.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-galois.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-generic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-gf8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-heal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-heald.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-inode-read.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-inode-write.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-locks.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-method.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxlator.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libxlator.lo: $(top_builddir)/xlators/lib/src/libxlator.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxlator.lo -MD -MP -MF $(DEPDIR)/libxlator.Tpo -c -o libxlator.lo `test -f '$(top_builddir)/xlators/lib/src/libxlator.c' || echo '$(srcdir)/'`$(top_builddir)/xlators/lib/src/libxlator.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxlator.Tpo $(DEPDIR)/libxlator.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_builddir)/xlators/lib/src/libxlator.c' object='libxlator.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxlator.lo `test -f '$(top_builddir)/xlators/lib/src/libxlator.c' || echo '$(srcdir)/'`$(top_builddir)/xlators/lib/src/libxlator.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-xlatorLTLIBRARIES .MAKE: install-am install-data-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-hook install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-local uninstall-xlatorLTLIBRARIES install-data-hook: ln -sf ec.so $(DESTDIR)$(xlatordir)/disperse.so uninstall-local: rm -f $(DESTDIR)$(xlatordir)/disperse.so # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code.h0000644000000000000000000000013214522202451022363 xustar000000000000000030 mtime=1699284265.634027332 30 atime=1699284265.634027332 30 ctime=1699284301.366134957 glusterfs-11.1/xlators/cluster/ec/src/ec-code.h0000664000175100017510000000220714522202451022643 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_CODE_H__ #define __EC_CODE_H__ #include #include "ec-types.h" #include "ec-galois.h" ec_code_gen_t * ec_code_detect(xlator_t *xl, const char *def); ec_code_t * ec_code_create(ec_gf_t *gf, ec_code_gen_t *gen); void ec_code_destroy(ec_code_t *code); ec_code_func_linear_t ec_code_build_linear(ec_code_t *code, uint32_t width, uint32_t *values, uint32_t count); ec_code_func_interleaved_t ec_code_build_interleaved(ec_code_t *code, uint32_t width, uint32_t *values, uint32_t count); void ec_code_release(ec_code_t *code, ec_code_func_t *func); void ec_code_error(ec_code_builder_t *builder, int32_t error); void ec_code_emit(ec_code_builder_t *builder, uint8_t *bytes, uint32_t count); #endif /* __EC_CODE_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-intel.h0000644000000000000000000000013214522202451023474 xustar000000000000000030 mtime=1699284265.633027329 30 atime=1699284265.633027329 30 ctime=1699284301.374134981 glusterfs-11.1/xlators/cluster/ec/src/ec-code-intel.h0000664000175100017510000001307314522202451023757 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_CODE_INTEL_H__ #define __EC_CODE_INTEL_H__ #include "ec-code.h" #define VEX_REG_NONE 0 enum _ec_code_intel_reg; typedef enum _ec_code_intel_reg ec_code_intel_reg_t; enum _ec_code_vex_prefix; typedef enum _ec_code_vex_prefix ec_code_vex_prefix_t; enum _ec_code_vex_opcode; typedef enum _ec_code_vex_opcode ec_code_vex_opcode_t; struct _ec_code_intel_buffer; typedef struct _ec_code_intel_buffer ec_code_intel_buffer_t; struct _ec_code_intel_sib; typedef struct _ec_code_intel_sib ec_code_intel_sib_t; struct _ec_code_intel_modrm; typedef struct _ec_code_intel_modrm ec_code_intel_modrm_t; struct _ec_code_intel_rex; typedef struct _ec_code_intel_rex ec_code_intel_rex_t; struct _ec_code_intel; typedef struct _ec_code_intel ec_code_intel_t; enum _ec_code_intel_reg { REG_NULL = -1, REG_AX, REG_CX, REG_DX, REG_BX, REG_SP, REG_BP, REG_SI, REG_DI, REG_8, REG_9, REG_10, REG_11, REG_12, REG_13, REG_14, REG_15 }; enum _ec_code_vex_prefix { VEX_PREFIX_NONE = 0, VEX_PREFIX_66, VEX_PREFIX_F3, VEX_PREFIX_F2 }; enum _ec_code_vex_opcode { VEX_OPCODE_NONE = 0, VEX_OPCODE_0F, VEX_OPCODE_0F_38, VEX_OPCODE_0F_3A }; struct _ec_code_intel_buffer { uint32_t bytes; union { uint8_t data[4]; uint32_t value; }; }; struct _ec_code_intel_sib { gf_boolean_t present; uint32_t base; uint32_t index; uint32_t scale; }; struct _ec_code_intel_modrm { gf_boolean_t present; uint32_t mod; uint32_t rm; uint32_t reg; }; struct _ec_code_intel_rex { gf_boolean_t present; uint32_t w; uint32_t r; uint32_t x; uint32_t b; }; struct _ec_code_intel { gf_boolean_t invalid; ec_code_intel_buffer_t prefix; ec_code_intel_buffer_t opcode; ec_code_intel_buffer_t offset; ec_code_intel_buffer_t immediate; ec_code_intel_buffer_t vex; ec_code_intel_rex_t rex; ec_code_intel_modrm_t modrm; ec_code_intel_sib_t sib; uint32_t reg; }; void ec_code_intel_op_push_r(ec_code_builder_t *builder, ec_code_intel_reg_t reg); void ec_code_intel_op_pop_r(ec_code_builder_t *builder, ec_code_intel_reg_t reg); void ec_code_intel_op_ret(ec_code_builder_t *builder, uint32_t size); void ec_code_intel_op_mov_r2r(ec_code_builder_t *builder, ec_code_intel_reg_t src, ec_code_intel_reg_t dst); void ec_code_intel_op_mov_r2m(ec_code_builder_t *builder, ec_code_intel_reg_t src, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset); void ec_code_intel_op_mov_m2r(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, ec_code_intel_reg_t dst); void ec_code_intel_op_xor_r2r(ec_code_builder_t *builder, ec_code_intel_reg_t src, ec_code_intel_reg_t dst); void ec_code_intel_op_xor_m2r(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, ec_code_intel_reg_t dst); void ec_code_intel_op_add_i2r(ec_code_builder_t *builder, int32_t value, ec_code_intel_reg_t reg); void ec_code_intel_op_test_i2r(ec_code_builder_t *builder, uint32_t value, ec_code_intel_reg_t reg); void ec_code_intel_op_jne(ec_code_builder_t *builder, uint32_t address); void ec_code_intel_op_mov_sse2sse(ec_code_builder_t *builder, uint32_t src, uint32_t dst); void ec_code_intel_op_mov_sse2m(ec_code_builder_t *builder, uint32_t src, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset); void ec_code_intel_op_mov_m2sse(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, uint32_t dst); void ec_code_intel_op_xor_sse2sse(ec_code_builder_t *builder, uint32_t src, uint32_t dst); void ec_code_intel_op_xor_m2sse(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, uint32_t dst); void ec_code_intel_op_mov_avx2avx(ec_code_builder_t *builder, uint32_t src, uint32_t dst); void ec_code_intel_op_mov_avx2m(ec_code_builder_t *builder, uint32_t src, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset); void ec_code_intel_op_mov_m2avx(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, uint32_t dst); void ec_code_intel_op_xor_avx2avx(ec_code_builder_t *builder, uint32_t src, uint32_t dst); void ec_code_intel_op_xor_m2avx(ec_code_builder_t *builder, ec_code_intel_reg_t base, ec_code_intel_reg_t index, uint32_t scale, int32_t offset, uint32_t dst); #endif /* __EC_CODE_INTEL_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451022747 xustar000000000000000030 mtime=1699284265.631027323 30 atime=1699284274.593054317 30 ctime=1699284301.320134818 glusterfs-11.1/xlators/cluster/ec/src/Makefile.am0000664000175100017510000000413214522202451023226 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = ec.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster ec_sources := ec.c ec_sources += ec-data.c ec_sources += ec-helpers.c ec_sources += ec-common.c ec_sources += ec-generic.c ec_sources += ec-locks.c ec_sources += ec-dir-read.c ec_sources += ec-dir-write.c ec_sources += ec-inode-read.c ec_sources += ec-inode-write.c ec_sources += ec-combine.c ec_sources += ec-method.c ec_sources += ec-galois.c ec_sources += ec-code.c ec_sources += ec-code-c.c ec_sources += ec-gf8.c ec_sources += ec-heal.c ec_sources += ec-heald.c ec_headers := ec.h ec_headers += ec-mem-types.h ec_headers += ec-helpers.h ec_headers += ec-data.h ec_headers += ec-fops.h ec_headers += ec-common.h ec_headers += ec-combine.h ec_headers += ec-method.h ec_headers += ec-galois.h ec_headers += ec-code.h ec_headers += ec-code-c.h ec_headers += ec-gf8.h ec_headers += ec-heald.h ec_headers += ec-messages.h ec_headers += ec-types.h if ENABLE_EC_DYNAMIC_INTEL ec_sources += ec-code-intel.c ec_headers += ec-code-intel.h endif if ENABLE_EC_DYNAMIC_X64 ec_sources += ec-code-x64.c ec_headers += ec-code-x64.h endif if ENABLE_EC_DYNAMIC_SSE ec_sources += ec-code-sse.c ec_headers += ec-code-sse.h endif if ENABLE_EC_DYNAMIC_AVX ec_sources += ec-code-avx.c ec_headers += ec-code-avx.h endif ec_ext_sources = $(top_builddir)/xlators/lib/src/libxlator.c ec_ext_headers = $(top_builddir)/xlators/lib/src/libxlator.h ec_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) ec_la_SOURCES = $(ec_sources) $(ec_headers) $(ec_ext_sources) $(ec_ext_headers) ec_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la AM_CPPFLAGS = $(GF_CPPFLAGS) AM_CPPFLAGS += -I$(top_srcdir)/libglusterfs/src AM_CPPFLAGS += -I$(top_srcdir)/xlators/lib/src AM_CPPFLAGS += -I$(top_srcdir)/rpc/rpc-lib/src AM_CPPFLAGS += -I$(top_srcdir)/rpc/xdr/src AM_CPPFLAGS += -I$(top_builddir)/rpc/xdr/src AM_CPPFLAGS += -DGLUSTERFS_LIBEXECDIR=\"$(GLUSTERFS_LIBEXECDIR)\" AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = install-data-hook: ln -sf ec.so $(DESTDIR)$(xlatordir)/disperse.so uninstall-local: rm -f $(DESTDIR)$(xlatordir)/disperse.so glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec.h0000644000000000000000000000013214522202451021453 xustar000000000000000030 mtime=1699284265.643027359 30 atime=1699284265.643027359 30 ctime=1699284301.353134918 glusterfs-11.1/xlators/cluster/ec/src/ec.h0000664000175100017510000000222114522202451021727 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_H__ #define __EC_H__ #include "ec-method.h" #define EC_XATTR_PREFIX "trusted.ec." #define EC_XATTR_CONFIG EC_XATTR_PREFIX "config" #define EC_XATTR_SIZE EC_XATTR_PREFIX "size" #define EC_XATTR_VERSION EC_XATTR_PREFIX "version" #define EC_XATTR_HEAL EC_XATTR_PREFIX "heal" #define EC_XATTR_HEAL_NEW EC_XATTR_PREFIX "heal-new" #define EC_XATTR_DIRTY EC_XATTR_PREFIX "dirty" #define EC_STRIPE_CACHE_MAX_SIZE 10 #define EC_VERSION_SIZE 2 #define EC_SHD_INODE_LRU_LIMIT 10 #define EC_MAX_FRAGMENTS EC_METHOD_MAX_FRAGMENTS /* The maximum number of nodes is derived from the maximum allowed fragments * using the rule that redundancy cannot be equal or greater than the number * of fragments. */ #define EC_MAX_NODES min(EC_MAX_FRAGMENTS * 2 - 1, EC_METHOD_MAX_NODES) #endif /* __EC_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-combine.h0000644000000000000000000000013214522202451023065 xustar000000000000000030 mtime=1699284265.634027332 30 atime=1699284265.634027332 30 ctime=1699284301.362134945 glusterfs-11.1/xlators/cluster/ec/src/ec-combine.h0000664000175100017510000000251614522202451023350 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_COMBINE_H__ #define __EC_COMBINE_H__ #define EC_COMBINE_DICT 0 #define EC_COMBINE_XDATA 1 typedef int32_t (*ec_combine_f)(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src); void ec_iatt_rebuild(ec_t *ec, struct iatt *iatt, int32_t count, int32_t answers); int32_t ec_iatt_combine(ec_fop_data_t *fop, struct iatt *dst, struct iatt *src, int32_t count); int32_t ec_dict_compare(dict_t *dict1, dict_t *dict2); int32_t ec_vector_compare(struct iovec *dst_vector, int32_t dst_count, struct iovec *src_vector, int32_t src_count); int32_t ec_flock_compare(struct gf_flock *dst, struct gf_flock *src); void ec_statvfs_combine(struct statvfs *dst, struct statvfs *src); int32_t ec_dict_combine(ec_cbk_data_t *cbk, int32_t which); void ec_combine(ec_cbk_data_t *cbk, ec_combine_f combine); int32_t ec_combine_write(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src); #endif /* __EC_COMBINE_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-common.h0000644000000000000000000000013214522202451022741 xustar000000000000000030 mtime=1699284265.635027335 30 atime=1699284265.635027335 30 ctime=1699284301.361134942 glusterfs-11.1/xlators/cluster/ec/src/ec-common.h0000664000175100017510000001617614522202451023233 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_COMMON_H__ #define __EC_COMMON_H__ #include "glusterfs/compat-errno.h" // for ENODATA on BSD #include "ec-data.h" typedef enum { EC_DATA_TXN, EC_METADATA_TXN } ec_txn_t; #define EC_FOP_HEAL -1 #define EC_FOP_FHEAL -2 #define EC_CONFIG_VERSION 0 #define EC_CONFIG_ALGORITHM 0 #define EC_FLAG_LOCK_SHARED 0x0001 #define QUORUM_CBK(fn, fop, frame, cookie, this, op_ret, op_errno, params...) \ do { \ ec_t *__ec = fop->xl->private; \ int32_t __op_ret = 0; \ int32_t __op_errno = 0; \ int32_t __success_count = gf_bits_count(fop->good); \ \ __op_ret = op_ret; \ __op_errno = op_errno; \ if (!fop->parent && frame && \ (GF_CLIENT_PID_SELF_HEALD != frame->root->pid) && \ __ec->quorum_count && (__success_count < __ec->quorum_count) && \ op_ret >= 0) { \ __op_ret = -1; \ __op_errno = EIO; \ gf_msg(__ec->xl->name, GF_LOG_ERROR, 0, \ EC_MSG_CHILDS_INSUFFICIENT, \ "Insufficient available children for this request " \ "(have %d, need %d). %s", \ __success_count, __ec->quorum_count, ec_msg_str(fop)); \ } \ fn(frame, cookie, this, __op_ret, __op_errno, params); \ } while (0) enum _ec_xattrop_flags { EC_FLAG_XATTROP, EC_FLAG_DATA_DIRTY, EC_FLAG_METADATA_DIRTY, /* Add any new flag here, before EC_FLAG_MAX. The maximum number of * flags that can be defined is 16. */ EC_FLAG_MAX }; /* We keep two sets of flags. One to determine what's really providing the * current xattrop and the other to know what the parent fop of the xattrop * needs to proceed. It might happen that a fop needs some information that * is being already requested by a previous fop. The two sets are stored * contiguously. */ #define EC_FLAG_NEEDS(_flag) (1 << (_flag)) #define EC_FLAG_PROVIDES(_flag) (1 << ((_flag) + EC_FLAG_MAX)) #define EC_NEEDED_FLAGS(_flags) ((_flags) & ((1 << EC_FLAG_MAX) - 1)) #define EC_PROVIDED_FLAGS(_flags) EC_NEEDED_FLAGS((_flags) >> EC_FLAG_MAX) #define EC_FLAGS_HAVE(_flags, _flag) (((_flags) & (1 << (_flag))) != 0) #define EC_SELFHEAL_BIT 62 #define EC_MINIMUM_ONE (1 << 6) #define EC_MINIMUM_MIN (2 << 6) #define EC_MINIMUM_ALL (3 << 6) #define EC_FOP_NO_PROPAGATE_ERROR (1 << 8) #define EC_FOP_MINIMUM(_flags) ((_flags)&255) #define EC_FOP_FLAGS(_flags) ((_flags) & ~255) #define EC_UPDATE_DATA 1 #define EC_UPDATE_META 2 #define EC_QUERY_INFO 4 #define EC_INODE_SIZE 8 #define EC_STATE_START 0 #define EC_STATE_END 0 #define EC_STATE_INIT 1 #define EC_STATE_LOCK 2 #define EC_STATE_DISPATCH 3 #define EC_STATE_PREPARE_ANSWER 4 #define EC_STATE_REPORT 5 #define EC_STATE_LOCK_REUSE 6 #define EC_STATE_UNLOCK 7 #define EC_STATE_DELAYED_START 100 #define EC_STATE_HEAL_ENTRY_LOOKUP 200 #define EC_STATE_HEAL_ENTRY_PREPARE 201 #define EC_STATE_HEAL_PRE_INODELK_LOCK 202 #define EC_STATE_HEAL_PRE_INODE_LOOKUP 203 #define EC_STATE_HEAL_XATTRIBUTES_REMOVE 204 #define EC_STATE_HEAL_XATTRIBUTES_SET 205 #define EC_STATE_HEAL_ATTRIBUTES 206 #define EC_STATE_HEAL_OPEN 207 #define EC_STATE_HEAL_REOPEN_FD 208 #define EC_STATE_HEAL_UNLOCK 209 #define EC_STATE_HEAL_UNLOCK_ENTRY 210 #define EC_STATE_HEAL_DATA_LOCK 211 #define EC_STATE_HEAL_DATA_COPY 212 #define EC_STATE_HEAL_DATA_UNLOCK 213 #define EC_STATE_HEAL_POST_INODELK_LOCK 214 #define EC_STATE_HEAL_POST_INODE_LOOKUP 215 #define EC_STATE_HEAL_SETATTR 216 #define EC_STATE_HEAL_POST_INODELK_UNLOCK 217 #define EC_STATE_HEAL_DISPATCH 218 /* Value to cover the full range of a file */ #define EC_RANGE_FULL ((uint64_t)LLONG_MAX + 1) gf_boolean_t ec_dispatch_one_retry(ec_fop_data_t *fop, ec_cbk_data_t **cbk); void ec_dispatch_next(ec_fop_data_t *fop, uint32_t idx); void ec_complete(ec_fop_data_t *fop); void ec_update_good(ec_fop_data_t *fop, uintptr_t good); void ec_fop_set_error(ec_fop_data_t *fop, int32_t error); void __ec_fop_set_error(ec_fop_data_t *fop, int32_t error); ec_cbk_data_t * ec_fop_prepare_answer(ec_fop_data_t *fop, gf_boolean_t ro); gf_boolean_t ec_cbk_set_error(ec_cbk_data_t *cbk, int32_t error, gf_boolean_t ro); void ec_lock_prepare_inode(ec_fop_data_t *fop, loc_t *loc, uint32_t flags, off_t fl_start, uint64_t fl_size); void ec_lock_prepare_parent_inode(ec_fop_data_t *fop, loc_t *loc, loc_t *base, uint32_t flags); void ec_lock_prepare_fd(ec_fop_data_t *fop, fd_t *fd, uint32_t flags, off_t fl_start, uint64_t fl_size); void ec_lock(ec_fop_data_t *fop); void ec_lock_reuse(ec_fop_data_t *fop); void ec_unlock(ec_fop_data_t *fop); void ec_lock_release(ec_t *ec, inode_t *inode); gf_boolean_t ec_get_inode_size(ec_fop_data_t *fop, inode_t *inode, uint64_t *size); gf_boolean_t __ec_get_inode_size(ec_fop_data_t *fop, inode_t *inode, uint64_t *size); gf_boolean_t ec_set_inode_size(ec_fop_data_t *fop, inode_t *inode, uint64_t size); gf_boolean_t __ec_set_inode_size(ec_fop_data_t *fop, inode_t *inode, uint64_t size); void ec_clear_inode_info(ec_fop_data_t *fop, inode_t *inode); void ec_flush_size_version(ec_fop_data_t *fop); void ec_dispatch_all(ec_fop_data_t *fop); void ec_dispatch_inc(ec_fop_data_t *fop); void ec_dispatch_min(ec_fop_data_t *fop); void ec_dispatch_one(ec_fop_data_t *fop); void ec_succeed_all(ec_fop_data_t *fop); void ec_sleep(ec_fop_data_t *fop); void ec_resume(ec_fop_data_t *fop, int32_t error); void ec_resume_parent(ec_fop_data_t *fop); void ec_manager(ec_fop_data_t *fop, int32_t error); void ec_handle_healers_done(ec_fop_data_t *fop); int32_t ec_get_heal_info(xlator_t *this, loc_t *loc, dict_t **dict); int32_t ec_lock_unlocked(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata); void ec_update_fd_status(fd_t *fd, xlator_t *xl, int child_index, int32_t ret_status); char * ec_msg_str(ec_fop_data_t *fop); gf_boolean_t __ec_is_last_fop(ec_t *ec); void ec_lock_update_good(ec_lock_t *lock, ec_fop_data_t *fop); #endif /* __EC_COMMON_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-fops.h0000644000000000000000000000013214522202451022420 xustar000000000000000030 mtime=1699284265.637027341 30 atime=1699284265.637027341 30 ctime=1699284301.359134936 glusterfs-11.1/xlators/cluster/ec/src/ec-fops.h0000664000175100017510000002325514522202451022706 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_FOPS_H__ #define __EC_FOPS_H__ #include "ec-types.h" #include "ec-common.h" void ec_access(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_access_cbk_t func, void *data, loc_t *loc, int32_t mask, dict_t *xdata); void ec_create(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_create_cbk_t func, void *data, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata); void ec_entrylk(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_entrylk_cbk_t func, void *data, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata); void ec_fentrylk(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fentrylk_cbk_t func, void *data, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata); void ec_flush(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_flush_cbk_t func, void *data, fd_t *fd, dict_t *xdata); void ec_fsync(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fsync_cbk_t func, void *data, fd_t *fd, int32_t datasync, dict_t *xdata); void ec_fsyncdir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fsyncdir_cbk_t func, void *data, fd_t *fd, int32_t datasync, dict_t *xdata); void ec_getxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_getxattr_cbk_t func, void *data, loc_t *loc, const char *name, dict_t *xdata); void ec_fgetxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fgetxattr_cbk_t func, void *data, fd_t *fd, const char *name, dict_t *xdata); void ec_heal(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_heal_cbk_t func, void *data, loc_t *loc, int32_t partial, dict_t *xdata); void ec_fheal(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fheal_cbk_t func, void *data, fd_t *fd, int32_t partial, dict_t *xdata); void ec_inodelk(call_frame_t *frame, xlator_t *this, gf_lkowner_t *owner, uintptr_t target, uint32_t fop_flags, fop_inodelk_cbk_t func, void *data, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata); void ec_finodelk(call_frame_t *frame, xlator_t *this, gf_lkowner_t *owner, uintptr_t target, uint32_t fop_flags, fop_finodelk_cbk_t func, void *data, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata); void ec_link(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_link_cbk_t func, void *data, loc_t *oldloc, loc_t *newloc, dict_t *xdata); void ec_lk(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_lk_cbk_t func, void *data, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata); void ec_lookup(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_lookup_cbk_t func, void *data, loc_t *loc, dict_t *xdata); void ec_mkdir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_mkdir_cbk_t func, void *data, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata); void ec_mknod(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_mknod_cbk_t func, void *data, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata); void ec_open(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_open_cbk_t func, void *data, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata); void ec_opendir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_opendir_cbk_t func, void *data, loc_t *loc, fd_t *fd, dict_t *xdata); void ec_readdir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_readdir_cbk_t func, void *data, fd_t *fd, size_t size, off_t offset, dict_t *xdata); void ec_readdirp(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_readdirp_cbk_t func, void *data, fd_t *fd, size_t size, off_t offset, dict_t *xdata); void ec_readlink(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_readlink_cbk_t func, void *data, loc_t *loc, size_t size, dict_t *xdata); void ec_readv(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_readv_cbk_t func, void *data, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata); void ec_removexattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_removexattr_cbk_t func, void *data, loc_t *loc, const char *name, dict_t *xdata); void ec_fremovexattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fremovexattr_cbk_t func, void *data, fd_t *fd, const char *name, dict_t *xdata); void ec_rename(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_rename_cbk_t func, void *data, loc_t *oldloc, loc_t *newloc, dict_t *xdata); void ec_rmdir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_rmdir_cbk_t func, void *data, loc_t *loc, int xflags, dict_t *xdata); void ec_setattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_setattr_cbk_t func, void *data, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata); void ec_fsetattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fsetattr_cbk_t func, void *data, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata); void ec_setxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_setxattr_cbk_t func, void *data, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata); void ec_fsetxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fsetxattr_cbk_t func, void *data, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata); void ec_stat(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_stat_cbk_t func, void *data, loc_t *loc, dict_t *xdata); void ec_fstat(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fstat_cbk_t func, void *data, fd_t *fd, dict_t *xdata); void ec_statfs(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_statfs_cbk_t func, void *data, loc_t *loc, dict_t *xdata); void ec_symlink(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_symlink_cbk_t func, void *data, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata); void ec_fallocate(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fallocate_cbk_t func, void *data, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata); void ec_discard(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_discard_cbk_t func, void *data, fd_t *fd, off_t offset, size_t len, dict_t *xdata); void ec_truncate(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_truncate_cbk_t func, void *data, loc_t *loc, off_t offset, dict_t *xdata); void ec_ftruncate(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_ftruncate_cbk_t func, void *data, fd_t *fd, off_t offset, dict_t *xdata); void ec_unlink(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_unlink_cbk_t func, void *data, loc_t *loc, int xflags, dict_t *xdata); void ec_writev(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_writev_cbk_t func, void *data, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata); void ec_xattrop(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_xattrop_cbk_t func, void *data, loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata); void ec_fxattrop(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fxattrop_cbk_t func, void *data, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata); void ec_seek(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_seek_cbk_t func, void *data, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata); void ec_ipc(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_ipc_cbk_t func, void *data, int32_t op, dict_t *xdata); #endif /* __EC_FOPS_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-inode-read.c0000644000000000000000000000013214522202451023453 xustar000000000000000030 mtime=1699284265.641027354 30 atime=1699284265.641027354 30 ctime=1699284301.333134857 glusterfs-11.1/xlators/cluster/ec/src/ec-inode-read.c0000664000175100017510000016115314522202451023741 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "ec.h" #include "ec-messages.h" #include "ec-helpers.h" #include "ec-common.h" #include "ec-combine.h" #include "ec-method.h" #include "ec-fops.h" /* FOP: access */ int32_t ec_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_ACCESS, idx, op_ret, op_errno); if (cbk) { if (xdata) cbk->xdata = dict_ref(xdata); ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_access(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_access_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->access, &fop->loc[0], fop->int32, fop->xdata); } int32_t ec_manager_access(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk = NULL; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_inode(fop, &fop->loc[0], EC_QUERY_INFO, 0, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_one(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: if (ec_dispatch_one_retry(fop, NULL)) { return EC_STATE_DISPATCH; } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk); if (fop->cbks.access != NULL) { if (cbk) { fop->cbks.access(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: if (fop->cbks.access != NULL) { fop->cbks.access(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_access(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_access_cbk_t func, void *data, loc_t *loc, int32_t mask, dict_t *xdata) { ec_cbk_t callback = {.access = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(ACCESS) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_ACCESS, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_access, ec_manager_access, callback, data); if (fop == NULL) { goto out; } fop->int32 = mask; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: getxattr */ int32_t ec_combine_getxattr(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_dict_compare(dst->dict, src->dict)) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_DICT_MISMATCH, "Mismatching dictionary in " "answers of 'GF_FOP_GETXATTR'"); return 0; } return 1; } int32_t ec_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_GETXATTR, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { if (dict != NULL) { cbk->dict = dict_ref(dict); if (cbk->dict == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, ec_combine_getxattr); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_getxattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_getxattr_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->getxattr, &fop->loc[0], fop->str[0], fop->xdata); } void ec_handle_special_xattrs(ec_fop_data_t *fop) { ec_cbk_data_t *cbk = NULL; /* Stime may not be available on all the bricks, so even if some of the * subvols succeed the operation, treat it as answer.*/ if (fop->str[0] && fnmatch(GF_XATTR_STIME_PATTERN, fop->str[0], 0) == 0) { if (!fop->answer || (fop->answer->op_ret < 0)) { list_for_each_entry(cbk, &fop->cbk_list, list) { if (cbk->op_ret >= 0) { fop->answer = cbk; break; } } } } } int32_t ec_manager_getxattr(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: /* clear-locks commands must be done without any locks acquired to avoid interferences. */ if ((fop->str[0] == NULL) || (strncmp(fop->str[0], GF_XATTR_CLRLK_CMD, SLEN(GF_XATTR_CLRLK_CMD)) != 0)) { if (fop->fd == NULL) { ec_lock_prepare_inode(fop, &fop->loc[0], EC_QUERY_INFO, 0, EC_RANGE_FULL); } else { ec_lock_prepare_fd(fop, fop->fd, EC_QUERY_INFO, 0, EC_RANGE_FULL); } ec_lock(fop); } return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: if (fop->minimum == EC_MINIMUM_ALL) { ec_dispatch_all(fop); } else { ec_dispatch_one(fop); } return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: ec_handle_special_xattrs(fop); if (fop->minimum == EC_MINIMUM_ALL) { cbk = ec_fop_prepare_answer(fop, _gf_true); } else { if (ec_dispatch_one_retry(fop, &cbk)) { return EC_STATE_DISPATCH; } } if (cbk != NULL) { int32_t err; err = ec_dict_combine(cbk, EC_COMBINE_DICT); if (!ec_cbk_set_error(cbk, -err, _gf_true)) { if (cbk->xdata != NULL) ec_filter_internal_xattrs(cbk->xdata); if (cbk->dict != NULL) ec_filter_internal_xattrs(cbk->dict); } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.getxattr != NULL) { fop->cbks.getxattr(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->dict, cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.getxattr != NULL) { fop->cbks.getxattr(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } int32_t ec_getxattr_heal_cbk(call_frame_t *frame, void *cookie, xlator_t *xl, int32_t op_ret, int32_t op_errno, uintptr_t mask, uintptr_t good, uintptr_t bad, uint32_t pending, dict_t *xdata) { fop_getxattr_cbk_t func = cookie; ec_t *ec = xl->private; dict_t *dict = NULL; char *str; char bin1[65], bin2[65]; /* We try to return the 'pending' information in xdata, but if this cannot * be set, we will ignore it silently. We prefer to report the success or * failure of the heal itself. */ if (xdata == NULL) { xdata = dict_new(); } else { dict_ref(xdata); } if (xdata != NULL) { if (dict_set_uint32(xdata, EC_XATTR_HEAL_NEW, pending) != 0) { /* dict_set_uint32() is marked as 'warn_unused_result' and gcc * enforces to check the result in this case. However we don't * really care if it succeeded or not. We'll just do the same. * * This empty 'if' avoids the warning, and it will be removed by * the optimizer. */ } } if (op_ret >= 0) { dict = dict_new(); if (dict == NULL) { op_ret = -1; op_errno = ENOMEM; } else { if (gf_asprintf(&str, "Good: %s, Bad: %s", ec_bin(bin1, sizeof(bin1), good, ec->nodes), ec_bin(bin2, sizeof(bin2), mask & ~(good | bad), ec->nodes)) < 0) { dict_unref(dict); dict = NULL; op_ret = -1; op_errno = ENOMEM; goto out; } if (dict_set_dynstr(dict, EC_XATTR_HEAL, str) != 0) { GF_FREE(str); dict_unref(dict); dict = NULL; op_ret = -1; op_errno = ENOMEM; goto out; } } } out: func(frame, NULL, xl, op_ret, op_errno, dict, xdata); if (dict != NULL) { dict_unref(dict); } if (xdata != NULL) { dict_unref(xdata); } return 0; } void ec_getxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_getxattr_cbk_t func, void *data, loc_t *loc, const char *name, dict_t *xdata) { ec_cbk_t callback = {.getxattr = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(GETXATTR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); /* Special handling of an explicit self-heal request */ if ((name != NULL) && (strcmp(name, EC_XATTR_HEAL) == 0)) { ec_heal(frame, this, target, EC_MINIMUM_ONE, ec_getxattr_heal_cbk, func, loc, 0, NULL); return; } fop = ec_fop_data_allocate( frame, this, GF_FOP_GETXATTR, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_getxattr, ec_manager_getxattr, callback, data); if (fop == NULL) { goto out; } if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (name != NULL) { /* In case of list-node-uuids xattr, set flag to indicate * the same and use node-uuid xattr for winding fop */ if (XATTR_IS_NODE_UUID_LIST(name)) { fop->int32 = 1; fop->str[0] = gf_strdup(GF_XATTR_NODE_UUID_KEY); } else { fop->str[0] = gf_strdup(name); } if (fop->str[0] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } /* FOP: fgetxattr */ int32_t ec_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FGETXATTR, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { if (dict != NULL) { cbk->dict = dict_ref(dict); if (cbk->dict == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, ec_combine_getxattr); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_fgetxattr(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_fgetxattr_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fgetxattr, fop->fd, fop->str[0], fop->xdata); } void ec_fgetxattr(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fgetxattr_cbk_t func, void *data, fd_t *fd, const char *name, dict_t *xdata) { ec_cbk_t callback = {.fgetxattr = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FGETXATTR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate( frame, this, GF_FOP_FGETXATTR, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_fgetxattr, ec_manager_getxattr, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (name != NULL) { fop->str[0] = gf_strdup(name); if (fop->str[0] == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a string."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } /* FOP: open */ int32_t ec_combine_open(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (dst->fd != src->fd) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_FD_MISMATCH, "Mismatching fd in answers " "of 'GF_FOP_OPEN': %p <-> %p", dst->fd, src->fd); return 0; } return 1; } int32_t ec_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_OPEN, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { if (fd != NULL) { cbk->fd = fd_ref(fd); if (cbk->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, ec_combine_open); ec_update_fd_status(fd, this, idx, op_ret); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_open(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_open_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->open, &fop->loc[0], fop->int32, fop->fd, fop->xdata); } int32_t ec_open_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { ec_fop_data_t *fop = cookie; int32_t error = 0; fop = fop->data; if (op_ret >= 0) { fop->answer->iatt[0] = *postbuf; } else { error = op_errno; } ec_resume(fop, error); return 0; } int32_t ec_manager_open(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; ec_fd_t *ctx; int32_t err; switch (state) { case EC_STATE_INIT: LOCK(&fop->fd->lock); ctx = __ec_fd_get(fop->fd, fop->xl); if (ctx == NULL) { UNLOCK(&fop->fd->lock); fop->error = ENOMEM; return EC_STATE_REPORT; } if (!ctx->loc.inode) { err = ec_loc_from_loc(fop->xl, &ctx->loc, &fop->loc[0]); if (err != 0) { UNLOCK(&fop->fd->lock); fop->error = -err; return EC_STATE_REPORT; } } ctx->flags = fop->int32; UNLOCK(&fop->fd->lock); /* We need to write to specific offsets on the bricks, so we need to remove O_APPEND from flags (if present). If O_TRUNC is specified, we remove it from open and an ftruncate will be executed later, which will correctly update the file size taking appropriate locks. O_TRUNC flag is saved into fop->uint32 to use it later.*/ fop->uint32 = fop->int32 & O_TRUNC; fop->int32 &= ~(O_APPEND | O_TRUNC); /* Fall through */ case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_true); if (cbk != NULL) { int32_t err; err = ec_loc_update(fop->xl, &fop->loc[0], cbk->fd->inode, NULL); if (!ec_cbk_set_error(cbk, -err, _gf_true)) { LOCK(&fop->fd->lock); ctx = __ec_fd_get(fop->fd, fop->xl); if (ctx != NULL) { ctx->open |= cbk->mask; } UNLOCK(&fop->fd->lock); /* If O_TRUNC was specified, call ftruncate to effectively trunc the file with appropriate locks acquired. We don't use ctx->flags because self-heal can use the same fd with different flags. */ if (fop->uint32 != 0) { ec_sleep(fop); ec_ftruncate(fop->req_frame, fop->xl, cbk->mask, fop->minimum, ec_open_truncate_cbk, fop, cbk->fd, 0, NULL); } } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.open != NULL) { fop->cbks.open(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->fd, cbk->xdata); } return EC_STATE_END; case -EC_STATE_INIT: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.open != NULL) { fop->cbks.open(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_open(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_open_cbk_t func, void *data, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { ec_cbk_t callback = {.open = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(OPEN) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_OPEN, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_open, ec_manager_open, callback, data); if (fop == NULL) { goto out; } fop->int32 = flags; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } /* FOP: readlink */ int32_t ec_combine_readlink(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_iatt_combine(fop, dst->iatt, src->iatt, 1)) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_IATT_MISMATCH, "Mismatching iatt in " "answers of 'GF_FOP_READLINK'"); return 0; } return 1; } int32_t ec_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, const char *path, struct iatt *buf, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, fop->id, idx, op_ret, op_errno); if (cbk) { if (xdata) cbk->xdata = dict_ref(xdata); if (cbk->op_ret >= 0) { cbk->iatt[0] = *buf; cbk->str = gf_strdup(path); if (!cbk->str) { ec_cbk_set_error(cbk, ENOMEM, _gf_true); } } ec_combine(cbk, NULL); } out: if (fop != NULL) ec_complete(fop); return 0; } void ec_wind_readlink(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_readlink_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->readlink, &fop->loc[0], fop->size, fop->xdata); } int32_t ec_manager_readlink(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk = NULL; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_inode(fop, &fop->loc[0], EC_QUERY_INFO, 0, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_one(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: if (ec_dispatch_one_retry(fop, &cbk)) { return EC_STATE_DISPATCH; } if ((cbk != NULL) && (cbk->op_ret >= 0)) { ec_iatt_rebuild(fop->xl->private, &cbk->iatt[0], 1, 1); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk); if (fop->cbks.readlink != NULL) { fop->cbks.readlink(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->str, &cbk->iatt[0], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: if (fop->cbks.readlink != NULL) { fop->cbks.readlink(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_readlink(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_readlink_cbk_t func, void *data, loc_t *loc, size_t size, dict_t *xdata) { ec_cbk_t callback = {.readlink = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(READLINK) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate( frame, this, GF_FOP_READLINK, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_readlink, ec_manager_readlink, callback, data); if (fop == NULL) { goto out; } fop->size = size; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } /* FOP: readv */ int32_t ec_readv_rebuild(ec_t *ec, ec_fop_data_t *fop, ec_cbk_data_t *cbk) { struct iovec vector[1]; ec_cbk_data_t *ans = NULL; struct iobref *iobref = NULL; void *ptr; uint64_t fsize = 0, size = 0, max = 0; int32_t pos, err = -ENOMEM; if (cbk->op_ret < 0) { err = -cbk->op_errno; goto out; } /* This shouldn't fail because we have the inode locked. */ GF_ASSERT(ec_get_inode_size(fop, fop->fd->inode, &cbk->iatt[0].ia_size)); if (cbk->op_ret > 0) { void *blocks[cbk->count]; uint32_t values[cbk->count]; fsize = cbk->op_ret; size = fsize * ec->fragments; for (ans = cbk; ans != NULL; ans = ans->next) { pos = gf_bits_count(cbk->mask & ((1 << ans->idx) - 1)); values[pos] = ans->idx + 1; blocks[pos] = ans->vector[0].iov_base; if ((ans->int32 != 1) || !EC_ALIGN_CHECK(blocks[pos], EC_METHOD_WORD_SIZE)) { if (iobref == NULL) { err = ec_buffer_alloc(ec->xl, size, &iobref, &ptr); if (err != 0) { goto out; } } ec_iov_copy_to(ptr, ans->vector, ans->int32, 0, fsize); blocks[pos] = ptr; ptr += fsize; } } err = ec_buffer_alloc(ec->xl, size, &iobref, &ptr); if (err != 0) { goto out; } err = ec_method_decode(&ec->matrix, fsize, cbk->mask, values, blocks, ptr); if (err != 0) { goto out; } vector[0].iov_base = ptr + fop->head; vector[0].iov_len = size - fop->head; max = fop->offset * ec->fragments + size; if (max > cbk->iatt[0].ia_size) { max = cbk->iatt[0].ia_size; } max -= fop->offset * ec->fragments + fop->head; if (max > fop->user_size) { max = fop->user_size; } size -= fop->head; if (size > max) { vector[0].iov_len -= size - max; size = max; } cbk->op_ret = size; cbk->int32 = 1; iobref_unref(cbk->buffers); cbk->buffers = iobref; GF_FREE(cbk->vector); cbk->vector = iov_dup(vector, 1); if (cbk->vector == NULL) { return -ENOMEM; } } return 0; out: if (iobref != NULL) { iobref_unref(iobref); } return err; } int32_t ec_combine_readv(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_vector_compare(dst->vector, dst->int32, src->vector, src->int32)) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_VECTOR_MISMATCH, "Mismatching vector in " "answers of 'GF_FOP_READ'"); return 0; } if (!ec_iatt_combine(fop, dst->iatt, src->iatt, 1)) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_IATT_MISMATCH, "Mismatching iatt in " "answers of 'GF_FOP_READ'"); return 0; } return 1; } int32_t ec_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; ec_t *ec = this->private; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_READ, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { cbk->int32 = count; if (count > 0) { cbk->vector = iov_dup(vector, count); if (cbk->vector == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY, "Failed to duplicate a " "vector list."); goto out; } cbk->int32 = count; } if (stbuf != NULL) { cbk->iatt[0] = *stbuf; } if (iobref != NULL) { cbk->buffers = iobref_ref(iobref); if (cbk->buffers == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_BUF_REF_FAIL, "Failed to reference a " "buffer."); goto out; } } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } if ((op_ret > 0) && ((op_ret % ec->fragment_size) != 0)) { ec_cbk_set_error(cbk, EIO, _gf_true); } ec_combine(cbk, ec_combine_readv); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_readv(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_readv_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->readv, fop->fd, fop->size, fop->offset, fop->uint32, fop->xdata); } int32_t ec_manager_readv(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; ec_t *ec = fop->xl->private; switch (state) { case EC_STATE_INIT: fop->user_size = fop->size; fop->head = ec_adjust_offset_down(fop->xl->private, &fop->offset, _gf_true); fop->size += fop->head; ec_adjust_size_up(fop->xl->private, &fop->size, _gf_true); /* Fall through */ case EC_STATE_LOCK: ec_lock_prepare_fd(fop, fop->fd, EC_QUERY_INFO, fop->offset, fop->size); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: if (ec->read_mask) { fop->mask &= ec->read_mask; } ec_dispatch_min(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_true); if (cbk != NULL) { int32_t err; ec_iatt_rebuild(fop->xl->private, cbk->iatt, 1, cbk->count); err = ec_readv_rebuild(fop->xl->private, fop, cbk); if (err != 0) { ec_cbk_set_error(cbk, -err, _gf_true); } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.readv != NULL) { fop->cbks.readv(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->vector, cbk->int32, &cbk->iatt[0], cbk->buffers, cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.readv != NULL) { fop->cbks.readv(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, 0, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_readv(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_readv_cbk_t func, void *data, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { ec_cbk_t callback = {.readv = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(READ) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_READ, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_readv, ec_manager_readv, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->size = size; fop->offset = offset; fop->uint32 = flags; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, 0, NULL, NULL, NULL); } } /* FOP: seek */ int32_t ec_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; ec_t *ec = this->private; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_SEEK, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { cbk->offset = offset; } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); } if ((op_ret > 0) && ((cbk->offset % ec->fragment_size) != 0)) { cbk->op_ret = -1; cbk->op_errno = EIO; } ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_seek(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_seek_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->seek, fop->fd, fop->offset, fop->seek, fop->xdata); } int32_t ec_manager_seek(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; uint64_t size; switch (state) { case EC_STATE_INIT: fop->user_size = fop->offset; fop->head = ec_adjust_offset_down(fop->xl->private, &fop->offset, _gf_true); /* Fall through */ case EC_STATE_LOCK: ec_lock_prepare_fd(fop, fop->fd, EC_QUERY_INFO, fop->offset, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: /* This shouldn't fail because we have the inode locked. */ GF_ASSERT( ec_get_inode_size(fop, fop->locks[0].lock->loc.inode, &size)); if (fop->user_size >= size) { ec_fop_set_error(fop, ENXIO); return EC_STATE_REPORT; } ec_dispatch_one(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: if (ec_dispatch_one_retry(fop, &cbk)) { return EC_STATE_DISPATCH; } if ((cbk != NULL) && (cbk->op_ret >= 0)) { ec_t *ec = fop->xl->private; /* This shouldn't fail because we have the inode locked. */ GF_ASSERT(ec_get_inode_size(fop, fop->locks[0].lock->loc.inode, &size)); cbk->offset *= ec->fragments; if (cbk->offset < fop->user_size) { cbk->offset = fop->user_size; } if (cbk->offset > size) { cbk->offset = size; } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.seek != NULL) { fop->cbks.seek(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->offset, cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.seek != NULL) { fop->cbks.seek(fop->req_frame, fop, fop->xl, -1, fop->error, 0, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, 0, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_seek(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_seek_cbk_t func, void *data, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { ec_cbk_t callback = {.seek = func}; ec_fop_data_t *fop = NULL; int32_t error = EIO; gf_msg_trace("ec", 0, "EC(SEEK) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_SEEK, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_seek, ec_manager_seek, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->offset = offset; fop->seek = what; if (fd != NULL) { fop->fd = fd_ref(fd); } if (xdata != NULL) { fop->xdata = dict_ref(xdata); } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, EIO, 0, NULL); } } /* FOP: stat */ int32_t ec_combine_stat(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_iatt_combine(fop, dst->iatt, src->iatt, 1)) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_IATT_MISMATCH, "Mismatching iatt in " "answers of 'GF_FOP_STAT'"); return 0; } return 1; } int32_t ec_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_STAT, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { if (buf != NULL) { cbk->iatt[0] = *buf; } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, ec_combine_stat); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_stat(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_stat_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->stat, &fop->loc[0], fop->xdata); } int32_t ec_manager_stat(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: if (fop->fd == NULL) { ec_lock_prepare_inode(fop, &fop->loc[0], EC_QUERY_INFO, 0, EC_RANGE_FULL); } else { ec_lock_prepare_fd(fop, fop->fd, EC_QUERY_INFO, 0, EC_RANGE_FULL); } ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_true); if (cbk != NULL) { if (cbk->iatt[0].ia_type == IA_IFREG) { ec_iatt_rebuild(fop->xl->private, cbk->iatt, 1, cbk->count); /* This shouldn't fail because we have the inode locked. */ GF_ASSERT(ec_get_inode_size(fop, fop->locks[0].lock->loc.inode, &cbk->iatt[0].ia_size)); } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->id == GF_FOP_STAT) { if (fop->cbks.stat != NULL) { fop->cbks.stat(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], cbk->xdata); } } else { if (fop->cbks.fstat != NULL) { fop->cbks.fstat(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], cbk->xdata); } } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->id == GF_FOP_STAT) { if (fop->cbks.stat != NULL) { fop->cbks.stat(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } } else { if (fop->cbks.fstat != NULL) { fop->cbks.fstat(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_stat(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_stat_cbk_t func, void *data, loc_t *loc, dict_t *xdata) { ec_cbk_t callback = {.stat = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(STAT) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_STAT, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_stat, ec_manager_stat, callback, data); if (fop == NULL) { goto out; } if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } /* FOP: fstat */ int32_t ec_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSTAT, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { if (buf != NULL) { cbk->iatt[0] = *buf; } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, ec_combine_stat); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_fstat(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_fstat_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fstat, fop->fd, fop->xdata); } void ec_fstat(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fstat_cbk_t func, void *data, fd_t *fd, dict_t *xdata) { ec_cbk_t callback = {.fstat = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FSTAT) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FSTAT, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_fstat, ec_manager_stat, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-generic.c0000644000000000000000000000013214522202451023060 xustar000000000000000030 mtime=1699284265.638027344 30 atime=1699284265.638027344 30 ctime=1699284301.328134842 glusterfs-11.1/xlators/cluster/ec/src/ec-generic.c0000664000175100017510000012575114522202451023352 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifdef __FreeBSD__ #include #else #include #endif #include "ec.h" #include "ec-messages.h" #include "ec-helpers.h" #include "ec-common.h" #include "ec-combine.h" #include "ec-fops.h" /* FOP: flush */ int32_t ec_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FLUSH, idx, op_ret, op_errno); if (cbk != NULL) { if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_flush(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_flush_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->flush, fop->fd, fop->xdata); } int32_t ec_manager_flush(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_fd(fop, fop->fd, 0, 0, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_flush_size_version(fop); return EC_STATE_DELAYED_START; case EC_STATE_DELAYED_START: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: ec_fop_prepare_answer(fop, _gf_false); return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.flush != NULL) { fop->cbks.flush(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DELAYED_START: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.flush != NULL) { fop->cbks.flush(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } static int32_t ec_validate_fd(fd_t *fd, xlator_t *xl) { uint64_t iversion = 0; uint64_t fversion = 0; ec_inode_t *inode_ctx = NULL; ec_fd_t *fd_ctx = NULL; LOCK(&fd->lock); { fd_ctx = __ec_fd_get(fd, xl); if (fd_ctx) { fversion = fd_ctx->bad_version; } } UNLOCK(&fd->lock); LOCK(&fd->inode->lock); { inode_ctx = __ec_inode_get(fd->inode, xl); if (inode_ctx) { iversion = inode_ctx->bad_version; } } UNLOCK(&fd->inode->lock); if (fversion < iversion) { return EBADF; } return 0; } void ec_flush(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_flush_cbk_t func, void *data, fd_t *fd, dict_t *xdata) { ec_cbk_t callback = {.flush = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FLUSH) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); if (fd) { error = ec_validate_fd(fd, this); if (error) { gf_msg(this->name, GF_LOG_ERROR, EBADF, EC_MSG_FD_BAD, "Failing %s on %s", gf_fop_list[GF_FOP_FLUSH], fd->inode ? uuid_utoa(fd->inode->gfid) : ""); goto out; } } fop = ec_fop_data_allocate(frame, this, GF_FOP_FLUSH, 0, target, fop_flags, ec_wind_flush, ec_manager_flush, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: fsync */ int32_t ec_combine_fsync(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_iatt_combine(fop, dst->iatt, src->iatt, 2)) { gf_msg(fop->xl->name, GF_LOG_NOTICE, 0, EC_MSG_IATT_MISMATCH, "Mismatching iatt in " "answers of 'GF_FOP_FSYNC'"); return 0; } return 1; } int32_t ec_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSYNC, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { if (prebuf != NULL) { cbk->iatt[0] = *prebuf; } if (postbuf != NULL) { cbk->iatt[1] = *postbuf; } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, ec_combine_fsync); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_fsync(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_fsync_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fsync, fop->fd, fop->int32, fop->xdata); } int32_t ec_manager_fsync(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_fd(fop, fop->fd, EC_QUERY_INFO, 0, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_flush_size_version(fop); return EC_STATE_DELAYED_START; case EC_STATE_DELAYED_START: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2, cbk->count); /* This shouldn't fail because we have the inode locked. */ GF_ASSERT(ec_get_inode_size(fop, fop->fd->inode, &cbk->iatt[0].ia_size)); cbk->iatt[1].ia_size = cbk->iatt[0].ia_size; } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.fsync != NULL) { fop->cbks.fsync(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1], cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: case -EC_STATE_DELAYED_START: GF_ASSERT(fop->error != 0); if (fop->cbks.fsync != NULL) { fop->cbks.fsync(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_fsync(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fsync_cbk_t func, void *data, fd_t *fd, int32_t datasync, dict_t *xdata) { ec_cbk_t callback = {.fsync = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FSYNC) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); if (fd) { error = ec_validate_fd(fd, this); if (error) { gf_msg(this->name, GF_LOG_ERROR, EBADF, EC_MSG_FD_BAD, "Failing %s on %s", gf_fop_list[GF_FOP_FSYNC], fd->inode ? uuid_utoa(fd->inode->gfid) : ""); goto out; } } fop = ec_fop_data_allocate(frame, this, GF_FOP_FSYNC, 0, target, fop_flags, ec_wind_fsync, ec_manager_fsync, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->int32 = datasync; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL); } } /* FOP: fsyncdir */ int32_t ec_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSYNCDIR, idx, op_ret, op_errno); if (cbk != NULL) { if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_fsyncdir(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_fsyncdir_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fsyncdir, fop->fd, fop->int32, fop->xdata); } int32_t ec_manager_fsyncdir(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: ec_lock_prepare_fd(fop, fop->fd, 0, 0, EC_RANGE_FULL); ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_flush_size_version(fop); return EC_STATE_DELAYED_START; case EC_STATE_DELAYED_START: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: ec_fop_prepare_answer(fop, _gf_false); return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.fsyncdir != NULL) { fop->cbks.fsyncdir(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: case -EC_STATE_DELAYED_START: GF_ASSERT(fop->error != 0); if (fop->cbks.fsyncdir != NULL) { fop->cbks.fsyncdir(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_fsyncdir(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fsyncdir_cbk_t func, void *data, fd_t *fd, int32_t datasync, dict_t *xdata) { ec_cbk_t callback = {.fsyncdir = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FSYNCDIR) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FSYNCDIR, 0, target, fop_flags, ec_wind_fsyncdir, ec_manager_fsyncdir, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->int32 = datasync; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } /* FOP: lookup */ void ec_lookup_rebuild(ec_t *ec, ec_fop_data_t *fop, ec_cbk_data_t *cbk) { ec_inode_t *ctx = NULL; uint64_t size = 0; int32_t have_size = 0, err; if (cbk->op_ret < 0) { return; } ec_dict_del_array(cbk->xdata, EC_XATTR_VERSION, cbk->version, EC_VERSION_SIZE); err = ec_loc_update(fop->xl, &fop->loc[0], cbk->inode, &cbk->iatt[0]); if (ec_cbk_set_error(cbk, -err, _gf_true)) { return; } LOCK(&cbk->inode->lock); ctx = __ec_inode_get(cbk->inode, fop->xl); if (ctx != NULL) { if (ctx->have_version) { cbk->version[0] = ctx->post_version[0]; cbk->version[1] = ctx->post_version[1]; } if (ctx->have_size) { size = ctx->post_size; have_size = 1; } } UNLOCK(&cbk->inode->lock); if (cbk->iatt[0].ia_type == IA_IFREG) { cbk->size = cbk->iatt[0].ia_size; ec_dict_del_number(cbk->xdata, EC_XATTR_SIZE, &cbk->iatt[0].ia_size); if (have_size) { cbk->iatt[0].ia_size = size; } } } int32_t ec_combine_lookup(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_iatt_combine(fop, dst->iatt, src->iatt, 2)) { gf_msg(fop->xl->name, GF_LOG_DEBUG, 0, EC_MSG_IATT_MISMATCH, "Mismatching iatt in " "answers of 'GF_FOP_LOOKUP'"); return 0; } return 1; } int32_t ec_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; uint64_t dirty[2] = {0}; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_LOOKUP, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { if (inode != NULL) { cbk->inode = inode_ref(inode); if (cbk->inode == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_INODE_REF_FAIL, "Failed to reference an inode."); goto out; } } if (buf != NULL) { cbk->iatt[0] = *buf; } if (postparent != NULL) { cbk->iatt[1] = *postparent; } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } ec_dict_del_array(xdata, EC_XATTR_DIRTY, dirty, EC_VERSION_SIZE); } ec_combine(cbk, ec_combine_lookup); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_lookup(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_lookup_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->lookup, &fop->loc[0], fop->xdata); } int32_t ec_manager_lookup(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; int32_t err; switch (state) { case EC_STATE_INIT: if (fop->xdata == NULL) { fop->xdata = dict_new(); if (fop->xdata == NULL) { gf_msg(fop->xl->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOOKUP_REQ_PREP_FAIL, "Unable to prepare " "lookup request"); fop->error = ENOMEM; return EC_STATE_REPORT; } } else { /*TODO: To be handled once we have 'syndromes' */ dict_del(fop->xdata, GF_CONTENT_KEY); } err = dict_set_uint64(fop->xdata, EC_XATTR_SIZE, 0); if (err == 0) { err = dict_set_uint64(fop->xdata, EC_XATTR_VERSION, 0); } if (err == 0) { err = dict_set_uint64(fop->xdata, EC_XATTR_DIRTY, 0); } if (err != 0) { gf_msg(fop->xl->name, GF_LOG_ERROR, -err, EC_MSG_LOOKUP_REQ_PREP_FAIL, "Unable to prepare lookup " "request"); fop->error = -err; return EC_STATE_REPORT; } /* Fall through */ case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: /* * Lookup happens without any lock, so there is a chance that it * will have answers before modification happened and after * modification happened in the same response. So choose the next * best answer when the answers don't match for EC_MINIMUM_MIN */ if (!fop->answer && !list_empty(&fop->cbk_list)) { fop->answer = list_entry(fop->cbk_list.next, ec_cbk_data_t, list); } cbk = ec_fop_prepare_answer(fop, _gf_true); if (cbk != NULL) { ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2, cbk->count); ec_lookup_rebuild(fop->xl->private, fop, cbk); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.lookup != NULL) { fop->cbks.lookup(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->inode, &cbk->iatt[0], cbk->xdata, &cbk->iatt[1]); } return EC_STATE_END; case -EC_STATE_INIT: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.lookup != NULL) { fop->cbks.lookup(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL, NULL, NULL); } return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_lookup(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_lookup_cbk_t func, void *data, loc_t *loc, dict_t *xdata) { ec_cbk_t callback = {.lookup = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(LOOKUP) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_LOOKUP, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_lookup, ec_manager_lookup, callback, data); if (fop == NULL) { goto out; } if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_copy_with_ref(xdata, NULL); /* Do not log failures here as a memory problem would have already * been logged by the corresponding alloc functions */ if (fop->xdata == NULL) goto out; } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL, NULL, NULL); } } /* FOP: statfs */ int32_t ec_combine_statfs(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { ec_statvfs_combine(&dst->statvfs, &src->statvfs); return 1; } int32_t ec_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_STATFS, idx, op_ret, op_errno); if (cbk != NULL) { if (op_ret >= 0) { if (buf != NULL) { cbk->statvfs = *buf; } } if (xdata != NULL) { cbk->xdata = dict_ref(xdata); if (cbk->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } ec_combine(cbk, ec_combine_statfs); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_statfs(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_statfs_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->statfs, &fop->loc[0], fop->xdata); } int32_t ec_manager_statfs(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk = NULL; gf_boolean_t deem_statfs_enabled = _gf_false; int32_t err = 0; switch (state) { case EC_STATE_INIT: case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_true); if (cbk != NULL) { ec_t *ec = fop->xl->private; if (cbk->xdata) { err = dict_get_int8(cbk->xdata, "quota-deem-statfs", (int8_t *)&deem_statfs_enabled); if (err != -ENOENT) { ec_cbk_set_error(cbk, -err, _gf_true); } } if (err != 0 || deem_statfs_enabled == _gf_false) { cbk->statvfs.f_blocks *= ec->fragments; cbk->statvfs.f_bfree *= ec->fragments; cbk->statvfs.f_bavail *= ec->fragments; } } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.statfs != NULL) { fop->cbks.statfs(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, &cbk->statvfs, cbk->xdata); } return EC_STATE_END; case -EC_STATE_INIT: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.statfs != NULL) { fop->cbks.statfs(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_statfs(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_statfs_cbk_t func, void *data, loc_t *loc, dict_t *xdata) { ec_cbk_t callback = {.statfs = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(STATFS) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_STATFS, EC_FLAG_LOCK_SHARED, target, fop_flags, ec_wind_statfs, ec_manager_statfs, callback, data); if (fop == NULL) { goto out; } if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } /* FOP: xattrop */ int32_t ec_combine_xattrop(ec_fop_data_t *fop, ec_cbk_data_t *dst, ec_cbk_data_t *src) { if (!ec_dict_compare(dst->dict, src->dict)) { gf_msg(fop->xl->name, GF_LOG_DEBUG, 0, EC_MSG_DICT_MISMATCH, "Mismatching dictionary in " "answers of 'GF_FOP_XATTROP'"); return 0; } return 1; } int32_t ec_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_lock_link_t *link = NULL; ec_cbk_data_t *cbk = NULL; uint64_t dirty[2] = {0}; data_t *data; uint64_t *version; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, fop->id, idx, op_ret, op_errno); if (!cbk) goto out; if (op_ret >= 0) { cbk->dict = dict_ref(xattr); data = dict_get(cbk->dict, EC_XATTR_VERSION); if ((data != NULL) && (data->len >= sizeof(uint64_t))) { version = (uint64_t *)data->data; if (((be64toh(version[0]) >> EC_SELFHEAL_BIT) & 1) != 0) { LOCK(&fop->lock); fop->healing |= 1ULL << idx; UNLOCK(&fop->lock); } } ec_dict_del_array(xattr, EC_XATTR_DIRTY, dirty, EC_VERSION_SIZE); link = fop->data; if (link) { /*Keep a note of if the dirty is already set or not*/ link->dirty[0] |= (dirty[0] != 0); link->dirty[1] |= (dirty[1] != 0); } } if (xdata) cbk->xdata = dict_ref(xdata); ec_combine(cbk, ec_combine_xattrop); out: if (fop) ec_complete(fop); return 0; } void ec_wind_xattrop(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_xattrop_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->xattrop, &fop->loc[0], fop->xattrop_flags, fop->dict, fop->xdata); } int32_t ec_manager_xattrop(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_LOCK: if (fop->fd == NULL) { ec_lock_prepare_inode(fop, &fop->loc[0], EC_UPDATE_META, 0, EC_RANGE_FULL); } else { ec_lock_prepare_fd(fop, fop->fd, EC_UPDATE_META, 0, EC_RANGE_FULL); } ec_lock(fop); return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: cbk = ec_fop_prepare_answer(fop, _gf_false); if (cbk != NULL) { int32_t err; err = ec_dict_combine(cbk, EC_COMBINE_DICT); ec_cbk_set_error(cbk, -err, _gf_false); } return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->id == GF_FOP_XATTROP) { if (fop->cbks.xattrop != NULL) { fop->cbks.xattrop(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->dict, cbk->xdata); } } else { if (fop->cbks.fxattrop != NULL) { fop->cbks.fxattrop(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->dict, cbk->xdata); } } return EC_STATE_LOCK_REUSE; case -EC_STATE_INIT: case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->id == GF_FOP_XATTROP) { if (fop->cbks.xattrop != NULL) { fop->cbks.xattrop(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } } else { if (fop->cbks.fxattrop != NULL) { fop->cbks.fxattrop(fop->req_frame, fop, fop->xl, -1, fop->error, NULL, NULL); } } return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK_REUSE: case EC_STATE_LOCK_REUSE: ec_lock_reuse(fop); return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_xattrop(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_xattrop_cbk_t func, void *data, loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { ec_cbk_t callback = {.xattrop = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(XATTROP) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_XATTROP, 0, target, fop_flags, ec_wind_xattrop, ec_manager_xattrop, callback, data); if (fop == NULL) { goto out; } fop->xattrop_flags = optype; if (loc != NULL) { if (loc_copy(&fop->loc[0], loc) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, EC_MSG_LOC_COPY_FAIL, "Failed to copy a location."); goto out; } } if (xattr != NULL) { fop->dict = dict_ref(xattr); if (fop->dict == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } void ec_wind_fxattrop(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_xattrop_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->fxattrop, fop->fd, fop->xattrop_flags, fop->dict, fop->xdata); } void ec_fxattrop(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_fxattrop_cbk_t func, void *data, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { ec_cbk_t callback = {.fxattrop = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(FXATTROP) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_FXATTROP, 0, target, fop_flags, ec_wind_fxattrop, ec_manager_xattrop, callback, data); if (fop == NULL) { goto out; } fop->use_fd = 1; fop->xattrop_flags = optype; if (fd != NULL) { fop->fd = fd_ref(fd); if (fop->fd == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_FILE_DESC_REF_FAIL, "Failed to reference a " "file descriptor."); goto out; } } if (xattr != NULL) { fop->dict = dict_ref(xattr); if (fop->dict == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } if (xdata != NULL) { fop->xdata = dict_ref(xdata); if (fop->xdata == NULL) { gf_msg(this->name, GF_LOG_ERROR, 0, EC_MSG_DICT_REF_FAIL, "Failed to reference a " "dictionary."); goto out; } } error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL, NULL); } } /* FOP: IPC */ int32_t ec_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { ec_fop_data_t *fop = NULL; ec_cbk_data_t *cbk = NULL; int32_t idx = (int32_t)(uintptr_t)cookie; VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, frame->local, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = frame->local; ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx, frame, op_ret, op_errno); cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_IPC, idx, op_ret, op_errno); if (cbk != NULL) { if (xdata != NULL) { cbk->xdata = dict_ref(xdata); } ec_combine(cbk, NULL); } out: if (fop != NULL) { ec_complete(fop); } return 0; } void ec_wind_ipc(ec_t *ec, ec_fop_data_t *fop, int32_t idx) { ec_trace("WIND", fop, "idx=%d", idx); STACK_WIND_COOKIE(fop->frame, ec_ipc_cbk, (void *)(uintptr_t)idx, ec->xl_list[idx], ec->xl_list[idx]->fops->ipc, fop->int32, fop->xdata); } int32_t ec_manager_ipc(ec_fop_data_t *fop, int32_t state) { ec_cbk_data_t *cbk; switch (state) { case EC_STATE_INIT: case EC_STATE_DISPATCH: ec_dispatch_all(fop); return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: ec_fop_prepare_answer(fop, _gf_true); return EC_STATE_REPORT; case EC_STATE_REPORT: cbk = fop->answer; GF_ASSERT(cbk != NULL); if (fop->cbks.ipc != NULL) { fop->cbks.ipc(fop->req_frame, fop, fop->xl, cbk->op_ret, cbk->op_errno, cbk->xdata); } return EC_STATE_END; case -EC_STATE_INIT: case -EC_STATE_DISPATCH: case -EC_STATE_PREPARE_ANSWER: case -EC_STATE_REPORT: GF_ASSERT(fop->error != 0); if (fop->cbks.ipc != NULL) { fop->cbks.ipc(fop->req_frame, fop, fop->xl, -1, fop->error, NULL); } return EC_STATE_END; default: gf_msg(fop->xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_UNHANDLED_STATE, "Unhandled state %d for %s", state, ec_fop_name(fop->id)); return EC_STATE_END; } } void ec_ipc(call_frame_t *frame, xlator_t *this, uintptr_t target, uint32_t fop_flags, fop_ipc_cbk_t func, void *data, int32_t op, dict_t *xdata) { ec_cbk_t callback = {.ipc = func}; ec_fop_data_t *fop = NULL; int32_t error = ENOMEM; gf_msg_trace("ec", 0, "EC(IPC) %p", frame); VALIDATE_OR_GOTO(this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); fop = ec_fop_data_allocate(frame, this, GF_FOP_IPC, 0, target, fop_flags, ec_wind_ipc, ec_manager_ipc, callback, data); if (fop == NULL) { goto out; } if (xdata != NULL) { fop->xdata = dict_ref(xdata); } fop->int32 = op; error = 0; out: if (fop != NULL) { ec_manager(fop, error); } else { func(frame, NULL, this, -1, error, NULL); } } glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-avx.c0000644000000000000000000000013214522202451023152 xustar000000000000000030 mtime=1699284265.631027323 30 atime=1699284265.631027323 30 ctime=1699284301.352134915 glusterfs-11.1/xlators/cluster/ec/src/ec-code-avx.c0000664000175100017510000000675414522202451023445 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "ec-code-intel.h" static void ec_code_avx_prolog(ec_code_builder_t *builder) { builder->loop = builder->address; } static void ec_code_avx_epilog(ec_code_builder_t *builder) { ec_code_intel_op_add_i2r(builder, 32, REG_DX); ec_code_intel_op_add_i2r(builder, 32, REG_DI); ec_code_intel_op_test_i2r(builder, builder->width - 1, REG_DX); ec_code_intel_op_jne(builder, builder->loop); ec_code_intel_op_ret(builder, 0); } static void ec_code_avx_load(ec_code_builder_t *builder, uint32_t dst, uint32_t idx, uint32_t bit) { if (builder->linear) { ec_code_intel_op_mov_m2avx( builder, REG_SI, REG_DX, 1, idx * builder->width * builder->bits + bit * builder->width, dst); } else { if (builder->base != idx) { ec_code_intel_op_mov_m2r(builder, REG_SI, REG_NULL, 0, idx * 8, REG_AX); builder->base = idx; } ec_code_intel_op_mov_m2avx(builder, REG_AX, REG_DX, 1, bit * builder->width, dst); } } static void ec_code_avx_store(ec_code_builder_t *builder, uint32_t src, uint32_t bit) { ec_code_intel_op_mov_avx2m(builder, src, REG_DI, REG_NULL, 0, bit * builder->width); } static void ec_code_avx_copy(ec_code_builder_t *builder, uint32_t dst, uint32_t src) { ec_code_intel_op_mov_avx2avx(builder, src, dst); } static void ec_code_avx_xor2(ec_code_builder_t *builder, uint32_t dst, uint32_t src) { ec_code_intel_op_xor_avx2avx(builder, src, dst); } static void ec_code_avx_xor3(ec_code_builder_t *builder, uint32_t dst, uint32_t src1, uint32_t src2) { ec_code_intel_op_mov_avx2avx(builder, src1, dst); ec_code_intel_op_xor_avx2avx(builder, src2, dst); } static void ec_code_avx_xorm(ec_code_builder_t *builder, uint32_t dst, uint32_t idx, uint32_t bit) { if (builder->linear) { ec_code_intel_op_xor_m2avx( builder, REG_SI, REG_DX, 1, idx * builder->width * builder->bits + bit * builder->width, dst); } else { if (builder->base != idx) { ec_code_intel_op_mov_m2r(builder, REG_SI, REG_NULL, 0, idx * 8, REG_AX); builder->base = idx; } ec_code_intel_op_xor_m2avx(builder, REG_AX, REG_DX, 1, bit * builder->width, dst); } } static char *ec_code_avx_needed_flags[] = {"avx2", NULL}; ec_code_gen_t ec_code_gen_avx = {.name = "avx", .flags = ec_code_avx_needed_flags, .width = 32, .prolog = ec_code_avx_prolog, .epilog = ec_code_avx_epilog, .load = ec_code_avx_load, .store = ec_code_avx_store, .copy = ec_code_avx_copy, .xor2 = ec_code_avx_xor2, .xor3 = ec_code_avx_xor3, .xorm = ec_code_avx_xorm}; glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-code-x64.c0000644000000000000000000000013214522202451022775 xustar000000000000000030 mtime=1699284265.633027329 30 atime=1699284265.633027329 30 ctime=1699284301.349134906 glusterfs-11.1/xlators/cluster/ec/src/ec-code-x64.c0000664000175100017510000001046614522202451023263 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "ec-code-intel.h" static ec_code_intel_reg_t ec_code_x64_regmap[] = { REG_AX, REG_CX, REG_BP, REG_8, REG_9, REG_10, REG_11, REG_12, REG_13, REG_14, REG_15}; static void ec_code_x64_prolog(ec_code_builder_t *builder) { uint32_t i; ec_code_intel_op_push_r(builder, REG_BP); if (!builder->linear) { ec_code_intel_op_push_r(builder, REG_BX); } if (builder->regs > 11) { ec_code_error(builder, EINVAL); return; } for (i = 7; i < builder->regs; i++) { ec_code_intel_op_push_r(builder, ec_code_x64_regmap[i]); } builder->loop = builder->address; } static void ec_code_x64_epilog(ec_code_builder_t *builder) { uint32_t i; ec_code_intel_op_add_i2r(builder, 8, REG_DX); ec_code_intel_op_add_i2r(builder, 8, REG_DI); ec_code_intel_op_test_i2r(builder, builder->width - 1, REG_DX); ec_code_intel_op_jne(builder, builder->loop); if (builder->regs > 11) { ec_code_error(builder, EINVAL); return; } for (i = builder->regs; i > 7; i--) { ec_code_intel_op_pop_r(builder, ec_code_x64_regmap[i - 1]); } if (!builder->linear) { ec_code_intel_op_pop_r(builder, REG_BX); } ec_code_intel_op_pop_r(builder, REG_BP); ec_code_intel_op_ret(builder, 0); } static void ec_code_x64_load(ec_code_builder_t *builder, uint32_t dst, uint32_t idx, uint32_t bit) { dst = ec_code_x64_regmap[dst]; if (builder->linear) { ec_code_intel_op_mov_m2r( builder, REG_SI, REG_DX, 1, idx * builder->width * builder->bits + bit * builder->width, dst); } else { if (builder->base != idx) { ec_code_intel_op_mov_m2r(builder, REG_SI, REG_NULL, 0, idx * 8, REG_BX); builder->base = idx; } ec_code_intel_op_mov_m2r(builder, REG_BX, REG_DX, 1, bit * builder->width, dst); } } static void ec_code_x64_store(ec_code_builder_t *builder, uint32_t src, uint32_t bit) { src = ec_code_x64_regmap[src]; ec_code_intel_op_mov_r2m(builder, src, REG_DI, REG_NULL, 0, bit * builder->width); } static void ec_code_x64_copy(ec_code_builder_t *builder, uint32_t dst, uint32_t src) { dst = ec_code_x64_regmap[dst]; src = ec_code_x64_regmap[src]; ec_code_intel_op_mov_r2r(builder, src, dst); } static void ec_code_x64_xor2(ec_code_builder_t *builder, uint32_t dst, uint32_t src) { dst = ec_code_x64_regmap[dst]; src = ec_code_x64_regmap[src]; ec_code_intel_op_xor_r2r(builder, src, dst); } static void ec_code_x64_xorm(ec_code_builder_t *builder, uint32_t dst, uint32_t idx, uint32_t bit) { dst = ec_code_x64_regmap[dst]; if (builder->linear) { ec_code_intel_op_xor_m2r( builder, REG_SI, REG_DX, 1, idx * builder->width * builder->bits + bit * builder->width, dst); } else { if (builder->base != idx) { ec_code_intel_op_mov_m2r(builder, REG_SI, REG_NULL, 0, idx * 8, REG_BX); builder->base = idx; } ec_code_intel_op_xor_m2r(builder, REG_BX, REG_DX, 1, bit * builder->width, dst); } } static char *ec_code_x64_needed_flags[] = {NULL}; ec_code_gen_t ec_code_gen_x64 = {.name = "x64", .flags = ec_code_x64_needed_flags, .width = sizeof(uint64_t), .prolog = ec_code_x64_prolog, .epilog = ec_code_x64_epilog, .load = ec_code_x64_load, .store = ec_code_x64_store, .copy = ec_code_x64_copy, .xor2 = ec_code_x64_xor2, .xor3 = NULL, .xorm = ec_code_x64_xorm}; glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-mem-types.h0000644000000000000000000000013214522202451023371 xustar000000000000000030 mtime=1699284265.642027356 30 atime=1699284265.642027356 30 ctime=1699284301.355134924 glusterfs-11.1/xlators/cluster/ec/src/ec-mem-types.h0000664000175100017510000000140314522202451023646 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2014 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_MEM_TYPES_H__ #define __EC_MEM_TYPES_H__ #include enum gf_ec_mem_types_ { ec_mt_ec_t = gf_common_mt_end + 1, ec_mt_xlator_t, ec_mt_ec_inode_t, ec_mt_ec_fd_t, ec_mt_subvol_healer_t, ec_mt_ec_gf_t, ec_mt_ec_code_t, ec_mt_ec_code_builder_t, ec_mt_ec_matrix_t, ec_mt_ec_stripe_t, ec_mt_end }; #endif /* __EC_MEM_TYPES_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-method.h0000644000000000000000000000013214522202451022731 xustar000000000000000030 mtime=1699284265.642027356 30 atime=1699284265.642027356 30 ctime=1699284301.363134948 glusterfs-11.1/xlators/cluster/ec/src/ec-method.h0000664000175100017510000000256214522202451023215 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_METHOD_H__ #define __EC_METHOD_H__ #include "ec-types.h" #include "ec-galois.h" #define EC_GF_BITS 8 #define EC_GF_MOD 0x11D #define EC_GF_SIZE (1 << EC_GF_BITS) /* Determines the maximum size of the matrix used to encode/decode data */ #define EC_METHOD_MAX_FRAGMENTS 16 /* Determines the maximum number of usable elements in the Galois Field */ #define EC_METHOD_MAX_NODES (EC_GF_SIZE - 1) #define EC_METHOD_WORD_SIZE 64 #define EC_METHOD_CHUNK_SIZE (EC_METHOD_WORD_SIZE * EC_GF_BITS) int32_t ec_method_init(xlator_t *xl, ec_matrix_list_t *list, uint32_t columns, uint32_t rows, uint32_t max, const char *gen); void ec_method_fini(ec_matrix_list_t *list); int32_t ec_method_update(xlator_t *xl, ec_matrix_list_t *list, const char *gen); void ec_method_encode(ec_matrix_list_t *list, uint64_t size, void *in, void **out); int32_t ec_method_decode(ec_matrix_list_t *list, uint64_t size, uintptr_t mask, uint32_t *rows, void **in, void *out); #endif /* __EC_METHOD_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-galois.h0000644000000000000000000000013214522202451022727 xustar000000000000000030 mtime=1699284265.638027344 30 atime=1699284265.637027341 30 ctime=1699284301.365134954 glusterfs-11.1/xlators/cluster/ec/src/ec-galois.h0000664000175100017510000000144214522202451023207 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __EC_GALOIS_H__ #define __EC_GALOIS_H__ #include #include "ec-types.h" ec_gf_t * ec_gf_prepare(uint32_t bits, uint32_t mod); void ec_gf_destroy(ec_gf_t *gf); uint32_t ec_gf_add(ec_gf_t *gf, uint32_t a, uint32_t b); uint32_t ec_gf_mul(ec_gf_t *gf, uint32_t a, uint32_t b); uint32_t ec_gf_div(ec_gf_t *gf, uint32_t a, uint32_t b); uint32_t ec_gf_exp(ec_gf_t *gf, uint32_t a, uint32_t b); #endif /* __EC_GALOIS_H__ */ glusterfs-11.1/xlators/cluster/ec/src/PaxHeaders.9031/ec-method.c0000644000000000000000000000013214522202451022724 xustar000000000000000030 mtime=1699284265.642027356 30 atime=1699284265.642027356 30 ctime=1699284301.338134872 glusterfs-11.1/xlators/cluster/ec/src/ec-method.c0000664000175100017510000002560014522202451023206 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2012-2015 DataLab, s.l. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "ec-types.h" #include "ec-mem-types.h" #include "ec-galois.h" #include "ec-code.h" #include "ec-method.h" #include "ec-helpers.h" static void ec_method_matrix_normal(ec_gf_t *gf, uint32_t *matrix, uint32_t columns, uint32_t *values, uint32_t count) { uint32_t i, j, v, tmp; columns--; for (i = 0; i < count; i++) { v = *values++; *matrix++ = tmp = ec_gf_exp(gf, v, columns); for (j = 0; j < columns; j++) { *matrix++ = tmp = ec_gf_div(gf, tmp, v); } } } static void ec_method_matrix_inverse(ec_gf_t *gf, uint32_t *matrix, uint32_t *values, uint32_t count) { uint32_t a[count]; uint32_t i, j, p, last, tmp; last = count - 1; for (i = 0; i < last; i++) { a[i] = 1; } a[i] = values[0]; for (i = last; i > 0; i--) { for (j = i - 1; j < last; j++) { a[j] = a[j + 1] ^ ec_gf_mul(gf, values[i], a[j]); } a[j] = ec_gf_mul(gf, values[i], a[j]); } for (i = 0; i < count; i++) { p = a[0]; matrix += count; *matrix = tmp = p ^ values[i]; for (j = 1; j < last; j++) { matrix += count; *matrix = tmp = a[j] ^ ec_gf_mul(gf, values[i], tmp); p = tmp ^ ec_gf_mul(gf, values[i], p); } for (j = 0; j < last; j++) { *matrix = ec_gf_div(gf, *matrix, p); matrix -= count; } *matrix = ec_gf_div(gf, 1, p); matrix++; } } static void ec_method_matrix_init(ec_matrix_list_t *list, ec_matrix_t *matrix, uintptr_t mask, uint32_t *rows, gf_boolean_t inverse) { uint32_t i; matrix->refs = 1; matrix->mask = mask; matrix->code = list->code; matrix->columns = list->columns; INIT_LIST_HEAD(&matrix->lru); if (inverse) { matrix->rows = list->columns; ec_method_matrix_inverse(matrix->code->gf, matrix->values, rows, matrix->rows); for (i = 0; i < matrix->rows; i++) { matrix->row_data[i].values = matrix->values + i * matrix->columns; matrix->row_data[i].func.interleaved = ec_code_build_interleaved( matrix->code, EC_METHOD_WORD_SIZE, matrix->row_data[i].values, matrix->columns); } } else { matrix->rows = list->rows; ec_method_matrix_normal(matrix->code->gf, matrix->values, matrix->columns, rows, matrix->rows); for (i = 0; i < matrix->rows; i++) { matrix->row_data[i].values = matrix->values + i * matrix->columns; matrix->row_data[i].func.linear = ec_code_build_linear( matrix->code, EC_METHOD_WORD_SIZE, matrix->row_data[i].values, matrix->columns); } } } static void ec_method_matrix_release(ec_matrix_t *matrix) { uint32_t i; for (i = 0; i < matrix->rows; i++) { if (matrix->row_data[i].func.linear != NULL) { ec_code_release(matrix->code, &matrix->row_data[i].func); matrix->row_data[i].func.linear = NULL; } } } static void ec_method_matrix_destroy(ec_matrix_list_t *list, ec_matrix_t *matrix) { list_del_init(&matrix->lru); ec_method_matrix_release(matrix); mem_put(matrix); list->count--; } static void ec_method_matrix_unref(ec_matrix_list_t *list, ec_matrix_t *matrix) { if (--matrix->refs == 0) { list_add_tail(&matrix->lru, &list->lru); if (list->count > list->max) { matrix = list_first_entry(&list->lru, ec_matrix_t, lru); ec_method_matrix_destroy(list, matrix); } } } static ec_matrix_t * ec_method_matrix_lookup(ec_matrix_list_t *list, uintptr_t mask, uint32_t *pos) { ec_matrix_t *matrix; uint32_t i, j, k; i = 0; j = list->count; while (i < j) { k = (i + j) >> 1; matrix = list->objects[k]; if (matrix->mask == mask) { *pos = k; return matrix; } if (matrix->mask < mask) { i = k + 1; } else { j = k; } } *pos = i; return NULL; } static void ec_method_matrix_remove(ec_matrix_list_t *list, uintptr_t mask) { uint32_t pos; if (ec_method_matrix_lookup(list, mask, &pos) != NULL) { list->count--; if (pos < list->count) { memmove(list->objects + pos, list->objects + pos + 1, sizeof(ec_matrix_t *) * (list->count - pos)); } } } static void ec_method_matrix_insert(ec_matrix_list_t *list, ec_matrix_t *matrix) { uint32_t pos; GF_ASSERT(ec_method_matrix_lookup(list, matrix->mask, &pos) == NULL); if (pos < list->count) { memmove(list->objects + pos + 1, list->objects + pos, sizeof(ec_matrix_t *) * (list->count - pos)); } list->objects[pos] = matrix; list->count++; } static ec_matrix_t * ec_method_matrix_get(ec_matrix_list_t *list, uintptr_t mask, uint32_t *rows) { ec_matrix_t *matrix; uint32_t pos; LOCK(&list->lock); matrix = ec_method_matrix_lookup(list, mask, &pos); if (matrix != NULL) { list_del_init(&matrix->lru); matrix->refs++; goto out; } if ((list->count >= list->max) && !list_empty(&list->lru)) { matrix = list_first_entry(&list->lru, ec_matrix_t, lru); list_del_init(&matrix->lru); ec_method_matrix_remove(list, matrix->mask); ec_method_matrix_release(matrix); } else { matrix = mem_get0(list->pool); if (matrix == NULL) { matrix = EC_ERR(ENOMEM); goto out; } matrix->values = (uint32_t *)((uintptr_t)matrix + sizeof(ec_matrix_t) + sizeof(ec_matrix_row_t) * list->columns); } ec_method_matrix_init(list, matrix, mask, rows, _gf_true); if (list->count < list->max) { ec_method_matrix_insert(list, matrix); } else { matrix->mask = 0; } out: UNLOCK(&list->lock); return matrix; } static void ec_method_matrix_put(ec_matrix_list_t *list, ec_matrix_t *matrix) { LOCK(&list->lock); ec_method_matrix_unref(list, matrix); UNLOCK(&list->lock); } static int32_t ec_method_setup(xlator_t *xl, ec_matrix_list_t *list, const char *gen) { ec_matrix_t *matrix; uint32_t values[list->rows]; uint32_t i; int32_t err; matrix = GF_MALLOC(sizeof(ec_matrix_t) + sizeof(ec_matrix_row_t) * list->rows + sizeof(uint32_t) * list->columns * list->rows, ec_mt_ec_matrix_t); if (matrix == NULL) { err = -ENOMEM; goto failed; } memset(matrix, 0, sizeof(ec_matrix_t)); matrix->values = (uint32_t *)((uintptr_t)matrix + sizeof(ec_matrix_t) + sizeof(ec_matrix_row_t) * list->rows); list->code = ec_code_create(list->gf, ec_code_detect(xl, gen)); if (EC_IS_ERR(list->code)) { err = EC_GET_ERR(list->code); list->code = NULL; goto failed_matrix; } for (i = 0; i < list->rows; i++) { values[i] = i + 1; } ec_method_matrix_init(list, matrix, 0, values, _gf_false); list->encode = matrix; return 0; failed_matrix: GF_FREE(matrix); failed: return err; } int32_t ec_method_init(xlator_t *xl, ec_matrix_list_t *list, uint32_t columns, uint32_t rows, uint32_t max, const char *gen) { list->columns = columns; list->rows = rows; list->max = max; list->stripe = EC_METHOD_CHUNK_SIZE * list->columns; INIT_LIST_HEAD(&list->lru); int32_t err; list->pool = mem_pool_new_fn(xl->ctx, sizeof(ec_matrix_t) + sizeof(ec_matrix_row_t) * columns + sizeof(uint32_t) * columns * columns, 128, "ec_matrix_t"); if (list->pool == NULL) { err = -ENOMEM; goto failed; } list->objects = GF_MALLOC(sizeof(ec_matrix_t *) * max, ec_mt_ec_matrix_t); if (list->objects == NULL) { err = -ENOMEM; goto failed_pool; } list->gf = ec_gf_prepare(EC_GF_BITS, EC_GF_MOD); if (EC_IS_ERR(list->gf)) { err = EC_GET_ERR(list->gf); goto failed_objects; } err = ec_method_setup(xl, list, gen); if (err != 0) { goto failed_gf; } LOCK_INIT(&list->lock); return 0; failed_gf: ec_gf_destroy(list->gf); failed_objects: GF_FREE(list->objects); failed_pool: mem_pool_destroy(list->pool); failed: list->pool = NULL; list->objects = NULL; list->gf = NULL; return err; } void ec_method_fini(ec_matrix_list_t *list) { ec_matrix_t *matrix; if (list->encode == NULL) { return; } while (!list_empty(&list->lru)) { matrix = list_first_entry(&list->lru, ec_matrix_t, lru); ec_method_matrix_destroy(list, matrix); } GF_ASSERT(list->count == 0); if (list->pool) /*Init was successful*/ LOCK_DESTROY(&list->lock); ec_method_matrix_release(list->encode); GF_FREE(list->encode); ec_code_destroy(list->code); ec_gf_destroy(list->gf); GF_FREE(list->objects); if (list->pool) mem_pool_destroy(list->pool); } int32_t ec_method_update(xlator_t *xl, ec_matrix_list_t *list, const char *gen) { /* TODO: Allow changing code generator */ return 0; } void ec_method_encode(ec_matrix_list_t *list, uint64_t size, void *in, void **out) { ec_matrix_t *matrix; uint64_t pos; uint32_t i; matrix = list->encode; for (pos = 0; pos < size; pos += list->stripe) { for (i = 0; i < matrix->rows; i++) { matrix->row_data[i].func.linear( out[i], in, pos, matrix->row_data[i].values, list->columns); out[i] += EC_METHOD_CHUNK_SIZE; } } } int32_t ec_method_decode(ec_matrix_list_t *list, uint64_t size, uintptr_t mask, uint32_t *rows, void **in, void *out) { ec_matrix_t *matrix; uint64_t pos; uint32_t i; matrix = ec_method_matrix_get(list, mask, rows); if (EC_IS_ERR(matrix)) { return EC_GET_ERR(matrix); } for (pos = 0; pos < size; pos += EC_METHOD_CHUNK_SIZE) { for (i = 0; i < matrix->rows; i++) { matrix->row_data[i].func.interleaved( out, in, pos, matrix->row_data[i].values, list->columns); out += EC_METHOD_CHUNK_SIZE; } } ec_method_matrix_put(list, matrix); return 0; } glusterfs-11.1/xlators/cluster/ec/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202462022172 xustar000000000000000030 mtime=1699284274.583054287 30 atime=1699284289.110098043 29 ctime=1699284301.27413468 glusterfs-11.1/xlators/cluster/ec/Makefile.in0000664000175100017510000005270514522202462022463 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/cluster/ec DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/cluster/ec/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/cluster/ec/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/cluster/ec/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451022160 xustar000000000000000030 mtime=1699284265.631027323 30 atime=1699284274.559054215 30 ctime=1699284301.275134683 glusterfs-11.1/xlators/cluster/ec/Makefile.am0000664000175100017510000000003514522202451022435 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/cluster/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202462021604 xustar000000000000000030 mtime=1699284274.358053609 30 atime=1699284288.997097702 30 ctime=1699284301.009133882 glusterfs-11.1/xlators/cluster/Makefile.in0000664000175100017510000005270314522202462022072 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/cluster DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = afr dht ec CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/cluster/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/cluster/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/cluster/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451021571 xustar000000000000000030 mtime=1699284265.611027263 30 atime=1699284274.333053534 30 ctime=1699284301.011133888 glusterfs-11.1/xlators/cluster/Makefile.am0000664000175100017510000000004414522202451022046 0ustar00jenkinsjenkins00000000000000SUBDIRS = afr dht ec CLEANFILES = glusterfs-11.1/xlators/PaxHeaders.9031/xlator.sym0000644000000000000000000000013214522202451020117 xustar000000000000000030 mtime=1699284265.790027802 30 atime=1699284265.790027802 30 ctime=1699284300.978133788 glusterfs-11.1/xlators/xlator.sym0000664000175100017510000000001314522202451020370 0ustar00jenkinsjenkins00000000000000xlator_api glusterfs-11.1/xlators/PaxHeaders.9031/features0000644000000000000000000000013214522202521017613 xustar000000000000000030 mtime=1699284305.994148896 30 atime=1699284309.685160013 30 ctime=1699284305.994148896 glusterfs-11.1/xlators/features/0002775000175100017510000000000014522202521020151 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/PaxHeaders.9031/utime0000644000000000000000000000013214522202521020736 xustar000000000000000030 mtime=1699284305.837148423 30 atime=1699284309.685160013 30 ctime=1699284305.837148423 glusterfs-11.1/xlators/features/utime/0002775000175100017510000000000014522202521021274 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/utime/PaxHeaders.9031/src0000644000000000000000000000013214522202521021525 xustar000000000000000030 mtime=1699284305.895148598 30 atime=1699284309.685160013 30 ctime=1699284305.895148598 glusterfs-11.1/xlators/features/utime/src/0002775000175100017510000000000014522202521022063 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime-helpers.h0000644000000000000000000000013214522202451024540 xustar000000000000000030 mtime=1699284265.699027528 30 atime=1699284265.699027528 30 ctime=1699284305.883148561 glusterfs-11.1/xlators/features/utime/src/utime-helpers.h0000664000175100017510000000126014522202451025016 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _UTIME_HELPERS_H #define _UTIME_HELPERS_H #include #include #include void gl_timespec_get(struct timespec *ts); void utime_update_attribute_flags(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop); #endif /* _UTIME_HELPERS_H */ glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime-autogen-fops-tmpl.h0000644000000000000000000000013214522202451026457 xustar000000000000000030 mtime=1699284265.698027525 30 atime=1699284265.698027525 30 ctime=1699284305.895148598 glusterfs-11.1/xlators/features/utime/src/utime-autogen-fops-tmpl.h0000664000175100017510000000114314522202451026735 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ /* File: utime-autogen-fops-tmpl.h * This file contains the utime autogenerated FOPs declarations. */ #ifndef _UTIME_AUTOGEN_FOPS_H #define _UTIME_AUTOGEN_FOPS_H #include #pragma generate #endif /* _UTIME_AUTOGEN_FOPS_H */ glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime-autogen-fops-tmpl.c0000644000000000000000000000013214522202451026452 xustar000000000000000030 mtime=1699284265.698027525 30 atime=1699284265.698027525 30 ctime=1699284305.893148592 glusterfs-11.1/xlators/features/utime/src/utime-autogen-fops-tmpl.c0000664000175100017510000000145014522202451026731 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ /* File: utime-autogen-fops-tmpl.c * This file contains the utime autogenerated FOPs. This is run through * the code generator, generator.py to generate the required FOPs. */ #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include #include #include #include #include "utime-helpers.h" #include #pragma generate glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime-mem-types.h0000644000000000000000000000013214522202451025016 xustar000000000000000030 mtime=1699284265.699027528 30 atime=1699284265.699027528 30 ctime=1699284305.888148577 glusterfs-11.1/xlators/features/utime/src/utime-mem-types.h0000664000175100017510000000111014522202451025266 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __UTIME_MEM_TYPES_H__ #define __UTIME_MEM_TYPES_H__ #include enum gf_utime_mem_types_ { utime_mt_utime_t = gf_common_mt_end + 1, utime_mt_end }; #endif /* __UTIME_MEM_TYPES_H__ */ glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime-gen-fops-h.py0000644000000000000000000000013214522202451025242 xustar000000000000000030 mtime=1699284265.699027528 30 atime=1699284265.699027528 30 ctime=1699284305.881148556 glusterfs-11.1/xlators/features/utime/src/utime-gen-fops-h.py0000775000175100017510000000203414522202451025523 0ustar00jenkinsjenkins00000000000000#!/usr/bin/python3 from __future__ import print_function import os import sys curdir = os.path.dirname(sys.argv[0]) gendir = os.path.join(curdir, '../../../../libglusterfs/src') sys.path.append(gendir) from generator import ops, fop_subs, generate OP_FOP_TEMPLATE = """ int32_t gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@); """ utime_ops = ['fallocate', 'zerofill', 'opendir', 'mknod', 'mkdir', 'unlink', 'rmdir', 'symlink', 'rename', 'link', 'truncate', 'ftruncate', 'create', 'open', 'removexattr', 'fremovexattr', 'readv', 'writev', 'setattr', 'fsetattr', 'copy_file_range'] def gen_defaults(): for name, value in ops.items(): if name in utime_ops: print(generate(OP_FOP_TEMPLATE, name, fop_subs)) for l in open(sys.argv[1], 'r').readlines(): if l.find('#pragma generate') != -1: print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") gen_defaults() print("/* END GENERATED CODE */") else: print(l[:-1]) glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465023656 xustar000000000000000030 mtime=1699284277.724063748 30 atime=1699284291.211104371 30 ctime=1699284305.876148541 glusterfs-11.1/xlators/features/utime/src/Makefile.in0000664000175100017510000006641314522202465024147 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/utime/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_PYTHON) \ $(top_srcdir)/py-compile $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) utime_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am__objects_1 = utime-helpers.lo utime.lo am_utime_la_OBJECTS = $(am__objects_1) nodist_utime_la_OBJECTS = utime-autogen-fops.lo utime_la_OBJECTS = $(am_utime_la_OBJECTS) $(nodist_utime_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = utime_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(utime_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(utime_la_SOURCES) $(nodist_utime_la_SOURCES) DIST_SOURCES = $(utime_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile) py_compile = $(top_srcdir)/py-compile HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = utime.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features UTIME_SRC = $(top_srcdir)/xlators/features/utime/src utime_sources = $(UTIME_SRC)/utime-helpers.c $(UTIME_SRC)/utime.c utime_la_SOURCES = $(utime_sources) nodist_utime_la_SOURCES = utime-autogen-fops.c utime-autogen-fops.h BUILT_SOURCES = utime-autogen-fops.h utime_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) utime_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS_utime = $(UTIME_SRC)/utime-helpers.h \ $(UTIME_SRC)/utime.h $(UTIME_SRC)/utime-messages.h \ $(UTIME_SRC)/utime-mem-types.h noinst_HEADERS = $(top_srcdir)/xlators/lib/src/libxlator.h \ $(noinst_HEADERS_utime) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/xlators/lib/src AM_CFLAGS = -Wall $(GF_CFLAGS) noinst_PYTHON = utime-gen-fops-c.py utime-gen-fops-h.py EXTRA_DIST = utime-autogen-fops-tmpl.c utime-autogen-fops-tmpl.h CLEANFILES = $(nodist_utime_la_SOURCES) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/utime/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/utime/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } utime.la: $(utime_la_OBJECTS) $(utime_la_DEPENDENCIES) $(EXTRA_utime_la_DEPENDENCIES) $(AM_V_CCLD)$(utime_la_LINK) -rpath $(xlatordir) $(utime_la_OBJECTS) $(utime_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utime-autogen-fops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utime-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utime.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< utime-helpers.lo: $(UTIME_SRC)/utime-helpers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utime-helpers.lo -MD -MP -MF $(DEPDIR)/utime-helpers.Tpo -c -o utime-helpers.lo `test -f '$(UTIME_SRC)/utime-helpers.c' || echo '$(srcdir)/'`$(UTIME_SRC)/utime-helpers.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utime-helpers.Tpo $(DEPDIR)/utime-helpers.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(UTIME_SRC)/utime-helpers.c' object='utime-helpers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utime-helpers.lo `test -f '$(UTIME_SRC)/utime-helpers.c' || echo '$(srcdir)/'`$(UTIME_SRC)/utime-helpers.c utime.lo: $(UTIME_SRC)/utime.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utime.lo -MD -MP -MF $(DEPDIR)/utime.Tpo -c -o utime.lo `test -f '$(UTIME_SRC)/utime.c' || echo '$(srcdir)/'`$(UTIME_SRC)/utime.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utime.Tpo $(DEPDIR)/utime.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(UTIME_SRC)/utime.c' object='utime.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utime.lo `test -f '$(UTIME_SRC)/utime.c' || echo '$(srcdir)/'`$(UTIME_SRC)/utime.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-xlatorLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-local uninstall-xlatorLTLIBRARIES utime-autogen-fops.c: utime-gen-fops-c.py utime-autogen-fops-tmpl.c $(PYTHON) $(UTIME_SRC)/utime-gen-fops-c.py $(UTIME_SRC)/utime-autogen-fops-tmpl.c > $@ utime-autogen-fops.h: utime-gen-fops-h.py utime-autogen-fops-tmpl.h $(PYTHON) $(UTIME_SRC)/utime-gen-fops-h.py $(UTIME_SRC)/utime-autogen-fops-tmpl.h > $@ uninstall-local: rm -f $(DESTDIR)$(xlatordir)/utime.so # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime.h0000644000000000000000000000013214522202451023100 xustar000000000000000030 mtime=1699284265.700027531 30 atime=1699284265.700027531 30 ctime=1699284305.885148568 glusterfs-11.1/xlators/features/utime/src/utime.h0000664000175100017510000000102314522202451023353 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __UTIME_H__ #define __UTIME_H__ #include "utime-autogen-fops.h" typedef struct utime_priv { gf_boolean_t noatime; } utime_priv_t; #endif /* __UTIME_H__ */ glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime-messages.h0000644000000000000000000000013214522202451024705 xustar000000000000000030 mtime=1699284265.699027528 30 atime=1699284265.699027528 30 ctime=1699284305.886148571 glusterfs-11.1/xlators/features/utime/src/utime-messages.h0000664000175100017510000000166714522202451025176 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __UTIME_MESSAGES_H__ #define __UTIME_MESSAGES_H__ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(UTIME, UTIME_MSG_NO_MEMORY, UTIME_MSG_SET_MDATA_FAILED, UTIME_MSG_DICT_SET_FAILED); #endif /* __UTIME_MESSAGES_H__ */ glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023640 xustar000000000000000030 mtime=1699284265.698027525 30 atime=1699284277.676063603 30 ctime=1699284305.877148544 glusterfs-11.1/xlators/features/utime/src/Makefile.am0000664000175100017510000000300014522202451024110 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = utime.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features UTIME_SRC = $(top_srcdir)/xlators/features/utime/src utime_sources = $(UTIME_SRC)/utime-helpers.c utime_sources += $(UTIME_SRC)/utime.c utime_la_SOURCES = $(utime_sources) nodist_utime_la_SOURCES = utime-autogen-fops.c utime-autogen-fops.h BUILT_SOURCES = utime-autogen-fops.h utime_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) utime_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS_utime = $(UTIME_SRC)/utime-helpers.h noinst_HEADERS_utime += $(UTIME_SRC)/utime.h noinst_HEADERS_utime += $(UTIME_SRC)/utime-messages.h noinst_HEADERS_utime += $(UTIME_SRC)/utime-mem-types.h noinst_HEADERS = $(top_srcdir)/xlators/lib/src/libxlator.h noinst_HEADERS += $(noinst_HEADERS_utime) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/xlators/lib/src AM_CFLAGS = -Wall $(GF_CFLAGS) noinst_PYTHON = utime-gen-fops-c.py utime-gen-fops-h.py EXTRA_DIST = utime-autogen-fops-tmpl.c utime-autogen-fops-tmpl.h utime-autogen-fops.c: utime-gen-fops-c.py utime-autogen-fops-tmpl.c $(PYTHON) $(UTIME_SRC)/utime-gen-fops-c.py $(UTIME_SRC)/utime-autogen-fops-tmpl.c > $@ utime-autogen-fops.h: utime-gen-fops-h.py utime-autogen-fops-tmpl.h $(PYTHON) $(UTIME_SRC)/utime-gen-fops-h.py $(UTIME_SRC)/utime-autogen-fops-tmpl.h > $@ CLEANFILES = $(nodist_utime_la_SOURCES) uninstall-local: rm -f $(DESTDIR)$(xlatordir)/utime.so glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime.c0000644000000000000000000000013214522202451023073 xustar000000000000000030 mtime=1699284265.699027528 30 atime=1699284265.699027528 30 ctime=1699284305.892148589 glusterfs-11.1/xlators/features/utime/src/utime.c0000664000175100017510000002236014522202451023355 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "utime.h" #include "utime-helpers.h" #include "utime-messages.h" #include "utime-mem-types.h" #include int32_t gf_utime_invalidate(xlator_t *this, inode_t *inode) { return 0; } int32_t gf_utime_forget(xlator_t *this, inode_t *inode) { return 0; } int32_t gf_utime_client_destroy(xlator_t *this, client_t *client) { return 0; } void gf_utime_ictxmerge(xlator_t *this, fd_t *fd, inode_t *inode, inode_t *linked_inode) { return; } int32_t gf_utime_release(xlator_t *this, fd_t *fd) { return 0; } int32_t gf_utime_releasedir(xlator_t *this, fd_t *fd) { return 0; } int32_t gf_utime_client_disconnect(xlator_t *this, client_t *client) { return 0; } int32_t gf_utime_fdctx_to_dict(xlator_t *this, fd_t *fd, dict_t *dict) { return 0; } int32_t gf_utime_inode(xlator_t *this) { return 0; } int32_t gf_utime_inode_to_dict(xlator_t *this, dict_t *dict) { return 0; } int32_t gf_utime_history(xlator_t *this) { return 0; } int32_t gf_utime_fd(xlator_t *this) { return 0; } int32_t gf_utime_fd_to_dict(xlator_t *this, dict_t *dict) { return 0; } int32_t gf_utime_fdctx(xlator_t *this, fd_t *fd) { return 0; } int32_t gf_utime_inodectx(xlator_t *this, inode_t *ino) { return 0; } int32_t gf_utime_inodectx_to_dict(xlator_t *this, inode_t *ino, dict_t *dict) { return 0; } int32_t gf_utime_priv_to_dict(xlator_t *this, dict_t *dict, char *brickname) { return 0; } int32_t gf_utime_priv(xlator_t *this) { return 0; } int32_t mem_acct_init(xlator_t *this) { if (xlator_mem_acct_init(this, utime_mt_end) != 0) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, UTIME_MSG_NO_MEMORY, "Memory accounting initialization failed."); return -1; } return 0; } int32_t gf_utime_set_mdata_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { call_stub_t *stub = frame->local; /* Don't fail lookup if mdata setxattr fails */ if (op_ret) { gf_msg(this->name, GF_LOG_ERROR, op_errno, UTIME_MSG_SET_MDATA_FAILED, "dict set of key for set-ctime-mdata failed"); } frame->local = NULL; call_resume(stub); STACK_DESTROY(frame->root); return 0; } int32_t gf_utime_set_mdata_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xdata, struct iatt *postparent) { dict_t *dict = NULL; struct mdata_iatt *mdata = NULL; int ret = 0; loc_t loc = { 0, }; call_frame_t *new_frame = NULL; if (!op_ret && dict_get(xdata, GF_XATTR_MDATA_KEY) == NULL) { dict = dict_new(); if (!dict) { op_errno = ENOMEM; goto err; } mdata = GF_MALLOC(sizeof(struct mdata_iatt), gf_common_mt_char); if (mdata == NULL) { op_errno = ENOMEM; goto err; } iatt_to_mdata(mdata, stbuf); ret = dict_set_mdata(dict, CTIME_MDATA_XDATA_KEY, mdata, _gf_false); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, UTIME_MSG_NO_MEMORY, "dict set of key for set-ctime-mdata failed"); goto err; } new_frame = copy_frame(frame); if (!new_frame) { op_errno = ENOMEM; goto stub_err; } new_frame->local = fop_lookup_cbk_stub(frame, default_lookup_cbk, op_ret, op_errno, inode, stbuf, xdata, postparent); if (!new_frame->local) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, UTIME_MSG_NO_MEMORY, "lookup_cbk stub allocation failed"); op_errno = ENOMEM; STACK_DESTROY(new_frame->root); goto stub_err; } loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, stbuf->ia_gfid); new_frame->root->uid = 0; new_frame->root->gid = 0; new_frame->root->pid = GF_CLIENT_PID_SET_UTIME; STACK_WIND(new_frame, gf_utime_set_mdata_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, &loc, dict, 0, NULL); dict_unref(dict); inode_unref(loc.inode); return 0; } STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, stbuf, xdata, postparent); return 0; err: if (mdata) { GF_FREE(mdata); } stub_err: if (dict) { dict_unref(dict); } STACK_UNWIND_STRICT(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } int gf_utime_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int op_errno = EINVAL; int ret = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); VALIDATE_OR_GOTO(loc->inode, err); xdata = xdata ? dict_ref(xdata) : dict_new(); if (!xdata) { op_errno = ENOMEM; goto err; } ret = dict_set_int8(xdata, GF_XATTR_MDATA_KEY, 1); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, -ret, UTIME_MSG_DICT_SET_FAILED, "%s: Unable to set dict value for %s", loc->path, GF_XATTR_MDATA_KEY); op_errno = -ret; goto free_dict; } STACK_WIND(frame, gf_utime_set_mdata_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); dict_unref(xdata); return 0; free_dict: dict_unref(xdata); err: STACK_UNWIND_STRICT(lookup, frame, ret, op_errno, NULL, NULL, NULL, NULL); return 0; } int32_t init(xlator_t *this) { utime_priv_t *utime = NULL; utime = GF_MALLOC(sizeof(*utime), utime_mt_utime_t); if (utime == NULL) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, UTIME_MSG_NO_MEMORY, "Failed to allocate private memory."); return -1; } memset(utime, 0, sizeof(*utime)); this->private = utime; GF_OPTION_INIT("noatime", utime->noatime, bool, err); return 0; err: return -1; } void fini(xlator_t *this) { utime_priv_t *utime = NULL; utime = this->private; GF_FREE(utime); return; } int32_t reconfigure(xlator_t *this, dict_t *options) { utime_priv_t *utime = this->private; GF_OPTION_RECONF("noatime", utime->noatime, options, bool, err); return 0; err: return -1; } int notify(xlator_t *this, int event, void *data, ...) { return default_notify(this, event, data); } struct xlator_fops fops = { .rename = gf_utime_rename, .mknod = gf_utime_mknod, .readv = gf_utime_readv, .fremovexattr = gf_utime_fremovexattr, .open = gf_utime_open, .create = gf_utime_create, .mkdir = gf_utime_mkdir, .writev = gf_utime_writev, .rmdir = gf_utime_rmdir, .fallocate = gf_utime_fallocate, .truncate = gf_utime_truncate, .symlink = gf_utime_symlink, .zerofill = gf_utime_zerofill, .link = gf_utime_link, .ftruncate = gf_utime_ftruncate, .unlink = gf_utime_unlink, .setattr = gf_utime_setattr, .fsetattr = gf_utime_fsetattr, .opendir = gf_utime_opendir, .removexattr = gf_utime_removexattr, .lookup = gf_utime_lookup, }; struct xlator_cbks cbks = { .invalidate = gf_utime_invalidate, .forget = gf_utime_forget, .client_destroy = gf_utime_client_destroy, .ictxmerge = gf_utime_ictxmerge, .release = gf_utime_release, .releasedir = gf_utime_releasedir, .client_disconnect = gf_utime_client_disconnect, }; struct xlator_dumpops dumpops = { .fdctx_to_dict = gf_utime_fdctx_to_dict, .inode = gf_utime_inode, .inode_to_dict = gf_utime_inode_to_dict, .history = gf_utime_history, .fd = gf_utime_fd, .fd_to_dict = gf_utime_fd_to_dict, .fdctx = gf_utime_fdctx, .inodectx = gf_utime_inodectx, .inodectx_to_dict = gf_utime_inodectx_to_dict, .priv_to_dict = gf_utime_priv_to_dict, .priv = gf_utime_priv, }; struct volume_options options[] = { {.key = {"noatime"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .op_version = {GD_OP_VERSION_5_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, .tags = {"ctime"}, .description = "Enable/Disable atime updation when ctime feature is " "enabled. When noatime is on, atime is not updated with " "ctime feature enabled and vice versa."}, {.key = {NULL}}}; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {GD_OP_VERSION_5_0}, .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "utime", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime-gen-fops-c.py0000644000000000000000000000013214522202451025235 xustar000000000000000030 mtime=1699284265.699027528 30 atime=1699284265.699027528 30 ctime=1699284305.879148549 glusterfs-11.1/xlators/features/utime/src/utime-gen-fops-c.py0000775000175100017510000001124114522202451025516 0ustar00jenkinsjenkins00000000000000#!/usr/bin/python3 from __future__ import print_function import os import sys curdir = os.path.dirname(sys.argv[0]) gendir = os.path.join(curdir, '../../../../libglusterfs/src') sys.path.append(gendir) from generator import ops, fop_subs, cbk_subs, generate FOPS_COMMON_TEMPLATE = """ int32_t gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { gl_timespec_get(&frame->root->ctime); (void) utime_update_attribute_flags(frame, this, GF_FOP_@UPNAME@); STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); return 0; } """ FOPS_CBK_COMMON_TEMPLATE = """ int32_t gf_utime_@NAME@_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, @LONG_ARGS@) { STACK_UNWIND_STRICT (@NAME@, frame, op_ret, op_errno, @SHORT_ARGS@); return 0; } """ FOPS_READ_TEMPLATE = """ int32_t gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { gl_timespec_get(&frame->root->ctime); (void) utime_update_attribute_flags(frame, this, GF_FOP_READ); STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); return 0; } """ FOPS_WRITE_TEMPLATE = """ int32_t gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { gl_timespec_get(&frame->root->ctime); (void) utime_update_attribute_flags(frame, this, GF_FOP_WRITE); STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); return 0; } """ FOPS_COPY_FILE_RANGE_TEMPLATE = """ int32_t gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { gl_timespec_get(&frame->root->ctime); (void) utime_update_attribute_flags(frame, this, GF_FOP_COPY_FILE_RANGE); STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); return 0; } """ FOPS_SETATTR_TEMPLATE = """ int32_t gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { gl_timespec_get(&frame->root->ctime); if (!valid) { frame->root->flags |= MDATA_CTIME; } if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)) { frame->root->flags |= MDATA_CTIME; } if (valid & GF_SET_ATTR_MODE) { frame->root->flags |= MDATA_CTIME; } if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { if (valid & GF_ATTR_ATIME_NOW) { frame->root->ctime.tv_sec = stbuf->ia_atime; frame->root->ctime.tv_nsec = stbuf->ia_atime_nsec; } else if (valid & GF_ATTR_MTIME_NOW) { frame->root->ctime.tv_sec = stbuf->ia_mtime; frame->root->ctime.tv_nsec = stbuf->ia_mtime_nsec; } } STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); return 0; } """ utime_ops = ['fallocate', 'zerofill', 'opendir', 'mknod', 'mkdir', 'unlink', 'rmdir', 'symlink', 'rename', 'link', 'truncate', 'ftruncate', 'create', 'open', 'removexattr', 'fremovexattr'] utime_read_op = ['readv'] utime_write_op = ['writev'] utime_setattr_ops = ['setattr', 'fsetattr'] utime_copy_file_range_ops = ['copy_file_range'] def gen_defaults(): for name in ops: if name in utime_ops: print(generate(FOPS_CBK_COMMON_TEMPLATE, name, cbk_subs)) print(generate(FOPS_COMMON_TEMPLATE, name, fop_subs)) if name in utime_read_op: print(generate(FOPS_CBK_COMMON_TEMPLATE, name, cbk_subs)) print(generate(FOPS_READ_TEMPLATE, name, fop_subs)) if name in utime_write_op: print(generate(FOPS_CBK_COMMON_TEMPLATE, name, cbk_subs)) print(generate(FOPS_WRITE_TEMPLATE, name, fop_subs)) if name in utime_setattr_ops: print(generate(FOPS_CBK_COMMON_TEMPLATE, name, cbk_subs)) print(generate(FOPS_SETATTR_TEMPLATE, name, fop_subs)) if name in utime_copy_file_range_ops: print(generate(FOPS_CBK_COMMON_TEMPLATE, name, cbk_subs)) print(generate(FOPS_COPY_FILE_RANGE_TEMPLATE, name, fop_subs)) for l in open(sys.argv[1], 'r').readlines(): if l.find('#pragma generate') != -1: print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") gen_defaults() print("/* END GENERATED CODE */") else: print(l[:-1]) glusterfs-11.1/xlators/features/utime/src/PaxHeaders.9031/utime-helpers.c0000644000000000000000000000013214522202451024533 xustar000000000000000030 mtime=1699284265.699027528 30 atime=1699284265.699027528 30 ctime=1699284305.890148583 glusterfs-11.1/xlators/features/utime/src/utime-helpers.c0000664000175100017510000000571714522202451025024 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "utime-helpers.h" #include "utime.h" void gl_timespec_get(struct timespec *ts) { #ifdef TIME_UTC timespec_get(ts, TIME_UTC); #else timespec_now_realtime(ts); #endif } void utime_update_attribute_flags(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop) { utime_priv_t *utime_priv = NULL; if (!frame || !this) { goto out; } utime_priv = this->private; switch (fop) { case GF_FOP_SETXATTR: case GF_FOP_FSETXATTR: frame->root->flags |= MDATA_CTIME; break; case GF_FOP_FALLOCATE: case GF_FOP_ZEROFILL: frame->root->flags |= MDATA_MTIME; frame->root->flags |= MDATA_ATIME; break; case GF_FOP_OPENDIR: case GF_FOP_OPEN: case GF_FOP_READ: if (!utime_priv->noatime) { frame->root->flags |= MDATA_ATIME; } break; case GF_FOP_MKNOD: case GF_FOP_MKDIR: case GF_FOP_SYMLINK: case GF_FOP_CREATE: frame->root->flags |= MDATA_ATIME; frame->root->flags |= MDATA_CTIME; frame->root->flags |= MDATA_MTIME; frame->root->flags |= MDATA_PAR_CTIME; frame->root->flags |= MDATA_PAR_MTIME; break; case GF_FOP_UNLINK: case GF_FOP_RMDIR: frame->root->flags |= MDATA_CTIME; frame->root->flags |= MDATA_PAR_CTIME; frame->root->flags |= MDATA_PAR_MTIME; break; case GF_FOP_WRITE: frame->root->flags |= MDATA_MTIME; frame->root->flags |= MDATA_CTIME; break; case GF_FOP_LINK: case GF_FOP_RENAME: frame->root->flags |= MDATA_CTIME; frame->root->flags |= MDATA_PAR_CTIME; frame->root->flags |= MDATA_PAR_MTIME; break; case GF_FOP_TRUNCATE: case GF_FOP_FTRUNCATE: frame->root->flags |= MDATA_CTIME; frame->root->flags |= MDATA_MTIME; break; case GF_FOP_REMOVEXATTR: case GF_FOP_FREMOVEXATTR: frame->root->flags |= MDATA_CTIME; break; case GF_FOP_COPY_FILE_RANGE: /* Below 2 are for destination fd */ frame->root->flags |= MDATA_CTIME; frame->root->flags |= MDATA_MTIME; /* Below flag is for the source fd */ if (!utime_priv->noatime) { frame->root->flags |= MDATA_ATIME; } break; default: frame->root->flags = 0; } out: return; } glusterfs-11.1/xlators/features/utime/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465023067 xustar000000000000000030 mtime=1699284277.666063573 30 atime=1699284291.191104311 30 ctime=1699284305.832148408 glusterfs-11.1/xlators/features/utime/Makefile.in0000664000175100017510000005272114522202465023355 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/utime DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/utime/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/utime/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/utime/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023051 xustar000000000000000030 mtime=1699284265.698027525 30 atime=1699284277.642063501 30 ctime=1699284305.833148411 glusterfs-11.1/xlators/features/utime/Makefile.am0000664000175100017510000000003414522202451023325 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/shard0000644000000000000000000000013214522202520020713 xustar000000000000000030 mtime=1699284304.837145411 30 atime=1699284309.685160013 30 ctime=1699284304.837145411 glusterfs-11.1/xlators/features/shard/0002775000175100017510000000000014522202520021251 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/shard/PaxHeaders.9031/src0000644000000000000000000000013214522202520021502 xustar000000000000000030 mtime=1699284304.878145535 30 atime=1699284309.685160013 30 ctime=1699284304.878145535 glusterfs-11.1/xlators/features/shard/src/0002775000175100017510000000000014522202520022040 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/shard/src/PaxHeaders.9031/shard-mem-types.h0000644000000000000000000000013214522202451024752 xustar000000000000000030 mtime=1699284265.689027498 30 atime=1699284265.688027495 30 ctime=1699284304.875145526 glusterfs-11.1/xlators/features/shard/src/shard-mem-types.h0000664000175100017510000000124114522202451025227 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __SHARD_MEM_TYPES_H__ #define __SHARD_MEM_TYPES_H__ #include enum gf_shard_mem_types_ { gf_shard_mt_priv_t = gf_common_mt_end + 1, gf_shard_mt_inode_list, gf_shard_mt_inode_ctx_t, gf_shard_mt_int64_t, gf_shard_mt_uint64_t, gf_shard_mt_end }; #endif glusterfs-11.1/xlators/features/shard/src/PaxHeaders.9031/shard.h0000644000000000000000000000013214522202451023034 xustar000000000000000030 mtime=1699284265.690027501 30 atime=1699284265.690027501 30 ctime=1699284304.873145519 glusterfs-11.1/xlators/features/shard/src/shard.h0000664000175100017510000004063714522202451023325 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __SHARD_H__ #define __SHARD_H__ #include #include #include "shard-messages.h" #include #define GF_SHARD_DIR ".shard" #define GF_SHARD_REMOVE_ME_DIR ".remove_me" #define SHARD_MIN_BLOCK_SIZE (4 * GF_UNIT_MB) #define SHARD_MAX_BLOCK_SIZE (4 * GF_UNIT_TB) #define SHARD_XATTR_PREFIX "trusted.glusterfs.shard." #define GF_XATTR_SHARD_BLOCK_SIZE "trusted.glusterfs.shard.block-size" /** * Bit masks for the valid flag, which is used while updating ctx **/ #define SHARD_MASK_BLOCK_SIZE (1 << 0) #define SHARD_MASK_PROT (1 << 1) #define SHARD_MASK_NLINK (1 << 2) #define SHARD_MASK_UID (1 << 3) #define SHARD_MASK_GID (1 << 4) #define SHARD_MASK_SIZE (1 << 6) #define SHARD_MASK_BLOCKS (1 << 7) #define SHARD_MASK_TIMES (1 << 8) #define SHARD_MASK_OTHERS (1 << 9) #define SHARD_MASK_REFRESH_RESET (1 << 10) #define SHARD_INODE_WRITE_MASK \ (SHARD_MASK_SIZE | SHARD_MASK_BLOCKS | SHARD_MASK_TIMES) #define SHARD_LOOKUP_MASK \ (SHARD_MASK_PROT | SHARD_MASK_NLINK | SHARD_MASK_UID | SHARD_MASK_GID | \ SHARD_MASK_TIMES | SHARD_MASK_OTHERS) #define SHARD_ALL_MASK \ (SHARD_MASK_BLOCK_SIZE | SHARD_MASK_PROT | SHARD_MASK_NLINK | \ SHARD_MASK_UID | SHARD_MASK_GID | SHARD_MASK_SIZE | SHARD_MASK_BLOCKS | \ SHARD_MASK_TIMES | SHARD_MASK_OTHERS) #define get_lowest_block(off, shard_size) ((off) / (shard_size)) #define get_highest_block(off, len, shard_size) \ (((((off) + (len)) == 0) ? 0 : ((off) + (len)-1)) / (shard_size)) int shard_unlock_inodelk(call_frame_t *frame, xlator_t *this); int shard_unlock_entrylk(call_frame_t *frame, xlator_t *this); #define SHARD_ENTRY_FOP_CHECK(loc, op_errno, label) \ do { \ if ((loc->name && !strcmp(GF_SHARD_DIR, loc->name)) && \ (((loc->parent) && __is_root_gfid(loc->parent->gfid)) || \ __is_root_gfid(loc->pargfid))) { \ op_errno = EPERM; \ goto label; \ } \ \ if ((loc->parent && __is_shard_dir(loc->parent->gfid)) || \ __is_shard_dir(loc->pargfid)) { \ op_errno = EPERM; \ goto label; \ } \ } while (0) #define SHARD_INODE_OP_CHECK(gfid, err, label) \ do { \ if (__is_shard_dir(gfid)) { \ err = EPERM; \ goto label; \ } \ } while (0) #define SHARD_STACK_UNWIND(fop, frame, params...) \ do { \ shard_local_t *__local = NULL; \ if (frame) { \ __local = frame->local; \ if (__local && __local->int_inodelk.acquired_lock) \ shard_unlock_inodelk(frame, frame->this); \ if (__local && __local->int_entrylk.acquired_lock) \ shard_unlock_entrylk(frame, frame->this); \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ if (__local) { \ shard_local_wipe(__local); \ mem_put(__local); \ } \ } while (0) #define SHARD_STACK_DESTROY(frame) \ do { \ shard_local_t *__local = NULL; \ __local = frame->local; \ frame->local = NULL; \ STACK_DESTROY(frame->root); \ if (__local) { \ shard_local_wipe(__local); \ mem_put(__local); \ } \ } while (0); #define SHARD_INODE_CREATE_INIT(this, block_size, xattr_req, loc, size, \ block_count, label) \ do { \ int __ret = -1; \ int64_t *__size_attr = NULL; \ uint64_t *__bs = 0; \ \ __bs = GF_MALLOC(sizeof(uint64_t), gf_shard_mt_uint64_t); \ if (!__bs) \ goto label; \ *__bs = htobe64(block_size); \ __ret = dict_set_bin(xattr_req, GF_XATTR_SHARD_BLOCK_SIZE, __bs, \ sizeof(*__bs)); \ if (__ret) { \ gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, \ "Failed to set key: %s " \ "on path %s", \ GF_XATTR_SHARD_BLOCK_SIZE, (loc)->path); \ GF_FREE(__bs); \ goto label; \ } \ \ __ret = shard_set_size_attrs(size, block_count, &__size_attr); \ if (__ret) \ goto label; \ \ __ret = dict_set_bin(xattr_req, GF_XATTR_SHARD_FILE_SIZE, __size_attr, \ 8 * 4); \ if (__ret) { \ gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, \ "Failed to set key: %s " \ "on path %s", \ GF_XATTR_SHARD_FILE_SIZE, (loc)->path); \ GF_FREE(__size_attr); \ goto label; \ } \ } while (0) #define SHARD_MD_READ_FOP_INIT_REQ_DICT(this, dict, gfid, local, label) \ do { \ int __ret = -1; \ \ __ret = dict_set_uint64(dict, GF_XATTR_SHARD_FILE_SIZE, 8 * 4); \ if (__ret) { \ local->op_ret = -1; \ local->op_errno = ENOMEM; \ gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, \ "Failed to set dict value:" \ " key:%s for %s.", \ GF_XATTR_SHARD_FILE_SIZE, uuid_utoa(gfid)); \ goto label; \ } \ } while (0) #define SHARD_SET_ROOT_FS_ID(frame, local) \ do { \ if (!local->is_set_fsid) { \ local->uid = frame->root->uid; \ local->gid = frame->root->gid; \ frame->root->uid = 0; \ frame->root->gid = 0; \ local->is_set_fsid = _gf_true; \ } \ } while (0) #define SHARD_UNSET_ROOT_FS_ID(frame, local) \ do { \ if (local->is_set_fsid) { \ frame->root->uid = local->uid; \ frame->root->gid = local->gid; \ local->is_set_fsid = _gf_false; \ } \ } while (0) #define SHARD_TIME_UPDATE(ctx_sec, ctx_nsec, new_sec, new_nsec) \ do { \ if (ctx_sec == new_sec) \ ctx_nsec = new_nsec = max(new_nsec, ctx_nsec); \ else if (ctx_sec > new_sec) { \ new_sec = ctx_sec; \ new_nsec = ctx_nsec; \ } else { \ ctx_sec = new_sec; \ ctx_nsec = new_nsec; \ } \ } while (0) typedef enum { SHARD_BG_DELETION_NONE = 0, SHARD_BG_DELETION_LAUNCHING, SHARD_BG_DELETION_IN_PROGRESS, } shard_bg_deletion_state_t; /* rm = "remove me" */ typedef struct shard_unlink_thread { pthread_mutex_t mutex; pthread_cond_t cond; pthread_t thread; xlator_t *this; gf_boolean_t running; gf_boolean_t rerun; gf_boolean_t stop; } shard_unlink_thread_t; typedef struct shard_priv { uint64_t block_size; uuid_t dot_shard_gfid; uuid_t dot_shard_rm_gfid; inode_t *dot_shard_inode; inode_t *dot_shard_rm_inode; gf_lock_t lock; struct list_head ilist_head; int inode_count; uint32_t deletion_rate; shard_bg_deletion_state_t bg_del_state; gf_boolean_t first_lookup_done; uint64_t lru_limit; shard_unlink_thread_t thread_info; } shard_priv_t; typedef struct { loc_t loc; char *domain; struct gf_flock flock; gf_boolean_t acquired_lock; } shard_inodelk_t; typedef struct { loc_t loc; char *domain; char *basename; entrylk_cmd cmd; entrylk_type type; gf_boolean_t acquired_lock; } shard_entrylk_t; typedef int32_t (*shard_post_fop_handler_t)(call_frame_t *frame, xlator_t *this); typedef int32_t (*shard_post_resolve_fop_handler_t)(call_frame_t *frame, xlator_t *this); typedef int32_t (*shard_post_lookup_shards_fop_handler_t)(call_frame_t *frame, xlator_t *this); typedef int32_t (*shard_post_mknod_fop_handler_t)(call_frame_t *frame, xlator_t *this); typedef int32_t (*shard_post_update_size_fop_handler_t)(call_frame_t *frame, xlator_t *this); typedef struct shard_local { int op_ret; int op_errno; uint64_t first_block; uint64_t last_block; uint64_t num_blocks; int call_count; int eexist_count; int create_count; int xflag; int count; uint32_t flags; uint32_t uid; uint32_t gid; uint64_t block_size; uint64_t dst_block_size; int32_t datasync; glusterfs_fop_t fop; off_t offset; size_t total_size; size_t written_size; size_t hole_size; size_t req_size; size_t readdir_size; int64_t delta_size; gf_atomic_t delta_blocks; loc_t loc; loc_t dot_shard_loc; loc_t dot_shard_rm_loc; loc_t loc2; loc_t tmp_loc; fd_t *fd; dict_t *xattr_req; dict_t *xattr_rsp; inode_t **inode_list; struct iatt prebuf; struct iatt postbuf; struct iatt preoldparent; struct iatt postoldparent; struct iatt prenewparent; struct iatt postnewparent; struct iovec *vector; struct iobref *iobref; struct iobuf *iobuf; gf_dirent_t entries_head; gf_boolean_t is_set_fsid; gf_boolean_t list_inited; gf_boolean_t first_lookup_done; gf_boolean_t lookup_shards_barriered; gf_boolean_t unlink_shards_barriered; gf_boolean_t resolve_not; gf_boolean_t cleanup_required; shard_post_fop_handler_t handler; shard_post_lookup_shards_fop_handler_t pls_fop_handler; shard_post_resolve_fop_handler_t post_res_handler; shard_post_mknod_fop_handler_t post_mknod_handler; shard_post_update_size_fop_handler_t post_update_size_handler; shard_inodelk_t int_inodelk; shard_entrylk_t int_entrylk; inode_t *resolver_base_inode; syncbarrier_t barrier; loc_t newloc; call_frame_t *main_frame; call_frame_t *inodelk_frame; call_frame_t *entrylk_frame; char *name; uint32_t deletion_rate; uuid_t base_gfid; } shard_local_t; typedef struct shard_inode_ctx { uint64_t block_size; /* The block size with which this inode is sharded */ struct iatt stat; /* The following members of inode ctx will be applicable only to the * individual shards' ctx and never the base file ctx. */ struct list_head ilist; uuid_t base_gfid; int block_num; gf_boolean_t refresh; gf_boolean_t refreshed; struct list_head to_fsync_list; int fsync_needed; int fsync_count; inode_t *inode; inode_t *base_inode; } shard_inode_ctx_t; typedef enum { SHARD_INTERNAL_DIR_DOT_SHARD = 1, SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME, } shard_internal_dir_type_t; #endif /* __SHARD_H__ */ glusterfs-11.1/xlators/features/shard/src/PaxHeaders.9031/shard-messages.h0000644000000000000000000000013214522202451024641 xustar000000000000000030 mtime=1699284265.689027498 30 atime=1699284265.689027498 30 ctime=1699284304.876145529 glusterfs-11.1/xlators/features/shard/src/shard-messages.h0000664000175100017510000000313014522202451025115 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _SHARD_MESSAGES_H_ #define _SHARD_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(SHARD, SHARD_MSG_BASE_FILE_LOOKUP_FAILED, SHARD_MSG_DICT_OP_FAILED, SHARD_MSG_DOT_SHARD_NODIR, SHARD_MSG_FD_CTX_SET_FAILED, SHARD_MSG_INODE_CTX_GET_FAILED, SHARD_MSG_INODE_CTX_SET_FAILED, SHARD_MSG_INODE_PATH_FAILED, SHARD_MSG_INTERNAL_XATTR_MISSING, SHARD_MSG_INVALID_VOLFILE, SHARD_MSG_LOOKUP_SHARD_FAILED, SHARD_MSG_MEM_ACCT_INIT_FAILED, SHARD_MSG_NULL_THIS, SHARD_MSG_SIZE_SET_FAILED, SHARD_MSG_STAT_FAILED, SHARD_MSG_TRUNCATE_LAST_SHARD_FAILED, SHARD_MSG_UPDATE_FILE_SIZE_FAILED, SHARD_MSG_FOP_NOT_SUPPORTED, SHARD_MSG_INVALID_FOP, SHARD_MSG_MEMALLOC_FAILED, SHARD_MSG_FOP_FAILED, SHARD_MSG_SHARDS_DELETION_FAILED, SHARD_MSG_SHARD_DELETION_COMPLETED); #endif /* !_SHARD_MESSAGES_H_ */ glusterfs-11.1/xlators/features/shard/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202465023633 xustar000000000000000030 mtime=1699284277.129061956 30 atime=1699284291.008103759 29 ctime=1699284304.87014551 glusterfs-11.1/xlators/features/shard/src/Makefile.in0000664000175100017510000005722514522202465024126 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/shard/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) shard_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_shard_la_OBJECTS = shard.lo shard_la_OBJECTS = $(am_shard_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = shard_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(shard_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(shard_la_SOURCES) DIST_SOURCES = $(shard_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = shard.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features shard_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) shard_la_SOURCES = shard.c shard_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = shard.h shard-mem-types.h shard-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/shard/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/shard/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } shard.la: $(shard_la_OBJECTS) $(shard_la_DEPENDENCIES) $(EXTRA_shard_la_DEPENDENCIES) $(AM_V_CCLD)$(shard_la_LINK) -rpath $(xlatordir) $(shard_la_OBJECTS) $(shard_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shard.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/shard/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023616 xustar000000000000000030 mtime=1699284265.688027495 30 atime=1699284277.092061845 30 ctime=1699284304.871145514 glusterfs-11.1/xlators/features/shard/src/Makefile.am0000664000175100017510000000074114522202451024077 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = shard.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features shard_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) shard_la_SOURCES = shard.c shard_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = shard.h shard-mem-types.h shard-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/shard/src/PaxHeaders.9031/shard.c0000644000000000000000000000013214522202451023027 xustar000000000000000030 mtime=1699284265.690027501 30 atime=1699284265.689027498 30 ctime=1699284304.878145535 glusterfs-11.1/xlators/features/shard/src/shard.c0000664000175100017510000070577414522202451023332 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "shard.h" #include "shard-mem-types.h" #include #include #define SHARD_PATH_MAX (sizeof(GF_SHARD_DIR) + GF_UUID_BUF_SIZE + 16) static gf_boolean_t __is_shard_dir(uuid_t gfid) { shard_priv_t *priv = THIS->private; if (gf_uuid_compare(gfid, priv->dot_shard_gfid) == 0) return _gf_true; return _gf_false; } static gf_boolean_t __is_gsyncd_on_shard_dir(call_frame_t *frame, loc_t *loc) { if (frame->root->pid == GF_CLIENT_PID_GSYNCD && (__is_shard_dir(loc->pargfid) || (loc->parent && __is_shard_dir(loc->parent->gfid)))) return _gf_true; return _gf_false; } static void shard_make_block_bname(int block_num, uuid_t gfid, char *buf, size_t len) { char gfid_str[GF_UUID_BUF_SIZE] = { 0, }; gf_uuid_unparse(gfid, gfid_str); snprintf(buf, len, "%s.%d", gfid_str, block_num); } static int shard_make_base_path(char *path, uuid_t gfid) { strcpy(path, "/" GF_SHARD_DIR "/"); uuid_utoa_r(gfid, path + sizeof(GF_SHARD_DIR) + 1); return (sizeof(GF_SHARD_DIR) + GF_UUID_BUF_SIZE); } static inline void shard_append_index(char *path, int path_size, int prefix_len, int shard_idx_iter) { snprintf(path + prefix_len, path_size - prefix_len, ".%d", shard_idx_iter); } static int __shard_inode_ctx_get(inode_t *inode, xlator_t *this, shard_inode_ctx_t **ctx) { int ret = -1; uint64_t ctx_uint = 0; shard_inode_ctx_t *ctx_p = NULL; ret = __inode_ctx_get(inode, this, &ctx_uint); if (ret == 0) { *ctx = (shard_inode_ctx_t *)(uintptr_t)ctx_uint; return ret; } ctx_p = GF_CALLOC(1, sizeof(*ctx_p), gf_shard_mt_inode_ctx_t); if (!ctx_p) return ret; INIT_LIST_HEAD(&ctx_p->ilist); INIT_LIST_HEAD(&ctx_p->to_fsync_list); ctx_uint = (uint64_t)(uintptr_t)ctx_p; ret = __inode_ctx_set(inode, this, &ctx_uint); if (ret < 0) { GF_FREE(ctx_p); return ret; } *ctx = ctx_p; return ret; } static int shard_inode_ctx_get(inode_t *inode, xlator_t *this, shard_inode_ctx_t **ctx) { int ret = 0; LOCK(&inode->lock); { ret = __shard_inode_ctx_get(inode, this, ctx); } UNLOCK(&inode->lock); return ret; } static int __shard_inode_ctx_set(inode_t *inode, xlator_t *this, struct iatt *stbuf, uint64_t block_size, int32_t valid) { int ret = -1; shard_inode_ctx_t *ctx = NULL; ret = __shard_inode_ctx_get(inode, this, &ctx); if (ret) return ret; if (valid & SHARD_MASK_BLOCK_SIZE) ctx->block_size = block_size; if (valid & SHARD_MASK_PROT) ctx->stat.ia_prot = stbuf->ia_prot; if (valid & SHARD_MASK_NLINK) ctx->stat.ia_nlink = stbuf->ia_nlink; if (valid & SHARD_MASK_UID) ctx->stat.ia_uid = stbuf->ia_uid; if (valid & SHARD_MASK_GID) ctx->stat.ia_gid = stbuf->ia_gid; if (valid & SHARD_MASK_SIZE) ctx->stat.ia_size = stbuf->ia_size; if (valid & SHARD_MASK_BLOCKS) ctx->stat.ia_blocks = stbuf->ia_blocks; if (valid & SHARD_MASK_TIMES) { SHARD_TIME_UPDATE(ctx->stat.ia_mtime, ctx->stat.ia_mtime_nsec, stbuf->ia_mtime, stbuf->ia_mtime_nsec); SHARD_TIME_UPDATE(ctx->stat.ia_ctime, ctx->stat.ia_ctime_nsec, stbuf->ia_ctime, stbuf->ia_ctime_nsec); SHARD_TIME_UPDATE(ctx->stat.ia_atime, ctx->stat.ia_atime_nsec, stbuf->ia_atime, stbuf->ia_atime_nsec); } if (valid & SHARD_MASK_OTHERS) { ctx->stat.ia_ino = stbuf->ia_ino; gf_uuid_copy(ctx->stat.ia_gfid, stbuf->ia_gfid); ctx->stat.ia_dev = stbuf->ia_dev; ctx->stat.ia_type = stbuf->ia_type; ctx->stat.ia_rdev = stbuf->ia_rdev; ctx->stat.ia_blksize = stbuf->ia_blksize; } if (valid & SHARD_MASK_REFRESH_RESET) ctx->refresh = _gf_false; return 0; } static int shard_inode_ctx_set(inode_t *inode, xlator_t *this, struct iatt *stbuf, uint64_t block_size, int32_t valid) { int ret = -1; LOCK(&inode->lock); { ret = __shard_inode_ctx_set(inode, this, stbuf, block_size, valid); } UNLOCK(&inode->lock); return ret; } static int __shard_inode_ctx_set_refresh_flag(inode_t *inode, xlator_t *this) { int ret = -1; shard_inode_ctx_t *ctx = NULL; ret = __shard_inode_ctx_get(inode, this, &ctx); if (ret) return ret; ctx->refresh = _gf_true; return 0; } static int shard_inode_ctx_set_refresh_flag(inode_t *inode, xlator_t *this) { int ret = -1; LOCK(&inode->lock); { ret = __shard_inode_ctx_set_refresh_flag(inode, this); } UNLOCK(&inode->lock); return ret; } static int __shard_inode_ctx_mark_dir_refreshed(inode_t *inode, xlator_t *this) { int ret = -1; shard_inode_ctx_t *ctx = NULL; ret = __shard_inode_ctx_get(inode, this, &ctx); if (ret) return ret; ctx->refreshed = _gf_true; return 0; } static int shard_inode_ctx_mark_dir_refreshed(inode_t *inode, xlator_t *this) { int ret = -1; LOCK(&inode->lock); { ret = __shard_inode_ctx_mark_dir_refreshed(inode, this); } UNLOCK(&inode->lock); return ret; } static int __shard_inode_ctx_add_to_fsync_list(inode_t *base_inode, xlator_t *this, inode_t *shard_inode) { int ret = -1; shard_inode_ctx_t *base_ictx = NULL; shard_inode_ctx_t *shard_ictx = NULL; ret = __shard_inode_ctx_get(base_inode, this, &base_ictx); if (ret) return ret; ret = __shard_inode_ctx_get(shard_inode, this, &shard_ictx); if (ret) return ret; if (shard_ictx->fsync_needed) { shard_ictx->fsync_needed++; return 1; } list_add_tail(&shard_ictx->to_fsync_list, &base_ictx->to_fsync_list); shard_ictx->inode = shard_inode; shard_ictx->fsync_needed++; base_ictx->fsync_count++; shard_ictx->base_inode = base_inode; return 0; } static int shard_inode_ctx_add_to_fsync_list(inode_t *base_inode, xlator_t *this, inode_t *shard_inode) { int ret = -1; /* This ref acts as a refkeepr on the base inode. We * need to keep this inode alive as it holds the head * of the to_fsync_list. */ inode_ref(base_inode); inode_ref(shard_inode); LOCK(&base_inode->lock); LOCK(&shard_inode->lock); { ret = __shard_inode_ctx_add_to_fsync_list(base_inode, this, shard_inode); } UNLOCK(&shard_inode->lock); UNLOCK(&base_inode->lock); /* Unref the base inode corresponding to the ref above, if the shard is * found to be already part of the fsync list. */ if (ret != 0) { inode_unref(base_inode); inode_unref(shard_inode); } return ret; } static gf_boolean_t __shard_inode_ctx_needs_lookup(inode_t *inode, xlator_t *this) { int ret = -1; shard_inode_ctx_t *ctx = NULL; ret = __shard_inode_ctx_get(inode, this, &ctx); /* If inode ctx get fails, better to err on the side of caution and * try again? Unless the failure is due to mem-allocation. */ if (ret) return _gf_true; return !ctx->refreshed; } static gf_boolean_t shard_inode_ctx_needs_lookup(inode_t *inode, xlator_t *this) { gf_boolean_t flag = _gf_false; LOCK(&inode->lock); { flag = __shard_inode_ctx_needs_lookup(inode, this); } UNLOCK(&inode->lock); return flag; } static int __shard_inode_ctx_invalidate(inode_t *inode, xlator_t *this, struct iatt *stbuf) { int ret = -1; shard_inode_ctx_t *ctx = NULL; ret = __shard_inode_ctx_get(inode, this, &ctx); if (ret) return ret; if ((stbuf->ia_size != ctx->stat.ia_size) || (stbuf->ia_blocks != ctx->stat.ia_blocks)) ctx->refresh = _gf_true; return 0; } static int shard_inode_ctx_invalidate(inode_t *inode, xlator_t *this, struct iatt *stbuf) { int ret = -1; LOCK(&inode->lock); { ret = __shard_inode_ctx_invalidate(inode, this, stbuf); } UNLOCK(&inode->lock); return ret; } static int __shard_inode_ctx_get_block_size(inode_t *inode, xlator_t *this, uint64_t *block_size) { int ret = -1; uint64_t ctx_uint = 0; shard_inode_ctx_t *ctx = NULL; ret = __inode_ctx_get(inode, this, &ctx_uint); if (ret < 0) return ret; ctx = (shard_inode_ctx_t *)(uintptr_t)ctx_uint; *block_size = ctx->block_size; return 0; } static int shard_inode_ctx_get_block_size(inode_t *inode, xlator_t *this, uint64_t *block_size) { int ret = -1; LOCK(&inode->lock); { ret = __shard_inode_ctx_get_block_size(inode, this, block_size); } UNLOCK(&inode->lock); return ret; } static int __shard_inode_ctx_get_fsync_count(inode_t *inode, xlator_t *this, int *fsync_count) { int ret = -1; uint64_t ctx_uint = 0; shard_inode_ctx_t *ctx = NULL; ret = __inode_ctx_get(inode, this, &ctx_uint); if (ret < 0) return ret; ctx = (shard_inode_ctx_t *)(uintptr_t)ctx_uint; *fsync_count = ctx->fsync_needed; return 0; } static int shard_inode_ctx_get_fsync_count(inode_t *inode, xlator_t *this, int *fsync_count) { int ret = -1; LOCK(&inode->lock); { ret = __shard_inode_ctx_get_fsync_count(inode, this, fsync_count); } UNLOCK(&inode->lock); return ret; } static int __shard_inode_ctx_get_all(inode_t *inode, xlator_t *this, shard_inode_ctx_t *ctx_out) { int ret = -1; uint64_t ctx_uint = 0; shard_inode_ctx_t *ctx = NULL; ret = __inode_ctx_get(inode, this, &ctx_uint); if (ret < 0) return ret; ctx = (shard_inode_ctx_t *)(uintptr_t)ctx_uint; memcpy(ctx_out, ctx, sizeof(shard_inode_ctx_t)); return 0; } static int shard_inode_ctx_get_all(inode_t *inode, xlator_t *this, shard_inode_ctx_t *ctx_out) { int ret = -1; LOCK(&inode->lock); { ret = __shard_inode_ctx_get_all(inode, this, ctx_out); } UNLOCK(&inode->lock); return ret; } int __shard_inode_ctx_fill_iatt_from_cache(inode_t *inode, xlator_t *this, struct iatt *buf, gf_boolean_t *need_refresh) { int ret = -1; uint64_t ctx_uint = 0; shard_inode_ctx_t *ctx = NULL; ret = __inode_ctx_get(inode, this, &ctx_uint); if (ret < 0) return ret; ctx = (shard_inode_ctx_t *)(uintptr_t)ctx_uint; if (ctx->refresh == _gf_false) *buf = ctx->stat; else *need_refresh = _gf_true; return 0; } int shard_inode_ctx_fill_iatt_from_cache(inode_t *inode, xlator_t *this, struct iatt *buf, gf_boolean_t *need_refresh) { int ret = -1; LOCK(&inode->lock); { ret = __shard_inode_ctx_fill_iatt_from_cache(inode, this, buf, need_refresh); } UNLOCK(&inode->lock); return ret; } void shard_local_wipe(shard_local_t *local) { int i = 0; int count = 0; count = local->num_blocks; syncbarrier_destroy(&local->barrier); loc_wipe(&local->loc); loc_wipe(&local->dot_shard_loc); loc_wipe(&local->dot_shard_rm_loc); loc_wipe(&local->loc2); loc_wipe(&local->tmp_loc); loc_wipe(&local->int_inodelk.loc); loc_wipe(&local->int_entrylk.loc); loc_wipe(&local->newloc); if (local->name) GF_FREE(local->name); if (local->int_entrylk.basename) GF_FREE(local->int_entrylk.basename); if (local->fd) fd_unref(local->fd); if (local->xattr_req) dict_unref(local->xattr_req); if (local->xattr_rsp) dict_unref(local->xattr_rsp); for (i = 0; i < count; i++) { if (!local->inode_list) break; if (local->inode_list[i]) inode_unref(local->inode_list[i]); } GF_FREE(local->inode_list); GF_FREE(local->vector); if (local->iobref) iobref_unref(local->iobref); if (local->list_inited) gf_dirent_free(&local->entries_head); if (local->inodelk_frame) SHARD_STACK_DESTROY(local->inodelk_frame); if (local->entrylk_frame) SHARD_STACK_DESTROY(local->entrylk_frame); } static int shard_modify_size_and_block_count(struct iatt *stbuf, dict_t *dict, gf_boolean_t logerror) { int ret = -1; void *size_attr = NULL; uint64_t size_array[4]; ret = dict_get_ptr(dict, GF_XATTR_SHARD_FILE_SIZE, &size_attr); if (ret) { if (logerror) gf_msg_callingfn( THIS->name, GF_LOG_ERROR, 0, SHARD_MSG_INTERNAL_XATTR_MISSING, "Failed to get " GF_XATTR_SHARD_FILE_SIZE " for %s", uuid_utoa(stbuf->ia_gfid)); return ret; } memcpy(size_array, size_attr, sizeof(size_array)); stbuf->ia_size = be64toh(size_array[0]); stbuf->ia_blocks = be64toh(size_array[2]); return 0; } static int shard_call_count_return(call_frame_t *frame) { int call_count = 0; shard_local_t *local = NULL; local = frame->local; LOCK(&frame->lock); { call_count = --local->call_count; } UNLOCK(&frame->lock); return call_count; } static char * shard_internal_dir_string(shard_internal_dir_type_t type) { switch (type) { case SHARD_INTERNAL_DIR_DOT_SHARD: return GF_SHARD_DIR; case SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME: return GF_SHARD_REMOVE_ME_DIR; default: return ""; } } static int shard_init_internal_dir_loc(xlator_t *this, shard_local_t *local, shard_internal_dir_type_t type) { int ret = -1; char *bname = NULL; inode_t *parent = NULL; loc_t *internal_dir_loc = NULL; shard_priv_t *priv = NULL; priv = this->private; if (!local) return -1; switch (type) { case SHARD_INTERNAL_DIR_DOT_SHARD: internal_dir_loc = &local->dot_shard_loc; bname = GF_SHARD_DIR; parent = inode_ref(this->itable->root); break; case SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME: internal_dir_loc = &local->dot_shard_rm_loc; bname = GF_SHARD_REMOVE_ME_DIR; parent = inode_ref(priv->dot_shard_inode); break; default: break; } internal_dir_loc->inode = inode_new(this->itable); internal_dir_loc->parent = parent; ret = inode_path(internal_dir_loc->parent, bname, (char **)&internal_dir_loc->path); if (ret < 0 || !(internal_dir_loc->inode)) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed on %s", bname); goto out; } internal_dir_loc->name = strrchr(internal_dir_loc->path, '/'); if (internal_dir_loc->name) internal_dir_loc->name++; ret = 0; out: return ret; } static inode_t * __shard_update_shards_inode_list(inode_t *linked_inode, xlator_t *this, inode_t *base_inode, int block_num, uuid_t gfid) { char block_bname[256] = { 0, }; inode_t *lru_inode = NULL; shard_priv_t *priv = NULL; shard_inode_ctx_t *ctx = NULL; shard_inode_ctx_t *lru_inode_ctx = NULL; shard_inode_ctx_t *lru_base_inode_ctx = NULL; inode_t *fsync_inode = NULL; inode_t *lru_base_inode = NULL; gf_boolean_t do_fsync = _gf_false; priv = this->private; shard_inode_ctx_get(linked_inode, this, &ctx); if (list_empty(&ctx->ilist)) { if (priv->inode_count + 1 <= priv->lru_limit) { /* If this inode was linked here for the first time (indicated * by empty list), and if there is still space in the priv list, * add this ctx to the tail of the list. */ /* For as long as an inode is in lru list, we try to * keep it alive by holding a ref on it. */ inode_ref(linked_inode); if (base_inode) gf_uuid_copy(ctx->base_gfid, base_inode->gfid); else gf_uuid_copy(ctx->base_gfid, gfid); ctx->block_num = block_num; list_add_tail(&ctx->ilist, &priv->ilist_head); priv->inode_count++; ctx->base_inode = inode_ref(base_inode); } else { /*If on the other hand there is no available slot for this inode * in the list, delete the lru inode from the head of the list, * unlink it. And in its place add this new inode into the list. */ lru_inode_ctx = list_first_entry(&priv->ilist_head, shard_inode_ctx_t, ilist); GF_ASSERT(lru_inode_ctx->block_num > 0); lru_base_inode = lru_inode_ctx->base_inode; list_del_init(&lru_inode_ctx->ilist); lru_inode = inode_find(linked_inode->table, lru_inode_ctx->stat.ia_gfid); /* If the lru inode was part of the pending-fsync list, * the base inode needs to be unref'd, the lru inode * deleted from fsync list and fsync'd in a new frame, * and then unlinked in memory and forgotten. */ if (!lru_base_inode) goto after_fsync_check; LOCK(&lru_base_inode->lock); LOCK(&lru_inode->lock); { if (!list_empty(&lru_inode_ctx->to_fsync_list)) { list_del_init(&lru_inode_ctx->to_fsync_list); lru_inode_ctx->fsync_needed = 0; do_fsync = _gf_true; __shard_inode_ctx_get(lru_base_inode, this, &lru_base_inode_ctx); lru_base_inode_ctx->fsync_count--; } } UNLOCK(&lru_inode->lock); UNLOCK(&lru_base_inode->lock); after_fsync_check: if (!do_fsync) { shard_make_block_bname(lru_inode_ctx->block_num, lru_inode_ctx->base_gfid, block_bname, sizeof(block_bname)); /* The following unref corresponds to the ref held at * the time the shard was added to the lru list. */ inode_unref(lru_inode); inode_unlink(lru_inode, priv->dot_shard_inode, block_bname); inode_forget(lru_inode, 0); } else { /* The following unref corresponds to the ref * held when the shard was added to fsync list. */ inode_unref(lru_inode); fsync_inode = lru_inode; if (lru_base_inode) inode_unref(lru_base_inode); } /* The following unref corresponds to the ref * held by inode_find() above. */ inode_unref(lru_inode); /* The following unref corresponds to the ref held on the base shard * at the time of adding shard inode to lru list */ if (lru_base_inode) inode_unref(lru_base_inode); /* For as long as an inode is in lru list, we try to * keep it alive by holding a ref on it. */ inode_ref(linked_inode); if (base_inode) gf_uuid_copy(ctx->base_gfid, base_inode->gfid); else gf_uuid_copy(ctx->base_gfid, gfid); ctx->block_num = block_num; ctx->base_inode = inode_ref(base_inode); list_add_tail(&ctx->ilist, &priv->ilist_head); } } else { /* If this is not the first time this inode is being operated on, move * it to the most recently used end of the list. */ list_move_tail(&ctx->ilist, &priv->ilist_head); } return fsync_inode; } static int shard_common_failure_unwind(glusterfs_fop_t fop, call_frame_t *frame, int32_t op_ret, int32_t op_errno) { switch (fop) { case GF_FOP_LOOKUP: SHARD_STACK_UNWIND(lookup, frame, op_ret, op_errno, NULL, NULL, NULL, NULL); break; case GF_FOP_STAT: SHARD_STACK_UNWIND(stat, frame, op_ret, op_errno, NULL, NULL); break; case GF_FOP_FSTAT: SHARD_STACK_UNWIND(fstat, frame, op_ret, op_errno, NULL, NULL); break; case GF_FOP_TRUNCATE: SHARD_STACK_UNWIND(truncate, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_FTRUNCATE: SHARD_STACK_UNWIND(ftruncate, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_MKNOD: SHARD_STACK_UNWIND(mknod, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL); break; case GF_FOP_LINK: SHARD_STACK_UNWIND(link, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL); break; case GF_FOP_CREATE: SHARD_STACK_UNWIND(create, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); break; case GF_FOP_UNLINK: SHARD_STACK_UNWIND(unlink, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_RENAME: SHARD_STACK_UNWIND(rename, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); break; case GF_FOP_WRITE: SHARD_STACK_UNWIND(writev, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_FALLOCATE: SHARD_STACK_UNWIND(fallocate, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_ZEROFILL: SHARD_STACK_UNWIND(zerofill, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_DISCARD: SHARD_STACK_UNWIND(discard, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_READ: SHARD_STACK_UNWIND(readv, frame, op_ret, op_errno, NULL, -1, NULL, NULL, NULL); break; case GF_FOP_FSYNC: SHARD_STACK_UNWIND(fsync, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_REMOVEXATTR: SHARD_STACK_UNWIND(removexattr, frame, op_ret, op_errno, NULL); break; case GF_FOP_FREMOVEXATTR: SHARD_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, NULL); break; case GF_FOP_FGETXATTR: SHARD_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, NULL, NULL); break; case GF_FOP_GETXATTR: SHARD_STACK_UNWIND(getxattr, frame, op_ret, op_errno, NULL, NULL); break; case GF_FOP_FSETXATTR: SHARD_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, NULL); break; case GF_FOP_SETXATTR: SHARD_STACK_UNWIND(setxattr, frame, op_ret, op_errno, NULL); break; case GF_FOP_SETATTR: SHARD_STACK_UNWIND(setattr, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_FSETATTR: SHARD_STACK_UNWIND(fsetattr, frame, op_ret, op_errno, NULL, NULL, NULL); break; case GF_FOP_SEEK: SHARD_STACK_UNWIND(seek, frame, op_ret, op_errno, 0, NULL); break; case GF_FOP_OPENDIR: SHARD_STACK_UNWIND(opendir, frame, op_ret, op_errno, 0, NULL); break; default: gf_msg(THIS->name, GF_LOG_WARNING, 0, SHARD_MSG_INVALID_FOP, "Invalid fop id = %d", fop); break; } return 0; } static int shard_common_inode_write_success_unwind(glusterfs_fop_t fop, call_frame_t *frame, int32_t op_ret) { shard_local_t *local = frame->local; /* the below 3 variables are required because, in SHARD_STACK_UNWIND() macro, there is a check for local being null. So many static analyzers backtrace the code with assumption of possible (local == NULL) case, and complains for below lines. By handling it like below, we overcome the warnings */ struct iatt *prebuf = ((local) ? &local->prebuf : NULL); struct iatt *postbuf = ((local) ? &local->postbuf : NULL); dict_t *xattr_rsp = ((local) ? local->xattr_rsp : NULL); switch (fop) { case GF_FOP_WRITE: SHARD_STACK_UNWIND(writev, frame, op_ret, 0, prebuf, postbuf, xattr_rsp); break; case GF_FOP_FALLOCATE: SHARD_STACK_UNWIND(fallocate, frame, op_ret, 0, prebuf, postbuf, xattr_rsp); break; case GF_FOP_ZEROFILL: SHARD_STACK_UNWIND(zerofill, frame, op_ret, 0, prebuf, postbuf, xattr_rsp); break; case GF_FOP_DISCARD: SHARD_STACK_UNWIND(discard, frame, op_ret, 0, prebuf, postbuf, xattr_rsp); break; default: gf_msg(THIS->name, GF_LOG_WARNING, 0, SHARD_MSG_INVALID_FOP, "Invalid fop id = %d", fop); break; } return 0; } static int shard_evicted_inode_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { char block_bname[256] = { 0, }; fd_t *anon_fd = cookie; inode_t *shard_inode = NULL; shard_inode_ctx_t *ctx = NULL; shard_priv_t *priv = NULL; priv = this->private; if (anon_fd == NULL || op_ret < 0) { gf_msg(this->name, GF_LOG_WARNING, op_errno, SHARD_MSG_MEMALLOC_FAILED, "fsync failed on shard"); goto out; } shard_inode = anon_fd->inode; LOCK(&priv->lock); LOCK(&shard_inode->lock); { __shard_inode_ctx_get(shard_inode, this, &ctx); if ((list_empty(&ctx->to_fsync_list)) && (list_empty(&ctx->ilist))) { shard_make_block_bname(ctx->block_num, ctx->base_gfid, block_bname, sizeof(block_bname)); inode_unlink(shard_inode, priv->dot_shard_inode, block_bname); /* The following unref corresponds to the ref held by * inode_link() at the time the shard was created or * looked up */ inode_unref(shard_inode); inode_forget(shard_inode, 0); } } UNLOCK(&shard_inode->lock); UNLOCK(&priv->lock); out: if (anon_fd) fd_unref(anon_fd); STACK_DESTROY(frame->root); return 0; } static int shard_initiate_evicted_inode_fsync(xlator_t *this, inode_t *inode) { fd_t *anon_fd = NULL; call_frame_t *fsync_frame = NULL; fsync_frame = create_frame(this, this->ctx->pool); if (!fsync_frame) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SHARD_MSG_MEMALLOC_FAILED, "Failed to create new frame " "to fsync shard"); return -1; } anon_fd = fd_anonymous(inode); if (!anon_fd) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SHARD_MSG_MEMALLOC_FAILED, "Failed to create anon fd to" " fsync shard"); STACK_DESTROY(fsync_frame->root); return -1; } STACK_WIND_COOKIE(fsync_frame, shard_evicted_inode_fsync_cbk, anon_fd, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, anon_fd, 1, NULL); return 0; } int shard_common_inode_write_post_lookup_shards_handler(call_frame_t *frame, xlator_t *this); int shard_common_resolve_shards(call_frame_t *frame, xlator_t *this, shard_post_resolve_fop_handler_t post_res_handler) { int i = -1; uint32_t shard_idx_iter = 0; int prefix_len = 0; char path[SHARD_PATH_MAX]; uuid_t gfid = { 0, }; inode_t *inode = NULL; inode_t *res_inode = NULL; inode_t *fsync_inode = NULL; shard_priv_t *priv = NULL; shard_local_t *local = NULL; uint64_t resolve_count = 0; priv = this->private; local = frame->local; local->call_count = 0; shard_idx_iter = local->first_block; res_inode = local->resolver_base_inode; if ((local->op_ret < 0) || (local->resolve_not)) goto out; /* If this prealloc FOP is for fresh file creation, then the size of the * file will be 0. Then there will be no shards associated with this file. * So we can skip the lookup process for the shards which do not exists * and directly issue mknod to crete shards. * * In case the prealloc fop is to extend the preallocated file to bigger * size then just lookup and populate inodes of existing shards and * update the create count */ if (local->fop == GF_FOP_FALLOCATE) { if (!local->prebuf.ia_size) { local->inode_list[0] = inode_ref(res_inode); local->create_count = local->last_block; shard_common_inode_write_post_lookup_shards_handler(frame, this); return 0; } if (local->prebuf.ia_size < local->total_size) local->create_count = local->last_block - ((local->prebuf.ia_size - 1) / local->block_size); } resolve_count = local->last_block - local->create_count; if (res_inode) gf_uuid_copy(gfid, res_inode->gfid); else gf_uuid_copy(gfid, local->base_gfid); /* Build base shard path before appending index of the shard */ prefix_len = shard_make_base_path(path, gfid); while (shard_idx_iter <= resolve_count) { i++; if (shard_idx_iter == 0) { local->inode_list[i] = inode_ref(res_inode); shard_idx_iter++; continue; } shard_append_index(path, SHARD_PATH_MAX, prefix_len, shard_idx_iter); inode = NULL; inode = inode_resolve(this->itable, path); if (inode) { gf_msg_debug(this->name, 0, "Shard %s already present. Saving inode for future.", path); local->inode_list[i] = inode; /* Let the ref on the inodes that are already present * in inode table still be held so that they don't get * forgotten by the time the fop reaches the actual * write stage. */ LOCK(&priv->lock); { fsync_inode = __shard_update_shards_inode_list( inode, this, res_inode, shard_idx_iter, gfid); } UNLOCK(&priv->lock); shard_idx_iter++; if (fsync_inode) shard_initiate_evicted_inode_fsync(this, fsync_inode); continue; } else { local->call_count++; shard_idx_iter++; } } out: post_res_handler(frame, this); return 0; } static int shard_update_file_size_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { inode_t *inode = NULL; shard_local_t *local = NULL; local = frame->local; if ((local->fd) && (local->fd->inode)) inode = local->fd->inode; else if (local->loc.inode) inode = local->loc.inode; if (op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_UPDATE_FILE_SIZE_FAILED, "Update to file size" " xattr failed on %s", uuid_utoa(inode->gfid)); local->op_ret = op_ret; local->op_errno = op_errno; goto err; } if (shard_modify_size_and_block_count(&local->postbuf, dict, _gf_true)) { local->op_ret = -1; local->op_errno = ENOMEM; goto err; } err: local->post_update_size_handler(frame, this); return 0; } int shard_set_size_attrs(int64_t size, int64_t block_count, int64_t **size_attr_p) { int ret = -1; int64_t *size_attr = NULL; if (!size_attr_p) goto out; size_attr = GF_CALLOC(4, sizeof(int64_t), gf_shard_mt_int64_t); if (!size_attr) goto out; size_attr[0] = htobe64(size); /* As sharding evolves, it _may_ be necessary to embed more pieces of * information within the same xattr. So allocating slots for them in * advance. For now, only bytes 0-63 and 128-191 which would make up the * current size and block count respectively of the file are valid. */ size_attr[2] = htobe64(block_count); *size_attr_p = size_attr; ret = 0; out: return ret; } int shard_update_file_size(call_frame_t *frame, xlator_t *this, fd_t *fd, loc_t *loc, shard_post_update_size_fop_handler_t handler) { int ret = -1; int64_t *size_attr = NULL; int64_t delta_blocks = 0; inode_t *inode = NULL; shard_local_t *local = NULL; dict_t *xattr_req = NULL; local = frame->local; local->post_update_size_handler = handler; xattr_req = dict_new(); if (!xattr_req) { local->op_ret = -1; local->op_errno = ENOMEM; goto out; } if (fd) inode = fd->inode; else inode = loc->inode; /* If both size and block count have not changed, then skip the xattrop. */ delta_blocks = GF_ATOMIC_GET(local->delta_blocks); if ((local->delta_size + local->hole_size == 0) && (delta_blocks == 0)) { goto out; } ret = shard_set_size_attrs(local->delta_size + local->hole_size, delta_blocks, &size_attr); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_SIZE_SET_FAILED, "Failed to set size attrs for %s", uuid_utoa(inode->gfid)); local->op_ret = -1; local->op_errno = ENOMEM; goto out; } ret = dict_set_bin(xattr_req, GF_XATTR_SHARD_FILE_SIZE, size_attr, 8 * 4); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set key %s into dict. gfid=%s", GF_XATTR_SHARD_FILE_SIZE, uuid_utoa(inode->gfid)); GF_FREE(size_attr); local->op_ret = -1; local->op_errno = ENOMEM; goto out; } if (fd) STACK_WIND(frame, shard_update_file_size_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, GF_XATTROP_ADD_ARRAY64, xattr_req, NULL); else STACK_WIND(frame, shard_update_file_size_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, GF_XATTROP_ADD_ARRAY64, xattr_req, NULL); dict_unref(xattr_req); return 0; out: if (xattr_req) dict_unref(xattr_req); handler(frame, this); return 0; } static inode_t * shard_link_internal_dir_inode(shard_local_t *local, inode_t *inode, xlator_t *this, struct iatt *buf, shard_internal_dir_type_t type) { inode_t *linked_inode = NULL; shard_priv_t *priv = NULL; char *bname = NULL; inode_t **priv_inode = NULL; inode_t *parent = NULL; priv = this->private; switch (type) { case SHARD_INTERNAL_DIR_DOT_SHARD: bname = GF_SHARD_DIR; priv_inode = &priv->dot_shard_inode; parent = inode->table->root; break; case SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME: bname = GF_SHARD_REMOVE_ME_DIR; priv_inode = &priv->dot_shard_rm_inode; parent = priv->dot_shard_inode; break; default: break; } linked_inode = inode_link(inode, parent, bname, buf); inode_lookup(linked_inode); *priv_inode = linked_inode; return linked_inode; } static int shard_refresh_internal_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { shard_local_t *local = NULL; inode_t *linked_inode = NULL; shard_internal_dir_type_t type = (shard_internal_dir_type_t)cookie; local = frame->local; if (op_ret) { local->op_ret = op_ret; local->op_errno = op_errno; goto out; } /* To-Do: Fix refcount increment per call to * shard_link_internal_dir_inode(). */ linked_inode = shard_link_internal_dir_inode(local, inode, this, buf, type); shard_inode_ctx_mark_dir_refreshed(linked_inode, this); out: shard_common_resolve_shards(frame, this, local->post_res_handler); return 0; } int shard_refresh_internal_dir(call_frame_t *frame, xlator_t *this, shard_internal_dir_type_t type) { loc_t loc = { 0, }; inode_t *inode = NULL; shard_priv_t *priv = NULL; shard_local_t *local = NULL; uuid_t gfid = { 0, }; local = frame->local; priv = this->private; switch (type) { case SHARD_INTERNAL_DIR_DOT_SHARD: gf_uuid_copy(gfid, priv->dot_shard_gfid); break; case SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME: gf_uuid_copy(gfid, priv->dot_shard_rm_gfid); break; default: break; } inode = inode_find(this->itable, gfid); if (!shard_inode_ctx_needs_lookup(inode, this)) { local->op_ret = 0; goto out; } /* Plain assignment because the ref is already taken above through * call to inode_find() */ loc.inode = inode; gf_uuid_copy(loc.gfid, gfid); STACK_WIND_COOKIE(frame, shard_refresh_internal_dir_cbk, (void *)(long)type, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &loc, NULL); loc_wipe(&loc); return 0; out: shard_common_resolve_shards(frame, this, local->post_res_handler); return 0; } int shard_lookup_internal_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { inode_t *link_inode = NULL; shard_local_t *local = NULL; shard_internal_dir_type_t type = (shard_internal_dir_type_t)cookie; local = frame->local; if (op_ret) { local->op_ret = op_ret; local->op_errno = op_errno; goto unwind; } if (!IA_ISDIR(buf->ia_type)) { gf_msg(this->name, GF_LOG_CRITICAL, 0, SHARD_MSG_DOT_SHARD_NODIR, "%s already exists and " "is not a directory. Please remove it from all bricks " "and try again", shard_internal_dir_string(type)); local->op_ret = -1; local->op_errno = EIO; goto unwind; } link_inode = shard_link_internal_dir_inode(local, inode, this, buf, type); if (link_inode != inode) { shard_refresh_internal_dir(frame, this, type); } else { shard_inode_ctx_mark_dir_refreshed(link_inode, this); shard_common_resolve_shards(frame, this, local->post_res_handler); } return 0; unwind: local->post_res_handler(frame, this); return 0; } int shard_lookup_internal_dir(call_frame_t *frame, xlator_t *this, shard_post_resolve_fop_handler_t post_res_handler, shard_internal_dir_type_t type) { int ret = -1; dict_t *xattr_req = NULL; shard_priv_t *priv = NULL; shard_local_t *local = NULL; uuid_t *gfid = NULL; loc_t *loc = NULL; gf_boolean_t free_gfid = _gf_true; local = frame->local; priv = this->private; local->post_res_handler = post_res_handler; gfid = GF_MALLOC(sizeof(uuid_t), gf_common_mt_uuid_t); if (!gfid) goto err; xattr_req = dict_new(); if (!xattr_req) { local->op_ret = -1; local->op_errno = ENOMEM; goto err; } switch (type) { case SHARD_INTERNAL_DIR_DOT_SHARD: gf_uuid_copy(*gfid, priv->dot_shard_gfid); loc = &local->dot_shard_loc; break; case SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME: gf_uuid_copy(*gfid, priv->dot_shard_rm_gfid); loc = &local->dot_shard_rm_loc; break; default: bzero(*gfid, sizeof(uuid_t)); break; } ret = dict_set_gfuuid(xattr_req, "gfid-req", *gfid, false); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set gfid of %s into dict", shard_internal_dir_string(type)); local->op_ret = -1; local->op_errno = ENOMEM; goto err; } else { free_gfid = _gf_false; } STACK_WIND_COOKIE(frame, shard_lookup_internal_dir_cbk, (void *)(long)type, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xattr_req); dict_unref(xattr_req); return 0; err: if (xattr_req) dict_unref(xattr_req); if (free_gfid) GF_FREE(gfid); post_res_handler(frame, this); return 0; } static void shard_inode_ctx_update(inode_t *inode, xlator_t *this, dict_t *xdata, struct iatt *buf) { int ret = 0; uint64_t size = 0; void *bsize = NULL; if (shard_inode_ctx_get_block_size(inode, this, &size)) { /* Fresh lookup */ ret = dict_get_ptr(xdata, GF_XATTR_SHARD_BLOCK_SIZE, &bsize); if (!ret) size = be64toh(*((uint64_t *)bsize)); /* If the file is sharded, set its block size, otherwise just * set 0. */ shard_inode_ctx_set(inode, this, buf, size, SHARD_MASK_BLOCK_SIZE); } /* If the file is sharded, also set the remaining attributes, * except for ia_size and ia_blocks. */ if (size) { shard_inode_ctx_set(inode, this, buf, 0, SHARD_LOOKUP_MASK); (void)shard_inode_ctx_invalidate(inode, this, buf); } } int shard_delete_shards(void *opaque); static int shard_delete_shards_cbk(int ret, call_frame_t *frame, void *data); int shard_start_background_deletion(xlator_t *this) { int ret = 0; gf_boolean_t i_cleanup = _gf_true; shard_priv_t *priv = NULL; call_frame_t *cleanup_frame = NULL; priv = this->private; LOCK(&priv->lock); { switch (priv->bg_del_state) { case SHARD_BG_DELETION_NONE: i_cleanup = _gf_true; priv->bg_del_state = SHARD_BG_DELETION_LAUNCHING; break; case SHARD_BG_DELETION_LAUNCHING: i_cleanup = _gf_false; break; case SHARD_BG_DELETION_IN_PROGRESS: priv->bg_del_state = SHARD_BG_DELETION_LAUNCHING; i_cleanup = _gf_false; break; default: break; } } UNLOCK(&priv->lock); if (!i_cleanup) return 0; cleanup_frame = create_frame(this, this->ctx->pool); if (!cleanup_frame) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SHARD_MSG_MEMALLOC_FAILED, "Failed to create " "new frame to delete shards"); ret = -ENOMEM; goto err; } set_lk_owner_from_ptr(&cleanup_frame->root->lk_owner, cleanup_frame->root); ret = synctask_new(this->ctx->env, shard_delete_shards, shard_delete_shards_cbk, cleanup_frame, cleanup_frame); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, errno, SHARD_MSG_SHARDS_DELETION_FAILED, "failed to create task to do background " "cleanup of shards"); STACK_DESTROY(cleanup_frame->root); goto err; } return 0; err: LOCK(&priv->lock); { priv->bg_del_state = SHARD_BG_DELETION_NONE; } UNLOCK(&priv->lock); return ret; } static int shard_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { int ret = -1; shard_priv_t *priv = NULL; gf_boolean_t i_start_cleanup = _gf_false; priv = this->private; if (op_ret < 0) goto unwind; if (IA_ISDIR(buf->ia_type)) goto unwind; /* Also, if the file is sharded, get the file size and block cnt xattr, * and store them in the stbuf appropriately. */ if (frame->root->pid != GF_CLIENT_PID_GSYNCD) shard_modify_size_and_block_count(buf, xdata, _gf_false); /* If this was a fresh lookup, there are two possibilities: * 1) If the file is sharded (indicated by the presence of block size * xattr), store this block size, along with rdev and mode in its * inode ctx. * 2) If the file is not sharded, store size along with rdev and mode * (which are anyway don't cares) in inode ctx. Since @ctx_tmp is * already initialised to all zeroes, nothing more needs to be done. */ (void)shard_inode_ctx_update(inode, this, xdata, buf); LOCK(&priv->lock); { if (priv->first_lookup_done == _gf_false) { priv->first_lookup_done = _gf_true; i_start_cleanup = _gf_true; } } UNLOCK(&priv->lock); if (!i_start_cleanup) goto unwind; ret = shard_start_background_deletion(this); if (ret < 0) { LOCK(&priv->lock); { priv->first_lookup_done = _gf_false; } UNLOCK(&priv->lock); } unwind: SHARD_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, buf, xdata, postparent); return 0; } int shard_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { int ret = -1; int32_t op_errno = ENOMEM; uint64_t block_size = 0; shard_local_t *local = NULL; this->itable = loc->inode->table; if ((frame->root->pid != GF_CLIENT_PID_GSYNCD) && (frame->root->pid != GF_CLIENT_PID_GLFS_HEAL)) { SHARD_ENTRY_FOP_CHECK(loc, op_errno, err); } local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; loc_copy(&local->loc, loc); local->xattr_req = xattr_req ? dict_ref(xattr_req) : dict_new(); if (!local->xattr_req) goto err; if (shard_inode_ctx_get_block_size(loc->inode, this, &block_size)) { ret = dict_set_uint64(local->xattr_req, GF_XATTR_SHARD_BLOCK_SIZE, 0); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set dict" " value: key:%s for path %s", GF_XATTR_SHARD_BLOCK_SIZE, loc->path); goto err; } } if (frame->root->pid != GF_CLIENT_PID_GSYNCD) { ret = dict_set_uint64(local->xattr_req, GF_XATTR_SHARD_FILE_SIZE, 8 * 4); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set dict value: key:%s for path %s.", GF_XATTR_SHARD_FILE_SIZE, loc->path); goto err; } } if ((xattr_req) && (dict_get(xattr_req, GF_CONTENT_KEY))) dict_del(xattr_req, GF_CONTENT_KEY); STACK_WIND(frame, shard_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, local->xattr_req); return 0; err: shard_common_failure_unwind(GF_FOP_LOOKUP, frame, -1, op_errno); return 0; } int shard_set_iattr_invoke_post_handler(call_frame_t *frame, xlator_t *this, inode_t *inode, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { int ret = -1; int32_t mask = SHARD_INODE_WRITE_MASK; shard_local_t *local = frame->local; shard_inode_ctx_t ctx = { 0, }; if (op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_BASE_FILE_LOOKUP_FAILED, "Lookup on base file" " failed : %s", uuid_utoa(inode->gfid)); local->op_ret = op_ret; local->op_errno = op_errno; goto unwind; } local->prebuf = *buf; if (shard_modify_size_and_block_count(&local->prebuf, xdata, _gf_true)) { local->op_ret = -1; local->op_errno = EINVAL; goto unwind; } if (shard_inode_ctx_get_all(inode, this, &ctx)) mask = SHARD_ALL_MASK; ret = shard_inode_ctx_set(inode, this, &local->prebuf, 0, (mask | SHARD_MASK_REFRESH_RESET)); if (ret) { gf_msg(this->name, GF_LOG_ERROR, SHARD_MSG_INODE_CTX_SET_FAILED, 0, "Failed to set inode" " write params into inode ctx for %s", uuid_utoa(buf->ia_gfid)); local->op_ret = -1; local->op_errno = ENOMEM; goto unwind; } unwind: local->handler(frame, this); return 0; } int shard_fstat_base_file_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { shard_local_t *local = frame->local; shard_set_iattr_invoke_post_handler(frame, this, local->fd->inode, op_ret, op_errno, buf, xdata); return 0; } int shard_lookup_base_file_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { /* In case of op_ret < 0, inode passed to this function will be NULL ex: in case of op_errno = ENOENT. So refer prefilled inode data which is part of local. Note: Reassigning/overriding the inode passed to this cbk with inode which is part of *struct shard_local_t* won't cause any issue as both inodes have same reference/address as of the inode passed */ inode = ((shard_local_t *)frame->local)->loc.inode; shard_set_iattr_invoke_post_handler(frame, this, inode, op_ret, op_errno, buf, xdata); return 0; } /* This function decides whether to make file based lookup or * fd based lookup (fstat) depending on the 3rd and 4th arg. * If fd != NULL and loc == NULL then call is for fstat * If fd == NULL and loc != NULL then call is for file based * lookup. Please pass args based on the requirement. */ int shard_refresh_base_file(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, shard_post_fop_handler_t handler) { int ret = -1; inode_t *inode = NULL; shard_local_t *local = NULL; dict_t *xattr_req = NULL; gf_boolean_t need_refresh = _gf_false; local = frame->local; local->handler = handler; inode = fd ? fd->inode : loc->inode; ret = shard_inode_ctx_fill_iatt_from_cache(inode, this, &local->prebuf, &need_refresh); /* By this time, inode ctx should have been created either in create, * mknod, readdirp or lookup. If not it is a bug! */ if ((ret == 0) && (need_refresh == _gf_false)) { gf_msg_debug(this->name, 0, "Skipping lookup on base file: %s" "Serving prebuf off the inode ctx cache", uuid_utoa(inode->gfid)); goto out; } xattr_req = dict_new(); if (!xattr_req) { local->op_ret = -1; local->op_errno = ENOMEM; goto out; } SHARD_MD_READ_FOP_INIT_REQ_DICT(this, xattr_req, inode->gfid, local, out); if (fd) STACK_WIND(frame, shard_fstat_base_file_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xattr_req); else STACK_WIND(frame, shard_lookup_base_file_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xattr_req); dict_unref(xattr_req); return 0; out: if (xattr_req) dict_unref(xattr_req); handler(frame, this); return 0; } static int shard_post_fstat_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret >= 0) shard_inode_ctx_set(local->fd->inode, this, &local->prebuf, 0, SHARD_LOOKUP_MASK); SHARD_STACK_UNWIND(fstat, frame, local->op_ret, local->op_errno, &local->prebuf, local->xattr_rsp); return 0; } static int shard_post_stat_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret >= 0) shard_inode_ctx_set(local->loc.inode, this, &local->prebuf, 0, SHARD_LOOKUP_MASK); SHARD_STACK_UNWIND(stat, frame, local->op_ret, local->op_errno, &local->prebuf, local->xattr_rsp); return 0; } int shard_common_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { inode_t *inode = NULL; shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_STAT_FAILED, "stat failed: %s", local->fd ? uuid_utoa(local->fd->inode->gfid) : uuid_utoa((local->loc.inode)->gfid)); local->op_ret = op_ret; local->op_errno = op_errno; goto unwind; } local->prebuf = *buf; if (shard_modify_size_and_block_count(&local->prebuf, xdata, _gf_true)) { local->op_ret = -1; local->op_errno = EINVAL; goto unwind; } local->xattr_rsp = dict_ref(xdata); if (local->loc.inode) inode = local->loc.inode; else inode = local->fd->inode; shard_inode_ctx_invalidate(inode, this, &local->prebuf); unwind: local->handler(frame, this); return 0; } int shard_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int ret = -1; uint64_t block_size = 0; shard_local_t *local = NULL; if ((IA_ISDIR(loc->inode->ia_type)) || (IA_ISLNK(loc->inode->ia_type))) { STACK_WIND(frame, default_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; } if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; } ret = shard_inode_ctx_get_block_size(loc->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size from inode ctx of %s", uuid_utoa(loc->inode->gfid)); goto err; } if (!block_size) { STACK_WIND(frame, default_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; } local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->handler = shard_post_stat_handler; loc_copy(&local->loc, loc); local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; SHARD_MD_READ_FOP_INIT_REQ_DICT(this, local->xattr_req, local->loc.gfid, local, err); STACK_WIND(frame, shard_common_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, local->xattr_req); return 0; err: shard_common_failure_unwind(GF_FOP_STAT, frame, -1, ENOMEM); return 0; } int shard_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int ret = -1; uint64_t block_size = 0; shard_local_t *local = NULL; if ((IA_ISDIR(fd->inode->ia_type)) || (IA_ISLNK(fd->inode->ia_type))) { STACK_WIND(frame, default_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; } if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; } ret = shard_inode_ctx_get_block_size(fd->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size from inode ctx of %s", uuid_utoa(fd->inode->gfid)); goto err; } if (!block_size) { STACK_WIND(frame, default_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; } if (!this->itable) this->itable = fd->inode->table; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->handler = shard_post_fstat_handler; local->fd = fd_ref(fd); local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; SHARD_MD_READ_FOP_INIT_REQ_DICT(this, local->xattr_req, fd->inode->gfid, local, err); STACK_WIND(frame, shard_common_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, local->xattr_req); return 0; err: shard_common_failure_unwind(GF_FOP_FSTAT, frame, -1, ENOMEM); return 0; } static int shard_post_update_size_truncate_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->fop == GF_FOP_TRUNCATE) SHARD_STACK_UNWIND(truncate, frame, local->op_ret, local->op_errno, &local->prebuf, &local->postbuf, NULL); else SHARD_STACK_UNWIND(ftruncate, frame, local->op_ret, local->op_errno, &local->prebuf, &local->postbuf, NULL); return 0; } int shard_truncate_last_shard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *inode = NULL; int64_t delta_blocks = 0; shard_local_t *local = NULL; local = frame->local; SHARD_UNSET_ROOT_FS_ID(frame, local); inode = (local->fop == GF_FOP_TRUNCATE) ? local->loc.inode : local->fd->inode; if (op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_TRUNCATE_LAST_SHARD_FAILED, "truncate on last" " shard failed : %s", uuid_utoa(inode->gfid)); local->op_ret = op_ret; local->op_errno = op_errno; goto err; } local->postbuf.ia_size = local->offset; /* Let the delta be negative. We want xattrop to do subtraction */ local->delta_size = local->postbuf.ia_size - local->prebuf.ia_size; delta_blocks = GF_ATOMIC_ADD(local->delta_blocks, postbuf->ia_blocks - prebuf->ia_blocks); GF_ASSERT(delta_blocks <= 0); local->postbuf.ia_blocks += delta_blocks; local->hole_size = 0; shard_inode_ctx_set(inode, this, &local->postbuf, 0, SHARD_MASK_TIMES); shard_update_file_size(frame, this, NULL, &local->loc, shard_post_update_size_truncate_handler); return 0; err: shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } static int shard_truncate_last_shard(call_frame_t *frame, xlator_t *this, inode_t *inode) { size_t last_shard_size_after = 0; loc_t loc = { 0, }; shard_local_t *local = NULL; local = frame->local; /* A NULL inode could be due to the fact that the last shard which * needs to be truncated does not exist due to it lying in a hole * region. So the only thing left to do in that case would be an * update to file size xattr. */ if (!inode) { gf_msg_debug(this->name, 0, "Last shard to be truncated absent in backend: %" PRIu64 " of gfid %s. Directly proceeding to update file size", local->first_block, uuid_utoa(local->loc.inode->gfid)); shard_update_file_size(frame, this, NULL, &local->loc, shard_post_update_size_truncate_handler); return 0; } SHARD_SET_ROOT_FS_ID(frame, local); loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); last_shard_size_after = (local->offset % local->block_size); STACK_WIND(frame, shard_truncate_last_shard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &loc, last_shard_size_after, NULL); loc_wipe(&loc); return 0; } void shard_unlink_block_inode(shard_local_t *local, int shard_block_num); static int shard_truncate_htol_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int ret = 0; int call_count = 0; int shard_block_num = (long)cookie; uint64_t block_count = 0; shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; goto done; } ret = dict_get_uint64(xdata, GF_GET_FILE_BLOCK_COUNT, &block_count); if (!ret) { GF_ATOMIC_SUB(local->delta_blocks, block_count); } else { /* dict_get failed possibly due to a heterogeneous cluster? */ gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to get key %s from dict during truncate of gfid %s", GF_GET_FILE_BLOCK_COUNT, uuid_utoa(local->resolver_base_inode->gfid)); } shard_unlink_block_inode(local, shard_block_num); done: call_count = shard_call_count_return(frame); if (call_count == 0) { SHARD_UNSET_ROOT_FS_ID(frame, local); shard_truncate_last_shard(frame, this, local->inode_list[0]); } return 0; } int shard_truncate_htol(call_frame_t *frame, xlator_t *this, inode_t *inode) { int i = 1; int ret = -1; int call_count = 0; uint32_t cur_block = 0; uint32_t last_block = 0; int prefix_len = 0; char path[SHARD_PATH_MAX]; char *bname = NULL; loc_t loc = { 0, }; gf_boolean_t wind_failed = _gf_false; shard_local_t *local = NULL; shard_priv_t *priv = NULL; dict_t *xdata_req = NULL; local = frame->local; priv = this->private; cur_block = local->first_block + 1; last_block = local->last_block; /* Determine call count */ for (i = 1; i < local->num_blocks; i++) { if (!local->inode_list[i]) continue; call_count++; } if (!call_count) { /* Call count = 0 implies that all of the shards that need to be * unlinked do not exist. So shard xlator would now proceed to * do the final truncate + size updates. */ gf_msg_debug(this->name, 0, "Shards to be unlinked as part of " "truncate absent in backend: %s. Directly " "proceeding to update file size", uuid_utoa(inode->gfid)); local->postbuf.ia_size = local->offset; local->postbuf.ia_blocks = local->prebuf.ia_blocks; local->delta_size = local->postbuf.ia_size - local->prebuf.ia_size; GF_ATOMIC_INIT(local->delta_blocks, 0); local->hole_size = 0; shard_update_file_size(frame, this, local->fd, &local->loc, shard_post_update_size_truncate_handler); return 0; } local->call_count = call_count; i = 1; xdata_req = dict_new(); if (!xdata_req) { shard_common_failure_unwind(local->fop, frame, -1, ENOMEM); return 0; } ret = dict_set_uint64(xdata_req, GF_GET_FILE_BLOCK_COUNT, 8 * 8); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set key %s into dict during truncate of %s", GF_GET_FILE_BLOCK_COUNT, uuid_utoa(local->resolver_base_inode->gfid)); dict_unref(xdata_req); shard_common_failure_unwind(local->fop, frame, -1, ENOMEM); return 0; } /* Build base shard path before appending index of the shard */ prefix_len = shard_make_base_path(path, inode->gfid); bname = path + sizeof(GF_SHARD_DIR) + 1; SHARD_SET_ROOT_FS_ID(frame, local); while (cur_block <= last_block) { if (!local->inode_list[i]) { cur_block++; i++; continue; } if (wind_failed) { shard_truncate_htol_cbk(frame, (void *)(long)cur_block, this, -1, ENOMEM, NULL, NULL, NULL); goto next; } shard_append_index(path, SHARD_PATH_MAX, prefix_len, cur_block); loc.parent = inode_ref(priv->dot_shard_inode); ret = inode_path(loc.parent, bname, (char **)&(loc.path)); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed on %s.", bname); local->op_ret = -1; local->op_errno = ENOMEM; loc_wipe(&loc); wind_failed = _gf_true; shard_truncate_htol_cbk(frame, (void *)(long)cur_block, this, -1, ENOMEM, NULL, NULL, NULL); goto next; } loc.name = strrchr(loc.path, '/'); if (loc.name) loc.name++; loc.inode = inode_ref(local->inode_list[i]); STACK_WIND_COOKIE(frame, shard_truncate_htol_cbk, (void *)(long)cur_block, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &loc, 0, xdata_req); loc_wipe(&loc); next: i++; cur_block++; if (!--call_count) break; } dict_unref(xdata_req); return 0; } int shard_truncate_do(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->num_blocks == 1) { /* This means that there are no shards to be unlinked. * The fop boils down to truncating the last shard, updating * the size and unwinding. */ shard_truncate_last_shard(frame, this, local->inode_list[0]); return 0; } else { shard_truncate_htol(frame, this, local->loc.inode); } return 0; } static int shard_post_lookup_shards_truncate_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } shard_truncate_do(frame, this); return 0; } static void shard_link_block_inode(shard_local_t *local, int block_num, inode_t *inode, struct iatt *buf) { int list_index = 0; char block_bname[256] = { 0, }; uuid_t gfid = { 0, }; inode_t *linked_inode = NULL; xlator_t *this = NULL; inode_t *fsync_inode = NULL; shard_priv_t *priv = NULL; inode_t *base_inode = NULL; this = THIS; priv = this->private; if (local->loc.inode) { gf_uuid_copy(gfid, local->loc.inode->gfid); base_inode = local->loc.inode; } else if (local->resolver_base_inode) { gf_uuid_copy(gfid, local->resolver_base_inode->gfid); base_inode = local->resolver_base_inode; } else { gf_uuid_copy(gfid, local->base_gfid); } shard_make_block_bname(block_num, gfid, block_bname, sizeof(block_bname)); shard_inode_ctx_set(inode, this, buf, 0, SHARD_LOOKUP_MASK); linked_inode = inode_link(inode, priv->dot_shard_inode, block_bname, buf); inode_lookup(linked_inode); list_index = block_num - local->first_block; local->inode_list[list_index] = linked_inode; LOCK(&priv->lock); { fsync_inode = __shard_update_shards_inode_list( linked_inode, this, base_inode, block_num, gfid); } UNLOCK(&priv->lock); if (fsync_inode) shard_initiate_evicted_inode_fsync(this, fsync_inode); } int shard_common_lookup_shards_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { int call_count = 0; int shard_block_num = (long)cookie; uuid_t gfid = { 0, }; shard_local_t *local = NULL; local = frame->local; if (local->resolver_base_inode) gf_uuid_copy(gfid, local->resolver_base_inode->gfid); else gf_uuid_copy(gfid, local->base_gfid); if (op_ret < 0) { /* Ignore absence of shards in the backend in truncate fop. */ switch (local->fop) { case GF_FOP_TRUNCATE: case GF_FOP_FTRUNCATE: case GF_FOP_RENAME: case GF_FOP_UNLINK: if (op_errno == ENOENT) goto done; break; case GF_FOP_WRITE: case GF_FOP_READ: case GF_FOP_ZEROFILL: case GF_FOP_DISCARD: case GF_FOP_FALLOCATE: if ((!local->first_lookup_done) && (op_errno == ENOENT)) { LOCK(&frame->lock); { local->create_count++; } UNLOCK(&frame->lock); goto done; } break; default: break; } /* else */ gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_LOOKUP_SHARD_FAILED, "Lookup on shard %d " "failed. Base file gfid = %s", shard_block_num, uuid_utoa(gfid)); local->op_ret = op_ret; local->op_errno = op_errno; goto done; } shard_link_block_inode(local, shard_block_num, inode, buf); done: if (local->lookup_shards_barriered) { syncbarrier_wake(&local->barrier); return 0; } else { call_count = shard_call_count_return(frame); if (call_count == 0) { if (!local->first_lookup_done) local->first_lookup_done = _gf_true; local->pls_fop_handler(frame, this); } } return 0; } dict_t * shard_create_gfid_dict(dict_t *dict) { int ret = 0; dict_t *new = NULL; unsigned char *gfid = NULL; new = dict_copy_with_ref(dict, NULL); if (!new) return NULL; gfid = GF_MALLOC(sizeof(uuid_t), gf_common_mt_char); if (!gfid) { ret = -1; goto out; } gf_uuid_generate(gfid); ret = dict_set_gfuuid(new, "gfid-req", gfid, false); out: if (ret) { dict_unref(new); new = NULL; GF_FREE(gfid); } return new; } static int shard_common_lookup_shards(call_frame_t *frame, xlator_t *this, inode_t *inode, shard_post_lookup_shards_fop_handler_t handler) { int i = 0; int ret = 0; int count = 0; int call_count = 0; int32_t shard_idx_iter = 0; int lookup_count = 0; char path[SHARD_PATH_MAX]; char *bname = NULL; loc_t loc = { 0, }; shard_local_t *local = NULL; shard_priv_t *priv = NULL; gf_boolean_t wind_failed = _gf_false; dict_t *xattr_req = NULL; priv = this->private; local = frame->local; count = call_count = local->call_count; shard_idx_iter = local->first_block; lookup_count = local->last_block - local->create_count; local->pls_fop_handler = handler; if (local->lookup_shards_barriered) local->barrier.waitfor = local->call_count; /* Build base shard path before appending index of the shard */ strcpy(path, "/" GF_SHARD_DIR "/"); if (inode) uuid_utoa_r(inode->gfid, path + sizeof(GF_SHARD_DIR) + 1); else uuid_utoa_r(local->base_gfid, path + sizeof(GF_SHARD_DIR) + 1); int prefix_len = sizeof(GF_SHARD_DIR) + GF_UUID_BUF_SIZE; bname = path + sizeof(GF_SHARD_DIR) + 1; while (shard_idx_iter <= lookup_count) { if (local->inode_list[i]) { i++; shard_idx_iter++; continue; } if (wind_failed) { shard_common_lookup_shards_cbk(frame, (void *)(long)shard_idx_iter, this, -1, ENOMEM, NULL, NULL, NULL, NULL); goto next; } shard_append_index(path, SHARD_PATH_MAX, prefix_len, shard_idx_iter); loc.inode = inode_new(this->itable); loc.parent = inode_ref(priv->dot_shard_inode); gf_uuid_copy(loc.pargfid, priv->dot_shard_gfid); ret = inode_path(loc.parent, bname, (char **)&(loc.path)); if (ret < 0 || !(loc.inode)) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed on %s", bname); local->op_ret = -1; local->op_errno = ENOMEM; loc_wipe(&loc); wind_failed = _gf_true; shard_common_lookup_shards_cbk(frame, (void *)(long)shard_idx_iter, this, -1, ENOMEM, NULL, NULL, NULL, NULL); goto next; } loc.name = strrchr(loc.path, '/'); if (loc.name) loc.name++; xattr_req = shard_create_gfid_dict(local->xattr_req); if (!xattr_req) { local->op_ret = -1; local->op_errno = ENOMEM; wind_failed = _gf_true; loc_wipe(&loc); shard_common_lookup_shards_cbk(frame, (void *)(long)shard_idx_iter, this, -1, ENOMEM, NULL, NULL, NULL, NULL); goto next; } STACK_WIND_COOKIE(frame, shard_common_lookup_shards_cbk, (void *)(long)shard_idx_iter, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &loc, xattr_req); loc_wipe(&loc); dict_unref(xattr_req); next: shard_idx_iter++; i++; if (!--call_count) break; } if (local->lookup_shards_barriered) { syncbarrier_wait(&local->barrier, count); local->pls_fop_handler(frame, this); } return 0; } static int shard_post_resolve_truncate_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { if (local->op_errno == ENOENT) { /* If lookup on /.shard fails with ENOENT, it means that * the file was 0-byte in size but truncated sometime in * the past to a higher size which is reflected in the * size xattr, and now being truncated to a lower size. * In this case, the only thing that needs to be done is * to update the size xattr of the file and unwind. */ local->first_block = local->last_block = 0; local->num_blocks = 1; local->call_count = 0; local->op_ret = 0; local->postbuf.ia_size = local->offset; shard_update_file_size(frame, this, local->fd, &local->loc, shard_post_update_size_truncate_handler); return 0; } else { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } } if (!local->call_count) shard_truncate_do(frame, this); else shard_common_lookup_shards(frame, this, local->loc.inode, shard_post_lookup_shards_truncate_handler); return 0; } static int shard_truncate_begin(call_frame_t *frame, xlator_t *this) { int ret = 0; shard_local_t *local = NULL; shard_priv_t *priv = NULL; priv = this->private; local = frame->local; /* First participant block here is the lowest numbered block that would * hold the last byte of the file post successful truncation. * Last participant block is the block that contains the last byte in * the current state of the file. * If (first block == last_block): * then that means that the file only needs truncation of the * first (or last since both are same) block. * Else * if (new_size % block_size == 0) * then that means there is no truncate to be done with * only shards from first_block + 1 through the last * block needing to be unlinked. * else * both truncate of the first block and unlink of the * remaining shards until end of file is required. */ local->first_block = (local->offset == 0) ? 0 : get_lowest_block(local->offset - 1, local->block_size); local->last_block = get_highest_block(0, local->prebuf.ia_size, local->block_size); local->num_blocks = local->last_block - local->first_block + 1; GF_ASSERT(local->num_blocks > 0); local->resolver_base_inode = (local->fop == GF_FOP_TRUNCATE) ? local->loc.inode : local->fd->inode; if ((local->first_block == 0) && (local->num_blocks == 1)) { if (local->fop == GF_FOP_TRUNCATE) STACK_WIND(frame, shard_truncate_last_shard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &local->loc, local->offset, local->xattr_req); else STACK_WIND(frame, shard_truncate_last_shard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, local->fd, local->offset, local->xattr_req); return 0; } local->inode_list = GF_CALLOC(local->num_blocks, sizeof(inode_t *), gf_shard_mt_inode_list); if (!local->inode_list) goto err; local->dot_shard_loc.inode = inode_find(this->itable, priv->dot_shard_gfid); if (!local->dot_shard_loc.inode) { ret = shard_init_internal_dir_loc(this, local, SHARD_INTERNAL_DIR_DOT_SHARD); if (ret) goto err; shard_lookup_internal_dir(frame, this, shard_post_resolve_truncate_handler, SHARD_INTERNAL_DIR_DOT_SHARD); } else { local->post_res_handler = shard_post_resolve_truncate_handler; shard_refresh_internal_dir(frame, this, SHARD_INTERNAL_DIR_DOT_SHARD); } return 0; err: shard_common_failure_unwind(local->fop, frame, -1, ENOMEM); return 0; } static int shard_post_lookup_truncate_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; struct iatt tmp_stbuf = { 0, }; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } local->postbuf = tmp_stbuf = local->prebuf; if (local->prebuf.ia_size == local->offset) { /* If the file size is same as requested size, unwind the call * immediately. */ if (local->fop == GF_FOP_TRUNCATE) SHARD_STACK_UNWIND(truncate, frame, 0, 0, &local->prebuf, &local->postbuf, NULL); else SHARD_STACK_UNWIND(ftruncate, frame, 0, 0, &local->prebuf, &local->postbuf, NULL); } else if (local->offset > local->prebuf.ia_size) { /* If the truncate is from a lower to a higher size, set the * new size xattr and unwind. */ local->hole_size = local->offset - local->prebuf.ia_size; local->delta_size = 0; GF_ATOMIC_INIT(local->delta_blocks, 0); local->postbuf.ia_size = local->offset; tmp_stbuf.ia_size = local->offset; shard_inode_ctx_set(local->loc.inode, this, &tmp_stbuf, 0, SHARD_INODE_WRITE_MASK); shard_update_file_size(frame, this, NULL, &local->loc, shard_post_update_size_truncate_handler); } else { /* ... else * i. unlink all shards that need to be unlinked. * ii. truncate the last of the shards. * iii. update the new size using setxattr. * and unwind the fop. */ local->hole_size = 0; local->delta_size = (local->offset - local->prebuf.ia_size); GF_ATOMIC_INIT(local->delta_blocks, 0); tmp_stbuf.ia_size = local->offset; shard_inode_ctx_set(local->loc.inode, this, &tmp_stbuf, 0, SHARD_INODE_WRITE_MASK); shard_truncate_begin(frame, this); } return 0; } /* TO-DO: * Fix updates to size and block count with racing write(s) and truncate(s). */ int shard_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { int ret = -1; uint64_t block_size = 0; shard_local_t *local = NULL; if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } ret = shard_inode_ctx_get_block_size(loc->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size from inode ctx of %s", uuid_utoa(loc->inode->gfid)); goto err; } if (!block_size) { STACK_WIND(frame, default_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } if (!this->itable) this->itable = loc->inode->table; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; ret = syncbarrier_init(&local->barrier); if (ret) goto err; loc_copy(&local->loc, loc); local->offset = offset; local->block_size = block_size; local->fop = GF_FOP_TRUNCATE; local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; local->resolver_base_inode = loc->inode; GF_ATOMIC_INIT(local->delta_blocks, 0); shard_refresh_base_file(frame, this, &local->loc, NULL, shard_post_lookup_truncate_handler); return 0; err: shard_common_failure_unwind(GF_FOP_TRUNCATE, frame, -1, ENOMEM); return 0; } int shard_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { int ret = -1; uint64_t block_size = 0; shard_local_t *local = NULL; if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } ret = shard_inode_ctx_get_block_size(fd->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size from inode ctx of %s", uuid_utoa(fd->inode->gfid)); goto err; } if (!block_size) { STACK_WIND(frame, default_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } if (!this->itable) this->itable = fd->inode->table; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; ret = syncbarrier_init(&local->barrier); if (ret) goto err; local->fd = fd_ref(fd); local->offset = offset; local->block_size = block_size; local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; local->fop = GF_FOP_FTRUNCATE; local->loc.inode = inode_ref(fd->inode); gf_uuid_copy(local->loc.gfid, fd->inode->gfid); local->resolver_base_inode = fd->inode; GF_ATOMIC_INIT(local->delta_blocks, 0); shard_refresh_base_file(frame, this, NULL, fd, shard_post_lookup_truncate_handler); return 0; err: shard_common_failure_unwind(GF_FOP_FTRUNCATE, frame, -1, ENOMEM); return 0; } int shard_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int ret = -1; shard_local_t *local = NULL; local = frame->local; if (op_ret == -1) goto unwind; ret = shard_inode_ctx_set(inode, this, buf, local->block_size, SHARD_ALL_MASK); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_INODE_CTX_SET_FAILED, "Failed to set inode " "ctx for %s", uuid_utoa(inode->gfid)); unwind: SHARD_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int shard_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { shard_priv_t *priv = NULL; shard_local_t *local = NULL; priv = this->private; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->block_size = priv->block_size; if (!__is_gsyncd_on_shard_dir(frame, loc)) { SHARD_INODE_CREATE_INIT(this, local->block_size, xdata, loc, 0, 0, err); } STACK_WIND(frame, shard_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; err: shard_common_failure_unwind(GF_FOP_MKNOD, frame, -1, ENOMEM); return 0; } int32_t shard_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) goto err; shard_inode_ctx_set(inode, this, buf, 0, SHARD_MASK_NLINK | SHARD_MASK_TIMES); buf->ia_size = local->prebuf.ia_size; buf->ia_blocks = local->prebuf.ia_blocks; SHARD_STACK_UNWIND(link, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; err: shard_common_failure_unwind(GF_FOP_LINK, frame, op_ret, op_errno); return 0; } static int shard_post_lookup_link_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { SHARD_STACK_UNWIND(link, frame, local->op_ret, local->op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } STACK_WIND(frame, shard_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, &local->loc, &local->loc2, local->xattr_req); return 0; } int32_t shard_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int ret = -1; uint64_t block_size = 0; shard_local_t *local = NULL; ret = shard_inode_ctx_get_block_size(oldloc->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size from inode ctx of %s", uuid_utoa(oldloc->inode->gfid)); goto err; } if (!block_size) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; } if (!this->itable) this->itable = oldloc->inode->table; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; loc_copy(&local->loc, oldloc); loc_copy(&local->loc2, newloc); local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; shard_refresh_base_file(frame, this, &local->loc, NULL, shard_post_lookup_link_handler); return 0; err: shard_common_failure_unwind(GF_FOP_LINK, frame, -1, ENOMEM); return 0; } static int shard_unlink_shards_do(call_frame_t *frame, xlator_t *this, inode_t *inode); static int shard_post_lookup_shards_unlink_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; uuid_t gfid = { 0, }; local = frame->local; if (local->resolver_base_inode) gf_uuid_copy(gfid, local->resolver_base_inode->gfid); else gf_uuid_copy(gfid, local->base_gfid); if ((local->op_ret < 0) && (local->op_errno != ENOENT)) { gf_msg(this->name, GF_LOG_ERROR, local->op_errno, SHARD_MSG_FOP_FAILED, "failed to delete shards of %s", uuid_utoa(gfid)); return 0; } local->op_ret = 0; local->op_errno = 0; shard_unlink_shards_do(frame, this, local->resolver_base_inode); return 0; } static int shard_post_resolve_unlink_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; local->lookup_shards_barriered = _gf_true; if (!local->call_count) shard_unlink_shards_do(frame, this, local->resolver_base_inode); else shard_common_lookup_shards(frame, this, local->resolver_base_inode, shard_post_lookup_shards_unlink_handler); return 0; } void shard_unlink_block_inode(shard_local_t *local, int shard_block_num) { char block_bname[256] = { 0, }; uuid_t gfid = { 0, }; inode_t *inode = NULL; inode_t *base_inode = NULL; xlator_t *this = NULL; shard_priv_t *priv = NULL; shard_inode_ctx_t *ctx = NULL; shard_inode_ctx_t *base_ictx = NULL; int unref_base_inode = 0; int unref_shard_inode = 0; this = THIS; priv = this->private; inode = local->inode_list[shard_block_num - local->first_block]; shard_inode_ctx_get(inode, this, &ctx); base_inode = ctx->base_inode; if (base_inode) gf_uuid_copy(gfid, base_inode->gfid); else gf_uuid_copy(gfid, ctx->base_gfid); shard_make_block_bname(shard_block_num, gfid, block_bname, sizeof(block_bname)); LOCK(&priv->lock); if (base_inode) LOCK(&base_inode->lock); LOCK(&inode->lock); { __shard_inode_ctx_get(inode, this, &ctx); if (!list_empty(&ctx->ilist)) { list_del_init(&ctx->ilist); priv->inode_count--; unref_base_inode++; unref_shard_inode++; GF_ASSERT(priv->inode_count >= 0); } if (ctx->fsync_needed) { unref_base_inode++; unref_shard_inode++; list_del_init(&ctx->to_fsync_list); if (base_inode) { __shard_inode_ctx_get(base_inode, this, &base_ictx); base_ictx->fsync_count--; } } } UNLOCK(&inode->lock); if (base_inode) UNLOCK(&base_inode->lock); inode_unlink(inode, priv->dot_shard_inode, block_bname); inode_ref_reduce_by_n(inode, unref_shard_inode); inode_forget(inode, 0); if (base_inode && unref_base_inode) inode_ref_reduce_by_n(base_inode, unref_base_inode); UNLOCK(&priv->lock); } static int shard_rename_cbk(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; SHARD_STACK_UNWIND(rename, frame, local->op_ret, local->op_errno, &local->prebuf, &local->preoldparent, &local->postoldparent, &local->prenewparent, &local->postnewparent, local->xattr_rsp); return 0; } static int32_t shard_unlink_cbk(call_frame_t *frame, xlator_t *this) { shard_local_t *local = frame->local; SHARD_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, &local->preoldparent, &local->postoldparent, local->xattr_rsp); return 0; } static int shard_unlink_shards_do_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int shard_block_num = (long)cookie; shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; goto done; } shard_unlink_block_inode(local, shard_block_num); done: syncbarrier_wake(&local->barrier); return 0; } static int shard_unlink_shards_do(call_frame_t *frame, xlator_t *this, inode_t *inode) { int i = 0; int ret = -1; int count = 0; uint32_t cur_block = 0; uint32_t cur_block_idx = 0; /*this is idx into inode_list[] array */ char *bname = NULL; char path[SHARD_PATH_MAX]; loc_t loc = { 0, }; gf_boolean_t wind_failed = _gf_false; shard_local_t *local = NULL; shard_priv_t *priv = NULL; priv = this->private; local = frame->local; /* Build base shard path before appending index of the shard */ strcpy(path, "/" GF_SHARD_DIR "/"); if (inode) uuid_utoa_r(inode->gfid, path + sizeof(GF_SHARD_DIR) + 1); else uuid_utoa_r(local->base_gfid, path + sizeof(GF_SHARD_DIR) + 1); int prefix_len = sizeof(GF_SHARD_DIR) + GF_UUID_BUF_SIZE; bname = path + sizeof(GF_SHARD_DIR) + 1; for (i = 0; i < local->num_blocks; i++) { if (!local->inode_list[i]) continue; count++; } if (!count) { /* callcount = 0 implies that all of the shards that need to be * unlinked are non-existent (in other words the file is full of * holes). */ gf_msg_debug(this->name, 0, "All shards that need to be " "unlinked are non-existent: %s", path); return 0; } SHARD_SET_ROOT_FS_ID(frame, local); local->barrier.waitfor = count; cur_block = cur_block_idx + local->first_block; while (cur_block_idx < local->num_blocks) { if (!local->inode_list[cur_block_idx]) goto next; if (wind_failed) { shard_unlink_shards_do_cbk(frame, (void *)(long)cur_block, this, -1, ENOMEM, NULL, NULL, NULL); goto next; } shard_append_index(path, SHARD_PATH_MAX, prefix_len, cur_block); loc.parent = inode_ref(priv->dot_shard_inode); ret = inode_path(loc.parent, bname, (char **)&(loc.path)); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed on %s", bname); local->op_ret = -1; local->op_errno = ENOMEM; loc_wipe(&loc); wind_failed = _gf_true; shard_unlink_shards_do_cbk(frame, (void *)(long)cur_block, this, -1, ENOMEM, NULL, NULL, NULL); goto next; } loc.name = strrchr(loc.path, '/'); if (loc.name) loc.name++; loc.inode = inode_ref(local->inode_list[cur_block_idx]); STACK_WIND_COOKIE(frame, shard_unlink_shards_do_cbk, (void *)(long)cur_block, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &loc, local->xflag, local->xattr_req); loc_wipe(&loc); next: cur_block++; cur_block_idx++; } syncbarrier_wait(&local->barrier, count); SHARD_UNSET_ROOT_FS_ID(frame, local); return 0; } static int shard_regulated_shards_deletion(call_frame_t *cleanup_frame, xlator_t *this, int now, int first_block, gf_dirent_t *entry) { int i = 0; int ret = 0; shard_local_t *local = NULL; uuid_t gfid = { 0, }; local = cleanup_frame->local; local->inode_list = GF_CALLOC(now, sizeof(inode_t *), gf_shard_mt_inode_list); if (!local->inode_list) return -ENOMEM; local->first_block = first_block; local->last_block = first_block + now - 1; local->num_blocks = now; gf_uuid_parse(entry->d_name, gfid); gf_uuid_copy(local->base_gfid, gfid); local->resolver_base_inode = inode_find(this->itable, gfid); local->call_count = 0; ret = syncbarrier_init(&local->barrier); if (ret) { GF_FREE(local->inode_list); local->inode_list = NULL; inode_unref(local->resolver_base_inode); local->resolver_base_inode = NULL; return -errno; } shard_common_resolve_shards(cleanup_frame, this, shard_post_resolve_unlink_handler); for (i = 0; i < local->num_blocks; i++) { if (local->inode_list[i]) inode_unref(local->inode_list[i]); } GF_FREE(local->inode_list); local->inode_list = NULL; if (local->op_ret) ret = -local->op_errno; syncbarrier_destroy(&local->barrier); inode_unref(local->resolver_base_inode); local->resolver_base_inode = NULL; STACK_RESET(cleanup_frame->root); return ret; } static int __shard_delete_shards_of_entry(call_frame_t *cleanup_frame, xlator_t *this, gf_dirent_t *entry, inode_t *inode) { int ret = 0; int shard_count = 0; int first_block = 0; int now = 0; uint64_t size = 0; uint64_t block_size = 0; uint64_t size_array[4] = { 0, }; void *bsize = NULL; void *size_attr = NULL; dict_t *xattr_rsp = NULL; loc_t loc = { 0, }; shard_local_t *local = NULL; shard_priv_t *priv = NULL; priv = this->private; local = cleanup_frame->local; ret = dict_reset(local->xattr_req); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to reset dict"); ret = -ENOMEM; goto err; } ret = dict_set_uint64(local->xattr_req, GF_XATTR_SHARD_BLOCK_SIZE, 0); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set dict value: key:%s", GF_XATTR_SHARD_BLOCK_SIZE); ret = -ENOMEM; goto err; } ret = dict_set_uint64(local->xattr_req, GF_XATTR_SHARD_FILE_SIZE, 8 * 4); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set dict value: key:%s", GF_XATTR_SHARD_FILE_SIZE); ret = -ENOMEM; goto err; } loc.inode = inode_ref(inode); loc.parent = inode_ref(priv->dot_shard_rm_inode); ret = inode_path(loc.parent, entry->d_name, (char **)&(loc.path)); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed on %s", entry->d_name); ret = -ENOMEM; goto err; } loc.name = strrchr(loc.path, '/'); if (loc.name) loc.name++; ret = syncop_lookup(FIRST_CHILD(this), &loc, NULL, NULL, local->xattr_req, &xattr_rsp); if (ret) goto err; ret = dict_get_ptr(xattr_rsp, GF_XATTR_SHARD_BLOCK_SIZE, &bsize); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to get dict value: key:%s", GF_XATTR_SHARD_BLOCK_SIZE); goto err; } block_size = be64toh(*((uint64_t *)bsize)); ret = dict_get_ptr(xattr_rsp, GF_XATTR_SHARD_FILE_SIZE, &size_attr); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to get dict value: key:%s", GF_XATTR_SHARD_FILE_SIZE); goto err; } memcpy(size_array, size_attr, sizeof(size_array)); size = be64toh(size_array[0]); shard_count = (size / block_size) - 1; if (shard_count < 0) { gf_msg_debug(this->name, 0, "Size of %s hasn't grown beyond " "its shard-block-size. Nothing to delete. " "Returning", entry->d_name); /* File size < shard-block-size, so nothing to delete */ ret = 0; goto delete_marker; } if ((size % block_size) > 0) shard_count++; if (shard_count == 0) { gf_msg_debug(this->name, 0, "Size of %s is exactly equal to " "its shard-block-size. Nothing to delete. " "Returning", entry->d_name); ret = 0; goto delete_marker; } gf_msg_debug(this->name, 0, "base file = %s, " "shard-block-size=%" PRIu64 ", file-size=%" PRIu64 ", " "shard_count=%d", entry->d_name, block_size, size, shard_count); /* Perform a gfid-based lookup to see if gfid corresponding to marker * file's base name exists. */ loc_wipe(&loc); loc.inode = inode_new(this->itable); if (!loc.inode) { ret = -ENOMEM; goto err; } gf_uuid_parse(entry->d_name, loc.gfid); ret = syncop_lookup(FIRST_CHILD(this), &loc, NULL, NULL, NULL, NULL); if (!ret) { gf_msg_debug(this->name, 0, "Base shard corresponding to gfid " "%s is present. Skipping shard deletion. " "Returning", entry->d_name); ret = 0; goto delete_marker; } first_block = 1; while (shard_count) { if (shard_count < local->deletion_rate) { now = shard_count; shard_count = 0; } else { now = local->deletion_rate; shard_count -= local->deletion_rate; } gf_msg_debug(this->name, 0, "deleting %d shards starting from " "block %d of gfid %s", now, first_block, entry->d_name); ret = shard_regulated_shards_deletion(cleanup_frame, this, now, first_block, entry); if (ret) goto err; first_block += now; } delete_marker: loc_wipe(&loc); loc.inode = inode_ref(inode); loc.parent = inode_ref(priv->dot_shard_rm_inode); ret = inode_path(loc.parent, entry->d_name, (char **)&(loc.path)); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed on %s", entry->d_name); ret = -ENOMEM; goto err; } loc.name = strrchr(loc.path, '/'); if (loc.name) loc.name++; ret = syncop_unlink(FIRST_CHILD(this), &loc, NULL, NULL); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_SHARDS_DELETION_FAILED, "Failed to delete %s " "from /%s", entry->d_name, GF_SHARD_REMOVE_ME_DIR); err: if (xattr_rsp) dict_unref(xattr_rsp); loc_wipe(&loc); return ret; } static int shard_delete_shards_of_entry(call_frame_t *cleanup_frame, xlator_t *this, gf_dirent_t *entry, inode_t *inode) { int ret = -1; loc_t loc = { 0, }; shard_priv_t *priv = NULL; priv = this->private; loc.inode = inode_ref(priv->dot_shard_rm_inode); ret = syncop_entrylk(FIRST_CHILD(this), this->name, &loc, entry->d_name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL, NULL); if (ret < 0) { if (ret == -EAGAIN) { ret = 0; } goto out; } { ret = __shard_delete_shards_of_entry(cleanup_frame, this, entry, inode); } syncop_entrylk(FIRST_CHILD(this), this->name, &loc, entry->d_name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL, NULL); out: loc_wipe(&loc); return ret; } static int shard_delete_shards_cbk(int ret, call_frame_t *frame, void *data) { SHARD_STACK_DESTROY(frame); return 0; } static int shard_resolve_internal_dir(xlator_t *this, shard_local_t *local, shard_internal_dir_type_t type) { int ret = 0; char *bname = NULL; loc_t *loc = NULL; shard_priv_t *priv = NULL; uuid_t gfid = { 0, }; struct iatt stbuf = { 0, }; priv = this->private; switch (type) { case SHARD_INTERNAL_DIR_DOT_SHARD: loc = &local->dot_shard_loc; gf_uuid_copy(gfid, priv->dot_shard_gfid); bname = GF_SHARD_DIR; break; case SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME: loc = &local->dot_shard_rm_loc; gf_uuid_copy(gfid, priv->dot_shard_rm_gfid); bname = GF_SHARD_REMOVE_ME_DIR; break; default: break; } loc->inode = inode_find(this->itable, gfid); if (!loc->inode) { ret = shard_init_internal_dir_loc(this, local, type); if (ret) goto err; ret = dict_reset(local->xattr_req); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to reset " "dict"); ret = -ENOMEM; goto err; } ret = dict_set_gfuuid(local->xattr_req, "gfid-req", gfid, true); ret = syncop_lookup(FIRST_CHILD(this), loc, &stbuf, NULL, local->xattr_req, NULL); if (ret < 0) { if (ret != -ENOENT) gf_msg(this->name, GF_LOG_ERROR, -ret, SHARD_MSG_SHARDS_DELETION_FAILED, "Lookup on %s failed, exiting", bname); goto err; } else { shard_link_internal_dir_inode(local, loc->inode, this, &stbuf, type); } } ret = 0; err: return ret; } static int shard_lookup_marker_entry(xlator_t *this, shard_local_t *local, gf_dirent_t *entry) { int ret = 0; loc_t loc = { 0, }; loc.inode = inode_new(this->itable); if (!loc.inode) { ret = -ENOMEM; goto err; } loc.parent = inode_ref(local->fd->inode); ret = inode_path(loc.parent, entry->d_name, (char **)&(loc.path)); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed on %s", entry->d_name); ret = -ENOMEM; goto err; } loc.name = strrchr(loc.path, '/'); if (loc.name) loc.name++; ret = syncop_lookup(FIRST_CHILD(this), &loc, NULL, NULL, NULL, NULL); if (ret < 0) { goto err; } entry->inode = inode_ref(loc.inode); ret = 0; err: loc_wipe(&loc); return ret; } static int shard_nameless_lookup_base_file(xlator_t *this, char *gfid) { int ret = 0; loc_t loc = { 0, }; dict_t *xattr_req = dict_new(); if (!xattr_req) { ret = -1; goto out; } loc.inode = inode_new(this->itable); if (loc.inode == NULL) { ret = -1; goto out; } ret = gf_uuid_parse(gfid, loc.gfid); if (ret < 0) goto out; ret = dict_set_uint32(xattr_req, GF_UNLINKED_LOOKUP, 1); if (ret < 0) goto out; ret = syncop_lookup(FIRST_CHILD(this), &loc, NULL, NULL, xattr_req, NULL); if (ret < 0) goto out; out: if (xattr_req) dict_unref(xattr_req); loc_wipe(&loc); return ret; } int shard_delete_shards(void *opaque) { int ret = 0; off_t offset = 0; loc_t loc = { 0, }; inode_t *link_inode = NULL; xlator_t *this = NULL; shard_priv_t *priv = NULL; shard_local_t *local = NULL; gf_dirent_t entries; gf_dirent_t *entry = NULL; call_frame_t *cleanup_frame = NULL; gf_boolean_t done = _gf_false; this = THIS; priv = this->private; INIT_LIST_HEAD(&entries.list); cleanup_frame = opaque; local = mem_get0(this->local_pool); if (!local) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SHARD_MSG_MEMALLOC_FAILED, "Failed to create local to " "delete shards"); ret = -ENOMEM; goto err; } cleanup_frame->local = local; local->fop = GF_FOP_UNLINK; local->xattr_req = dict_new(); if (!local->xattr_req) { ret = -ENOMEM; goto err; } local->deletion_rate = priv->deletion_rate; ret = shard_resolve_internal_dir(this, local, SHARD_INTERNAL_DIR_DOT_SHARD); if (ret == -ENOENT) { gf_msg_debug(this->name, 0, ".shard absent. Nothing to" " delete. Exiting"); ret = 0; goto err; } else if (ret < 0) { goto err; } ret = shard_resolve_internal_dir(this, local, SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME); if (ret == -ENOENT) { gf_msg_debug(this->name, 0, ".remove_me absent. " "Nothing to delete. Exiting"); ret = 0; goto err; } else if (ret < 0) { goto err; } local->fd = fd_anonymous(local->dot_shard_rm_loc.inode); if (!local->fd) { ret = -ENOMEM; goto err; } for (;;) { offset = 0; LOCK(&priv->lock); { if (priv->bg_del_state == SHARD_BG_DELETION_LAUNCHING) { priv->bg_del_state = SHARD_BG_DELETION_IN_PROGRESS; } else if (priv->bg_del_state == SHARD_BG_DELETION_IN_PROGRESS) { priv->bg_del_state = SHARD_BG_DELETION_NONE; done = _gf_true; } } UNLOCK(&priv->lock); if (done) break; while ( (ret = syncop_readdirp(FIRST_CHILD(this), local->fd, 131072, offset, &entries, local->xattr_req, NULL))) { if (ret > 0) ret = 0; list_for_each_entry(entry, &entries.list, list) { offset = entry->d_off; /* skip . and .. */ if (inode_dir_or_parentdir(entry)) continue; if (!entry->inode) { ret = shard_lookup_marker_entry(this, local, entry); if (ret < 0) continue; } ret = shard_nameless_lookup_base_file(this, entry->d_name); if (!ret) continue; link_inode = inode_link(entry->inode, local->fd->inode, entry->d_name, &entry->d_stat); gf_msg_debug(this->name, 0, "Initiating deletion of " "shards of gfid %s", entry->d_name); ret = shard_delete_shards_of_entry(cleanup_frame, this, entry, link_inode); inode_unlink(link_inode, local->fd->inode, entry->d_name); inode_unref(link_inode); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, SHARD_MSG_SHARDS_DELETION_FAILED, "Failed to clean up shards of gfid %s", entry->d_name); continue; } gf_msg(this->name, GF_LOG_INFO, 0, SHARD_MSG_SHARD_DELETION_COMPLETED, "Deleted " "shards of gfid=%s from backend", entry->d_name); } gf_dirent_free(&entries); if (ret) break; } } ret = 0; loc_wipe(&loc); return ret; err: LOCK(&priv->lock); { priv->bg_del_state = SHARD_BG_DELETION_NONE; } UNLOCK(&priv->lock); loc_wipe(&loc); return ret; } int shard_unlock_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { if (op_ret) gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_FOP_FAILED, "Unlock failed. Please check brick logs for " "more details"); SHARD_STACK_DESTROY(frame); return 0; } int shard_unlock_inodelk(call_frame_t *frame, xlator_t *this) { loc_t *loc = NULL; call_frame_t *lk_frame = NULL; shard_local_t *local = NULL; shard_local_t *lk_local = NULL; shard_inodelk_t *lock = NULL; local = frame->local; lk_frame = local->inodelk_frame; lk_local = lk_frame->local; local->inodelk_frame = NULL; loc = &local->int_inodelk.loc; lock = &lk_local->int_inodelk; lock->flock.l_type = F_UNLCK; STACK_WIND(lk_frame, shard_unlock_inodelk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, lock->domain, loc, F_SETLK, &lock->flock, NULL); local->int_inodelk.acquired_lock = _gf_false; return 0; } int shard_rename_src_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata); int shard_rename_src_base_file(call_frame_t *frame, xlator_t *this) { int ret = 0; loc_t *dst_loc = NULL; loc_t tmp_loc = { 0, }; shard_local_t *local = frame->local; if (local->dst_block_size) { tmp_loc.parent = inode_ref(local->loc2.parent); ret = inode_path(tmp_loc.parent, local->loc2.name, (char **)&tmp_loc.path); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed" " on pargfid=%s bname=%s", uuid_utoa(tmp_loc.parent->gfid), local->loc2.name); local->op_ret = -1; local->op_errno = ENOMEM; goto err; } tmp_loc.name = strrchr(tmp_loc.path, '/'); if (tmp_loc.name) tmp_loc.name++; dst_loc = &tmp_loc; } else { dst_loc = &local->loc2; } /* To-Do: Request open-fd count on dst base file */ STACK_WIND(frame, shard_rename_src_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, &local->loc, dst_loc, local->xattr_req); loc_wipe(&tmp_loc); return 0; err: loc_wipe(&tmp_loc); shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } int shard_unlink_base_file(call_frame_t *frame, xlator_t *this); int shard_set_size_attrs_on_marker_file_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { shard_priv_t *priv = NULL; shard_local_t *local = NULL; priv = this->private; local = frame->local; if (op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_FOP_FAILED, "Xattrop on marker file failed " "while performing %s; entry gfid=%s", gf_fop_string(local->fop), local->newloc.name); goto err; } inode_unlink(local->newloc.inode, priv->dot_shard_rm_inode, local->newloc.name); if (local->fop == GF_FOP_UNLINK) shard_unlink_base_file(frame, this); else if (local->fop == GF_FOP_RENAME) shard_rename_src_base_file(frame, this); return 0; err: shard_common_failure_unwind(local->fop, frame, op_ret, op_errno); return 0; } int shard_set_size_attrs_on_marker_file(call_frame_t *frame, xlator_t *this) { int op_errno = ENOMEM; uint64_t bs = 0; dict_t *xdata = NULL; shard_local_t *local = NULL; local = frame->local; xdata = dict_new(); if (!xdata) goto err; if (local->fop == GF_FOP_UNLINK) bs = local->block_size; else if (local->fop == GF_FOP_RENAME) bs = local->dst_block_size; SHARD_INODE_CREATE_INIT(this, bs, xdata, &local->newloc, local->prebuf.ia_size, 0, err); STACK_WIND(frame, shard_set_size_attrs_on_marker_file_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, &local->newloc, GF_XATTROP_GET_AND_SET, xdata, NULL); dict_unref(xdata); return 0; err: if (xdata) dict_unref(xdata); shard_common_failure_unwind(local->fop, frame, -1, op_errno); return 0; } int shard_lookup_marker_file_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { inode_t *linked_inode = NULL; shard_priv_t *priv = NULL; shard_local_t *local = NULL; local = frame->local; priv = this->private; if (op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_FOP_FAILED, "Lookup on marker file failed " "while performing %s; entry gfid=%s", gf_fop_string(local->fop), local->newloc.name); goto err; } linked_inode = inode_link(inode, priv->dot_shard_rm_inode, local->newloc.name, buf); inode_unref(local->newloc.inode); local->newloc.inode = linked_inode; shard_set_size_attrs_on_marker_file(frame, this); return 0; err: shard_common_failure_unwind(local->fop, frame, op_ret, op_errno); return 0; } int shard_lookup_marker_file(call_frame_t *frame, xlator_t *this) { int op_errno = ENOMEM; dict_t *xattr_req = NULL; shard_local_t *local = NULL; local = frame->local; xattr_req = shard_create_gfid_dict(local->xattr_req); if (!xattr_req) goto err; STACK_WIND(frame, shard_lookup_marker_file_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &local->newloc, xattr_req); dict_unref(xattr_req); return 0; err: shard_common_failure_unwind(local->fop, frame, -1, op_errno); return 0; } int shard_create_marker_file_under_remove_me_cbk( call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { inode_t *linked_inode = NULL; shard_priv_t *priv = NULL; shard_local_t *local = NULL; local = frame->local; priv = this->private; SHARD_UNSET_ROOT_FS_ID(frame, local); if (op_ret < 0) { if ((op_errno != EEXIST) && (op_errno != ENODATA)) { local->op_ret = op_ret; local->op_errno = op_errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_FOP_FAILED, "Marker file creation " "failed while performing %s; entry gfid=%s", gf_fop_string(local->fop), local->newloc.name); goto err; } else { shard_lookup_marker_file(frame, this); return 0; } } linked_inode = inode_link(inode, priv->dot_shard_rm_inode, local->newloc.name, buf); inode_unref(local->newloc.inode); local->newloc.inode = linked_inode; if (local->fop == GF_FOP_UNLINK) shard_unlink_base_file(frame, this); else if (local->fop == GF_FOP_RENAME) shard_rename_src_base_file(frame, this); return 0; err: shard_common_failure_unwind(local->fop, frame, -1, local->op_errno); return 0; } int shard_create_marker_file_under_remove_me(call_frame_t *frame, xlator_t *this, loc_t *loc) { int ret = 0; int op_errno = ENOMEM; uint64_t bs = 0; char g1[64] = { 0, }; char g2[64] = { 0, }; dict_t *xattr_req = NULL; shard_priv_t *priv = NULL; shard_local_t *local = NULL; priv = this->private; local = frame->local; SHARD_SET_ROOT_FS_ID(frame, local); xattr_req = shard_create_gfid_dict(local->xattr_req); if (!xattr_req) goto err; local->newloc.inode = inode_new(this->itable); local->newloc.parent = inode_ref(priv->dot_shard_rm_inode); ret = inode_path(local->newloc.parent, uuid_utoa(loc->inode->gfid), (char **)&local->newloc.path); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed on " "pargfid=%s bname=%s", uuid_utoa_r(priv->dot_shard_rm_gfid, g1), uuid_utoa_r(loc->inode->gfid, g2)); goto err; } local->newloc.name = strrchr(local->newloc.path, '/'); if (local->newloc.name) local->newloc.name++; if (local->fop == GF_FOP_UNLINK) bs = local->block_size; else if (local->fop == GF_FOP_RENAME) bs = local->dst_block_size; SHARD_INODE_CREATE_INIT(this, bs, xattr_req, &local->newloc, local->prebuf.ia_size, 0, err); /* Mark this as an internal operation, so that in case of disk full, * the marker file will be created as part of reserve space */ ret = dict_set_int32_sizen(xattr_req, GLUSTERFS_INTERNAL_FOP_KEY, 1); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set key: %s on path %s", GLUSTERFS_INTERNAL_FOP_KEY, local->newloc.path); goto err; } STACK_WIND(frame, shard_create_marker_file_under_remove_me_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, &local->newloc, 0, 0, 0644, xattr_req); dict_unref(xattr_req); return 0; err: if (xattr_req) dict_unref(xattr_req); shard_create_marker_file_under_remove_me_cbk(frame, 0, this, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int shard_unlock_entrylk(call_frame_t *frame, xlator_t *this); static int shard_unlink_handler_spawn(xlator_t *this); int shard_unlink_base_file_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int ret = 0; shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; } else { shard_inode_ctx_set_refresh_flag(local->int_inodelk.loc.inode, this); local->preoldparent = *preparent; local->postoldparent = *postparent; if (xdata) local->xattr_rsp = dict_ref(xdata); if (local->cleanup_required) shard_unlink_handler_spawn(this); } if (local->entrylk_frame) { ret = shard_unlock_entrylk(frame, this); if (ret < 0) { local->op_ret = -1; local->op_errno = -ret; } } ret = shard_unlock_inodelk(frame, this); if (ret < 0) { local->op_ret = -1; local->op_errno = -ret; } shard_unlink_cbk(frame, this); return 0; } int shard_unlink_base_file(call_frame_t *frame, xlator_t *this) { shard_local_t *local = frame->local; /* To-Do: Request open-fd count on base file */ STACK_WIND(frame, shard_unlink_base_file_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &local->loc, local->xflag, local->xattr_req); return 0; } int shard_unlock_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { if (op_ret) gf_msg(this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_FOP_FAILED, "Unlock failed. Please check brick logs for " "more details"); SHARD_STACK_DESTROY(frame); return 0; } int shard_unlock_entrylk(call_frame_t *frame, xlator_t *this) { loc_t *loc = NULL; call_frame_t *lk_frame = NULL; shard_local_t *local = NULL; shard_local_t *lk_local = NULL; shard_entrylk_t *lock = NULL; local = frame->local; lk_frame = local->entrylk_frame; lk_local = lk_frame->local; local->entrylk_frame = NULL; lock = &lk_local->int_entrylk; loc = &lock->loc; STACK_WIND(lk_frame, shard_unlock_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, loc, lk_local->int_entrylk.basename, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL); local->int_entrylk.acquired_lock = _gf_false; return 0; } int shard_post_entrylk_fop_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; switch (local->fop) { case GF_FOP_UNLINK: case GF_FOP_RENAME: shard_create_marker_file_under_remove_me(frame, this, &local->int_inodelk.loc); break; default: gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_INVALID_FOP, "post-entrylk handler not defined. This case should not" " be hit"); break; } return 0; } int shard_acquire_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { call_frame_t *main_frame = NULL; shard_local_t *local = NULL; shard_local_t *main_local = NULL; local = frame->local; main_frame = local->main_frame; main_local = main_frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(main_local->fop, main_frame, op_ret, op_errno); return 0; } main_local->int_entrylk.acquired_lock = _gf_true; shard_post_entrylk_fop_handler(main_frame, this); return 0; } int shard_acquire_entrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, uuid_t gfid) { char gfid_str[GF_UUID_BUF_SIZE] = { 0, }; shard_local_t *local = NULL; shard_local_t *entrylk_local = NULL; shard_entrylk_t *int_entrylk = NULL; call_frame_t *entrylk_frame = NULL; local = frame->local; entrylk_frame = create_frame(this, this->ctx->pool); if (!entrylk_frame) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SHARD_MSG_MEMALLOC_FAILED, "Failed to create new frame " "to lock marker file"); goto err; } entrylk_local = mem_get0(this->local_pool); if (!entrylk_local) { STACK_DESTROY(entrylk_frame->root); goto err; } entrylk_frame->local = entrylk_local; entrylk_local->main_frame = frame; int_entrylk = &entrylk_local->int_entrylk; int_entrylk->loc.inode = inode_ref(inode); set_lk_owner_from_ptr(&entrylk_frame->root->lk_owner, entrylk_frame->root); local->entrylk_frame = entrylk_frame; gf_uuid_unparse(gfid, gfid_str); int_entrylk->basename = gf_strdup(gfid_str); STACK_WIND(entrylk_frame, shard_acquire_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &int_entrylk->loc, int_entrylk->basename, ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL); return 0; err: shard_common_failure_unwind(local->fop, frame, -1, ENOMEM); return 0; } int shard_post_lookup_base_shard_rm_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; shard_priv_t *priv = NULL; priv = this->private; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, -1, local->op_errno); return 0; } if (local->prebuf.ia_nlink > 1) { gf_msg_debug(this->name, 0, "link count on %s > 1:%d, " "performing rename()/unlink()", local->int_inodelk.loc.path, local->prebuf.ia_nlink); if (local->fop == GF_FOP_RENAME) shard_rename_src_base_file(frame, this); else if (local->fop == GF_FOP_UNLINK) shard_unlink_base_file(frame, this); } else { gf_msg_debug(this->name, 0, "link count on %s = 1, creating " "file under .remove_me", local->int_inodelk.loc.path); local->cleanup_required = _gf_true; shard_acquire_entrylk(frame, this, priv->dot_shard_rm_inode, local->prebuf.ia_gfid); } return 0; } int shard_post_inodelk_fop_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; switch (local->fop) { case GF_FOP_UNLINK: case GF_FOP_RENAME: shard_refresh_base_file(frame, this, &local->int_inodelk.loc, NULL, shard_post_lookup_base_shard_rm_handler); break; default: gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_INVALID_FOP, "post-inodelk handler not defined. This case should not" " be hit"); break; } return 0; } int shard_acquire_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { call_frame_t *main_frame = NULL; shard_local_t *local = NULL; shard_local_t *main_local = NULL; local = frame->local; main_frame = local->main_frame; main_local = main_frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(main_local->fop, main_frame, op_ret, op_errno); return 0; } main_local->int_inodelk.acquired_lock = _gf_true; shard_post_inodelk_fop_handler(main_frame, this); return 0; } static int shard_acquire_inodelk(call_frame_t *frame, xlator_t *this, loc_t *loc) { call_frame_t *lk_frame = NULL; shard_local_t *local = NULL; shard_local_t *lk_local = NULL; shard_inodelk_t *int_inodelk = NULL; local = frame->local; lk_frame = create_frame(this, this->ctx->pool); if (!lk_frame) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SHARD_MSG_MEMALLOC_FAILED, "Failed to create new frame " "to lock base shard"); goto err; } lk_local = mem_get0(this->local_pool); if (!lk_local) { STACK_DESTROY(lk_frame->root); goto err; } lk_frame->local = lk_local; lk_local->main_frame = frame; int_inodelk = &lk_local->int_inodelk; int_inodelk->flock.l_len = 0; int_inodelk->flock.l_start = 0; int_inodelk->domain = this->name; int_inodelk->flock.l_type = F_WRLCK; loc_copy(&local->int_inodelk.loc, loc); set_lk_owner_from_ptr(&lk_frame->root->lk_owner, lk_frame->root); local->inodelk_frame = lk_frame; STACK_WIND(lk_frame, shard_acquire_inodelk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, int_inodelk->domain, &local->int_inodelk.loc, F_SETLKW, &int_inodelk->flock, NULL); return 0; err: shard_common_failure_unwind(local->fop, frame, -1, ENOMEM); return 0; } int shard_post_mkdir_rm_handler(call_frame_t *frame, xlator_t *this) { loc_t *loc = NULL; shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, -1, local->op_errno); return 0; } if (local->fop == GF_FOP_UNLINK) loc = &local->loc; else if (local->fop == GF_FOP_RENAME) loc = &local->loc2; shard_acquire_inodelk(frame, this, loc); return 0; } static int shard_mkdir_internal_dir(call_frame_t *frame, xlator_t *this, shard_post_resolve_fop_handler_t handler, shard_internal_dir_type_t type); static int shard_pre_mkdir_rm_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, -1, local->op_errno); return 0; } shard_mkdir_internal_dir(frame, this, shard_post_mkdir_rm_handler, SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME); return 0; } static void shard_begin_rm_resolution(call_frame_t *frame, xlator_t *this) { shard_priv_t *priv = NULL; shard_local_t *local = NULL; priv = this->private; local = frame->local; local->dot_shard_rm_loc.inode = inode_find(this->itable, priv->dot_shard_rm_gfid); if (!local->dot_shard_rm_loc.inode) { local->dot_shard_loc.inode = inode_find(this->itable, priv->dot_shard_gfid); if (!local->dot_shard_loc.inode) { shard_mkdir_internal_dir(frame, this, shard_pre_mkdir_rm_handler, SHARD_INTERNAL_DIR_DOT_SHARD); } else { local->post_res_handler = shard_pre_mkdir_rm_handler; shard_refresh_internal_dir(frame, this, SHARD_INTERNAL_DIR_DOT_SHARD); } } else { local->post_res_handler = shard_post_mkdir_rm_handler; shard_refresh_internal_dir(frame, this, SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME); } } int shard_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { int ret = -1; uint64_t block_size = 0; shard_local_t *local = NULL; if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; } ret = shard_inode_ctx_get_block_size(loc->inode, this, &block_size); if ((ret) && (!IA_ISLNK(loc->inode->ia_type))) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size from inode ctx of %s", uuid_utoa(loc->inode->gfid)); goto err; } if (!block_size) { STACK_WIND(frame, default_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; } local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; loc_copy(&local->loc, loc); local->xflag = xflag; local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); local->block_size = block_size; local->resolver_base_inode = loc->inode; local->fop = GF_FOP_UNLINK; if (!this->itable) this->itable = (local->loc.inode)->table; local->resolve_not = _gf_true; shard_begin_rm_resolution(frame, this); return 0; err: shard_common_failure_unwind(GF_FOP_UNLINK, frame, -1, ENOMEM); return 0; } int shard_post_rename_lookup_handler(call_frame_t *frame, xlator_t *this) { shard_rename_cbk(frame, this); return 0; } int shard_rename_src_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { int ret = 0; shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; goto err; } /* Set ctx->refresh to TRUE to force a lookup on disk when * shard_lookup_base_file() is called next to refresh the hard link * count in ctx. Note that this is applicable only to the case where * the rename dst is already existent and sharded. */ if ((local->dst_block_size) && (!local->cleanup_required)) shard_inode_ctx_set_refresh_flag(local->int_inodelk.loc.inode, this); local->prebuf = *buf; local->preoldparent = *preoldparent; local->postoldparent = *postoldparent; local->prenewparent = *prenewparent; local->postnewparent = *postnewparent; if (xdata) local->xattr_rsp = dict_ref(xdata); if (local->dst_block_size) { if (local->entrylk_frame) { ret = shard_unlock_entrylk(frame, this); if (ret < 0) { local->op_ret = -1; local->op_errno = -ret; } } ret = shard_unlock_inodelk(frame, this); if (ret < 0) { local->op_ret = -1; local->op_errno = -ret; goto err; } if (local->cleanup_required) shard_start_background_deletion(this); } /* Now the base file of src, if sharded, is looked up to gather ia_size * and ia_blocks.*/ if (local->block_size) { local->tmp_loc.inode = inode_new(this->itable); gf_uuid_copy(local->tmp_loc.gfid, (local->loc.inode)->gfid); shard_refresh_base_file(frame, this, &local->tmp_loc, NULL, shard_post_rename_lookup_handler); } else { shard_rename_cbk(frame, this); } return 0; err: shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } int shard_post_lookup_dst_base_file_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } /* Save dst base file attributes into postbuf so the information is not * lost when it is overwritten after lookup on base file of src in * shard_lookup_base_file_cbk(). */ local->postbuf = local->prebuf; shard_rename_src_base_file(frame, this); return 0; } int shard_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int ret = -1; uint64_t block_size = 0; uint64_t dst_block_size = 0; shard_local_t *local = NULL; if (IA_ISDIR(oldloc->inode->ia_type)) { STACK_WIND(frame, default_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; } ret = shard_inode_ctx_get_block_size(oldloc->inode, this, &block_size); if ((ret) && (!IA_ISLNK(oldloc->inode->ia_type))) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size from inode ctx of %s", uuid_utoa(oldloc->inode->gfid)); goto err; } if (newloc->inode) ret = shard_inode_ctx_get_block_size(newloc->inode, this, &dst_block_size); /* The following stack_wind covers the case where: * a. the src file is not sharded and dst doesn't exist, OR * b. the src and dst both exist but are not sharded. */ if (((!block_size) && (!dst_block_size)) || frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; } local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; loc_copy(&local->loc, oldloc); loc_copy(&local->loc2, newloc); local->resolver_base_inode = newloc->inode; local->fop = GF_FOP_RENAME; local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; local->block_size = block_size; local->dst_block_size = dst_block_size; if (!this->itable) this->itable = (local->loc.inode)->table; local->resolve_not = _gf_true; /* The following if-block covers the case where the dst file exists * and is sharded. */ if (local->dst_block_size) { shard_begin_rm_resolution(frame, this); } else { /* The following block covers the case where the dst either doesn't * exist or is NOT sharded but the src is sharded. In this case, shard * xlator would go ahead and rename src to dst. Once done, it would also * lookup the base shard of src to get the ia_size and ia_blocks xattr * values. */ shard_rename_src_base_file(frame, this); } return 0; err: shard_common_failure_unwind(GF_FOP_RENAME, frame, -1, ENOMEM); return 0; } int shard_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int ret = -1; shard_local_t *local = NULL; local = frame->local; if (op_ret == -1) goto unwind; ret = shard_inode_ctx_set(inode, this, stbuf, local->block_size, SHARD_ALL_MASK); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_INODE_CTX_SET_FAILED, "Failed to set inode " "ctx for %s", uuid_utoa(inode->gfid)); unwind: SHARD_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, stbuf, preparent, postparent, xdata); return 0; } int shard_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { shard_priv_t *priv = NULL; shard_local_t *local = NULL; priv = this->private; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->block_size = priv->block_size; if (!__is_gsyncd_on_shard_dir(frame, loc)) { SHARD_INODE_CREATE_INIT(this, local->block_size, xdata, loc, 0, 0, err); } STACK_WIND(frame, shard_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; err: shard_common_failure_unwind(GF_FOP_CREATE, frame, -1, ENOMEM); return 0; } int shard_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { /* To-Do: Handle open with O_TRUNC under locks */ SHARD_STACK_UNWIND(open, frame, op_ret, op_errno, fd, xdata); return 0; } int shard_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { SHARD_STACK_UNWIND(open, frame, op_ret, op_errno, fd, xdata); return 0; } int shard_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { STACK_WIND(frame, shard_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; } int shard_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { int ret; xdata = xdata ? dict_ref(xdata) : dict_new(); if (!xdata) { ret = -1; goto err; } /* if the file is sharded then server will return the below * xattr as part of dict that is used to update the ia_size * in d_stat. This is helpful incase readdir-ahead is enabled */ ret = dict_set_uint64(xdata, GF_XATTR_SHARD_FILE_SIZE, 8 * 4); if (ret) { gf_msg_debug(this->name, -ret, "Unable to set GF_XATTR_SHARD_FILE_SIZE in the dict "); goto err; } STACK_WIND(frame, shard_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); dict_unref(xdata); return 0; err: if (xdata) dict_unref(xdata); shard_common_failure_unwind(GF_FOP_OPENDIR, frame, -1, ENOMEM); return 0; } int shard_readv_do_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { int i = 0; int call_count = 0; void *address = NULL; uint64_t block_num = 0; off_t off = 0; struct iovec vec = { 0, }; shard_local_t *local = NULL; fd_t *anon_fd = cookie; shard_inode_ctx_t *ctx = NULL; local = frame->local; /* If shard has already seen a failure here before, there is no point * in aggregating subsequent reads, so just go to out. */ if (local->op_ret < 0) goto out; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; goto out; } if (local->op_ret >= 0) local->op_ret += op_ret; shard_inode_ctx_get(anon_fd->inode, this, &ctx); block_num = ctx->block_num; if (block_num == local->first_block) { address = local->iobuf->ptr; } else { /* else * address to start writing to = beginning of buffer + * number of bytes until end of first block + * + block_size times number of blocks * between the current block and the first */ address = (char *)local->iobuf->ptr + (local->block_size - (local->offset % local->block_size)) + ((block_num - local->first_block - 1) * local->block_size); } for (i = 0; i < count; i++) { address = (char *)address + off; memcpy(address, vector[i].iov_base, vector[i].iov_len); off += vector[i].iov_len; } out: if (anon_fd) fd_unref(anon_fd); call_count = shard_call_count_return(frame); if (call_count == 0) { SHARD_UNSET_ROOT_FS_ID(frame, local); if (local->op_ret < 0) { shard_common_failure_unwind(GF_FOP_READ, frame, local->op_ret, local->op_errno); } else { if (xdata) local->xattr_rsp = dict_ref(xdata); vec.iov_base = local->iobuf->ptr; if (local->offset + local->req_size > local->prebuf.ia_size) local->total_size = local->prebuf.ia_size - local->offset; vec.iov_len = local->total_size; local->op_ret = local->total_size; SHARD_STACK_UNWIND(readv, frame, local->op_ret, local->op_errno, &vec, 1, &local->prebuf, local->iobref, local->xattr_rsp); return 0; } } return 0; } int shard_readv_do(call_frame_t *frame, xlator_t *this) { int i = 0; int call_count = 0; int last_block = 0; int cur_block = 0; off_t orig_offset = 0; off_t shard_offset = 0; size_t read_size = 0; size_t remaining_size = 0; fd_t *fd = NULL; fd_t *anon_fd = NULL; shard_local_t *local = NULL; gf_boolean_t wind_failed = _gf_false; local = frame->local; fd = local->fd; orig_offset = local->offset; cur_block = local->first_block; last_block = local->last_block; remaining_size = local->total_size; local->call_count = call_count = local->num_blocks; SHARD_SET_ROOT_FS_ID(frame, local); if (fd->flags & O_DIRECT) local->flags = O_DIRECT; while (cur_block <= last_block) { if (wind_failed) { shard_readv_do_cbk(frame, (void *)(long)0, this, -1, ENOMEM, NULL, 0, NULL, NULL, NULL); goto next; } shard_offset = orig_offset % local->block_size; read_size = local->block_size - shard_offset; if (read_size > remaining_size) read_size = remaining_size; remaining_size -= read_size; if (cur_block == 0) { anon_fd = fd_ref(fd); } else { anon_fd = fd_anonymous(local->inode_list[i]); if (!anon_fd) { local->op_ret = -1; local->op_errno = ENOMEM; wind_failed = _gf_true; shard_readv_do_cbk(frame, (void *)(long)anon_fd, this, -1, ENOMEM, NULL, 0, NULL, NULL, NULL); goto next; } } STACK_WIND_COOKIE(frame, shard_readv_do_cbk, anon_fd, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, anon_fd, read_size, shard_offset, local->flags, local->xattr_req); orig_offset += read_size; next: cur_block++; i++; call_count--; } return 0; } int shard_common_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int shard_block_num = (long)cookie; int call_count = 0; shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) { if (op_errno == EEXIST) { LOCK(&frame->lock); { local->eexist_count++; } UNLOCK(&frame->lock); } else { local->op_ret = op_ret; local->op_errno = op_errno; } gf_msg_debug(this->name, op_errno, "mknod of shard %d failed", shard_block_num); goto done; } shard_link_block_inode(local, shard_block_num, inode, buf); done: call_count = shard_call_count_return(frame); if (call_count == 0) { SHARD_UNSET_ROOT_FS_ID(frame, local); local->create_count = 0; local->post_mknod_handler(frame, this); } return 0; } int shard_common_resume_mknod(call_frame_t *frame, xlator_t *this, shard_post_mknod_fop_handler_t post_mknod_handler) { int i = 0; int shard_idx_iter = 0; int last_block = 0; int ret = 0; int call_count = 0; int prefix_len = 0; char path[SHARD_PATH_MAX]; mode_t mode = 0; char *bname = NULL; shard_priv_t *priv = NULL; shard_inode_ctx_t ctx_tmp = { 0, }; shard_local_t *local = NULL; gf_boolean_t wind_failed = _gf_false; fd_t *fd = NULL; loc_t loc = { 0, }; dict_t *xattr_req = NULL; local = frame->local; priv = this->private; fd = local->fd; shard_idx_iter = local->first_block; last_block = local->last_block; call_count = local->call_count = local->create_count; local->post_mknod_handler = post_mknod_handler; /* Build base shard path before appending index of the shard */ prefix_len = shard_make_base_path(path, fd->inode->gfid); bname = path + sizeof(GF_SHARD_DIR) + 1; SHARD_SET_ROOT_FS_ID(frame, local); ret = shard_inode_ctx_get_all(fd->inode, this, &ctx_tmp); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get inode " "ctx for %s", uuid_utoa(fd->inode->gfid)); local->op_ret = -1; local->op_errno = ENOMEM; goto err; } mode = st_mode_from_ia(ctx_tmp.stat.ia_prot, ctx_tmp.stat.ia_type); while (shard_idx_iter <= last_block) { if (local->inode_list[i]) { shard_idx_iter++; i++; continue; } if (wind_failed) { shard_common_mknod_cbk(frame, (void *)(long)shard_idx_iter, this, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); goto next; } shard_append_index(path, SHARD_PATH_MAX, prefix_len, shard_idx_iter); xattr_req = shard_create_gfid_dict(local->xattr_req); if (!xattr_req) { local->op_ret = -1; local->op_errno = ENOMEM; wind_failed = _gf_true; shard_common_mknod_cbk(frame, (void *)(long)shard_idx_iter, this, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); goto next; } loc.inode = inode_new(this->itable); loc.parent = inode_ref(priv->dot_shard_inode); ret = inode_path(loc.parent, bname, (char **)&(loc.path)); if (ret < 0 || !(loc.inode)) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_PATH_FAILED, "Inode path failed" "on %s, base file gfid = %s", bname, uuid_utoa(fd->inode->gfid)); local->op_ret = -1; local->op_errno = ENOMEM; wind_failed = _gf_true; loc_wipe(&loc); dict_unref(xattr_req); shard_common_mknod_cbk(frame, (void *)(long)shard_idx_iter, this, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); goto next; } loc.name = strrchr(loc.path, '/'); if (loc.name) loc.name++; STACK_WIND_COOKIE(frame, shard_common_mknod_cbk, (void *)(long)shard_idx_iter, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, &loc, mode, ctx_tmp.stat.ia_rdev, 0, xattr_req); loc_wipe(&loc); dict_unref(xattr_req); next: shard_idx_iter++; i++; if (!--call_count) break; } return 0; err: /* * This block is for handling failure in shard_inode_ctx_get_all(). * Failures in the while-loop are handled within the loop. */ SHARD_UNSET_ROOT_FS_ID(frame, local); post_mknod_handler(frame, this); return 0; } int shard_post_mknod_readv_handler(call_frame_t *frame, xlator_t *this); int shard_post_lookup_shards_readv_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(GF_FOP_READ, frame, local->op_ret, local->op_errno); return 0; } if (local->create_count) { shard_common_resume_mknod(frame, this, shard_post_mknod_readv_handler); } else { shard_readv_do(frame, this); } return 0; } int shard_post_mknod_readv_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(GF_FOP_READ, frame, local->op_ret, local->op_errno); return 0; } if (!local->eexist_count) { shard_readv_do(frame, this); } else { local->call_count = local->eexist_count; shard_common_lookup_shards(frame, this, local->loc.inode, shard_post_lookup_shards_readv_handler); } return 0; } int shard_post_resolve_readv_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { if (local->op_errno != ENOENT) { shard_common_failure_unwind(GF_FOP_READ, frame, local->op_ret, local->op_errno); return 0; } else { struct iovec vec = { 0, }; vec.iov_base = local->iobuf->ptr; vec.iov_len = local->total_size; local->op_ret = local->total_size; SHARD_STACK_UNWIND(readv, frame, local->op_ret, 0, &vec, 1, &local->prebuf, local->iobref, NULL); return 0; } } if (local->call_count) { shard_common_lookup_shards(frame, this, local->resolver_base_inode, shard_post_lookup_shards_readv_handler); } else { shard_readv_do(frame, this); } return 0; } int shard_post_lookup_readv_handler(call_frame_t *frame, xlator_t *this) { int ret = 0; struct iobuf *iobuf = NULL; shard_local_t *local = NULL; shard_priv_t *priv = NULL; priv = this->private; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(GF_FOP_READ, frame, local->op_ret, local->op_errno); return 0; } if (local->offset >= local->prebuf.ia_size) { /* If the read is being performed past the end of the file, * unwind the FOP with 0 bytes read as status. */ struct iovec vec = { 0, }; iobuf = iobuf_get2(this->ctx->iobuf_pool, local->req_size); if (!iobuf) goto err; vec.iov_base = iobuf->ptr; vec.iov_len = 0; local->iobref = iobref_new(); iobref_add(local->iobref, iobuf); iobuf_unref(iobuf); SHARD_STACK_UNWIND(readv, frame, 0, 0, &vec, 1, &local->prebuf, local->iobref, NULL); return 0; } local->first_block = get_lowest_block(local->offset, local->block_size); local->total_size = local->req_size; local->last_block = get_highest_block(local->offset, local->total_size, local->block_size); local->num_blocks = local->last_block - local->first_block + 1; GF_ASSERT(local->num_blocks > 0); local->resolver_base_inode = local->loc.inode; local->inode_list = GF_CALLOC(local->num_blocks, sizeof(inode_t *), gf_shard_mt_inode_list); if (!local->inode_list) goto err; iobuf = iobuf_get2(this->ctx->iobuf_pool, local->total_size); if (!iobuf) goto err; local->iobref = iobref_new(); if (!local->iobref) { iobuf_unref(iobuf); goto err; } if (iobref_add(local->iobref, iobuf) != 0) { iobuf_unref(iobuf); goto err; } memset(iobuf->ptr, 0, local->total_size); iobuf_unref(iobuf); local->iobuf = iobuf; local->dot_shard_loc.inode = inode_find(this->itable, priv->dot_shard_gfid); if (!local->dot_shard_loc.inode) { ret = shard_init_internal_dir_loc(this, local, SHARD_INTERNAL_DIR_DOT_SHARD); if (ret) goto err; shard_lookup_internal_dir(frame, this, shard_post_resolve_readv_handler, SHARD_INTERNAL_DIR_DOT_SHARD); } else { local->post_res_handler = shard_post_resolve_readv_handler; shard_refresh_internal_dir(frame, this, SHARD_INTERNAL_DIR_DOT_SHARD); } return 0; err: shard_common_failure_unwind(GF_FOP_READ, frame, -1, ENOMEM); return 0; } int shard_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { int ret = 0; uint64_t block_size = 0; shard_local_t *local = NULL; if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; } ret = shard_inode_ctx_get_block_size(fd->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size for %s from its inode ctx", uuid_utoa(fd->inode->gfid)); goto err; } if (!block_size) { STACK_WIND(frame, default_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; } if (!this->itable) this->itable = fd->inode->table; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; ret = syncbarrier_init(&local->barrier); if (ret) goto err; local->fd = fd_ref(fd); local->block_size = block_size; local->offset = offset; local->req_size = size; local->flags = flags; local->fop = GF_FOP_READ; local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; local->loc.inode = inode_ref(fd->inode); gf_uuid_copy(local->loc.gfid, fd->inode->gfid); shard_refresh_base_file(frame, this, NULL, fd, shard_post_lookup_readv_handler); return 0; err: shard_common_failure_unwind(GF_FOP_READ, frame, -1, ENOMEM); return 0; } static int shard_common_inode_write_post_update_size_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); } else { shard_common_inode_write_success_unwind(local->fop, frame, local->written_size); } return 0; } static gf_boolean_t shard_is_appending_write(shard_local_t *local) { if (local->fop != GF_FOP_WRITE) return _gf_false; if (local->flags & O_APPEND) return _gf_true; if (local->fd->flags & O_APPEND) return _gf_true; return _gf_false; } int __shard_get_delta_size_from_inode_ctx(shard_local_t *local, inode_t *inode, xlator_t *this) { int ret = -1; uint64_t ctx_uint = 0; shard_inode_ctx_t *ctx = NULL; ret = __inode_ctx_get(inode, this, &ctx_uint); if (ret < 0) return ret; ctx = (shard_inode_ctx_t *)(uintptr_t)ctx_uint; if (shard_is_appending_write(local)) { local->delta_size = local->total_size; } else if (local->offset + local->total_size > ctx->stat.ia_size) { local->delta_size = (local->offset + local->total_size) - ctx->stat.ia_size; } else { local->delta_size = 0; } ctx->stat.ia_size += (local->delta_size); local->postbuf = ctx->stat; return 0; } int shard_get_delta_size_from_inode_ctx(shard_local_t *local, inode_t *inode, xlator_t *this) { int ret = -1; LOCK(&inode->lock); { ret = __shard_get_delta_size_from_inode_ctx(local, inode, this); } UNLOCK(&inode->lock); return ret; } int shard_common_inode_write_do_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { int call_count = 0; fd_t *anon_fd = cookie; shard_local_t *local = NULL; glusterfs_fop_t fop = 0; local = frame->local; fop = local->fop; LOCK(&frame->lock); { if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; } else { local->written_size += op_ret; GF_ATOMIC_ADD(local->delta_blocks, post->ia_blocks - pre->ia_blocks); local->delta_size += (post->ia_size - pre->ia_size); shard_inode_ctx_set(local->fd->inode, this, post, 0, SHARD_MASK_TIMES); if (local->fd->inode != anon_fd->inode) shard_inode_ctx_add_to_fsync_list(local->fd->inode, this, anon_fd->inode); } } UNLOCK(&frame->lock); if (anon_fd) fd_unref(anon_fd); call_count = shard_call_count_return(frame); if (call_count == 0) { SHARD_UNSET_ROOT_FS_ID(frame, local); if (local->op_ret < 0) { shard_common_failure_unwind(fop, frame, local->op_ret, local->op_errno); } else { shard_get_delta_size_from_inode_ctx(local, local->fd->inode, this); local->hole_size = 0; if (xdata) local->xattr_rsp = dict_ref(xdata); shard_update_file_size( frame, this, local->fd, NULL, shard_common_inode_write_post_update_size_handler); } } return 0; } int shard_common_inode_write_wind(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vec, int count, off_t shard_offset, size_t size) { shard_local_t *local = NULL; local = frame->local; switch (local->fop) { case GF_FOP_WRITE: STACK_WIND_COOKIE( frame, shard_common_inode_write_do_cbk, fd, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vec, count, shard_offset, local->flags, local->iobref, local->xattr_req); break; case GF_FOP_FALLOCATE: STACK_WIND_COOKIE( frame, shard_common_inode_write_do_cbk, fd, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, local->flags, shard_offset, size, local->xattr_req); break; case GF_FOP_ZEROFILL: STACK_WIND_COOKIE(frame, shard_common_inode_write_do_cbk, fd, FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill, fd, shard_offset, size, local->xattr_req); break; case GF_FOP_DISCARD: STACK_WIND_COOKIE(frame, shard_common_inode_write_do_cbk, fd, FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard, fd, shard_offset, size, local->xattr_req); break; default: gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_INVALID_FOP, "Invalid fop id = %d", local->fop); break; } return 0; } int shard_common_inode_write_do(call_frame_t *frame, xlator_t *this) { int i = 0; int count = 0; int call_count = 0; int last_block = 0; uint32_t cur_block = 0; fd_t *fd = NULL; fd_t *anon_fd = NULL; shard_local_t *local = NULL; struct iovec *vec = NULL; gf_boolean_t wind_failed = _gf_false; gf_boolean_t odirect = _gf_false; off_t orig_offset = 0; off_t shard_offset = 0; off_t vec_offset = 0; size_t remaining_size = 0; size_t shard_write_size = 0; local = frame->local; fd = local->fd; orig_offset = local->offset; remaining_size = local->total_size; cur_block = local->first_block; local->call_count = call_count = local->num_blocks; last_block = local->last_block; SHARD_SET_ROOT_FS_ID(frame, local); if (dict_set_uint32(local->xattr_req, GLUSTERFS_WRITE_UPDATE_ATOMIC, 4)) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set " GLUSTERFS_WRITE_UPDATE_ATOMIC " into " "dict: %s", uuid_utoa(fd->inode->gfid)); local->op_ret = -1; local->op_errno = ENOMEM; local->call_count = 1; shard_common_inode_write_do_cbk(frame, (void *)(long)0, this, -1, ENOMEM, NULL, NULL, NULL); return 0; } if ((fd->flags & O_DIRECT) && (local->fop == GF_FOP_WRITE)) odirect = _gf_true; while (cur_block <= last_block) { if (wind_failed) { shard_common_inode_write_do_cbk(frame, (void *)(long)0, this, -1, ENOMEM, NULL, NULL, NULL); goto next; } shard_offset = orig_offset % local->block_size; shard_write_size = local->block_size - shard_offset; if (shard_write_size > remaining_size) shard_write_size = remaining_size; remaining_size -= shard_write_size; if (local->fop == GF_FOP_WRITE) { vec = NULL; count = iov_subset(local->vector, local->count, vec_offset, shard_write_size, &vec, 0); if (count < 0) { local->op_ret = -1; local->op_errno = ENOMEM; wind_failed = _gf_true; shard_common_inode_write_do_cbk(frame, (void *)(long)0, this, -1, ENOMEM, NULL, NULL, NULL); goto next; } } if (cur_block == 0) { anon_fd = fd_ref(fd); } else { anon_fd = fd_anonymous(local->inode_list[i]); if (!anon_fd) { local->op_ret = -1; local->op_errno = ENOMEM; wind_failed = _gf_true; GF_FREE(vec); shard_common_inode_write_do_cbk(frame, (void *)(long)anon_fd, this, -1, ENOMEM, NULL, NULL, NULL); goto next; } if (local->fop == GF_FOP_WRITE) { if (odirect) local->flags = O_DIRECT; else local->flags = GF_ANON_FD_FLAGS; } } shard_common_inode_write_wind(frame, this, anon_fd, vec, count, shard_offset, shard_write_size); if (vec) vec_offset += shard_write_size; orig_offset += shard_write_size; GF_FREE(vec); vec = NULL; next: cur_block++; i++; call_count--; } return 0; } static int shard_common_inode_write_post_mknod_handler(call_frame_t *frame, xlator_t *this); int shard_common_inode_write_post_lookup_shards_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } if (local->create_count) { shard_common_resume_mknod(frame, this, shard_common_inode_write_post_mknod_handler); } else { shard_common_inode_write_do(frame, this); } return 0; } static int shard_common_inode_write_post_mknod_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } if (!local->eexist_count) { shard_common_inode_write_do(frame, this); } else { local->call_count = local->eexist_count; shard_common_lookup_shards( frame, this, local->loc.inode, shard_common_inode_write_post_lookup_shards_handler); } return 0; } static int shard_common_inode_write_post_resolve_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } if (local->call_count) { shard_common_lookup_shards( frame, this, local->resolver_base_inode, shard_common_inode_write_post_lookup_shards_handler); } else if (local->create_count) { shard_common_inode_write_post_lookup_shards_handler(frame, this); } else { shard_common_inode_write_do(frame, this); } return 0; } static int shard_common_inode_write_post_lookup_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = frame->local; shard_priv_t *priv = this->private; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } local->postbuf = local->prebuf; /*Adjust offset to EOF so that correct shard is chosen for append*/ if (shard_is_appending_write(local)) local->offset = local->prebuf.ia_size; local->first_block = get_lowest_block(local->offset, local->block_size); local->last_block = get_highest_block(local->offset, local->total_size, local->block_size); local->num_blocks = local->last_block - local->first_block + 1; GF_ASSERT(local->num_blocks > 0); local->inode_list = GF_CALLOC(local->num_blocks, sizeof(inode_t *), gf_shard_mt_inode_list); if (!local->inode_list) { shard_common_failure_unwind(local->fop, frame, -1, ENOMEM); return 0; } gf_msg_trace(this->name, 0, "%s: gfid=%s first_block=%" PRIu64 " " "last_block=%" PRIu64 " num_blocks=%" PRIu64 " offset=%" PRId64 " total_size=%zu flags=%" PRId32 "", gf_fop_list[local->fop], uuid_utoa(local->resolver_base_inode->gfid), local->first_block, local->last_block, local->num_blocks, local->offset, local->total_size, local->flags); local->dot_shard_loc.inode = inode_find(this->itable, priv->dot_shard_gfid); if (!local->dot_shard_loc.inode) { /*change handler*/ shard_mkdir_internal_dir(frame, this, shard_common_inode_write_post_resolve_handler, SHARD_INTERNAL_DIR_DOT_SHARD); } else { /*change handler*/ local->post_res_handler = shard_common_inode_write_post_resolve_handler; shard_refresh_internal_dir(frame, this, SHARD_INTERNAL_DIR_DOT_SHARD); } return 0; } int shard_mkdir_internal_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { inode_t *link_inode = NULL; shard_local_t *local = NULL; shard_internal_dir_type_t type = (shard_internal_dir_type_t)cookie; local = frame->local; SHARD_UNSET_ROOT_FS_ID(frame, local); if (op_ret == -1) { if (op_errno != EEXIST) { local->op_ret = op_ret; local->op_errno = op_errno; goto unwind; } else { gf_msg_debug(this->name, 0, "mkdir on %s failed " "with EEXIST. Attempting lookup now", shard_internal_dir_string(type)); shard_lookup_internal_dir(frame, this, local->post_res_handler, type); return 0; } } link_inode = shard_link_internal_dir_inode(local, inode, this, buf, type); if (link_inode != inode) { shard_refresh_internal_dir(frame, this, type); } else { shard_inode_ctx_mark_dir_refreshed(link_inode, this); shard_common_resolve_shards(frame, this, local->post_res_handler); } return 0; unwind: shard_common_resolve_shards(frame, this, local->post_res_handler); return 0; } static int shard_mkdir_internal_dir(call_frame_t *frame, xlator_t *this, shard_post_resolve_fop_handler_t handler, shard_internal_dir_type_t type) { int ret = -1; shard_local_t *local = NULL; shard_priv_t *priv = NULL; dict_t *xattr_req = NULL; uuid_t *gfid = NULL; loc_t *loc = NULL; gf_boolean_t free_gfid = _gf_true; local = frame->local; priv = this->private; local->post_res_handler = handler; gfid = GF_MALLOC(sizeof(uuid_t), gf_common_mt_uuid_t); if (!gfid) goto err; switch (type) { case SHARD_INTERNAL_DIR_DOT_SHARD: gf_uuid_copy(*gfid, priv->dot_shard_gfid); loc = &local->dot_shard_loc; break; case SHARD_INTERNAL_DIR_DOT_SHARD_REMOVE_ME: gf_uuid_copy(*gfid, priv->dot_shard_rm_gfid); loc = &local->dot_shard_rm_loc; break; default: bzero(*gfid, sizeof(uuid_t)); break; } xattr_req = dict_new(); if (!xattr_req) goto err; ret = shard_init_internal_dir_loc(this, local, type); if (ret) goto err; ret = dict_set_gfuuid(xattr_req, "gfid-req", *gfid, false); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set gfid-req for %s", shard_internal_dir_string(type)); goto err; } else { free_gfid = _gf_false; } SHARD_SET_ROOT_FS_ID(frame, local); /* Mark this as an internal operation, so that in case of disk full * the internal dir will be created as part of reserve space */ ret = dict_set_int32_sizen(xattr_req, GLUSTERFS_INTERNAL_FOP_KEY, 1); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED, "Failed to set key: %s on path %s", GLUSTERFS_INTERNAL_FOP_KEY, loc->path); goto err; } STACK_WIND_COOKIE(frame, shard_mkdir_internal_dir_cbk, (void *)(long)type, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, 0755, 0, xattr_req); dict_unref(xattr_req); return 0; err: if (xattr_req) dict_unref(xattr_req); local->op_ret = -1; local->op_errno = ENOMEM; if (free_gfid) GF_FREE(gfid); handler(frame, this); return 0; } int shard_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { /* To-Do: Wind flush on all shards of the file */ SHARD_STACK_UNWIND(flush, frame, op_ret, op_errno, xdata); return 0; } int shard_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { STACK_WIND(frame, shard_flush_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush, fd, xdata); return 0; } int __shard_get_timestamps_from_inode_ctx(shard_local_t *local, inode_t *inode, xlator_t *this) { int ret = -1; uint64_t ctx_uint = 0; shard_inode_ctx_t *ctx = NULL; ret = __inode_ctx_get(inode, this, &ctx_uint); if (ret < 0) return ret; ctx = (shard_inode_ctx_t *)(uintptr_t)ctx_uint; local->postbuf.ia_ctime = ctx->stat.ia_ctime; local->postbuf.ia_ctime_nsec = ctx->stat.ia_ctime_nsec; local->postbuf.ia_atime = ctx->stat.ia_atime; local->postbuf.ia_atime_nsec = ctx->stat.ia_atime_nsec; local->postbuf.ia_mtime = ctx->stat.ia_mtime; local->postbuf.ia_mtime_nsec = ctx->stat.ia_mtime_nsec; return 0; } static int shard_get_timestamps_from_inode_ctx(shard_local_t *local, inode_t *inode, xlator_t *this) { int ret = 0; LOCK(&inode->lock); { ret = __shard_get_timestamps_from_inode_ctx(local, inode, this); } UNLOCK(&inode->lock); return ret; } static int shard_fsync_shards_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { int call_count = 0; uint64_t fsync_count = 0; fd_t *anon_fd = cookie; shard_local_t *local = NULL; shard_inode_ctx_t *ctx = NULL; shard_inode_ctx_t *base_ictx = NULL; inode_t *base_inode = NULL; gf_boolean_t unref_shard_inode = _gf_false; local = frame->local; base_inode = local->fd->inode; if (local->op_ret < 0) goto out; LOCK(&frame->lock); { if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; UNLOCK(&frame->lock); goto out; } shard_inode_ctx_set(local->fd->inode, this, postbuf, 0, SHARD_MASK_TIMES); } UNLOCK(&frame->lock); out: if (anon_fd && (base_inode != anon_fd->inode)) { fsync_count = fd_ctx_get(anon_fd, this); LOCK(&base_inode->lock); LOCK(&anon_fd->inode->lock); { __shard_inode_ctx_get(anon_fd->inode, this, &ctx); __shard_inode_ctx_get(base_inode, this, &base_ictx); if (op_ret == 0) ctx->fsync_needed -= fsync_count; GF_ASSERT(ctx->fsync_needed >= 0); if (ctx->fsync_needed != 0) { list_add_tail(&ctx->to_fsync_list, &base_ictx->to_fsync_list); base_ictx->fsync_count++; } else { unref_shard_inode = _gf_true; } } UNLOCK(&anon_fd->inode->lock); UNLOCK(&base_inode->lock); } if (unref_shard_inode) inode_unref(anon_fd->inode); if (anon_fd) fd_unref(anon_fd); call_count = shard_call_count_return(frame); if (call_count != 0) return 0; if (local->op_ret < 0) { shard_common_failure_unwind(GF_FOP_FSYNC, frame, local->op_ret, local->op_errno); } else { shard_get_timestamps_from_inode_ctx(local, base_inode, this); SHARD_STACK_UNWIND(fsync, frame, local->op_ret, local->op_errno, &local->prebuf, &local->postbuf, local->xattr_rsp); } return 0; } static int shard_post_lookup_fsync_handler(call_frame_t *frame, xlator_t *this) { int ret = 0; int call_count = 0; int fsync_count = 0; fd_t *anon_fd = NULL; inode_t *base_inode = NULL; shard_local_t *local = NULL; shard_inode_ctx_t *ctx = NULL; shard_inode_ctx_t *iter = NULL; struct list_head copy = { 0, }; shard_inode_ctx_t *tmp = NULL; local = frame->local; base_inode = local->fd->inode; local->postbuf = local->prebuf; INIT_LIST_HEAD(©); if (local->op_ret < 0) { shard_common_failure_unwind(GF_FOP_FSYNC, frame, local->op_ret, local->op_errno); return 0; } LOCK(&base_inode->lock); { __shard_inode_ctx_get(base_inode, this, &ctx); list_splice_init(&ctx->to_fsync_list, ©); call_count = ctx->fsync_count; ctx->fsync_count = 0; } UNLOCK(&base_inode->lock); local->call_count = ++call_count; /* Send fsync() on the base shard first */ anon_fd = fd_ref(local->fd); STACK_WIND_COOKIE(frame, shard_fsync_shards_cbk, anon_fd, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, anon_fd, local->datasync, local->xattr_req); call_count--; anon_fd = NULL; list_for_each_entry_safe(iter, tmp, ©, to_fsync_list) { list_del_init(&iter->to_fsync_list); fsync_count = 0; shard_inode_ctx_get_fsync_count(iter->inode, this, &fsync_count); GF_ASSERT(fsync_count > 0); anon_fd = fd_anonymous(iter->inode); if (!anon_fd) { local->op_ret = -1; local->op_errno = ENOMEM; gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SHARD_MSG_MEMALLOC_FAILED, "Failed to create " "anon fd to fsync shard"); shard_fsync_shards_cbk(frame, (void *)(long)anon_fd, this, -1, ENOMEM, NULL, NULL, NULL); continue; } ret = fd_ctx_set(anon_fd, this, fsync_count); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_FD_CTX_SET_FAILED, "Failed to set fd " "ctx for shard inode gfid=%s", uuid_utoa(iter->inode->gfid)); local->op_ret = -1; local->op_errno = ENOMEM; shard_fsync_shards_cbk(frame, (void *)(long)anon_fd, this, -1, ENOMEM, NULL, NULL, NULL); continue; } STACK_WIND_COOKIE(frame, shard_fsync_shards_cbk, anon_fd, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, anon_fd, local->datasync, local->xattr_req); call_count--; } return 0; } static int shard_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { int ret = 0; uint64_t block_size = 0; shard_local_t *local = NULL; if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_fsync_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata); return 0; } ret = shard_inode_ctx_get_block_size(fd->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size for %s from its inode ctx", uuid_utoa(fd->inode->gfid)); goto err; } if (!block_size) { STACK_WIND(frame, default_fsync_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata); return 0; } if (!this->itable) this->itable = fd->inode->table; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->fd = fd_ref(fd); local->fop = GF_FOP_FSYNC; local->datasync = datasync; local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; local->loc.inode = inode_ref(fd->inode); gf_uuid_copy(local->loc.gfid, fd->inode->gfid); shard_refresh_base_file(frame, this, NULL, fd, shard_post_lookup_fsync_handler); return 0; err: shard_common_failure_unwind(GF_FOP_FSYNC, frame, -1, ENOMEM); return 0; } static int shard_readdir_past_dot_shard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *orig_entries, dict_t *xdata) { gf_dirent_t *entry = NULL; gf_dirent_t *tmp = NULL; shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) goto unwind; list_for_each_entry_safe(entry, tmp, (&orig_entries->list), list) { list_move_tail(&entry->list, &local->entries_head.list); if (!entry->dict) continue; if (IA_ISDIR(entry->d_stat.ia_type)) continue; shard_modify_size_and_block_count(&entry->d_stat, entry->dict, _gf_false); if (!entry->inode) continue; shard_inode_ctx_update(entry->inode, this, entry->dict, &entry->d_stat); } local->op_ret += op_ret; unwind: if (local->fop == GF_FOP_READDIR) SHARD_STACK_UNWIND(readdir, frame, local->op_ret, local->op_errno, &local->entries_head, xdata); else SHARD_STACK_UNWIND(readdirp, frame, op_ret, op_errno, &local->entries_head, xdata); return 0; } static int32_t shard_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *orig_entries, dict_t *xdata) { fd_t *fd = NULL; gf_dirent_t *entry = NULL; gf_dirent_t *tmp = NULL; shard_local_t *local = NULL; gf_boolean_t last_entry = _gf_false; gf_boolean_t is_root_gfid = _gf_false; gf_boolean_t is_client_pid_not_gsyncd = _gf_false; local = frame->local; if (op_ret < 0) goto unwind; fd = local->fd; is_root_gfid = __is_root_gfid(fd->inode->gfid); if (frame->root->pid != GF_CLIENT_PID_GSYNCD) is_client_pid_not_gsyncd = _gf_true; list_for_each_entry_safe(entry, tmp, (&orig_entries->list), list) { if (last_entry) last_entry = _gf_false; if (is_root_gfid && !(strcmp(entry->d_name, GF_SHARD_DIR))) { local->offset = entry->d_off; op_ret--; last_entry = _gf_true; continue; } list_move_tail(&entry->list, &local->entries_head.list); if (!entry->dict) continue; if (IA_ISDIR(entry->d_stat.ia_type)) continue; if (is_client_pid_not_gsyncd) shard_modify_size_and_block_count(&entry->d_stat, entry->dict, _gf_false); if (!entry->inode) continue; shard_inode_ctx_update(entry->inode, this, entry->dict, &entry->d_stat); } local->op_ret = op_ret; if (last_entry) { if (local->fop == GF_FOP_READDIR) STACK_WIND(frame, shard_readdir_past_dot_shard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, local->fd, local->readdir_size, local->offset, local->xattr_req); else STACK_WIND(frame, shard_readdir_past_dot_shard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, local->fd, local->readdir_size, local->offset, local->xattr_req); return 0; } unwind: if (local->fop == GF_FOP_READDIR) SHARD_STACK_UNWIND(readdir, frame, op_ret, op_errno, &local->entries_head, xdata); else SHARD_STACK_UNWIND(readdirp, frame, op_ret, op_errno, &local->entries_head, xdata); return 0; } static int shard_readdir_do(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, int whichop, dict_t *xdata) { int ret = 0; shard_local_t *local = NULL; local = mem_get0(this->local_pool); if (!local) { goto err; } frame->local = local; local->fd = fd_ref(fd); local->fop = whichop; local->readdir_size = size; INIT_LIST_HEAD(&local->entries_head.list); local->list_inited = _gf_true; if (whichop == GF_FOP_READDIR) { STACK_WIND(frame, shard_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, fd, size, offset, xdata); } else { local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); SHARD_MD_READ_FOP_INIT_REQ_DICT(this, local->xattr_req, fd->inode->gfid, local, err); ret = dict_set_uint64(local->xattr_req, GF_XATTR_SHARD_BLOCK_SIZE, 0); if (ret) { gf_log(this->name, GF_LOG_WARNING, "Failed to set " "dict value: key:%s, directory gfid=%s", GF_XATTR_SHARD_BLOCK_SIZE, uuid_utoa(fd->inode->gfid)); goto err; } STACK_WIND(frame, shard_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, local->xattr_req); } return 0; err: STACK_UNWIND_STRICT(readdir, frame, -1, ENOMEM, NULL, NULL); return 0; } static int32_t shard_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { shard_readdir_do(frame, this, fd, size, offset, GF_FOP_READDIR, xdata); return 0; } static int32_t shard_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { shard_readdir_do(frame, this, fd, size, offset, GF_FOP_READDIRP, xdata); return 0; } static int32_t shard_modify_and_set_iatt_in_dict(dict_t *xdata, shard_local_t *local, char *key) { int ret = 0; struct iatt *tmpbuf = NULL; struct iatt *stbuf = NULL; data_t *data = NULL; if (!xdata) return 0; data = dict_get(xdata, key); if (!data) return 0; tmpbuf = data_to_iatt(data, key); stbuf = GF_MALLOC(sizeof(struct iatt), gf_common_mt_char); if (stbuf == NULL) { local->op_ret = -1; local->op_errno = ENOMEM; goto err; } *stbuf = *tmpbuf; stbuf->ia_size = local->prebuf.ia_size; stbuf->ia_blocks = local->prebuf.ia_blocks; ret = dict_set_iatt(xdata, key, stbuf, false); if (ret < 0) { local->op_ret = -1; local->op_errno = ENOMEM; goto err; } return 0; err: GF_FREE(stbuf); return -1; } int32_t shard_common_remove_xattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { int ret = -1; shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; goto err; } ret = shard_modify_and_set_iatt_in_dict(xdata, local, GF_PRESTAT); if (ret < 0) goto err; ret = shard_modify_and_set_iatt_in_dict(xdata, local, GF_POSTSTAT); if (ret < 0) goto err; if (local->fd) SHARD_STACK_UNWIND(fremovexattr, frame, local->op_ret, local->op_errno, xdata); else SHARD_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, xdata); return 0; err: shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } static int32_t shard_post_lookup_remove_xattr_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } if (local->fd) STACK_WIND(frame, shard_common_remove_xattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, local->fd, local->name, local->xattr_req); else STACK_WIND(frame, shard_common_remove_xattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, &local->loc, local->name, local->xattr_req); return 0; } static int32_t shard_common_remove_xattr(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop, loc_t *loc, fd_t *fd, const char *name, dict_t *xdata) { int ret = -1; int op_errno = ENOMEM; uint64_t block_size = 0; shard_local_t *local = NULL; inode_t *inode = loc ? loc->inode : fd->inode; if ((IA_ISDIR(inode->ia_type)) || (IA_ISLNK(inode->ia_type))) { if (loc) STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; } /* If shard's special xattrs are attempted to be removed, * fail the fop with EPERM (except if the client is gsyncd). */ if (frame->root->pid != GF_CLIENT_PID_GSYNCD) { GF_IF_NATIVE_XATTR_GOTO(SHARD_XATTR_PREFIX "*", name, op_errno, err); } /* Repeat the same check for bulk-removexattr */ if (xdata && (frame->root->pid != GF_CLIENT_PID_GSYNCD)) { dict_del(xdata, GF_XATTR_SHARD_BLOCK_SIZE); dict_del(xdata, GF_XATTR_SHARD_FILE_SIZE); } if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { if (loc) STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; } ret = shard_inode_ctx_get_block_size(inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block size from inode ctx of %s", uuid_utoa(inode->gfid)); goto err; } if (!block_size) { if (loc) STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; } local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->fop = fop; if (loc) { if (loc_copy(&local->loc, loc) != 0) goto err; } if (fd) { local->fd = fd_ref(fd); local->loc.inode = inode_ref(fd->inode); gf_uuid_copy(local->loc.gfid, fd->inode->gfid); } if (name) { local->name = gf_strdup(name); if (!local->name) goto err; } if (xdata) local->xattr_req = dict_ref(xdata); shard_refresh_base_file(frame, this, loc, fd, shard_post_lookup_remove_xattr_handler); return 0; err: shard_common_failure_unwind(fop, frame, -1, op_errno); return 0; } static int32_t shard_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { shard_common_remove_xattr(frame, this, GF_FOP_REMOVEXATTR, loc, NULL, name, xdata); return 0; } static int32_t shard_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { shard_common_remove_xattr(frame, this, GF_FOP_FREMOVEXATTR, NULL, fd, name, xdata); return 0; } static int32_t shard_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { if (op_ret < 0) goto unwind; if (dict && (frame->root->pid != GF_CLIENT_PID_GSYNCD)) { dict_del(dict, GF_XATTR_SHARD_BLOCK_SIZE); dict_del(dict, GF_XATTR_SHARD_FILE_SIZE); } unwind: SHARD_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, dict, xdata); return 0; } int32_t shard_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int op_errno = EINVAL; if ((frame->root->pid != GF_CLIENT_PID_GSYNCD) && (name) && (!strncmp(name, SHARD_XATTR_PREFIX, SLEN(SHARD_XATTR_PREFIX)))) { op_errno = ENODATA; goto out; } STACK_WIND(frame, shard_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); return 0; out: shard_common_failure_unwind(GF_FOP_FGETXATTR, frame, -1, op_errno); return 0; } int32_t shard_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { if (op_ret < 0) goto unwind; if (dict && (frame->root->pid != GF_CLIENT_PID_GSYNCD)) { dict_del(dict, GF_XATTR_SHARD_BLOCK_SIZE); dict_del(dict, GF_XATTR_SHARD_FILE_SIZE); } unwind: SHARD_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } int32_t shard_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int op_errno = EINVAL; if ((frame->root->pid != GF_CLIENT_PID_GSYNCD) && (name) && (!strncmp(name, SHARD_XATTR_PREFIX, sizeof(SHARD_XATTR_PREFIX) - 1))) { op_errno = ENODATA; goto out; } STACK_WIND(frame, shard_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); return 0; out: shard_common_failure_unwind(GF_FOP_GETXATTR, frame, -1, op_errno); return 0; } static int32_t shard_common_set_xattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { int ret = -1; shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; goto err; } ret = shard_modify_and_set_iatt_in_dict(xdata, local, GF_PRESTAT); if (ret < 0) goto err; ret = shard_modify_and_set_iatt_in_dict(xdata, local, GF_POSTSTAT); if (ret < 0) goto err; if (local->fd) SHARD_STACK_UNWIND(fsetxattr, frame, local->op_ret, local->op_errno, xdata); else SHARD_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, xdata); return 0; err: shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } int32_t shard_post_lookup_set_xattr_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->op_ret < 0) { shard_common_failure_unwind(local->fop, frame, local->op_ret, local->op_errno); return 0; } if (local->fd) STACK_WIND(frame, shard_common_set_xattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, local->fd, local->xattr_req, local->flags, local->xattr_rsp); else STACK_WIND(frame, shard_common_set_xattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, &local->loc, local->xattr_req, local->flags, local->xattr_rsp); return 0; } static int32_t shard_common_set_xattr(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop, loc_t *loc, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { int ret = -1; int op_errno = ENOMEM; uint64_t block_size = 0; shard_local_t *local = NULL; inode_t *inode = loc ? loc->inode : fd->inode; if ((IA_ISDIR(inode->ia_type)) || (IA_ISLNK(inode->ia_type))) { if (loc) STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; } /* Sharded or not, if shard's special xattrs are attempted to be set, * fail the fop with EPERM (except if the client is gsyncd. */ if (frame->root->pid != GF_CLIENT_PID_GSYNCD) { GF_IF_INTERNAL_XATTR_GOTO(SHARD_XATTR_PREFIX "*", dict, op_errno, err); } if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { if (loc) STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; } ret = shard_inode_ctx_get_block_size(inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block size from inode ctx of %s", uuid_utoa(inode->gfid)); goto err; } if (!block_size) { if (loc) STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; } local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->fop = fop; if (loc) { if (loc_copy(&local->loc, loc) != 0) goto err; } if (fd) { local->fd = fd_ref(fd); local->loc.inode = inode_ref(fd->inode); gf_uuid_copy(local->loc.gfid, fd->inode->gfid); } local->flags = flags; /* Reusing local->xattr_req and local->xattr_rsp to store the setxattr dict * and the xdata dict */ if (dict) local->xattr_req = dict_ref(dict); if (xdata) local->xattr_rsp = dict_ref(xdata); shard_refresh_base_file(frame, this, loc, fd, shard_post_lookup_set_xattr_handler); return 0; err: shard_common_failure_unwind(fop, frame, -1, op_errno); return 0; } int32_t shard_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { shard_common_set_xattr(frame, this, GF_FOP_FSETXATTR, NULL, fd, dict, flags, xdata); return 0; } int32_t shard_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { shard_common_set_xattr(frame, this, GF_FOP_SETXATTR, loc, NULL, dict, flags, xdata); return 0; } static int shard_post_setattr_handler(call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; local = frame->local; if (local->fop == GF_FOP_SETATTR) { if (local->op_ret >= 0) shard_inode_ctx_set(local->loc.inode, this, &local->postbuf, 0, SHARD_LOOKUP_MASK); SHARD_STACK_UNWIND(setattr, frame, local->op_ret, local->op_errno, &local->prebuf, &local->postbuf, local->xattr_rsp); } else if (local->fop == GF_FOP_FSETATTR) { if (local->op_ret >= 0) shard_inode_ctx_set(local->fd->inode, this, &local->postbuf, 0, SHARD_LOOKUP_MASK); SHARD_STACK_UNWIND(fsetattr, frame, local->op_ret, local->op_errno, &local->prebuf, &local->postbuf, local->xattr_rsp); } return 0; } int shard_common_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { shard_local_t *local = NULL; local = frame->local; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; goto unwind; } local->prebuf = *prebuf; if (shard_modify_size_and_block_count(&local->prebuf, xdata, _gf_true)) { local->op_ret = -1; local->op_errno = EINVAL; goto unwind; } if (xdata) local->xattr_rsp = dict_ref(xdata); local->postbuf = *postbuf; local->postbuf.ia_size = local->prebuf.ia_size; local->postbuf.ia_blocks = local->prebuf.ia_blocks; unwind: local->handler(frame, this); return 0; } int shard_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int ret = -1; uint64_t block_size = 0; shard_local_t *local = NULL; if ((IA_ISDIR(loc->inode->ia_type)) || (IA_ISLNK(loc->inode->ia_type))) { STACK_WIND(frame, default_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } ret = shard_inode_ctx_get_block_size(loc->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block size from inode ctx of %s", uuid_utoa(loc->inode->gfid)); goto err; } if (!block_size) { STACK_WIND(frame, default_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->handler = shard_post_setattr_handler; local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; local->fop = GF_FOP_SETATTR; loc_copy(&local->loc, loc); SHARD_MD_READ_FOP_INIT_REQ_DICT(this, local->xattr_req, local->loc.gfid, local, err); STACK_WIND(frame, shard_common_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, local->xattr_req); return 0; err: shard_common_failure_unwind(GF_FOP_SETATTR, frame, -1, ENOMEM); return 0; } int shard_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int ret = -1; uint64_t block_size = 0; shard_local_t *local = NULL; if ((IA_ISDIR(fd->inode->ia_type)) || (IA_ISLNK(fd->inode->ia_type))) { STACK_WIND(frame, default_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { STACK_WIND(frame, default_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } ret = shard_inode_ctx_get_block_size(fd->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block size from inode ctx of %s", uuid_utoa(fd->inode->gfid)); goto err; } if (!block_size) { STACK_WIND(frame, default_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } if (!this->itable) this->itable = fd->inode->table; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->handler = shard_post_setattr_handler; local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto err; local->fop = GF_FOP_FSETATTR; local->fd = fd_ref(fd); SHARD_MD_READ_FOP_INIT_REQ_DICT(this, local->xattr_req, fd->inode->gfid, local, err); STACK_WIND(frame, shard_common_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, local->xattr_req); return 0; err: shard_common_failure_unwind(GF_FOP_FSETATTR, frame, -1, ENOMEM); return 0; } static inline void shard_common_unwind_based_on_fop(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, size_t len, struct iobref *iobref, dict_t *xdata) { switch (fop) { case GF_FOP_WRITE: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); break; case GF_FOP_FALLOCATE: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, flags, offset, len, xdata); break; case GF_FOP_ZEROFILL: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata); break; case GF_FOP_DISCARD: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); break; default: gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_INVALID_FOP, "Invalid fop id = %d", fop); break; } } static int shard_common_inode_write_begin(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, size_t len, struct iobref *iobref, dict_t *xdata) { int ret = 0; int i = 0; uint64_t block_size = 0; shard_local_t *local = NULL; if (frame->root->pid == GF_CLIENT_PID_GSYNCD) { shard_common_unwind_based_on_fop(frame, this, fop, fd, vector, count, offset, flags, len, iobref, xdata); return 0; } ret = shard_inode_ctx_get_block_size(fd->inode, this, &block_size); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block " "size for %s from its inode ctx", uuid_utoa(fd->inode->gfid)); goto out; } if (!block_size) { shard_common_unwind_based_on_fop(frame, this, fop, fd, vector, count, offset, flags, len, iobref, xdata); return 0; } if (!this->itable) this->itable = fd->inode->table; local = mem_get0(this->local_pool); if (!local) goto out; frame->local = local; ret = syncbarrier_init(&local->barrier); if (ret) goto out; local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); if (!local->xattr_req) goto out; if (vector) { local->vector = iov_dup(vector, count); if (!local->vector) goto out; for (i = 0; i < count; i++) local->total_size += vector[i].iov_len; local->count = count; } else { local->total_size = len; } local->fop = fop; local->offset = offset; local->flags = flags; if (iobref) local->iobref = iobref_ref(iobref); local->fd = fd_ref(fd); local->block_size = block_size; local->resolver_base_inode = local->fd->inode; GF_ATOMIC_INIT(local->delta_blocks, 0); local->loc.inode = inode_ref(fd->inode); gf_uuid_copy(local->loc.gfid, fd->inode->gfid); shard_refresh_base_file(frame, this, NULL, fd, shard_common_inode_write_post_lookup_handler); return 0; out: shard_common_failure_unwind(fop, frame, -1, ENOMEM); return 0; } int shard_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { shard_common_inode_write_begin(frame, this, GF_FOP_WRITE, fd, vector, count, offset, flags, 0, iobref, xdata); return 0; } int shard_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_size, off_t offset, size_t len, dict_t *xdata) { if ((keep_size != 0) && (keep_size != FALLOC_FL_ZERO_RANGE) && (keep_size != (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))) goto out; shard_common_inode_write_begin(frame, this, GF_FOP_FALLOCATE, fd, NULL, 0, offset, keep_size, len, NULL, xdata); return 0; out: shard_common_failure_unwind(GF_FOP_FALLOCATE, frame, -1, ENOTSUP); return 0; } int shard_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { shard_common_inode_write_begin(frame, this, GF_FOP_ZEROFILL, fd, NULL, 0, offset, 0, len, NULL, xdata); return 0; } int shard_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { shard_common_inode_write_begin(frame, this, GF_FOP_DISCARD, fd, NULL, 0, offset, 0, len, NULL, xdata); return 0; } int32_t shard_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { /* TBD */ gf_msg(this->name, GF_LOG_INFO, ENOTSUP, SHARD_MSG_FOP_NOT_SUPPORTED, "seek called on %s.", uuid_utoa(fd->inode->gfid)); shard_common_failure_unwind(GF_FOP_SEEK, frame, -1, ENOTSUP); return 0; } static void shard_unlink_wait(shard_unlink_thread_t *ti) { struct timespec wait_till = { 0, }; pthread_mutex_lock(&ti->mutex); { /* shard_unlink_handler() runs every 10 mins of interval */ wait_till.tv_sec = time(NULL) + 600; while (!ti->rerun) { if (pthread_cond_timedwait(&ti->cond, &ti->mutex, &wait_till) == ETIMEDOUT) break; } ti->rerun = _gf_false; } pthread_mutex_unlock(&ti->mutex); } static void * shard_unlink_handler(void *data) { shard_unlink_thread_t *ti = data; xlator_t *this = ti->this; THIS = this; while (!ti->stop) { shard_start_background_deletion(this); shard_unlink_wait(ti); } return NULL; } static int shard_unlink_handler_spawn(xlator_t *this) { int ret = 0; shard_priv_t *priv = this->private; shard_unlink_thread_t *ti = &priv->thread_info; ti->this = this; pthread_mutex_lock(&ti->mutex); { if (ti->running) { pthread_cond_signal(&ti->cond); } else { ret = gf_thread_create(&ti->thread, NULL, shard_unlink_handler, ti, "shard_unlink"); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "Failed to create \"shard_unlink\" thread"); goto unlock; } ti->running = _gf_true; } ti->rerun = _gf_true; } unlock: pthread_mutex_unlock(&ti->mutex); return ret; } static int shard_unlink_handler_init(shard_unlink_thread_t *ti) { int ret = 0; xlator_t *this = THIS; ret = pthread_mutex_init(&ti->mutex, NULL); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to init mutex for \"shard_unlink\" thread"); goto out; } ret = pthread_cond_init(&ti->cond, NULL); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to init cond var for \"shard_unlink\" thread"); pthread_mutex_destroy(&ti->mutex); goto out; } ti->running = _gf_false; ti->rerun = _gf_false; ti->stop = _gf_false; out: return -ret; } static void shard_unlink_handler_fini(shard_unlink_thread_t *ti) { int ret = 0; xlator_t *this = THIS; if (!ti) return; pthread_mutex_lock(&ti->mutex); if (ti->running) { ti->rerun = _gf_true; ti->stop = _gf_true; pthread_cond_signal(&ti->cond); } pthread_mutex_unlock(&ti->mutex); if (ti->running) { ret = pthread_join(ti->thread, NULL); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, 0, "Failed to clean up shard unlink thread."); ti->running = _gf_false; } ti->thread = 0; pthread_cond_destroy(&ti->cond); pthread_mutex_destroy(&ti->mutex); } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_shard_mt_end); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_MEM_ACCT_INIT_FAILED, "Memory accounting init" "failed"); return ret; } return ret; } int init(xlator_t *this) { int ret = -1; shard_priv_t *priv = NULL; if (!this) { gf_msg("shard", GF_LOG_ERROR, 0, SHARD_MSG_NULL_THIS, "this is NULL. init() failed"); return -1; } if (!this->parents) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INVALID_VOLFILE, "Dangling volume. Check volfile"); goto out; } if (!this->children || this->children->next) { gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INVALID_VOLFILE, "shard not configured with exactly one sub-volume. " "Check volfile"); goto out; } priv = GF_CALLOC(1, sizeof(shard_priv_t), gf_shard_mt_priv_t); if (!priv) goto out; GF_OPTION_INIT("shard-block-size", priv->block_size, size_uint64, out); GF_OPTION_INIT("shard-deletion-rate", priv->deletion_rate, uint32, out); GF_OPTION_INIT("shard-lru-limit", priv->lru_limit, uint64, out); this->local_pool = mem_pool_new(shard_local_t, 128); if (!this->local_pool) { ret = -1; goto out; } gf_uuid_parse(SHARD_ROOT_GFID, priv->dot_shard_gfid); gf_uuid_parse(DOT_SHARD_REMOVE_ME_GFID, priv->dot_shard_rm_gfid); this->private = priv; LOCK_INIT(&priv->lock); INIT_LIST_HEAD(&priv->ilist_head); ret = shard_unlink_handler_init(&priv->thread_info); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to initialize resources for \"shard_unlink\" thread"); goto out; } ret = 0; out: if (ret) { GF_FREE(priv); mem_pool_destroy(this->local_pool); } return ret; } void fini(xlator_t *this) { shard_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("shard", this, out); /*Itable was not created by shard, hence setting to NULL.*/ this->itable = NULL; mem_pool_destroy(this->local_pool); this->local_pool = NULL; priv = this->private; if (!priv) goto out; shard_unlink_handler_fini(&priv->thread_info); this->private = NULL; LOCK_DESTROY(&priv->lock); GF_FREE(priv); out: return; } int reconfigure(xlator_t *this, dict_t *options) { int ret = -1; shard_priv_t *priv = NULL; priv = this->private; GF_OPTION_RECONF("shard-block-size", priv->block_size, options, size, out); GF_OPTION_RECONF("shard-deletion-rate", priv->deletion_rate, options, uint32, out); ret = 0; out: return ret; } int shard_forget(xlator_t *this, inode_t *inode) { uint64_t ctx_uint = 0; shard_inode_ctx_t *ctx = NULL; shard_priv_t *priv = NULL; priv = this->private; if (!priv) return 0; inode_ctx_del(inode, this, &ctx_uint); if (!ctx_uint) return 0; ctx = (shard_inode_ctx_t *)(uintptr_t)ctx_uint; /* When LRU limit reaches inode will be forcefully removed from the * table, inode needs to be removed from LRU of shard as well. */ if (!list_empty(&ctx->ilist)) { LOCK(&priv->lock); { list_del_init(&ctx->ilist); priv->inode_count--; } UNLOCK(&priv->lock); } GF_FREE(ctx); return 0; } int shard_release(xlator_t *this, fd_t *fd) { /* TBD */ return 0; } int shard_priv_dump(xlator_t *this) { shard_priv_t *priv = NULL; char key_prefix[GF_DUMP_MAX_BUF_LEN] = { 0, }; char *str = NULL; priv = this->private; snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type, this->name); gf_proc_dump_add_section("%s", key_prefix); str = gf_uint64_2human_readable(priv->block_size); gf_proc_dump_write("shard-block-size", "%s", str); gf_proc_dump_write("inode-count", "%d", priv->inode_count); gf_proc_dump_write("ilist_head", "%p", &priv->ilist_head); gf_proc_dump_write("lru-max-limit", "%" PRIu64, priv->lru_limit); GF_FREE(str); return 0; } int shard_releasedir(xlator_t *this, fd_t *fd) { return 0; } struct xlator_fops fops = { .lookup = shard_lookup, .open = shard_open, .opendir = shard_opendir, .flush = shard_flush, .fsync = shard_fsync, .stat = shard_stat, .fstat = shard_fstat, .getxattr = shard_getxattr, .fgetxattr = shard_fgetxattr, .readv = shard_readv, .writev = shard_writev, .truncate = shard_truncate, .ftruncate = shard_ftruncate, .setxattr = shard_setxattr, .fsetxattr = shard_fsetxattr, .setattr = shard_setattr, .fsetattr = shard_fsetattr, .removexattr = shard_removexattr, .fremovexattr = shard_fremovexattr, .fallocate = shard_fallocate, .discard = shard_discard, .zerofill = shard_zerofill, .readdir = shard_readdir, .readdirp = shard_readdirp, .create = shard_create, .mknod = shard_mknod, .link = shard_link, .unlink = shard_unlink, .rename = shard_rename, .seek = shard_seek, }; struct xlator_cbks cbks = { .forget = shard_forget, .release = shard_release, .releasedir = shard_releasedir, }; struct xlator_dumpops dumpops = { .priv = shard_priv_dump, }; struct volume_options options[] = { { .key = {"shard"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "enable/disable shard", .op_version = {GD_OP_VERSION_6_0}, .flags = OPT_FLAG_SETTABLE, }, { .key = {"shard-block-size"}, .type = GF_OPTION_TYPE_SIZET, .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, .tags = {"shard"}, .default_value = "64MB", .min = SHARD_MIN_BLOCK_SIZE, .max = SHARD_MAX_BLOCK_SIZE, .description = "The size unit used to break a file into multiple " "chunks", }, { .key = {"shard-deletion-rate"}, .type = GF_OPTION_TYPE_INT, .op_version = {GD_OP_VERSION_5_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, .tags = {"shard"}, .default_value = "100", .min = 100, .max = INT_MAX, .description = "The number of shards to send deletes on at a time", }, { .key = {"shard-lru-limit"}, .type = GF_OPTION_TYPE_INT, .op_version = {GD_OP_VERSION_5_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT, .tags = {"shard"}, .default_value = "16384", .min = 20, .max = INT_MAX, .description = "The number of resolved shard inodes to keep in " "memory. A higher number means shards that are " "resolved will remain in memory longer, avoiding " "frequent lookups on them when they participate in " "file operations. The option also has a bearing on " "amount of memory consumed by these inodes and their " "internal metadata", }, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "shard", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/shard/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465023045 xustar000000000000000030 mtime=1699284277.082061814 30 atime=1699284290.987103696 30 ctime=1699284304.832145396 glusterfs-11.1/xlators/features/shard/Makefile.in0000664000175100017510000005272114522202465023333 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/shard DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/shard/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/shard/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/shard/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023027 xustar000000000000000030 mtime=1699284265.688027495 30 atime=1699284277.058061742 30 ctime=1699284304.833145399 glusterfs-11.1/xlators/features/shard/Makefile.am0000664000175100017510000000003414522202451023303 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/thin-arbiter0000644000000000000000000000013214522202521022203 xustar000000000000000030 mtime=1699284305.755148176 30 atime=1699284309.685160013 30 ctime=1699284305.755148176 glusterfs-11.1/xlators/features/thin-arbiter/0002775000175100017510000000000014522202521022541 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/thin-arbiter/PaxHeaders.9031/src0000644000000000000000000000013214522202521022772 xustar000000000000000030 mtime=1699284305.798148306 30 atime=1699284309.686160016 30 ctime=1699284305.798148306 glusterfs-11.1/xlators/features/thin-arbiter/src/0002775000175100017510000000000014522202521023330 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/thin-arbiter/src/PaxHeaders.9031/thin-arbiter-mem-types.h0000644000000000000000000000013214522202451027530 xustar000000000000000030 mtime=1699284265.695027516 30 atime=1699284265.695027516 30 ctime=1699284305.795148297 glusterfs-11.1/xlators/features/thin-arbiter/src/thin-arbiter-mem-types.h0000664000175100017510000000114114522202451030004 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __THIN_ARBITER_MEM_TYPES_H__ #define __THIN_ARBITER_MEM_TYPES_H__ #include typedef enum gf_ta_mem_types_ { gf_ta_mt_local_t = gf_common_mt_end + 1, gf_ta_mt_char, gf_ta_mt_end } gf_ta_mem_types_t; #endif glusterfs-11.1/xlators/features/thin-arbiter/src/PaxHeaders.9031/thin-arbiter.h0000644000000000000000000000013214522202451025612 xustar000000000000000030 mtime=1699284265.695027516 30 atime=1699284265.695027516 30 ctime=1699284305.793148291 glusterfs-11.1/xlators/features/thin-arbiter/src/thin-arbiter.h0000664000175100017510000000443514522202451026077 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _THIN_ARBITER_H #define _THIN_ARBITER_H #include #include #include #define THIN_ARBITER_SOURCE_XATTR "trusted.ta.source" #define THIN_ARBITER_SOURCE_SIZE 2 #define TA_FAILED_FOP(fop, frame, op_errno) \ do { \ default_##fop##_failure_cbk(frame, op_errno); \ } while (0) #define TA_STACK_UNWIND(fop, frame, op_ret, op_errno, params...) \ do { \ ta_fop_t *__local = NULL; \ int32_t __op_ret = 0; \ int32_t __op_errno = 0; \ \ __local = frame->local; \ __op_ret = op_ret; \ __op_errno = op_errno; \ if (__local) { \ ta_release_fop(__local); \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, __op_ret, __op_errno, params); \ \ } while (0) struct _ta_fop; typedef struct _ta_fop ta_fop_t; struct _ta_fop { gf_xattrop_flags_t xattrop_flags; loc_t loc; fd_t *fd; dict_t *dict; dict_t *brick_xattr; int32_t on_disk[2]; int32_t idx; }; #endif /* _THIN_ARBITER_H */ glusterfs-11.1/xlators/features/thin-arbiter/src/PaxHeaders.9031/thin-arbiter.c0000644000000000000000000000013214522202451025605 xustar000000000000000030 mtime=1699284265.695027516 30 atime=1699284265.695027516 30 ctime=1699284305.798148306 glusterfs-11.1/xlators/features/thin-arbiter/src/thin-arbiter.c0000664000175100017510000003533514522202451026075 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "thin-arbiter.h" #include "thin-arbiter-messages.h" #include "thin-arbiter-mem-types.h" #include #include #include int ta_set_incoming_values(dict_t *dict, char *key, data_t *value, void *data) { int32_t ret = 0; ta_fop_t *fop = (ta_fop_t *)data; int32_t *pending = NULL; pending = GF_CALLOC(1, value->len, gf_ta_mt_char); if (!pending) { ret = -ENOMEM; goto out; } ret = dict_set_bin(fop->brick_xattr, key, pending, value->len); out: return ret; } int ta_get_incoming_and_brick_values(dict_t *dict, char *key, data_t *value, void *data) { ta_fop_t *fop = data; char *source = NULL; char *in_coming = NULL; int32_t len = 0, ret = 0; source = GF_CALLOC(1, value->len, gf_ta_mt_char); if (!source) { ret = -ENOMEM; goto out; } ret = dict_get_ptr_and_len(fop->dict, key, (void **)&in_coming, &len); if (!in_coming || value->len != len) { ret = -EINVAL; goto out; } if (!memcmp(value->data, source, value->len) && (!memcmp(in_coming, source, len))) { fop->on_disk[fop->idx] = 0; } else { fop->on_disk[fop->idx] = 1; } fop->idx++; out: GF_FREE(source); return ret; } void ta_release_fop(ta_fop_t *fop) { if (!fop) { return; } if (fop->fd) { fd_unref(fop->fd); } loc_wipe(&fop->loc); if (fop->dict) { dict_unref(fop->dict); } if (fop->brick_xattr) { dict_unref(fop->brick_xattr); } GF_FREE(fop); return; } int32_t ta_set_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { TA_STACK_UNWIND(xattrop, frame, op_ret, op_errno, dict, xdata); return 0; } /* case 1 - If brick value is 0 and incoming value is also 0, fine case 2 - If brick value is 0 and incoming value is non 0, fine case 3 - If brick value is non 0 and incoming value is also 0, fine case 4 - If brick value is non 0 and incoming value is non 0, fine case 5 - If incoming value is non zero on both brick, it is wrong case 6 - If incoming value is non zero but brick value for other brick is also non zero, wrong */ int32_t ta_verify_on_disk_source(ta_fop_t *fop, dict_t *dict) { int ret = 0; if (!fop) { return -EINVAL; } ret = dict_foreach(dict, ta_get_incoming_and_brick_values, (void *)fop); if (ret < 0) { return ret; } if (fop->on_disk[0] && fop->on_disk[1]) { return -EINVAL; } return 0; } int32_t ta_get_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { ta_fop_t *fop = NULL; int ret = 0; fop = frame->local; if (op_ret) { goto unwind; } ret = ta_verify_on_disk_source(fop, dict); if (ret < 0) { op_errno = -ret; goto unwind; } if (fop->fd) { STACK_WIND(frame, ta_set_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fop->fd, fop->xattrop_flags, fop->dict, NULL); } else { STACK_WIND(frame, ta_set_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, &fop->loc, fop->xattrop_flags, fop->dict, NULL); } return 0; unwind: TA_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL); return -1; } ta_fop_t * ta_prepare_fop(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { ta_fop_t *fop = NULL; int ret = 0; fop = GF_CALLOC(1, sizeof(*fop), gf_ta_mt_local_t); if (!fop) { goto out; } if (loc) { loc_copy(&fop->loc, loc); } if (fd) { fop->fd = fd_ref(fd); } fop->xattrop_flags = flags; fop->idx = 0; if (dict != NULL) { fop->dict = dict_ref(dict); } fop->brick_xattr = dict_new(); if (fop->brick_xattr == NULL) { goto out; } ret = dict_foreach(dict, ta_set_incoming_values, (void *)fop); if (ret < 0) { goto out; } frame->local = fop; return fop; out: ta_release_fop(fop); return NULL; } int32_t ta_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { int ret = 0; ta_fop_t *fop = NULL; fop = ta_prepare_fop(frame, this, NULL, fd, flags, dict, xdata); if (!fop) { ret = -ENOMEM; goto unwind; } STACK_WIND(frame, ta_get_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, flags, fop->brick_xattr, xdata); return 0; unwind: TA_STACK_UNWIND(xattrop, frame, -1, -ret, NULL, NULL); return 0; } int32_t ta_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { int ret = 0; ta_fop_t *fop = NULL; fop = ta_prepare_fop(frame, this, loc, NULL, flags, dict, xdata); if (!fop) { ret = -ENOMEM; goto unwind; } STACK_WIND(frame, ta_get_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, flags, fop->brick_xattr, xdata); return 0; unwind: TA_STACK_UNWIND(xattrop, frame, -1, -ret, NULL, NULL); return 0; } int32_t ta_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { TA_FAILED_FOP(writev, frame, EINVAL); return 0; } int32_t ta_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { TA_FAILED_FOP(fsetxattr, frame, EINVAL); return 0; } int32_t ta_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { TA_FAILED_FOP(setxattr, frame, EINVAL); return 0; } int32_t ta_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_size, off_t offset, size_t len, dict_t *xdata) { TA_FAILED_FOP(fallocate, frame, EINVAL); return 0; } int32_t ta_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { TA_FAILED_FOP(access, frame, EINVAL); return 0; } int32_t ta_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { TA_FAILED_FOP(discard, frame, EINVAL); return 0; } int32_t ta_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { TA_FAILED_FOP(entrylk, frame, EINVAL); return 0; } int32_t ta_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { TA_FAILED_FOP(fentrylk, frame, EINVAL); return 0; } int32_t ta_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { TA_FAILED_FOP(flush, frame, EINVAL); return 0; } int32_t ta_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { TA_FAILED_FOP(fsync, frame, EINVAL); return 0; } int32_t ta_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { TA_FAILED_FOP(fsyncdir, frame, EINVAL); return 0; } int32_t ta_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { TA_FAILED_FOP(getxattr, frame, EINVAL); return 0; } int32_t ta_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { TA_FAILED_FOP(fgetxattr, frame, EINVAL); return 0; } int32_t ta_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { TA_FAILED_FOP(link, frame, EINVAL); return 0; } int32_t ta_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { TA_FAILED_FOP(lk, frame, EINVAL); return 0; } int32_t ta_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { TA_FAILED_FOP(mkdir, frame, EINVAL); return 0; } int32_t ta_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { TA_FAILED_FOP(mknod, frame, EINVAL); return 0; } int32_t ta_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { TA_FAILED_FOP(open, frame, EINVAL); return 0; } int32_t ta_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { TA_FAILED_FOP(opendir, frame, EINVAL); return 0; } int32_t ta_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { TA_FAILED_FOP(readdir, frame, EINVAL); return 0; } int32_t ta_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { TA_FAILED_FOP(readdirp, frame, EINVAL); return 0; } int32_t ta_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { TA_FAILED_FOP(readlink, frame, EINVAL); return 0; } int32_t ta_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { TA_FAILED_FOP(readv, frame, EINVAL); return 0; } int32_t ta_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { TA_FAILED_FOP(removexattr, frame, EINVAL); return 0; } int32_t ta_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { TA_FAILED_FOP(fremovexattr, frame, EINVAL); return 0; } int32_t ta_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { TA_FAILED_FOP(rename, frame, EINVAL); return 0; } int32_t ta_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { TA_FAILED_FOP(rmdir, frame, EINVAL); return 0; } int32_t ta_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { TA_FAILED_FOP(setattr, frame, EINVAL); return 0; } int32_t ta_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { TA_FAILED_FOP(fsetattr, frame, EINVAL); return 0; } int32_t ta_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { TA_FAILED_FOP(stat, frame, EINVAL); return 0; } int32_t ta_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { TA_FAILED_FOP(fstat, frame, EINVAL); return 0; } int32_t ta_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { TA_FAILED_FOP(statfs, frame, EINVAL); return 0; } int32_t ta_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { TA_FAILED_FOP(symlink, frame, EINVAL); return 0; } int32_t ta_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { TA_FAILED_FOP(truncate, frame, EINVAL); return 0; } int32_t ta_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { TA_FAILED_FOP(ftruncate, frame, EINVAL); return 0; } int32_t ta_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { TA_FAILED_FOP(unlink, frame, EINVAL); return 0; } int32_t ta_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { TA_FAILED_FOP(zerofill, frame, EINVAL); return 0; } int32_t ta_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { TA_FAILED_FOP(seek, frame, EINVAL); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; ret = xlator_mem_acct_init(this, gf_ta_mt_end); if (ret) gf_log(this->name, GF_LOG_ERROR, "Memory accounting " "initialization failed."); return ret; } int reconfigure(xlator_t *this, dict_t *options) { return 0; } int32_t init(xlator_t *this) { if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "'thin_arbiter' not configured with exactly one child"); return -1; } if (!this->parents) { gf_log(this->name, GF_LOG_ERROR, "dangling volume. check volfile "); } return 0; } void fini(xlator_t *this) { return; } struct xlator_fops fops = { /*Passed fop*/ .xattrop = ta_xattrop, .fxattrop = ta_fxattrop, /*Failed fop*/ .writev = ta_writev, .stat = ta_stat, .fstat = ta_fstat, .truncate = ta_truncate, .ftruncate = ta_ftruncate, .access = ta_access, .readlink = ta_readlink, .mknod = ta_mknod, .mkdir = ta_mkdir, .unlink = ta_unlink, .rmdir = ta_rmdir, .symlink = ta_symlink, .rename = ta_rename, .link = ta_link, .open = ta_open, .readv = ta_readv, .flush = ta_flush, .fsync = ta_fsync, .opendir = ta_opendir, .readdir = ta_readdir, .readdirp = ta_readdirp, .fsyncdir = ta_fsyncdir, .statfs = ta_statfs, .setxattr = ta_setxattr, .getxattr = ta_getxattr, .fsetxattr = ta_fsetxattr, .fgetxattr = ta_fgetxattr, .removexattr = ta_removexattr, .fremovexattr = ta_fremovexattr, .lk = ta_lk, .entrylk = ta_entrylk, .fentrylk = ta_fentrylk, .setattr = ta_setattr, .fsetattr = ta_fsetattr, .fallocate = ta_fallocate, .discard = ta_discard, .zerofill = ta_zerofill, .seek = ta_seek, }; struct xlator_cbks cbks = {}; struct volume_options options[] = { {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {GD_OP_VERSION_6_0}, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "thin-arbiter", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/thin-arbiter/src/PaxHeaders.9031/thin-arbiter-messages.h0000644000000000000000000000013214522202451027417 xustar000000000000000030 mtime=1699284265.695027516 30 atime=1699284265.695027516 30 ctime=1699284305.796148299 glusterfs-11.1/xlators/features/thin-arbiter/src/thin-arbiter-messages.h0000664000175100017510000000154314522202451027701 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _TA_MESSAGES_H_ #define _TA_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(TA, TA_MSG_INVALID_FOP); #endif /* !_TA_MESSAGES_H_ */ glusterfs-11.1/xlators/features/thin-arbiter/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465025123 xustar000000000000000030 mtime=1699284277.464062965 30 atime=1699284290.128101109 30 ctime=1699284305.789148278 glusterfs-11.1/xlators/features/thin-arbiter/src/Makefile.in0000664000175100017510000006234314522202465025412 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/thin-arbiter/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) thin_arbiter_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_thin_arbiter_la_OBJECTS = thin-arbiter.lo libxlator.lo thin_arbiter_la_OBJECTS = $(am_thin_arbiter_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = thin_arbiter_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(thin_arbiter_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(thin_arbiter_la_SOURCES) DIST_SOURCES = $(thin_arbiter_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = thin-arbiter.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features thin_arbiter_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) thin_arbiter_la_SOURCES = thin-arbiter.c \ $(top_builddir)/xlators/lib/src/libxlator.c thin_arbiter_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = thin-arbiter.h thin-arbiter-mem-types.h thin-arbiter-messages.h \ $(top_builddir)/xlators/lib/src/libxlator.h AM_CPPFLAGS = $(GF_CPPFLAGS) \ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/xlators/lib/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/thin-arbiter/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/thin-arbiter/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } thin-arbiter.la: $(thin_arbiter_la_OBJECTS) $(thin_arbiter_la_DEPENDENCIES) $(EXTRA_thin_arbiter_la_DEPENDENCIES) $(AM_V_CCLD)$(thin_arbiter_la_LINK) -rpath $(xlatordir) $(thin_arbiter_la_OBJECTS) $(thin_arbiter_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxlator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thin-arbiter.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libxlator.lo: $(top_builddir)/xlators/lib/src/libxlator.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxlator.lo -MD -MP -MF $(DEPDIR)/libxlator.Tpo -c -o libxlator.lo `test -f '$(top_builddir)/xlators/lib/src/libxlator.c' || echo '$(srcdir)/'`$(top_builddir)/xlators/lib/src/libxlator.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxlator.Tpo $(DEPDIR)/libxlator.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_builddir)/xlators/lib/src/libxlator.c' object='libxlator.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxlator.lo `test -f '$(top_builddir)/xlators/lib/src/libxlator.c' || echo '$(srcdir)/'`$(top_builddir)/xlators/lib/src/libxlator.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/thin-arbiter/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451025105 xustar000000000000000030 mtime=1699284265.695027516 30 atime=1699284277.424062844 30 ctime=1699284305.791148284 glusterfs-11.1/xlators/features/thin-arbiter/src/Makefile.am0000664000175100017510000000131514522202451025364 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = thin-arbiter.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features thin_arbiter_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) thin_arbiter_la_SOURCES = thin-arbiter.c \ $(top_builddir)/xlators/lib/src/libxlator.c thin_arbiter_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = thin-arbiter.h thin-arbiter-mem-types.h thin-arbiter-messages.h \ $(top_builddir)/xlators/lib/src/libxlator.h AM_CPPFLAGS = $(GF_CPPFLAGS) \ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/xlators/lib/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/thin-arbiter/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465024334 xustar000000000000000030 mtime=1699284277.414062814 30 atime=1699284290.106101043 30 ctime=1699284305.750148161 glusterfs-11.1/xlators/features/thin-arbiter/Makefile.in0000664000175100017510000005274614522202465024631 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/thin-arbiter DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/thin-arbiter/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/thin-arbiter/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/thin-arbiter/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024316 xustar000000000000000030 mtime=1699284265.694027513 30 atime=1699284277.390062742 30 ctime=1699284305.751148164 glusterfs-11.1/xlators/features/thin-arbiter/Makefile.am0000664000175100017510000000003414522202451024572 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/namespace0000644000000000000000000000013014522202521021545 xustar000000000000000029 mtime=1699284305.33814692 30 atime=1699284309.686160016 29 ctime=1699284305.33814692 glusterfs-11.1/xlators/features/namespace/0002775000175100017510000000000014522202521022105 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/namespace/PaxHeaders.9031/src0000644000000000000000000000013014522202521022334 xustar000000000000000029 mtime=1699284305.37814704 30 atime=1699284309.686160016 29 ctime=1699284305.37814704 glusterfs-11.1/xlators/features/namespace/src/0002775000175100017510000000000014522202521022674 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/namespace/src/PaxHeaders.9031/namespace.h0000644000000000000000000000013214522202451024522 xustar000000000000000030 mtime=1699284265.681027474 30 atime=1699284265.681027474 30 ctime=1699284305.377147038 glusterfs-11.1/xlators/features/namespace/src/namespace.h0000664000175100017510000000071214522202451025001 0ustar00jenkinsjenkins00000000000000#ifndef __NAMESPACE_H__ #define __NAMESPACE_H__ #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include #define GF_NAMESPACE "namespace" typedef struct { gf_boolean_t tag_namespaces; } ns_private_t; typedef struct { loc_t loc; /* We store a "fake" loc_t for the getxattr wind. */ call_stub_t *stub; /* A stub back to the function we're resuming. */ } ns_local_t; #endif /* __NAMESPACE_H__ */ glusterfs-11.1/xlators/features/namespace/src/PaxHeaders.9031/namespace.c0000644000000000000000000000013114522202451024514 xustar000000000000000030 mtime=1699284265.681027474 30 atime=1699284265.680027471 29 ctime=1699284305.37814704 glusterfs-11.1/xlators/features/namespace/src/namespace.c0000664000175100017510000012354114522202451025002 0ustar00jenkinsjenkins00000000000000/* * Copyright (c) 2008-2012 Red Hat, Inc. * This file is part of GlusterFS. * * This file is licensed to you under your choice of the GNU Lesser * General Public License, version 3 or any later version (LGPLv3 or * later), or the GNU General Public License, version 2 (GPLv2), in all * cases as published by the Free Software Foundation. * * xlators/features/namespace: * This translator tags each request with a namespace hash, * which then can be used in later translators to track and * throttle fops per namespace. */ #include #include #include #include "namespace.h" /* Return codes for common path parsing functions. */ enum _path_parse_result { PATH_PARSE_RESULT_NO_PATH = 0, PATH_PARSE_RESULT_FOUND = 1, PATH_PARSE_RESULT_IS_GFID = 2, }; typedef enum _path_parse_result path_parse_result_t; /* Clean up an ns_local struct. Wipe a loc (its inode is ref'd, so we're good.) */ static inline void ns_local_cleanup(ns_local_t *local) { if (!local) { return; } loc_wipe(&local->loc); GF_FREE(local); } /* Create a new ns_local. We ref the inode, fake a new loc struct, and stash * the stub given to us. */ static inline ns_local_t * ns_local_new(call_stub_t *stub, inode_t *inode) { ns_local_t *local = NULL; loc_t loc = { 0, }; if (!stub || !inode) { goto out; } local = GF_CALLOC(1, sizeof(ns_local_t), 0); if (local == NULL) { goto out; } /* Set up a fake loc_t struct to give to the getxattr call. */ gf_uuid_copy(loc.gfid, inode->gfid); loc.inode = inode_ref(inode); /* If for some reason inode_ref() fails, then just give up. */ if (!loc.inode) { GF_FREE(local); goto out; } local->stub = stub; local->loc = loc; out: return local; } /* Try parsing a path string. If the path string is a GFID, then return * with PATH_PARSE_RESULT_IS_GFID. If we have no namespace (i.e. '/') then * return PATH_PARSE_RESULT_NO_PATH and set the hash to 1. Otherwise, hash the * namespace and store it in the info struct. */ static path_parse_result_t parse_path(ns_info_t *info, const char *path) { int len = 0; const char *ns_begin = path; const char *ns_end = NULL; if (!path || strlen(path) == 0) { return PATH_PARSE_RESULT_NO_PATH; } if (path[0] == '<') { return PATH_PARSE_RESULT_IS_GFID; } /* Right now we only want the top-level directory, so * skip the initial '/' and read until the next '/'. */ while (*ns_begin == '/') { ns_begin++; } /* ns_end will point to the next '/' or NULL if there is no delimiting * '/' (i.e. "/directory" or the top level "/") */ ns_end = strchr(ns_begin, '/'); len = ns_end ? (ns_end - ns_begin) : strlen(ns_begin); if (len != 0) { info->hash = SuperFastHash(ns_begin, len); } else { /* If our substring is empty, then we can hash '/' instead. * '/' is used in the namespace config for the top-level * namespace. */ info->hash = SuperFastHash("/", 1); } info->found = _gf_true; return PATH_PARSE_RESULT_FOUND; } /* Cache namespace info stored in the stack (info) into the inode. */ static int ns_inode_ctx_put(inode_t *inode, xlator_t *this, ns_info_t *info) { ns_info_t *cached_ns_info = NULL; uint64_t ns_as_64 = 0; int ret = -1; if (!inode || !this) { gf_log(this ? this->name : "namespace", GF_LOG_WARNING, "Need a valid inode and xlator to cache ns_info."); ret = -1; goto out; } cached_ns_info = GF_CALLOC(1, sizeof(ns_info_t), 0); /* If we've run out of memory, then return ENOMEM. */ if (cached_ns_info == NULL) { gf_log(this->name, GF_LOG_WARNING, "No memory to cache ns_info."); ret = -(ENOMEM); goto out; } *cached_ns_info = *info; ns_as_64 = (uint64_t)(uintptr_t)cached_ns_info; ret = inode_ctx_put(inode, this, ns_as_64); if (ret) { goto out; } ret = 0; out: if (ret && cached_ns_info) { GF_FREE(cached_ns_info); } return ret; } /* Retrieve namespace info cached in the inode into the stack for use in later * translators. */ static int ns_inode_ctx_get(inode_t *inode, xlator_t *this, ns_info_t *info) { ns_info_t *cached_ns_info = NULL; uint64_t ns_as_64 = 0; int ret = -1; if (!inode) { ret = -ENOENT; goto out; } ret = inode_ctx_get(inode, this, &ns_as_64); if (!ret) { cached_ns_info = (ns_info_t *)(uintptr_t)ns_as_64; *info = *cached_ns_info; } out: return ret; } /* This callback is the top of the unwind path of our attempt to get the path * manually from the posix translator. We'll try to parse the path returned * if it exists, then cache the hash if possible. Then just return to the * default stub that we provide in the local, since there's nothing else to do * once we've gotten the namespace hash. */ int32_t get_path_resume_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { path_parse_result_t ret = PATH_PARSE_RESULT_NO_PATH; call_frame_t *resume_frame = NULL; ns_local_t *local = NULL; call_stub_t *stub = NULL; ns_info_t *info = NULL; char *path = NULL; GF_VALIDATE_OR_GOTO(this->name, frame, out); local = frame->local; GF_VALIDATE_OR_GOTO(this->name, local, out); stub = local->stub; GF_VALIDATE_OR_GOTO(this->name, stub, out); /* Get the ns_info from the frame that we will eventually resume, * not the frame that we're going to destroy (frame). */ resume_frame = stub->frame; GF_VALIDATE_OR_GOTO(this->name, resume_frame, out); GF_VALIDATE_OR_GOTO(this->name, resume_frame->root, out); info = &resume_frame->root->ns_info; GF_VALIDATE_OR_GOTO(this->name, dict, out); /* If we get a value back for the GET_ANCESTRY_PATH_KEY, then we * try to access it and parse it like a path. */ if (!op_ret && !dict_get_str(dict, GET_ANCESTRY_PATH_KEY, &path)) { gf_log(this->name, GF_LOG_DEBUG, "G>P %s retrieved path %s", uuid_utoa(local->loc.gfid), path); /* Now let's parse a path, finally. */ ret = parse_path(info, path); } if (ret == PATH_PARSE_RESULT_FOUND) { /* If we finally found namespace, then stash it. */ ns_inode_ctx_put(local->loc.inode, this, info); gf_log(this->name, GF_LOG_DEBUG, "G>P %s %10u namespace found %s", uuid_utoa(local->loc.inode->gfid), info->hash, path); } else if (ret == PATH_PARSE_RESULT_NO_PATH) { gf_log(this->name, GF_LOG_WARNING, "G>P %s has no path", uuid_utoa(local->loc.inode->gfid)); } else if (ret == PATH_PARSE_RESULT_IS_GFID) { gf_log(this->name, GF_LOG_WARNING, "G>P %s winding failed, still have gfid", uuid_utoa(local->loc.inode->gfid)); } out: /* Make sure to clean up local finally. */ if (frame) { frame->local = NULL; STACK_DESTROY(frame->root); } if (local) { ns_local_cleanup(local); } if (stub) { call_resume(stub); } return 0; } /* This function tries first to set a namespace based on the information that * it can retrieve from an `loc_t`. This includes first looking for a cached * namespace in the inode, then trying to parse the path string in the `loc_t` * struct. If this fails, then it will try to call inode_path. */ static path_parse_result_t set_ns_from_loc(const char *fn, call_frame_t *frame, xlator_t *this, loc_t *loc) { path_parse_result_t ret = PATH_PARSE_RESULT_NO_PATH; ns_private_t *priv = (ns_private_t *)this->private; ns_info_t *info = &frame->root->ns_info; char *path = NULL; info->hash = 0; info->found = _gf_false; if (!priv->tag_namespaces) { return ret; } /* This is our first pass at trying to get a path. Try getting * from the inode context, then from the loc's path itself. */ if (!loc || !loc->path || !loc->inode) { ret = PATH_PARSE_RESULT_NO_PATH; } else if (!ns_inode_ctx_get(loc->inode, this, info)) { ret = PATH_PARSE_RESULT_FOUND; } else { ret = parse_path(info, loc->path); gf_log(this->name, GF_LOG_DEBUG, "%s: LOC retrieved path %s", fn, loc->path); if (ret == PATH_PARSE_RESULT_FOUND) { ns_inode_ctx_put(loc->inode, this, info); } } /* Keep trying by calling inode_path next, making sure to copy the loc's gfid into its inode if necessary. */ if (ret == PATH_PARSE_RESULT_IS_GFID) { if (gf_uuid_is_null(loc->inode->gfid)) { gf_uuid_copy(loc->inode->gfid, loc->gfid); } if (inode_path(loc->inode, NULL, &path) >= 0 && path) { ret = parse_path(info, loc->path); gf_log(this->name, GF_LOG_DEBUG, "%s: LOC retrieved path %s", fn, path); if (ret == PATH_PARSE_RESULT_FOUND) { ns_inode_ctx_put(loc->inode, this, info); } } if (path) { GF_FREE(path); } } /* Report our status, and if we have a GFID, we'll eventually try a * GET_ANCESTRY_PATH_KEY wind when we return from this function. */ if (ret == PATH_PARSE_RESULT_FOUND) { gf_log(this->name, GF_LOG_DEBUG, "%s: LOC %s %10u namespace found for %s", fn, uuid_utoa(loc->inode->gfid), info->hash, loc->path); } else if (ret == PATH_PARSE_RESULT_NO_PATH) { gf_log(this->name, GF_LOG_WARNING, "%s: LOC has no path", fn); } else if (ret == PATH_PARSE_RESULT_IS_GFID) { /* Make sure to copy the inode's gfid for the eventual wind. */ if (gf_uuid_is_null(loc->inode->gfid)) { gf_uuid_copy(loc->inode->gfid, loc->gfid); } gf_log(this->name, GF_LOG_DEBUG, "%s: LOC %s winding, looking for path", fn, uuid_utoa(loc->inode->gfid)); } return ret; } /* This function tries first to set a namespace based on the information that * it can retrieve from an `fd_t`. This includes first looking for a cached * namespace in the inode, then trying to call inode_path manually. */ static path_parse_result_t set_ns_from_fd(const char *fn, call_frame_t *frame, xlator_t *this, fd_t *fd) { path_parse_result_t ret = PATH_PARSE_RESULT_NO_PATH; ns_private_t *priv = (ns_private_t *)this->private; ns_info_t *info = &frame->root->ns_info; char *path = NULL; info->hash = 0; info->found = _gf_false; if (!priv->tag_namespaces) { return ret; } /* This is our first pass at trying to get a path. Try getting * from the inode context, then inode_path. */ if (!fd || !fd->inode) { ret = PATH_PARSE_RESULT_NO_PATH; } else if (!ns_inode_ctx_get(fd->inode, this, info)) { ret = PATH_PARSE_RESULT_FOUND; } else if (inode_path(fd->inode, NULL, &path) >= 0 && path) { ret = parse_path(info, path); gf_log(this->name, GF_LOG_DEBUG, "%s: FD retrieved path %s", fn, path); if (ret == PATH_PARSE_RESULT_FOUND) { ns_inode_ctx_put(fd->inode, this, info); } } if (path) { GF_FREE(path); } /* Report our status, and if we have a GFID, we'll eventually try a * GET_ANCESTRY_PATH_KEY wind when we return from this function. */ if (ret == PATH_PARSE_RESULT_FOUND) { gf_log(this->name, GF_LOG_DEBUG, "%s: FD %s %10u namespace found", fn, uuid_utoa(fd->inode->gfid), info->hash); } else if (ret == PATH_PARSE_RESULT_NO_PATH) { gf_log(this->name, GF_LOG_WARNING, "%s: FD has no path", fn); } else if (ret == PATH_PARSE_RESULT_IS_GFID) { gf_log(this->name, GF_LOG_DEBUG, "%s: FD %s winding, looking for path", fn, uuid_utoa(fd->inode->gfid)); } return ret; } /* This macro does the work of winding down a call of `getxattr` in the case * that we have to retrieve the path manually. It assumes that there is a label * called `wind` and the existence of several basic variables (frame, this), * but otherwise is general enough for any fop (fd- or loc-based.) */ #define GET_ANCESTRY_PATH_WIND(fop, inode, args...) \ do { \ ns_info_t *info = &frame->root->ns_info; \ call_frame_t *new_frame = NULL; \ ns_local_t *local = NULL; \ call_stub_t *stub = NULL; \ \ gf_log(this->name, GF_LOG_DEBUG, " %s winding, looking for path", \ uuid_utoa(inode->gfid)); \ \ new_frame = create_frame(this, this->ctx->pool); \ if (!new_frame) { \ gf_log(this->name, GF_LOG_ERROR, \ "Cannot allocate new call frame."); \ goto wind; \ } \ \ stub = fop_##fop##_stub(frame, default_##fop, args); \ if (!stub) { \ gf_log(this->name, GF_LOG_ERROR, \ "Cannot allocate function stub."); \ goto wind; \ } \ \ new_frame->root->uid = 0; \ new_frame->root->gid = 0; \ /* Put a phony "not found" NS info into this call. */ \ new_frame->root->ns_info = *info; \ \ local = ns_local_new(stub, inode); \ if (!local) { \ gf_log(this->name, GF_LOG_ERROR, \ "Cannot allocate function local."); \ goto wind; \ } \ \ new_frame->local = local; \ /* After allocating a new frame, a call stub (to \ * resume our current fop), and a local variables \ * struct (for our loc to getxattr and our resume \ * stub), call getxattr and unwind to get_path_resume_cbk. \ */ \ STACK_WIND(new_frame, get_path_resume_cbk, FIRST_CHILD(this), \ FIRST_CHILD(this)->fops->getxattr, &local->loc, \ GET_ANCESTRY_PATH_KEY, NULL); \ } while (0) int32_t ns_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(rmdir, loc->inode, loc, xflags, xdata); return 0; } wind: STACK_WIND(frame, default_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, xflags, xdata); return 0; } int32_t ns_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(unlink, loc->inode, loc, xflags, xdata); return 0; } wind: STACK_WIND(frame, default_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflags, xdata); return 0; } int32_t ns_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, newloc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(rename, newloc->inode, oldloc, newloc, xdata); return 0; } wind: STACK_WIND(frame, default_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; } int32_t ns_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, newloc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(link, newloc->inode, oldloc, newloc, xdata); return 0; } wind: STACK_WIND(frame, default_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; } int32_t ns_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(mkdir, loc->inode, loc, mode, umask, xdata); return 0; } wind: STACK_WIND(frame, default_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; } int32_t ns_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(symlink, loc->inode, linkname, loc, umask, xdata); return 0; } wind: STACK_WIND(frame, default_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkname, loc, umask, xdata); return 0; } int32_t ns_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(mknod, loc->inode, loc, mode, dev, umask, xdata); return 0; } wind: STACK_WIND(frame, default_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, dev, umask, xdata); return 0; } int32_t ns_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(create, loc->inode, loc, flags, mode, umask, fd, xdata); return 0; } wind: STACK_WIND(frame, default_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; } int32_t ns_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fsetattr, fd->inode, fd, stbuf, valid, xdata); return 0; } wind: STACK_WIND(frame, default_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } int32_t ns_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(setattr, loc->inode, loc, stbuf, valid, xdata); return 0; } wind: STACK_WIND(frame, default_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } int32_t ns_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fremovexattr, fd->inode, fd, name, xdata); return 0; } wind: STACK_WIND(frame, default_fremovexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; } int32_t ns_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(removexattr, loc->inode, loc, name, xdata); return 0; } wind: STACK_WIND(frame, default_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; } int32_t ns_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(setxattr, loc->inode, loc, dict, flags, xdata); return 0; } wind: STACK_WIND(frame, default_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; } int32_t ns_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fsetxattr, fd->inode, fd, dict, flags, xdata); return 0; } wind: STACK_WIND(frame, default_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; } int32_t ns_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(truncate, loc->inode, loc, offset, xdata); return 0; } wind: STACK_WIND(frame, default_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } int32_t ns_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(ftruncate, fd->inode, fd, offset, xdata); return 0; } wind: STACK_WIND(frame, default_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } int32_t ns_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(writev, fd->inode, fd, vector, count, offset, flags, iobref, xdata); return 0; } wind: STACK_WIND(frame, default_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; } int32_t ns_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(lookup, loc->inode, loc, xdata); return 0; } wind: STACK_WIND(frame, default_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); return 0; } int32_t ns_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(stat, loc->inode, loc, xdata); return 0; } wind: STACK_WIND(frame, default_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; } int32_t ns_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fstat, fd->inode, fd, xdata); return 0; } wind: STACK_WIND(frame, default_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; } int32_t ns_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(readlink, loc->inode, loc, size, xdata); return 0; } wind: STACK_WIND(frame, default_readlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink, loc, size, xdata); return 0; } int32_t ns_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(access, loc->inode, loc, mask, xdata); return 0; } wind: STACK_WIND(frame, default_access_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->access, loc, mask, xdata); return 0; } int32_t ns_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(open, fd->inode, loc, flags, fd, xdata); return 0; } wind: STACK_WIND(frame, default_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; } int32_t ns_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(readv, fd->inode, fd, size, offset, flags, xdata); return 0; } wind: STACK_WIND(frame, default_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; } int32_t ns_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(flush, fd->inode, fd, xdata); return 0; } wind: STACK_WIND(frame, default_flush_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush, fd, xdata); return 0; } int32_t ns_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fsync, fd->inode, fd, datasync, xdata); return 0; } wind: STACK_WIND(frame, default_fsync_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata); return 0; } int32_t ns_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(opendir, loc->inode, loc, fd, xdata); return 0; } wind: STACK_WIND(frame, default_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); return 0; } int32_t ns_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fsyncdir, fd->inode, fd, datasync, xdata); return 0; } wind: STACK_WIND(frame, default_fsyncdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsyncdir, fd, datasync, xdata); return 0; } int32_t ns_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, int32_t len, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(rchecksum, fd->inode, fd, offset, len, xdata); return 0; } wind: STACK_WIND(frame, default_rchecksum_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata); return 0; } int32_t ns_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(statfs, loc->inode, loc, xdata); return 0; } wind: STACK_WIND(frame, default_statfs_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, loc, xdata); return 0; } int32_t ns_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(inodelk, loc->inode, volume, loc, cmd, flock, xdata); return 0; } wind: STACK_WIND(frame, default_inodelk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, volume, loc, cmd, flock, xdata); return 0; } int32_t ns_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(finodelk, fd->inode, volume, fd, cmd, flock, xdata); return 0; } wind: STACK_WIND(frame, default_finodelk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd, flock, xdata); return 0; } int32_t ns_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(entrylk, loc->inode, volume, loc, basename, cmd, type, xdata); return 0; } wind: STACK_WIND(frame, default_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, volume, loc, basename, cmd, type, xdata); return 0; } int32_t ns_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fentrylk, fd->inode, volume, fd, basename, cmd, type, xdata); return 0; } wind: STACK_WIND(frame, default_fentrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fentrylk, volume, fd, basename, cmd, type, xdata); return 0; } int32_t ns_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fgetxattr, fd->inode, fd, name, xdata); return 0; } wind: STACK_WIND(frame, default_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); return 0; } int32_t ns_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(getxattr, loc->inode, loc, name, xdata); return 0; } wind: STACK_WIND(frame, default_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); return 0; } int32_t ns_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(lk, fd->inode, fd, cmd, flock, xdata); return 0; } wind: STACK_WIND(frame, default_lk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lk, fd, cmd, flock, xdata); return 0; } int32_t ns_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(readdir, fd->inode, fd, size, offset, xdata); return 0; } wind: STACK_WIND(frame, default_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, fd, size, offset, xdata); return 0; } int32_t ns_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *dict) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(readdirp, fd->inode, fd, size, offset, dict); return 0; } wind: STACK_WIND(frame, default_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); return 0; } int32_t ns_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { path_parse_result_t ret = set_ns_from_loc(__FUNCTION__, frame, this, loc); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(xattrop, loc->inode, loc, flags, dict, xdata); return 0; } wind: STACK_WIND(frame, default_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata); return 0; } int32_t ns_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fxattrop, fd->inode, fd, flags, dict, xdata); return 0; } wind: STACK_WIND(frame, default_fxattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata); return 0; } int32_t ns_getspec(call_frame_t *frame, xlator_t *this, const char *key, int32_t flag) { STACK_WIND(frame, default_getspec_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getspec, key, flag); return 0; } int32_t ns_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_size, off_t offset, size_t len, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(fallocate, fd->inode, fd, keep_size, offset, len, xdata); return 0; } wind: STACK_WIND(frame, default_fallocate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset, len, xdata); return 0; } int32_t ns_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(discard, fd->inode, fd, offset, len, xdata); return 0; } wind: STACK_WIND(frame, default_discard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); return 0; } int32_t ns_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { path_parse_result_t ret = set_ns_from_fd(__FUNCTION__, frame, this, fd); if (ret == PATH_PARSE_RESULT_IS_GFID) { GET_ANCESTRY_PATH_WIND(zerofill, fd->inode, fd, offset, len, xdata); return 0; } wind: STACK_WIND(frame, default_zerofill_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata); return 0; } int ns_forget(xlator_t *this, inode_t *inode) { uint64_t ns_as_64 = 0; ns_info_t *info = NULL; inode_ctx_del(inode, this, &ns_as_64); if (!ns_as_64) { return 0; } info = (ns_info_t *)(uintptr_t)ns_as_64; GF_FREE(info); return 0; } int32_t init(xlator_t *this) { int32_t ret = -1; ns_private_t *priv = NULL; GF_VALIDATE_OR_GOTO(GF_NAMESPACE, this, out); if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "translator needs a single subvolume."); goto out; } if (!this->parents) { gf_log(this->name, GF_LOG_ERROR, "dangling volume. please check volfile."); goto out; } priv = GF_CALLOC(1, sizeof(ns_private_t), 0); if (!priv) { gf_log(this->name, GF_LOG_ERROR, "Can't allocate ns_priv structure."); goto out; } GF_OPTION_INIT("tag-namespaces", priv->tag_namespaces, bool, out); gf_log(this->name, GF_LOG_INFO, "Namespace xlator loaded"); this->private = priv; ret = 0; out: if (ret) { GF_FREE(priv); } return ret; } void fini(xlator_t *this) { GF_FREE(this->private); } int reconfigure(xlator_t *this, dict_t *options) { int ret = -1; ns_private_t *priv = NULL; GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, options, out); priv = (ns_private_t *)this->private; GF_OPTION_RECONF("tag-namespaces", priv->tag_namespaces, options, bool, out); ret = 0; out: return ret; } struct xlator_fops fops = { .lookup = ns_lookup, .stat = ns_stat, .fstat = ns_fstat, .truncate = ns_truncate, .ftruncate = ns_ftruncate, .access = ns_access, .readlink = ns_readlink, .mknod = ns_mknod, .mkdir = ns_mkdir, .unlink = ns_unlink, .rmdir = ns_rmdir, .symlink = ns_symlink, .rename = ns_rename, .link = ns_link, .create = ns_create, .open = ns_open, .readv = ns_readv, .writev = ns_writev, .flush = ns_flush, .fsync = ns_fsync, .opendir = ns_opendir, .readdir = ns_readdir, .readdirp = ns_readdirp, .fsyncdir = ns_fsyncdir, .statfs = ns_statfs, .setxattr = ns_setxattr, .getxattr = ns_getxattr, .fsetxattr = ns_fsetxattr, .fgetxattr = ns_fgetxattr, .removexattr = ns_removexattr, .fremovexattr = ns_fremovexattr, .lk = ns_lk, .inodelk = ns_inodelk, .finodelk = ns_finodelk, .entrylk = ns_entrylk, .fentrylk = ns_fentrylk, .rchecksum = ns_rchecksum, .xattrop = ns_xattrop, .fxattrop = ns_fxattrop, .setattr = ns_setattr, .fsetattr = ns_fsetattr, .getspec = ns_getspec, .fallocate = ns_fallocate, .discard = ns_discard, .zerofill = ns_zerofill, }; struct xlator_cbks cbks = { .forget = ns_forget, }; struct xlator_dumpops dumpops; struct volume_options options[] = { { .key = {"tag-namespaces"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "This option enables this translator's functionality " "that tags every fop with a namespace hash for later " "throttling, stats collection, logging, etc.", .op_version = {GD_OP_VERSION_4_1_0}, .tags = {"namespace"}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, }, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .op_version = {GD_OP_VERSION_3_12_0}, .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "namespace", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/features/namespace/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464024466 xustar000000000000000030 mtime=1699284276.626060441 30 atime=1699284290.611102564 30 ctime=1699284305.374147028 glusterfs-11.1/xlators/features/namespace/src/Makefile.in0000664000175100017510000005737514522202464024766 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/namespace/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) namespace_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_namespace_la_OBJECTS = namespace.lo namespace_la_OBJECTS = $(am_namespace_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = namespace_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(namespace_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(namespace_la_SOURCES) DIST_SOURCES = $(namespace_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = namespace.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features namespace_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) namespace_la_SOURCES = namespace.c namespace_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = namespace.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/xlators/lib/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/namespace/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/namespace/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } namespace.la: $(namespace_la_OBJECTS) $(namespace_la_DEPENDENCIES) $(EXTRA_namespace_la_DEPENDENCIES) $(AM_V_CCLD)$(namespace_la_LINK) -rpath $(xlatordir) $(namespace_la_OBJECTS) $(namespace_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namespace.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/namespace/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451024450 xustar000000000000000030 mtime=1699284265.680027471 29 atime=1699284276.58906033 30 ctime=1699284305.375147032 glusterfs-11.1/xlators/features/namespace/src/Makefile.am0000664000175100017510000000077014522202451024734 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = namespace.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features namespace_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) namespace_la_SOURCES = namespace.c namespace_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = namespace.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/xlators/lib/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/namespace/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023677 xustar000000000000000030 mtime=1699284276.578060296 30 atime=1699284290.588102494 30 ctime=1699284305.333146905 glusterfs-11.1/xlators/features/namespace/Makefile.in0000664000175100017510000005273514522202464024172 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/namespace DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/namespace/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/namespace/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/namespace/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023662 xustar000000000000000030 mtime=1699284265.680027471 30 atime=1699284276.554060224 30 ctime=1699284305.335146911 glusterfs-11.1/xlators/features/namespace/Makefile.am0000664000175100017510000000003414522202451024136 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/cloudsync0000644000000000000000000000013214522202521021616 xustar000000000000000030 mtime=1699284305.420147167 30 atime=1699284309.686160016 30 ctime=1699284305.420147167 glusterfs-11.1/xlators/features/cloudsync/0002775000175100017510000000000014522202521022154 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/cloudsync/PaxHeaders.9031/src0000644000000000000000000000013214522202521022405 xustar000000000000000030 mtime=1699284305.477147339 30 atime=1699284309.686160016 30 ctime=1699284305.477147339 glusterfs-11.1/xlators/features/cloudsync/src/0002775000175100017510000000000014522202521022743 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync-plugins0000644000000000000000000000013214522202521026067 xustar000000000000000030 mtime=1699284305.515147453 30 atime=1699284309.686160016 30 ctime=1699284305.515147453 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/0002775000175100017510000000000014522202521026425 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/PaxHeaders.9031/src0000644000000000000000000000013214522202521026656 xustar000000000000000030 mtime=1699284305.630147799 30 atime=1699284309.686160016 30 ctime=1699284305.630147799 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/0002775000175100017510000000000014522202521027214 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463031005 xustar000000000000000030 mtime=1699284275.790057923 30 atime=1699284291.252104494 30 ctime=1699284305.546147547 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/Makefile.in0000664000175100017510000005325014522202463031271 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/cloudsync/src/cloudsync-plugins/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = cloudsyncs3 cvlt DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @BUILD_AMAZONS3_PLUGIN_TRUE@AMAZONS3_DIR = cloudsyncs3 @BUILD_CVLT_PLUGIN_TRUE@CVLT_DIR = cvlt SUBDIRS = ${AMAZONS3_DIR} ${CVLT_DIR} CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451030771 xustar000000000000000030 mtime=1699284265.664027423 30 atime=1699284275.765057848 30 ctime=1699284305.547147549 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/Makefile.am0000664000175100017510000000023714522202451031252 0ustar00jenkinsjenkins00000000000000if BUILD_AMAZONS3_PLUGIN AMAZONS3_DIR = cloudsyncs3 endif if BUILD_CVLT_PLUGIN CVLT_DIR = cvlt endif SUBDIRS = ${AMAZONS3_DIR} ${CVLT_DIR} CLEANFILES = glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/PaxHeaders.9031/cvlt0000644000000000000000000000013214522202521027626 xustar000000000000000030 mtime=1699284305.666147908 30 atime=1699284309.686160016 30 ctime=1699284305.666147908 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/0002775000175100017510000000000014522202521030164 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/PaxHeaders.9031/src0000644000000000000000000000013214522202521030415 xustar000000000000000030 mtime=1699284305.710148041 30 atime=1699284309.686160016 30 ctime=1699284305.710148041 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/0002775000175100017510000000000014522202521030753 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/PaxHeaders.9031/libcvlt0000644000000000000000000000013214522202451032056 xustar000000000000000030 mtime=1699284265.666027429 30 atime=1699284265.666027429 30 ctime=1699284305.706148029 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcvlt-mem-types.h0000664000175100017510000000117614522202451034506 0ustar00jenkinsjenkins00000000000000/* * Copyright (c) 2018 Commvault Systems, Inc. * This file is part of GlusterFS. * * This file is licensed to you under your choice of the GNU Lesser * General Public License, version 3 or any later version (LGPLv3 or * later), or the GNU General Public License, version 2 (GPLv2), in all * cases as published by the Free Software Foundation. */ #ifndef __LIBCVLT_MEM_TYPES_H__ #define __LIBCVLT_MEM_TYPES_H__ #include enum libcvlt_mem_types_ { gf_libcvlt_mt_cvlt_private_t = gf_common_mt_end + 1, gf_libcvlt_mt_end }; #endif /* __LIBCVLT_MEM_TYPES_H__ */ glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/PaxHeaders.9031/libcvlt0000644000000000000000000000013214522202451032056 xustar000000000000000030 mtime=1699284265.666027429 30 atime=1699284265.666027429 30 ctime=1699284305.709148037 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcvlt.c0000664000175100017510000004616514522202451032572 0ustar00jenkinsjenkins00000000000000#include #include "libcvlt.h" #include "cloudsync-common.h" #include "cvlt-messages.h" #define LIBARCHIVE_SO "libopenarchive.so" #define ALIGN_SIZE 4096 #define CVLT_TRAILER "cvltv1" store_methods_t store_ops = { .fop_download = cvlt_download, .fop_init = cvlt_init, .fop_reconfigure = cvlt_reconfigure, .fop_fini = cvlt_fini, .fop_remote_read = cvlt_read, }; static const int32_t num_req = 32; static const int32_t num_iatt = 32; static char *plugin = "cvlt_cloudSync"; int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_libcvlt_mt_end); if (ret != 0) { return ret; } return ret; } static void cvlt_free_resources(archive_t *arch) { /* * We will release all the resources that were allocated by the xlator. * Check whether there are any buffers which have not been released * back to a mempool. */ if (arch->handle) { dlclose(arch->handle); } if (arch->iobuf_pool) { iobuf_pool_destroy(arch->iobuf_pool); } if (arch->req_pool) { mem_pool_destroy(arch->req_pool); arch->req_pool = NULL; } return; } static int32_t cvlt_extract_store_fops(xlator_t *this, archive_t *arch) { int32_t op_ret = -1; get_archstore_methods_t get_archstore_methods; /* * libopenarchive.so defines methods for performing data management * operations. We will extract the methods from library and these * methods will be invoked for moving data between glusterfs volume * and the data management product. */ VALIDATE_OR_GOTO(arch, err); arch->handle = dlopen(LIBARCHIVE_SO, RTLD_NOW); if (!arch->handle) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_DLOPEN_FAILED, " failed to open %s ", LIBARCHIVE_SO); return op_ret; } dlerror(); /* Clear any existing error */ get_archstore_methods = dlsym(arch->handle, "get_archstore_methods"); if (!get_archstore_methods) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_EXTRACTION_FAILED, " Error extracting get_archstore_methods()"); dlclose(arch->handle); arch->handle = NULL; return op_ret; } op_ret = get_archstore_methods(&(arch->fops)); if (op_ret) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_EXTRACTION_FAILED, " Failed to extract methods in get_archstore_methods"); dlclose(arch->handle); arch->handle = NULL; return op_ret; } err: return op_ret; } static int32_t cvlt_alloc_resources(xlator_t *this, archive_t *arch, int num_req, int num_iatt) { /* * Initialize information about all the memory pools that will be * used by this xlator. */ arch->nreqs = 0; arch->req_pool = NULL; arch->handle = NULL; arch->xl = this; arch->req_pool = mem_pool_new(cvlt_request_t, num_req); if (!arch->req_pool) { goto err; } arch->iobuf_pool = iobuf_pool_new(); if (!arch->iobuf_pool) { goto err; } if (cvlt_extract_store_fops(this, arch)) { goto err; } return 0; err: return -1; } static void cvlt_req_init(cvlt_request_t *req) { sem_init(&(req->sem), 0, 0); return; } static void cvlt_req_destroy(cvlt_request_t *req) { if (req->iobuf) { iobuf_unref(req->iobuf); } if (req->iobref) { iobref_unref(req->iobref); } sem_destroy(&(req->sem)); return; } static cvlt_request_t * cvlt_alloc_req(archive_t *arch) { cvlt_request_t *reqptr = NULL; if (!arch) { goto err; } if (arch->req_pool) { reqptr = mem_get0(arch->req_pool); if (reqptr) { cvlt_req_init(reqptr); } } if (reqptr) { LOCK(&(arch->lock)); arch->nreqs++; UNLOCK(&(arch->lock)); } err: return reqptr; } static int32_t cvlt_free_req(archive_t *arch, cvlt_request_t *reqptr) { if (!reqptr) { goto err; } if (!arch) { goto err; } if (arch->req_pool) { /* * Free the request resources if they exist. */ cvlt_req_destroy(reqptr); mem_put(reqptr); LOCK(&(arch->lock)); arch->nreqs--; UNLOCK(&(arch->lock)); } return 0; err: return -1; } static int32_t cvlt_init_xlator(xlator_t *this, archive_t *arch, int num_req, int num_iatt) { int32_t ret = -1; int32_t errnum = -1; int32_t locked = 0; /* * Perform all the initializations needed for brining up the xlator. */ if (!arch) { goto err; } LOCK_INIT(&(arch->lock)); LOCK(&(arch->lock)); locked = 1; ret = cvlt_alloc_resources(this, arch, num_req, num_iatt); if (ret) { goto err; } /* * Now that the fops have been extracted initialize the store */ ret = arch->fops.init(&(arch->descinfo), &errnum, plugin); if (ret) { goto err; } UNLOCK(&(arch->lock)); locked = 0; ret = 0; return ret; err: if (arch) { cvlt_free_resources(arch); if (locked) { UNLOCK(&(arch->lock)); } } return ret; } static int32_t cvlt_term_xlator(archive_t *arch) { int32_t errnum = -1; if (!arch) { goto err; } LOCK(&(arch->lock)); /* * Release the resources that have been allocated inside store */ arch->fops.fini(&(arch->descinfo), &errnum); cvlt_free_resources(arch); UNLOCK(&(arch->lock)); GF_FREE(arch); return 0; err: return -1; } static int32_t cvlt_init_store_info(archive_t *priv, archstore_info_t *store_info) { if (!store_info) { return -1; } store_info->prod = priv->product_id; store_info->prodlen = strlen(priv->product_id); store_info->id = priv->store_id; store_info->idlen = strlen(priv->store_id); return 0; } static int32_t cvlt_init_file_info(cs_loc_xattr_t *xattr, archstore_fileinfo_t *file_info) { if (!xattr || !file_info) { return -1; } gf_uuid_copy(file_info->uuid, xattr->uuid); file_info->path = xattr->file_path; file_info->pathlength = strlen(xattr->file_path); return 0; } static int32_t cvlt_init_gluster_store_info(cs_loc_xattr_t *xattr, archstore_info_t *store_info) { static char *product = "glusterfs"; if (!xattr || !store_info) { return -1; } store_info->prod = product; store_info->prodlen = strlen(product); store_info->id = xattr->volname; store_info->idlen = strlen(xattr->volname); return 0; } static int32_t cvlt_init_gluster_file_info(cs_loc_xattr_t *xattr, archstore_fileinfo_t *file_info) { if (!xattr || !file_info) { return -1; } gf_uuid_copy(file_info->uuid, xattr->gfid); file_info->path = xattr->file_path; file_info->pathlength = strlen(xattr->file_path); return 0; } static void cvlt_copy_stat_info(struct iatt *buf, cs_size_xattr_t *xattrs) { /* * If the file was archived then the reported size will not be a * correct one. We need to fix this. */ if (buf && xattrs) { buf->ia_size = xattrs->size; buf->ia_blksize = xattrs->blksize; buf->ia_blocks = xattrs->blocks; } return; } static void cvlt_readv_complete(archstore_desc_t *desc, app_callback_info_t *cbkinfo, void *cookie, int64_t op_ret, int32_t op_errno) { struct iovec iov; xlator_t *this = NULL; struct iatt postbuf = { 0, }; call_frame_t *frame = NULL; cvlt_request_t *req = (cvlt_request_t *)cookie; cs_local_t *local = NULL; cs_private_t *cspriv = NULL; archive_t *priv = NULL; frame = req->frame; this = frame->this; local = frame->local; cspriv = this->private; priv = (archive_t *)cspriv->stores->config; if (strcmp(priv->trailer, CVLT_TRAILER)) { op_ret = -1; op_errno = EINVAL; goto out; } gf_msg_debug(plugin, 0, " Read callback invoked offset:%" PRIu64 "bytes: %" PRIu64 " op : %d ret : %" PRId64 " errno : %d", req->offset, req->bytes, req->op_type, op_ret, op_errno); if (op_ret < 0) { goto out; } req->iobref = iobref_new(); if (!req->iobref) { op_ret = -1; op_errno = ENOMEM; goto out; } iobref_add(req->iobref, req->iobuf); iov.iov_base = iobuf_ptr(req->iobuf); iov.iov_len = op_ret; cvlt_copy_stat_info(&postbuf, &(req->szxattr)); /* * Hack to notify higher layers of EOF. */ if (!postbuf.ia_size || (req->offset + iov.iov_len >= postbuf.ia_size)) { gf_msg_debug(plugin, 0, " signalling end-of-file for uuid=%s", uuid_utoa(req->file_info.uuid)); op_errno = ENOENT; } out: STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, &iov, 1, &postbuf, req->iobref, local->xattr_rsp); cvlt_free_req(priv, req); return; } static void cvlt_download_complete(archstore_desc_t *store, app_callback_info_t *cbk_info, void *cookie, int64_t ret, int errcode) { cvlt_request_t *req = (cvlt_request_t *)cookie; gf_msg_debug(plugin, 0, " Download callback invoked ret : %" PRId64 " errno : %d", ret, errcode); req->op_ret = ret; req->op_errno = errcode; sem_post(&(req->sem)); return; } void * cvlt_init(xlator_t *this) { int ret = 0; archive_t *priv = NULL; if (!this->children || this->children->next) { gf_msg(plugin, GF_LOG_ERROR, ENOMEM, 0, "should have exactly one child"); ret = -1; goto out; } if (!this->parents) { gf_msg(plugin, GF_LOG_ERROR, ENOMEM, 0, "dangling volume. check volfile"); ret = -1; goto out; } priv = GF_CALLOC(1, sizeof(archive_t), gf_libcvlt_mt_cvlt_private_t); if (!priv) { ret = -1; goto out; } priv->trailer = CVLT_TRAILER; if (cvlt_init_xlator(this, priv, num_req, num_iatt)) { gf_msg(plugin, GF_LOG_ERROR, ENOMEM, 0, "xlator init failed"); ret = -1; goto out; } GF_OPTION_INIT("cloudsync-store-id", priv->store_id, str, out); GF_OPTION_INIT("cloudsync-product-id", priv->product_id, str, out); gf_msg(plugin, GF_LOG_INFO, 0, 0, "store id is : %s " "product id is : %s.", priv->store_id, priv->product_id); out: if (ret == -1) { cvlt_term_xlator(priv); return (NULL); } return priv; } int cvlt_reconfigure(xlator_t *this, dict_t *options) { cs_private_t *cspriv = NULL; archive_t *priv = NULL; cspriv = this->private; priv = (archive_t *)cspriv->stores->config; if (strcmp(priv->trailer, CVLT_TRAILER)) goto out; GF_OPTION_RECONF("cloudsync-store-id", priv->store_id, options, str, out); GF_OPTION_RECONF("cloudsync-product-id", priv->product_id, options, str, out); gf_msg_debug(plugin, 0, "store id is : %s " "product id is : %s.", priv->store_id, priv->product_id); return 0; out: return -1; } void cvlt_fini(void *config) { archive_t *priv = NULL; priv = (archive_t *)config; if (strcmp(priv->trailer, CVLT_TRAILER)) return; cvlt_term_xlator(priv); gf_msg(plugin, GF_LOG_INFO, 0, CVLT_FREE, " released xlator resources"); return; } int cvlt_download(call_frame_t *frame, void *config) { archive_t *parch = NULL; cs_local_t *local = frame->local; cs_loc_xattr_t *locxattr = local->xattrinfo.lxattr; cvlt_request_t *req = NULL; archstore_info_t dest_storeinfo; archstore_fileinfo_t dest_fileinfo; int32_t op_ret, op_errno; parch = (archive_t *)config; if (strcmp(parch->trailer, CVLT_TRAILER)) { op_ret = -1; op_errno = EINVAL; goto err; } gf_msg_debug(plugin, 0, " download invoked for uuid = %s gfid=%s ", locxattr->uuid, uuid_utoa(locxattr->gfid)); if (!(parch->fops.restore)) { op_errno = ELIBBAD; goto err; } /* * Download needs to be processed. Allocate a request. */ req = cvlt_alloc_req(parch); if (!req) { gf_msg(plugin, GF_LOG_ERROR, ENOMEM, CVLT_RESOURCE_ALLOCATION_FAILED, " failed to allocated request for gfid=%s", uuid_utoa(locxattr->gfid)); op_errno = ENOMEM; goto err; } /* * Initialize the request object. */ req->op_type = CVLT_RESTORE_OP; req->frame = frame; /* * The file is currently residing inside a data management store. * To restore the file contents we need to provide the information * about data management store. */ op_ret = cvlt_init_store_info(parch, &(req->store_info)); if (op_ret < 0) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_EXTRACTION_FAILED, " failed to extract store info for gfid=%s", uuid_utoa(locxattr->gfid)); goto err; } op_ret = cvlt_init_file_info(locxattr, &(req->file_info)); if (op_ret < 0) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_EXTRACTION_FAILED, " failed to extract file info for gfid=%s", uuid_utoa(locxattr->gfid)); goto err; } /* * We need to perform in-place restore of the file from data management * store to gusterfs volume. */ op_ret = cvlt_init_gluster_store_info(locxattr, &dest_storeinfo); if (op_ret < 0) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_EXTRACTION_FAILED, " failed to extract destination store info for gfid=%s", uuid_utoa(locxattr->gfid)); goto err; } op_ret = cvlt_init_gluster_file_info(locxattr, &dest_fileinfo); if (op_ret < 0) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_EXTRACTION_FAILED, " failed to extract file info for gfid=%s", uuid_utoa(locxattr->gfid)); goto err; } /* * Submit the restore request. */ op_ret = parch->fops.restore(&(parch->descinfo), &(req->store_info), &(req->file_info), &dest_storeinfo, &dest_fileinfo, &op_errno, cvlt_download_complete, req); if (op_ret < 0) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_RESTORE_FAILED, " failed to restore file gfid=%s from data management store", uuid_utoa(locxattr->gfid)); goto err; } /* * Wait for the restore to complete. */ sem_wait(&(req->sem)); if (req->op_ret < 0) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_RESTORE_FAILED, " restored failed for gfid=%s", uuid_utoa(locxattr->gfid)); goto err; } if (req) { cvlt_free_req(parch, req); } return 0; err: if (req) { cvlt_free_req(parch, req); } return -1; } int cvlt_read(call_frame_t *frame, void *config) { int32_t op_ret = -1; int32_t op_errno = 0; archive_t *parch = NULL; cvlt_request_t *req = NULL; struct iovec iov = { 0, }; struct iobref *iobref; size_t size = 0; off_t off = 0; cs_local_t *local = frame->local; cs_loc_xattr_t *locxattr = local->xattrinfo.lxattr; size = local->xattrinfo.size; off = local->xattrinfo.offset; parch = (archive_t *)config; if (strcmp(parch->trailer, CVLT_TRAILER)) { op_ret = -1; op_errno = EINVAL; goto err; } gf_msg_debug(plugin, 0, " read invoked for gfid = %s offset = %" PRIu64 " file_size = %" PRIu64, uuid_utoa(locxattr->gfid), off, local->stbuf.ia_size); if (off >= local->stbuf.ia_size) { /* * Hack to notify higher layers of EOF. */ op_errno = ENOENT; op_ret = 0; gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_READ_FAILED, " reporting end-of-file for gfid=%s", uuid_utoa(locxattr->gfid)); goto err; } if (!size) { op_errno = EINVAL; gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_READ_FAILED, " zero size read attempted on gfid=%s", uuid_utoa(locxattr->gfid)); goto err; } if (!(parch->fops.read)) { op_errno = ELIBBAD; goto err; } /* * The read request need to be processed. Allocate a request. */ req = cvlt_alloc_req(parch); if (!req) { gf_msg(plugin, GF_LOG_ERROR, ENOMEM, CVLT_NO_MEMORY, " failed to allocated request for gfid=%s", uuid_utoa(locxattr->gfid)); op_errno = ENOMEM; goto err; } req->iobuf = iobuf_get_page_aligned(parch->iobuf_pool, size, ALIGN_SIZE); if (!req->iobuf) { op_errno = ENOMEM; goto err; } /* * Initialize the request object. */ req->op_type = CVLT_READ_OP; req->offset = off; req->bytes = size; req->frame = frame; req->szxattr.size = local->stbuf.ia_size; req->szxattr.blocks = local->stbuf.ia_blocks; req->szxattr.blksize = local->stbuf.ia_blksize; /* * The file is currently residing inside a data management store. * To read the file contents we need to provide the information * about data management store. */ op_ret = cvlt_init_store_info(parch, &(req->store_info)); if (op_ret < 0) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_EXTRACTION_FAILED, " failed to extract store info for gfid=%s" " offset=%" PRIu64 " size=%" GF_PRI_SIZET ", " " buf=%p", uuid_utoa(locxattr->gfid), off, size, req->iobuf->ptr); goto err; } op_ret = cvlt_init_file_info(locxattr, &(req->file_info)); if (op_ret < 0) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_EXTRACTION_FAILED, " failed to extract file info for gfid=%s" " offset=%" PRIu64 " size=%" GF_PRI_SIZET ", " " buf=%p", uuid_utoa(locxattr->gfid), off, size, req->iobuf->ptr); goto err; } /* * Submit the read request. */ op_ret = parch->fops.read(&(parch->descinfo), &(req->store_info), &(req->file_info), off, req->iobuf->ptr, size, &op_errno, cvlt_readv_complete, req); if (op_ret < 0) { gf_msg(plugin, GF_LOG_ERROR, 0, CVLT_EXTRACTION_FAILED, " read failed on gfid=%s" " offset=%" PRIu64 " size=%" GF_PRI_SIZET ", " " buf=%p", uuid_utoa(locxattr->gfid), off, size, req->iobuf->ptr); goto err; } return 0; err: iobref = iobref_new(); gf_msg_debug(plugin, 0, " read unwinding stack op_ret = %d, op_errno = %d", op_ret, op_errno); STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, &iov, 1, &(local->stbuf), iobref, local->xattr_rsp); if (iobref) { iobref_unref(iobref); } if (req) { cvlt_free_req(parch, req); } return 0; } glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/PaxHeaders.9031/libclou0000644000000000000000000000013214522202451032050 xustar000000000000000030 mtime=1699284265.666027429 30 atime=1699284265.666027429 30 ctime=1699284305.711148044 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcloudsynccvlt.sym0000664000175100017510000000001214522202451035061 0ustar00jenkinsjenkins00000000000000store_ops glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/PaxHeaders.9031/Makefil0000644000000000000000000000013214522202463031772 xustar000000000000000030 mtime=1699284275.958058429 30 atime=1699284291.340104759 30 ctime=1699284305.701148013 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/Makefile.in0000664000175100017510000006276514522202463033043 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = \ xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(cspdir)" LTLIBRARIES = $(csp_LTLIBRARIES) cloudsynccvlt_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_cloudsynccvlt_la_OBJECTS = libcvlt.lo cloudsync-common.lo cloudsynccvlt_la_OBJECTS = $(am_cloudsynccvlt_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = cloudsynccvlt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cloudsynccvlt_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(cloudsynccvlt_la_SOURCES) DIST_SOURCES = $(cloudsynccvlt_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ csp_LTLIBRARIES = cloudsynccvlt.la cspdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/cloudsync-plugins cloudsynccvlt_la_SOURCES = libcvlt.c $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c cloudsynccvlt_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la cloudsynccvlt_la_LDFLAGS = -module -avoid-version -export-symbols $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcloudsynccvlt.sym AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src noinst_HEADERS = archivestore.h libcvlt.h libcvlt-mem-types.h cvlt-messages.h AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) -I$(top_srcdir)/xlators/features/cloudsync/src CLEANFILES = EXTRA_DIST = libcloudsynccvlt.sym all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-cspLTLIBRARIES: $(csp_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(csp_LTLIBRARIES)'; test -n "$(cspdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(cspdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(cspdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(cspdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(cspdir)"; \ } uninstall-cspLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(csp_LTLIBRARIES)'; test -n "$(cspdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(cspdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(cspdir)/$$f"; \ done clean-cspLTLIBRARIES: -test -z "$(csp_LTLIBRARIES)" || rm -f $(csp_LTLIBRARIES) @list='$(csp_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } cloudsynccvlt.la: $(cloudsynccvlt_la_OBJECTS) $(cloudsynccvlt_la_DEPENDENCIES) $(EXTRA_cloudsynccvlt_la_DEPENDENCIES) $(AM_V_CCLD)$(cloudsynccvlt_la_LINK) -rpath $(cspdir) $(cloudsynccvlt_la_OBJECTS) $(cloudsynccvlt_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cloudsync-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcvlt.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< cloudsync-common.lo: $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cloudsync-common.lo -MD -MP -MF $(DEPDIR)/cloudsync-common.Tpo -c -o cloudsync-common.lo `test -f '$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c' || echo '$(srcdir)/'`$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cloudsync-common.Tpo $(DEPDIR)/cloudsync-common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c' object='cloudsync-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cloudsync-common.lo `test -f '$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c' || echo '$(srcdir)/'`$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(cspdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-cspLTLIBRARIES clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-cspLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-cspLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-cspLTLIBRARIES clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-cspLTLIBRARIES \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-cspLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/PaxHeaders.9031/libcvlt0000644000000000000000000000013214522202451032056 xustar000000000000000030 mtime=1699284265.666027429 30 atime=1699284265.666027429 30 ctime=1699284305.705148025 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcvlt.h0000664000175100017510000000407214522202451032566 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Commvault Systems, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _LIBCVLT_H #define _LIBCVLT_H #include #include #include "cloudsync-common.h" #include "libcvlt-mem-types.h" #include "archivestore.h" enum _cvlt_op { CVLT_READ_OP = 1, CVLT_WRITE_OP = 2, CVLT_RESTORE_OP = 3, CVLT_ARCHIVE_OP = 4, CVLT_LOOKUP_OP = 5, CVLT_XATTR_OP = 6, CVLT_STAT_OP = 7, CVLT_FSTAT_op = 8, CVLT_UNDEF_OP = 127 }; typedef enum _cvlt_op cvlt_op_t; struct _archive; struct _cvlt_request { uint64_t offset; uint64_t bytes; struct iobuf *iobuf; struct iobref *iobref; call_frame_t *frame; cvlt_op_t op_type; int32_t op_ret; int32_t op_errno; xlator_t *this; sem_t sem; archstore_info_t store_info; archstore_fileinfo_t file_info; cs_size_xattr_t szxattr; }; typedef struct _cvlt_request cvlt_request_t; struct _archive { gf_lock_t lock; /* lock for controlling access */ xlator_t *xl; /* xlator */ void *handle; /* handle returned from dlopen */ int32_t nreqs; /* num requests active */ struct mem_pool *req_pool; /* pool for requests */ struct iobuf_pool *iobuf_pool; /* iobuff pool */ archstore_desc_t descinfo; /* Archive store descriptor info */ archstore_methods_t fops; /* function pointers */ char *product_id; char *store_id; char *trailer; }; typedef struct _archive archive_t; void * cvlt_init(xlator_t *); int cvlt_reconfigure(xlator_t *, dict_t *); void cvlt_fini(void *); int cvlt_download(call_frame_t *, void *); int cvlt_read(call_frame_t *, void *); #endif glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/PaxHeaders.9031/Makefil0000644000000000000000000000013214522202451031767 xustar000000000000000030 mtime=1699284265.665027426 30 atime=1699284275.920058314 30 ctime=1699284305.702148016 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/Makefile.am0000664000175100017510000000142514522202451033011 0ustar00jenkinsjenkins00000000000000csp_LTLIBRARIES = cloudsynccvlt.la cspdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/cloudsync-plugins cloudsynccvlt_la_SOURCES = libcvlt.c $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c cloudsynccvlt_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la cloudsynccvlt_la_LDFLAGS = -module -avoid-version -export-symbols $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcloudsynccvlt.sym AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src noinst_HEADERS = archivestore.h libcvlt.h libcvlt-mem-types.h cvlt-messages.h AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) -I$(top_srcdir)/xlators/features/cloudsync/src CLEANFILES = EXTRA_DIST = libcloudsynccvlt.sym glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/PaxHeaders.9031/cvlt-me0000644000000000000000000000013214522202451031766 xustar000000000000000030 mtime=1699284265.665027426 30 atime=1699284265.665027426 30 ctime=1699284305.708148034 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/cvlt-messages.h0000664000175100017510000000176714522202451033714 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CVLT_MESSAGES_H_ #define _CVLT_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(CVLT, CVLT_EXTRACTION_FAILED, CVLT_FREE, CVLT_RESOURCE_ALLOCATION_FAILED, CVLT_RESTORE_FAILED, CVLT_READ_FAILED, CVLT_NO_MEMORY, CVLT_DLOPEN_FAILED); #endif /* !_CVLT_MESSAGES_H_ */ glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/PaxHeaders.9031/archive0000644000000000000000000000013214522202451032040 xustar000000000000000030 mtime=1699284265.665027426 30 atime=1699284265.665027426 30 ctime=1699284305.704148022 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/archivestore.h0000664000175100017510000002064414522202451033630 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Commvault Systems, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __ARCHIVESTORE_H__ #define __ARCHIVESTORE_H__ #include #include #include #include #include #define CS_XATTR_ARCHIVE_UUID "trusted.cloudsync.uuid" #define CS_XATTR_PRODUCT_ID "trusted.cloudsync.product-id" #define CS_XATTR_STORE_ID "trusted.cloudsync.store-id" struct _archstore_methods; typedef struct _archstore_methods archstore_methods_t; struct _archstore_desc { void *priv; /* Private field for store mgmt. */ /* To be used only by archive store*/ }; typedef struct _archstore_desc archstore_desc_t; struct _archstore_info { char *id; /* Identifier for the archivestore */ uint32_t idlen; /* Length of identifier string */ char *prod; /* Name of the data mgmt. product */ uint32_t prodlen; /* Length of the product string */ }; typedef struct _archstore_info archstore_info_t; struct _archstore_fileinfo { uuid_t uuid; /* uuid of the file */ char *path; /* file path */ uint32_t pathlength; /* length of file path */ }; typedef struct _archstore_fileinfo archstore_fileinfo_t; struct _app_callback_info { archstore_info_t *src_archstore; archstore_fileinfo_t *src_archfile; archstore_info_t *dest_archstore; archstore_fileinfo_t *dest_archfile; }; typedef struct _app_callback_info app_callback_info_t; typedef void (*app_callback_t)(archstore_desc_t *, app_callback_info_t *, void *, int64_t, int32_t); enum _archstore_scan_type { FULL = 1, INCREMENTAL = 2 }; typedef enum _archstore_scan_type archstore_scan_type_t; typedef int32_t archstore_errno_t; /* * Initialize archive store. * arg1 pointer to structure containing archive store information * arg2 error number if any generated during the initialization * arg3 name of the log file */ typedef int32_t (*init_archstore_t)(archstore_desc_t *, archstore_errno_t *, const char *); /* * Clean up archive store. * arg1 pointer to structure containing archive store information * arg2 error number if any generated during the cleanup */ typedef int32_t (*term_archstore_t)(archstore_desc_t *, archstore_errno_t *); /* * Read the contents of the file from archive store * arg1 pointer to structure containing archive store description * arg2 pointer to structure containing archive store information * arg3 pointer to structure containing information about file to be read * arg4 offset in the file from which data should be read * arg5 buffer where the data should be read * arg6 number of bytes of data to be read * arg7 error number if any generated during the read from file * arg8 callback handler to be invoked after the data is read * arg9 cookie to be passed when callback is invoked */ typedef int32_t (*read_archstore_t)(archstore_desc_t *, archstore_info_t *, archstore_fileinfo_t *, off_t, char *, size_t, archstore_errno_t *, app_callback_t, void *); /* * Restore the contents of the file from archive store * This is basically in-place restore * arg1 pointer to structure containing archive store description * arg2 pointer to structure containing archive store information * arg3 pointer to structure containing information about file to be restored * arg4 error number if any generated during the file restore * arg5 callback to be invoked after the file is restored * arg6 cookie to be passed when callback is invoked */ typedef int32_t (*recall_archstore_t)(archstore_desc_t *, archstore_info_t *, archstore_fileinfo_t *, archstore_errno_t *, app_callback_t, void *); /* * Restore the contents of the file from archive store to a different store * This is basically out-of-place restore * arg1 pointer to structure containing archive store description * arg2 pointer to structure containing source archive store information * arg3 pointer to structure containing information about file to be restored * arg4 pointer to structure containing destination archive store information * arg5 pointer to structure containing information about the location to which the file will be restored * arg6 error number if any generated during the file restore * arg7 callback to be invoked after the file is restored * arg8 cookie to be passed when callback is invoked */ typedef int32_t (*restore_archstore_t)(archstore_desc_t *, archstore_info_t *, archstore_fileinfo_t *, archstore_info_t *, archstore_fileinfo_t *, archstore_errno_t *, app_callback_t, void *); /* * Archive the contents of the file to archive store * arg1 pointer to structure containing archive store description * arg2 pointer to structure containing source archive store information * arg3 pointer to structure containing information about files to be archived * arg4 pointer to structure containing destination archive store information * arg5 pointer to structure containing information about files that failed * to be archived * arg6 error number if any generated during the file archival * arg7 callback to be invoked after the file is archived * arg8 cookie to be passed when callback is invoked */ typedef int32_t (*archive_archstore_t)(archstore_desc_t *, archstore_info_t *, archstore_fileinfo_t *, archstore_info_t *, archstore_fileinfo_t *, archstore_errno_t *, app_callback_t, void *); /* * Backup list of files provided in the input file * arg1 pointer to structure containing archive store description * arg2 pointer to structure containing source archive store information * arg3 pointer to structure containing information about files to be backed up * arg4 pointer to structure containing destination archive store information * arg5 pointer to structure containing information about files that failed * to be backed up * arg6 error number if any generated during the file archival * arg7 callback to be invoked after the file is archived * arg8 cookie to be passed when callback is invoked */ typedef int32_t (*backup_archstore_t)(archstore_desc_t *, archstore_info_t *, archstore_fileinfo_t *, archstore_info_t *, archstore_fileinfo_t *, archstore_errno_t *, app_callback_t, void *); /* * Scan the contents of a store and determine the files which need to be * backed up. * arg1 pointer to structure containing archive store description * arg2 pointer to structure containing archive store information * arg3 type of scan whether full or incremental * arg4 path to file that contains list of files to be backed up * arg5 error number if any generated during scan operation */ typedef int32_t (*scan_archstore_t)(archstore_desc_t *, archstore_info_t *, archstore_scan_type_t, char *, archstore_errno_t *); struct _archstore_methods { init_archstore_t init; term_archstore_t fini; backup_archstore_t backup; archive_archstore_t archive; scan_archstore_t scan; restore_archstore_t restore; recall_archstore_t recall; read_archstore_t read; }; typedef int (*get_archstore_methods_t)(archstore_methods_t *); /* * Single function that will be invoked by applications for extracting * the function pointers to all data management functions. */ int32_t get_archstore_methods(archstore_methods_t *); #endif /* End of __ARCHIVESTORE_H__ */ glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463031755 xustar000000000000000030 mtime=1699284275.909058281 30 atime=1699284291.318104693 30 ctime=1699284305.661147893 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/Makefile.in0000664000175100017510000005307214522202463032243 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451031741 xustar000000000000000030 mtime=1699284265.665027426 30 atime=1699284275.885058209 30 ctime=1699284305.662147896 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/Makefile.am0000664000175100017510000000003414522202451032215 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/PaxHeaders.9031/cloudsyncs30000644000000000000000000000013214522202521031127 xustar000000000000000030 mtime=1699284305.584147661 30 atime=1699284309.686160016 30 ctime=1699284305.584147661 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/0002775000175100017510000000000014522202521031465 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/PaxHeaders.9031/src0000644000000000000000000000013214522202521031716 xustar000000000000000030 mtime=1699284305.627147791 30 atime=1699284309.686160016 30 ctime=1699284305.627147791 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/0002775000175100017510000000000014522202521032254 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/PaxHeaders.9031/0000644000000000000000000000031214522202451031777 xustar0000000000000000112 path=glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3.sym 30 mtime=1699284265.665027426 30 atime=1699284265.665027426 30 ctime=1699284305.627147791 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3.s0000664000175100017510000000001214522202451035371 0ustar00jenkinsjenkins00000000000000store_ops glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/PaxHeaders.9031/0000644000000000000000000000032214522202451032000 xustar0000000000000000120 path=glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3-mem-types.h 30 mtime=1699284265.664027423 30 atime=1699284265.664027423 30 ctime=1699284305.624147782 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3-m0000664000175100017510000000115514522202451035373 0ustar00jenkinsjenkins00000000000000/* * Copyright (c) 2018 Red Hat, Inc. * This file is part of GlusterFS. * * This file is licensed to you under your choice of the GNU Lesser * General Public License, version 3 or any later version (LGPLv3 or * later), or the GNU General Public License, version 2 (GPLv2), in all * cases as published by the Free Software Foundation. */ #ifndef __LIBAWS_MEM_TYPES_H__ #define __LIBAWS_MEM_TYPES_H__ #include enum libaws_mem_types_ { gf_libaws_mt_aws_private_t = gf_common_mt_end + 1, gf_libaws_mt_end }; #endif /* __CLOUDSYNC_MEM_TYPES_H__ */ glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/PaxHeaders.9031/0000644000000000000000000000013214522202451031777 xustar000000000000000030 mtime=1699284265.665027426 30 atime=1699284265.665027426 30 ctime=1699284305.625147784 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3.c0000664000175100017510000003614414522202451035370 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include "libcloudsyncs3.h" #include "cloudsync-common.h" #define RESOURCE_SIZE 4096 store_methods_t store_ops = { .fop_download = aws_download_s3, .fop_init = aws_init, .fop_reconfigure = aws_reconfigure, .fop_fini = aws_fini, }; typedef struct aws_private { char *hostname; char *bucketid; char *awssekey; char *awskeyid; gf_boolean_t abortdl; pthread_spinlock_t lock; } aws_private_t; void * aws_init(xlator_t *this) { aws_private_t *priv = NULL; char *temp_str = NULL; int ret = 0; priv = GF_CALLOC(1, sizeof(aws_private_t), gf_libaws_mt_aws_private_t); if (!priv) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insufficient memory"); return NULL; } priv->abortdl = _gf_false; pthread_spin_init(&priv->lock, PTHREAD_PROCESS_PRIVATE); pthread_spin_lock(&(priv->lock)); { if (dict_get_str(this->options, "s3plugin-seckey", &temp_str) == 0) { priv->awssekey = gf_strdup(temp_str); if (!priv->awssekey) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "initializing aws secret key failed"); ret = -1; goto unlock; } } if (dict_get_str(this->options, "s3plugin-keyid", &temp_str) == 0) { priv->awskeyid = gf_strdup(temp_str); if (!priv->awskeyid) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "initializing aws key ID failed"); ret = -1; goto unlock; } } if (dict_get_str(this->options, "s3plugin-bucketid", &temp_str) == 0) { priv->bucketid = gf_strdup(temp_str); if (!priv->bucketid) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "initializing aws bucketid failed"); ret = -1; goto unlock; } } if (dict_get_str(this->options, "s3plugin-hostname", &temp_str) == 0) { priv->hostname = gf_strdup(temp_str); if (!priv->hostname) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "initializing aws hostname failed"); ret = -1; goto unlock; } } gf_msg_debug(this->name, 0, "stored key: %s id: %s " "bucketid %s hostname: %s", priv->awssekey, priv->awskeyid, priv->bucketid, priv->hostname); } unlock: pthread_spin_unlock(&(priv->lock)); if (ret == -1) { GF_FREE(priv->awskeyid); GF_FREE(priv->awssekey); GF_FREE(priv->bucketid); GF_FREE(priv->hostname); GF_FREE(priv); priv = NULL; } return (void *)priv; } int aws_reconfigure(xlator_t *this, dict_t *options) { aws_private_t *priv = NULL; char *temp_str = NULL; int ret = 0; cs_private_t *cspriv = NULL; cspriv = this->private; priv = cspriv->stores->config; if (!priv) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "null priv"); return -1; } pthread_spin_lock(&(priv->lock)); { if (dict_get_str(options, "s3plugin-seckey", &temp_str) == 0) { priv->awssekey = gf_strdup(temp_str); if (!priv->awssekey) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "initializing aws secret key failed"); ret = -1; goto out; } } if (dict_get_str(options, "s3plugin-keyid", &temp_str) == 0) { priv->awskeyid = gf_strdup(temp_str); if (!priv->awskeyid) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "initializing aws key ID failed"); ret = -1; goto out; } } if (dict_get_str(options, "s3plugin-bucketid", &temp_str) == 0) { priv->bucketid = gf_strdup(temp_str); if (!priv->bucketid) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "initializing aws bucketid failed"); ret = -1; goto out; } } if (dict_get_str(options, "s3plugin-hostname", &temp_str) == 0) { priv->hostname = gf_strdup(temp_str); if (!priv->hostname) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "initializing aws hostname failed"); ret = -1; goto out; } } } out: pthread_spin_unlock(&(priv->lock)); gf_msg_debug(this->name, 0, "stored key: %s id: %s " "bucketid %s hostname: %s", priv->awssekey, priv->awskeyid, priv->bucketid, priv->hostname); return ret; } void aws_fini(void *config) { aws_private_t *priv = NULL; priv = (aws_private_t *)priv; if (priv) { GF_FREE(priv->hostname); GF_FREE(priv->bucketid); GF_FREE(priv->awssekey); GF_FREE(priv->awskeyid); pthread_spin_destroy(&priv->lock); GF_FREE(priv); } } int32_t mem_acct_init(xlator_t *this) { int ret = -1; GF_VALIDATE_OR_GOTO("dht", this, out); ret = xlator_mem_acct_init(this, gf_libaws_mt_end); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "Memory accounting init failed"); return ret; } out: return ret; } char * aws_form_request(char *resource, char **date, char *reqtype, char *bucketid, char *filepath) { char httpdate[256]; time_t ctime; struct tm *gtime = NULL; char *sign_req = NULL; int signreq_len = -1; int date_len = -1; int res_len = -1; ctime = gf_time(); gtime = gmtime(&ctime); date_len = strftime(httpdate, sizeof(httpdate), "%a, %d %b %Y %H:%M:%S +0000", gtime); *date = gf_strndup(httpdate, date_len); if (*date == NULL) { gf_msg("CS", GF_LOG_ERROR, ENOMEM, 0, "memory allocation " "failure for date"); goto out; } res_len = snprintf(resource, RESOURCE_SIZE, "%s/%s", bucketid, filepath); gf_msg_debug("CS", 0, "resource %s", resource); /* 6 accounts for the 4 new line chars, one forward slash and * one null char */ signreq_len = res_len + date_len + strlen(reqtype) + 6; sign_req = GF_MALLOC(signreq_len, gf_common_mt_char); if (sign_req == NULL) { gf_msg("CS", GF_LOG_ERROR, ENOMEM, 0, "memory allocation " "failure for sign_req"); goto out; } snprintf(sign_req, signreq_len, "%s\n\n%s\n%s\n/%s", reqtype, "", *date, resource); out: return sign_req; } char * aws_b64_encode(const unsigned char *input, int length) { BIO *bio, *b64; BUF_MEM *bptr; char *buff = NULL; b64 = BIO_new(BIO_f_base64()); bio = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bio); BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); buff = GF_MALLOC(bptr->length, gf_common_mt_char); memcpy(buff, bptr->data, bptr->length - 1); buff[bptr->length - 1] = 0; BIO_free_all(b64); return buff; } char * aws_sign_request(char *const str, char *awssekey) { #if (OPENSSL_VERSION_NUMBER < 0x1010002f) // 1.0.1-beta2 HMAC_CTX ctx; #endif HMAC_CTX *pctx = NULL; ; unsigned char md[256]; unsigned len; char *base64 = NULL; #if (OPENSSL_VERSION_NUMBER < 0x1010002f) // 1.0.1-beta2 HMAC_CTX_init(&ctx); pctx = &ctx; #else pctx = HMAC_CTX_new(); #endif HMAC_Init_ex(pctx, awssekey, strlen(awssekey), EVP_sha1(), NULL); HMAC_Update(pctx, (unsigned char *)str, strlen(str)); HMAC_Final(pctx, (unsigned char *)md, &len); #if (OPENSSL_VERSION_NUMBER < 0x1010002f) // 1.0.1-beta2 HMAC_CTX_cleanup(pctx); #else HMAC_CTX_free(pctx); #endif base64 = aws_b64_encode(md, len); return base64; } int aws_dlwritev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { aws_private_t *priv = NULL; if (op_ret == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, op_errno, "write failed " ". Aborting Download"); priv = this->private; pthread_spin_lock(&(priv->lock)); { priv->abortdl = _gf_true; } pthread_spin_unlock(&(priv->lock)); } CS_STACK_DESTROY(frame); return op_ret; } size_t aws_write_callback(void *dlbuf, size_t size, size_t nitems, void *mainframe) { call_frame_t *frame = NULL; fd_t *dlfd = NULL; int ret = 0; cs_local_t *local = NULL; struct iovec iov = { 0, }; struct iobref *iobref = NULL; struct iobuf *iobuf = NULL; struct iovec dliov = { 0, }; size_t tsize = 0; xlator_t *this = NULL; cs_private_t *xl_priv = NULL; aws_private_t *priv = NULL; call_frame_t *dlframe = NULL; frame = (call_frame_t *)mainframe; this = frame->this; xl_priv = this->private; priv = xl_priv->stores->config; pthread_spin_lock(&(priv->lock)); { /* returning size other than the size passed from curl will * abort further download*/ if (priv->abortdl) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "aborting download"); pthread_spin_unlock(&(priv->lock)); return 0; } } pthread_spin_unlock(&(priv->lock)); local = frame->local; dlfd = local->dlfd; tsize = size * nitems; dliov.iov_base = (void *)dlbuf; dliov.iov_len = tsize; ret = iobuf_copy(this->ctx->iobuf_pool, &dliov, 1, &iobref, &iobuf, &iov); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "iobuf_copy failed"); goto out; } /* copy frame */ dlframe = copy_frame(frame); if (!dlframe) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "copy_frame failed"); tsize = 0; goto out; } STACK_WIND(dlframe, aws_dlwritev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, dlfd, &iov, 1, local->dloffset, 0, iobref, NULL); local->dloffset += tsize; out: if (iobuf) iobuf_unref(iobuf); if (iobref) iobref_unref(iobref); return tsize; } int aws_download_s3(call_frame_t *frame, void *config) { char *buf; int bufsize = -1; CURL *handle = NULL; struct curl_slist *slist = NULL; struct curl_slist *tmp = NULL; xlator_t *this = NULL; int ret = 0; int debug = 1; CURLcode res; char errbuf[CURL_ERROR_SIZE]; size_t len = 0; long responsecode; char *sign_req = NULL; char *date = NULL; char *const reqtype = "GET"; char *signature = NULL; cs_local_t *local = NULL; char resource[RESOURCE_SIZE] = { 0, }; aws_private_t *priv = NULL; this = frame->this; local = frame->local; priv = (aws_private_t *)config; if (!priv->bucketid || !priv->hostname || !priv->awssekey || !priv->awskeyid) { ret = -1; goto out; } sign_req = aws_form_request(resource, &date, reqtype, priv->bucketid, local->remotepath); if (!sign_req) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "null sign_req, " "aborting download"); ret = -1; goto out; } gf_msg_debug("CS", 0, "sign_req %s date %s", sign_req, date); signature = aws_sign_request(sign_req, priv->awssekey); if (!signature) { gf_msg("CS", GF_LOG_ERROR, 0, 0, "null signature, " "aborting download"); ret = -1; goto out; } handle = curl_easy_init(); this = frame->this; /* special numbers 6, 20, 10 accounts for static characters in the * below snprintf string format arguments*/ bufsize = strlen(date) + 6 + strlen(priv->awskeyid) + strlen(signature) + 20 + strlen(priv->hostname) + 10; buf = (char *)alloca(bufsize); if (!buf) { gf_msg("CS", GF_LOG_ERROR, ENOMEM, 0, "mem allocation " "failed for buf"); ret = -1; goto out; } snprintf(buf, bufsize, "Date: %s", date); slist = curl_slist_append(slist, buf); snprintf(buf, bufsize, "Authorization: AWS %s:%s", priv->awskeyid, signature); slist = curl_slist_append(slist, buf); snprintf(buf, bufsize, "https://%s/%s", priv->hostname, resource); if (gf_log_get_loglevel() >= GF_LOG_DEBUG) { tmp = slist; while (tmp) { gf_msg_debug(this->name, 0, "slist for curl - %s", tmp->data); tmp = tmp->next; } } curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist); curl_easy_setopt(handle, CURLOPT_URL, buf); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, aws_write_callback); curl_easy_setopt(handle, CURLOPT_WRITEDATA, frame); curl_easy_setopt(handle, CURLOPT_VERBOSE, debug); curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errbuf); res = curl_easy_perform(handle); if (res != CURLE_OK) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "download failed. err: %s\n", curl_easy_strerror(res)); ret = -1; len = strlen(errbuf); if (len) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "curl failure %s", errbuf); } else { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "curl error " "%s\n", curl_easy_strerror(res)); } } if (res == CURLE_OK) { curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &responsecode); gf_msg_debug(this->name, 0, "response code %ld", responsecode); if (responsecode != 200) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, 0, "curl download failed"); } } curl_slist_free_all(slist); curl_easy_cleanup(handle); out: if (sign_req) GF_FREE(sign_req); if (date) GF_FREE(date); if (signature) GF_FREE(signature); return ret; } struct volume_options cs_options[] = { {.key = {"s3plugin-seckey"}, .type = GF_OPTION_TYPE_STR, .description = "aws secret key"}, {.key = {"s3plugin-keyid"}, .type = GF_OPTION_TYPE_STR, .description = "aws key ID" }, {.key = {"s3plugin-bucketid"}, .type = GF_OPTION_TYPE_STR, .description = "aws bucketid"}, {.key = {"s3plugin-hostname"}, .type = GF_OPTION_TYPE_STR, .description = "aws hostname e.g. s3.amazonaws.com"}, {.key = {NULL}}, }; glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/PaxHeaders.9031/0000644000000000000000000000013214522202463032002 xustar000000000000000030 mtime=1699284275.874058176 30 atime=1699284291.295104624 30 ctime=1699284305.620147769 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/Makefile.in0000664000175100017510000006302114522202463034326 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(cspdir)" LTLIBRARIES = $(csp_LTLIBRARIES) cloudsyncs3_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_cloudsyncs3_la_OBJECTS = libcloudsyncs3.lo cloudsync-common.lo cloudsyncs3_la_OBJECTS = $(am_cloudsyncs3_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = cloudsyncs3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cloudsyncs3_la_LDFLAGS) $(LDFLAGS) -o \ $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(cloudsyncs3_la_SOURCES) DIST_SOURCES = $(cloudsyncs3_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ csp_LTLIBRARIES = cloudsyncs3.la cspdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/cloudsync-plugins cloudsyncs3_la_SOURCES = libcloudsyncs3.c $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c cloudsyncs3_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la cloudsyncs3_la_LDFLAGS = -module -export-symbols $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3.sym $(GF_XLATOR_LDFLAGS) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src -lcurlpp -lcryptopp noinst_HEADERS = libcloudsyncs3.h libcloudsyncs3-mem-types.h AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) -lcurl -lcrypto -I$(top_srcdir)/xlators/features/cloudsync/src CLEANFILES = EXTRA_DIST = libcloudsyncs3.sym all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-cspLTLIBRARIES: $(csp_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(csp_LTLIBRARIES)'; test -n "$(cspdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(cspdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(cspdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(cspdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(cspdir)"; \ } uninstall-cspLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(csp_LTLIBRARIES)'; test -n "$(cspdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(cspdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(cspdir)/$$f"; \ done clean-cspLTLIBRARIES: -test -z "$(csp_LTLIBRARIES)" || rm -f $(csp_LTLIBRARIES) @list='$(csp_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } cloudsyncs3.la: $(cloudsyncs3_la_OBJECTS) $(cloudsyncs3_la_DEPENDENCIES) $(EXTRA_cloudsyncs3_la_DEPENDENCIES) $(AM_V_CCLD)$(cloudsyncs3_la_LINK) -rpath $(cspdir) $(cloudsyncs3_la_OBJECTS) $(cloudsyncs3_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cloudsync-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcloudsyncs3.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< cloudsync-common.lo: $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cloudsync-common.lo -MD -MP -MF $(DEPDIR)/cloudsync-common.Tpo -c -o cloudsync-common.lo `test -f '$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c' || echo '$(srcdir)/'`$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cloudsync-common.Tpo $(DEPDIR)/cloudsync-common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c' object='cloudsync-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cloudsync-common.lo `test -f '$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c' || echo '$(srcdir)/'`$(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(cspdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-cspLTLIBRARIES clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-cspLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-cspLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-cspLTLIBRARIES clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-cspLTLIBRARIES \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-cspLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/PaxHeaders.9031/0000644000000000000000000000013214522202451031777 xustar000000000000000030 mtime=1699284265.664027423 30 atime=1699284275.835058058 30 ctime=1699284305.621147772 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/Makefile.am0000664000175100017510000000146014522202451034311 0ustar00jenkinsjenkins00000000000000csp_LTLIBRARIES = cloudsyncs3.la cspdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/cloudsync-plugins cloudsyncs3_la_SOURCES = libcloudsyncs3.c $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-common.c cloudsyncs3_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la cloudsyncs3_la_LDFLAGS = -module -export-symbols $(top_srcdir)/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3.sym $(GF_XLATOR_LDFLAGS) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src -lcurlpp -lcryptopp noinst_HEADERS = libcloudsyncs3.h libcloudsyncs3-mem-types.h AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) -lcurl -lcrypto -I$(top_srcdir)/xlators/features/cloudsync/src CLEANFILES = EXTRA_DIST = libcloudsyncs3.sym glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/PaxHeaders.9031/0000644000000000000000000000013214522202451031777 xustar000000000000000030 mtime=1699284265.665027426 30 atime=1699284265.665027426 30 ctime=1699284305.623147778 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3.h0000664000175100017510000000224714522202451035372 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _LIBAWS_H #define _LIBAWS_H #include #include "cloudsync-common.h" #include "libcloudsyncs3-mem-types.h" char * aws_b64_encode(const unsigned char *input, int length); size_t aws_write_callback(void *dlbuf, size_t size, size_t nitems, void *mainframe); int aws_download_s3(call_frame_t *frame, void *config); int aws_dlwritev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); void * aws_init(xlator_t *this); int aws_reconfigure(xlator_t *this, dict_t *options); char * aws_form_request(char *resource, char **date, char *reqtype, char *bucketid, char *filepath); char * aws_sign_request(char *const str, char *awssekey); void aws_fini(void *config); #endif glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/PaxHeaders.9031/Make0000644000000000000000000000013214522202463032011 xustar000000000000000030 mtime=1699284275.825058028 30 atime=1699284291.274104561 30 ctime=1699284305.579147646 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/Makefile.in0000664000175100017510000005311714522202463033544 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/PaxHeaders.9031/Make0000644000000000000000000000013214522202451032006 xustar000000000000000030 mtime=1699284265.664027423 30 atime=1699284275.801057956 30 ctime=1699284305.580147649 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/Makefile.am0000664000175100017510000000003414522202451033516 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463030216 xustar000000000000000030 mtime=1699284275.755057817 30 atime=1699284291.232104434 30 ctime=1699284305.508147432 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/Makefile.in0000664000175100017510000005303714522202463030505 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/cloudsync/src/cloudsync-plugins DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/cloudsync/src/cloudsync-plugins/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451030202 xustar000000000000000030 mtime=1699284265.664027423 30 atime=1699284275.731057745 30 ctime=1699284305.510147438 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-plugins/Makefile.am0000664000175100017510000000003414522202451030456 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync-messages.h0000644000000000000000000000013214522202451026445 xustar000000000000000030 mtime=1699284265.664027423 30 atime=1699284265.664027423 30 ctime=1699284305.466147306 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-messages.h0000664000175100017510000000101714522202451026723 0ustar00jenkinsjenkins00000000000000/* * Copyright (c) 2018 Red Hat, Inc. * This file is part of GlusterFS. * * This file is licensed to you under your choice of the GNU Lesser * General Public License, version 3 or any later version (LGPLv3 or * later), or the GNU General Public License, version 2 (GPLv2), in all * cases as published by the Free Software Foundation. */ #ifndef __CLOUDSYNC_MESSAGES_H__ #define __CLOUDSYNC_MESSAGES_H__ /*TODO: define relevant message ids */ #endif /* __CLOUDSYNC_MESSAGES_H__ */ glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync-autogen-fops-tmpl.c0000644000000000000000000000013014522202451030210 xustar000000000000000029 mtime=1699284265.66302742 29 atime=1699284265.66302742 30 ctime=1699284305.472147324 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-autogen-fops-tmpl.c0000664000175100017510000000150414522202451030471 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ /* File: cloudsync-autogen-fops-tmpl.c * This file contains the CLOUDSYNC autogenerated FOPs. This is run through * the code generator, generator.py to generate the required FOPs. */ #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include #include #include #include #include "cloudsync.h" #include "cloudsync-common.h" #include #pragma generate glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync-autogen-fops-tmpl.h0000644000000000000000000000013014522202451030215 xustar000000000000000029 mtime=1699284265.66302742 29 atime=1699284265.66302742 30 ctime=1699284305.473147327 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-autogen-fops-tmpl.h0000664000175100017510000000126014522202451030475 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ /* File: clousync-autogen-fops-tmpl.h * This file contains the cloudsync autogenerated FOPs declarations. */ #ifndef _CLOUDSYNC_AUTOGEN_FOPS_H #define _CLOUDSYNC_AUTOGEN_FOPS_H #include #include "cloudsync.h" #include "cloudsync-common.h" #pragma generate #endif /* _CLOUDSYNC_AUTOGEN_FOPS_H */ glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync-common.h0000644000000000000000000000013014522202451026124 xustar000000000000000029 mtime=1699284265.66302742 29 atime=1699284265.66302742 30 ctime=1699284305.468147312 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-common.h0000664000175100017510000001111314522202451026402 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CLOUDSYNC_COMMON_H #define _CLOUDSYNC_COMMON_H #include #include #include #include "cloudsync-mem-types.h" #include "cloudsync-messages.h" typedef struct cs_loc_xattr { char *file_path; uuid_t uuid; uuid_t gfid; char *volname; } cs_loc_xattr_t; typedef struct cs_size_xattr { uint64_t size; uint64_t blksize; uint64_t blocks; } cs_size_xattr_t; typedef struct cs_local { loc_t loc; fd_t *fd; call_stub_t *stub; call_frame_t *main_frame; int op_errno; int op_ret; fd_t *dlfd; off_t dloffset; struct iatt stbuf; dict_t *xattr_rsp; dict_t *xattr_req; glusterfs_fop_t fop; gf_boolean_t locked; int call_cnt; inode_t *inode; char *remotepath; struct { /* offset, flags and size are the information needed * by read fop for remote read operation. These will be * populated in cloudsync read fop, before being passed * on to the plugin performing remote read. */ off_t offset; uint32_t flags; size_t size; cs_loc_xattr_t *lxattr; } xattrinfo; } cs_local_t; typedef int (*fop_download_t)(call_frame_t *frame, void *config); typedef int (*fop_remote_read_t)(call_frame_t *, void *); typedef void *(*store_init)(xlator_t *this); typedef int (*store_reconfigure)(xlator_t *this, dict_t *options); typedef void (*store_fini)(void *config); struct cs_remote_stores { char *name; /* store name */ void *config; /* store related information */ fop_download_t dlfop; /* store specific download function */ fop_remote_read_t rdfop; /* store specific read function */ store_init init; /* store init to initialize store config */ store_reconfigure reconfigure; /* reconfigure store config */ store_fini fini; void *handle; /* shared library handle*/ }; typedef struct cs_private { xlator_t *this; struct cs_remote_stores *stores; gf_boolean_t abortdl; pthread_spinlock_t lock; gf_boolean_t remote_read; } cs_private_t; void cs_local_wipe(xlator_t *this, cs_local_t *local); void cs_xattrinfo_wipe(cs_local_t *local); #define CS_STACK_UNWIND(fop, frame, params...) \ do { \ cs_local_t *__local = NULL; \ xlator_t *__xl = NULL; \ if (frame) { \ __xl = frame->this; \ __local = frame->local; \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ cs_local_wipe(__xl, __local); \ } while (0) #define CS_STACK_DESTROY(frame) \ do { \ cs_local_t *__local = NULL; \ xlator_t *__xl = NULL; \ __xl = frame->this; \ __local = frame->local; \ frame->local = NULL; \ STACK_DESTROY(frame->root); \ cs_local_wipe(__xl, __local); \ } while (0) typedef struct store_methods { int (*fop_download)(call_frame_t *frame, void *config); int (*fop_remote_read)(call_frame_t *, void *); /* return type should be the store config */ void *(*fop_init)(xlator_t *this); int (*fop_reconfigure)(xlator_t *this, dict_t *options); void (*fop_fini)(void *config); } store_methods_t; #endif /* _CLOUDSYNC_COMMON_H */ glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync-mem-types.h0000644000000000000000000000013114522202451026555 xustar000000000000000030 mtime=1699284265.664027423 29 atime=1699284265.66302742 30 ctime=1699284305.465147302 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-mem-types.h0000664000175100017510000000127614522202451027043 0ustar00jenkinsjenkins00000000000000/* * Copyright (c) 2018 Red Hat, Inc. * This file is part of GlusterFS. * * This file is licensed to you under your choice of the GNU Lesser * General Public License, version 3 or any later version (LGPLv3 or * later), or the GNU General Public License, version 2 (GPLv2), in all * cases as published by the Free Software Foundation. */ #ifndef __CLOUDSYNC_MEM_TYPES_H__ #define __CLOUDSYNC_MEM_TYPES_H__ #include enum cs_mem_types_ { gf_cs_mt_cs_private_t = gf_common_mt_end + 1, gf_cs_mt_cs_remote_stores_t, gf_cs_mt_cs_inode_ctx_t, gf_cs_mt_cs_lxattr_t, gf_cs_mt_end }; #endif /* __CLOUDSYNC_MEM_TYPES_H__ */ glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync.c0000644000000000000000000000013214522202451024633 xustar000000000000000030 mtime=1699284265.666027429 30 atime=1699284265.666027429 30 ctime=1699284305.469147315 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync.c0000664000175100017510000014543614522202451025127 0ustar00jenkinsjenkins00000000000000/* * Copyright (c) 2018 Red Hat, Inc. * This file is part of GlusterFS. * * This file is licensed to you under your choice of the GNU Lesser * General Public License, version 3 or any later version (LGPLv3 or * later), or the GNU General Public License, version 2 (GPLv2), in all * cases as published by the Free Software Foundation. */ #include "cloudsync.h" #include "cloudsync-common.h" #include #include "cloudsync-autogen-fops.h" #include #include static void cs_cleanup_private(cs_private_t *priv) { if (priv) { if (priv->stores) { priv->stores->fini(priv->stores->config); GF_FREE(priv->stores); } pthread_spin_destroy(&priv->lock); GF_FREE(priv); } return; } static struct cs_plugin plugins[] = { {.name = "cloudsyncs3", .library = "cloudsyncs3.so", .description = "cloudsync s3 store."}, #if defined(__linux__) {.name = "cvlt", .library = "cloudsynccvlt.so", .description = "Commvault content store."}, #endif {.name = NULL}, }; int cs_init(xlator_t *this) { cs_private_t *priv = NULL; gf_boolean_t per_vol = _gf_false; int ret = 0; char *libpath = NULL; store_methods_t *store_methods = NULL; void *handle = NULL; char *temp_str = NULL; int index = 0; char *libname = NULL; priv = GF_CALLOC(1, sizeof(*priv), gf_cs_mt_cs_private_t); if (!priv) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insufficient memory"); goto out; } priv->this = this; this->local_pool = mem_pool_new(cs_local_t, 512); if (!this->local_pool) { gf_msg(this->name, GF_LOG_ERROR, 0, ENOMEM, "initialisation failed."); ret = -1; goto out; } this->private = priv; GF_OPTION_INIT("cloudsync-remote-read", priv->remote_read, bool, out); /* temp workaround. Should be configurable through glusterd*/ per_vol = _gf_true; if (per_vol) { if (dict_get_str_sizen(this->options, "cloudsync-storetype", &temp_str) == 0) { for (index = 0; plugins[index].name; index++) { if (!strcmp(temp_str, plugins[index].name)) { libname = plugins[index].library; break; } } } else { ret = 0; } if (!libname) { gf_msg(this->name, GF_LOG_WARNING, 0, 0, "no plugin enabled"); ret = 0; goto out; } ret = gf_asprintf(&libpath, "%s/%s", CS_PLUGINDIR, libname); if (ret == -1) { goto out; } handle = dlopen(libpath, RTLD_NOW); if (!handle) { gf_msg(this->name, GF_LOG_WARNING, 0, 0, "could not " "load the required library. %s", dlerror()); ret = 0; goto out; } else { gf_msg(this->name, GF_LOG_INFO, 0, 0, "loading library:%s successful", libname); } priv->stores = GF_CALLOC(1, sizeof(struct cs_remote_stores), gf_cs_mt_cs_remote_stores_t); if (!priv->stores) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "Could not " "allocate memory for priv->stores"); ret = -1; goto out; } (void)dlerror(); /* clear out previous error string */ /* load library methods */ store_methods = (store_methods_t *)dlsym(handle, "store_ops"); if (!store_methods) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "null store_methods %s", dlerror()); ret = -1; goto out; } (void)dlerror(); if (priv->remote_read) { priv->stores->rdfop = store_methods->fop_remote_read; if (!priv->stores->rdfop) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "failed to get" " read fop %s", dlerror()); ret = -1; goto out; } } priv->stores->dlfop = store_methods->fop_download; if (!priv->stores->dlfop) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "failed to get" " download fop %s", dlerror()); ret = -1; goto out; } (void)dlerror(); priv->stores->init = store_methods->fop_init; if (!priv->stores->init) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "failed to get" " init fop %s", dlerror()); ret = -1; goto out; } (void)dlerror(); priv->stores->reconfigure = store_methods->fop_reconfigure; if (!priv->stores->reconfigure) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "failed to get" " reconfigure fop %s", dlerror()); ret = -1; goto out; } priv->stores->handle = handle; priv->stores->config = (void *)((priv->stores->init)(this)); if (!priv->stores->config) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "null config"); ret = -1; goto out; } } ret = 0; out: if (ret == -1) { if (this->local_pool) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; } cs_cleanup_private(priv); if (handle) { dlclose(handle); } } GF_FREE(libpath); return ret; } int cs_forget(xlator_t *this, inode_t *inode) { uint64_t ctx_int = 0; cs_inode_ctx_t *ctx = NULL; inode_ctx_del(inode, this, &ctx_int); if (!ctx_int) return 0; ctx = (cs_inode_ctx_t *)(uintptr_t)ctx_int; GF_FREE(ctx); return 0; } void cs_fini(xlator_t *this) { cs_private_t *priv = NULL; priv = this->private; cs_cleanup_private(priv); } int cs_reconfigure(xlator_t *this, dict_t *options) { cs_private_t *priv = NULL; int ret = 0; priv = this->private; if (!priv) { ret = -1; goto out; } GF_OPTION_RECONF("cloudsync-remote-read", priv->remote_read, options, bool, out); /* needed only for per volume configuration*/ ret = priv->stores->reconfigure(this, options); out: return ret; } int32_t cs_mem_acct_init(xlator_t *this) { int ret = -1; GF_VALIDATE_OR_GOTO("cloudsync", this, out); ret = xlator_mem_acct_init(this, gf_cs_mt_end); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "Memory accounting init failed"); return ret; } out: return ret; } int32_t cs_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { int ret = 0; int op_errno = ENOMEM; if (!xdata) { xdata = dict_new(); if (!xdata) { gf_msg(this->name, GF_LOG_ERROR, 0, ENOMEM, "failed to create " "dict"); goto err; } } ret = dict_set_uint32(xdata, GF_CS_OBJECT_STATUS, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:" " %s", GF_CS_OBJECT_STATUS); goto err; } STACK_WIND(frame, default_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata); return 0; err: STACK_UNWIND_STRICT(readdirp, frame, -1, op_errno, NULL, NULL); return 0; } int32_t cs_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { cs_local_t *local = NULL; int ret = 0; uint64_t val = 0; local = frame->local; local->call_cnt++; if (op_ret == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "truncate failed"); ret = dict_get_uint64(xdata, GF_CS_OBJECT_STATUS, &val); if (ret == 0) { if (val == GF_CS_ERROR) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "could not get file state, unwinding"); op_ret = -1; op_errno = EIO; goto unwind; } else { __cs_inode_ctx_update(this, local->loc.inode, val); gf_msg(this->name, GF_LOG_INFO, 0, 0, " state = %" PRIu64, val); if (local->call_cnt == 1 && (val == GF_CS_REMOTE || val == GF_CS_DOWNLOADING)) { gf_msg(this->name, GF_LOG_WARNING, 0, 0, "will repair and download " "the file, current state : %" PRIu64, val); goto repair; } else { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "second truncate, Unwinding"); goto unwind; } } } else { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "file state " "could not be figured, unwinding"); goto unwind; } } else { /* successful write => file is local */ __cs_inode_ctx_update(this, local->loc.inode, GF_CS_LOCAL); gf_msg(this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL" ", truncate successful"); goto unwind; } repair: ret = locate_and_execute(frame); if (ret) { goto unwind; } return 0; unwind: CS_STACK_UNWIND(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t cs_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { cs_local_t *local = NULL; int ret = 0; cs_inode_ctx_t *ctx = NULL; gf_cs_obj_state state = -1; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); local = cs_local_init(this, frame, loc, NULL, GF_FOP_TRUNCATE); if (!local) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "local init failed"); goto err; } __cs_inode_ctx_get(this, loc->inode, &ctx); if (ctx) state = __cs_get_file_state(loc->inode, ctx); else state = GF_CS_LOCAL; local->xattr_req = xdata ? dict_ref(xdata) : (xdata = dict_new()); ret = dict_set_uint32(local->xattr_req, GF_CS_OBJECT_STATUS, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:" " %s", GF_CS_OBJECT_STATUS); goto err; } local->stub = fop_truncate_stub(frame, cs_resume_truncate, loc, offset, xdata); if (!local->stub) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insufficient memory"); goto err; } if (state == GF_CS_LOCAL) { STACK_WIND(frame, cs_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); } else { local->call_cnt++; ret = locate_and_execute(frame); if (ret) { goto err; } } return 0; err: CS_STACK_UNWIND(truncate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } int32_t cs_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata) { STACK_UNWIND_STRICT(statfs, frame, op_ret, op_errno, buf, xdata); return 0; } int32_t cs_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { STACK_WIND(frame, cs_statfs_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, loc, xdata); return 0; } int32_t cs_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } int32_t cs_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xattr_req) { STACK_WIND(frame, cs_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xattr_req); return 0; } int32_t cs_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { cs_local_t *local = NULL; local = frame->local; if (local->locked) cs_inodelk_unlock(frame); CS_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); return 0; } int32_t cs_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { data_t *tmp = NULL; cs_local_t *local = NULL; int ret = 0; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); local = cs_local_init(this, frame, loc, NULL, GF_FOP_SETXATTR); if (!local) { ret = -1; goto err; } local->xattr_req = xdata ? dict_ref(xdata) : (xdata = dict_new()); tmp = dict_get_sizen(dict, GF_CS_OBJECT_UPLOAD_COMPLETE); if (tmp) { /* Value of key should be the atime */ local->stub = fop_setxattr_stub(frame, cs_resume_setxattr, loc, dict, flags, xdata); if (!local->stub) goto err; ret = locate_and_execute(frame); if (ret) { goto err; } return 0; } STACK_WIND(frame, cs_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; err: CS_STACK_UNWIND(setxattr, frame, -1, errno, NULL); return 0; } int32_t cs_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, xdata); return 0; } int32_t cs_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { STACK_WIND(frame, cs_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); return 0; } int32_t cs_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); return 0; } int32_t cs_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { STACK_WIND(frame, cs_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; } int32_t cs_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int32_t cs_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, dict_t *xattr_req) { cs_local_t *local = NULL; int ret = 0; local = cs_local_init(this, frame, loc, NULL, GF_FOP_UNLINK); if (!local) goto err; local->xattr_req = xattr_req ? dict_ref(xattr_req) : dict_new(); ret = dict_set_uint32(local->xattr_req, GF_CS_OBJECT_STATUS, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:" " %s", GF_CS_OBJECT_STATUS); goto err; } STACK_WIND(frame, cs_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, flags, local->xattr_req); return 0; err: CS_STACK_UNWIND(unlink, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t cs_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { int ret = 0; uint64_t val = 0; if (op_ret == 0) { ret = dict_get_uint64(xdata, GF_CS_OBJECT_STATUS, &val); if (!ret) { ret = __cs_inode_ctx_update(this, fd->inode, val); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "ctx update failed"); } } } else { cs_inode_ctx_reset(this, fd->inode); } CS_STACK_UNWIND(open, frame, op_ret, op_errno, fd, xdata); return 0; } int32_t cs_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xattr_req) { cs_local_t *local = NULL; int ret = 0; local = cs_local_init(this, frame, NULL, fd, GF_FOP_OPEN); if (!local) goto err; local->xattr_req = xattr_req ? dict_ref(xattr_req) : dict_new(); ret = dict_set_uint32(local->xattr_req, GF_CS_OBJECT_STATUS, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:" " %s", GF_CS_OBJECT_STATUS); goto err; } STACK_WIND(frame, cs_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, local->xattr_req); return 0; err: CS_STACK_UNWIND(open, frame, -1, errno, NULL, NULL); return 0; } int32_t cs_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { int ret = 0; uint64_t val = 0; fd_t *fd = NULL; cs_local_t *local = NULL; local = frame->local; fd = local->fd; if (op_ret == 0) { ret = dict_get_uint64(xdata, GF_CS_OBJECT_STATUS, &val); if (!ret) { gf_msg_debug(this->name, 0, "state %" PRIu64, val); ret = __cs_inode_ctx_update(this, fd->inode, val); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "ctx update failed"); } } } else { cs_inode_ctx_reset(this, fd->inode); } CS_STACK_UNWIND(fstat, frame, op_ret, op_errno, buf, xdata); return 0; } int32_t cs_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xattr_req) { cs_local_t *local = NULL; int ret = 0; local = cs_local_init(this, frame, NULL, fd, GF_FOP_FSTAT); if (!local) goto err; if (fd->inode->ia_type == IA_IFDIR) goto wind; local->xattr_req = xattr_req ? dict_ref(xattr_req) : dict_new(); ret = dict_set_uint32(local->xattr_req, GF_CS_OBJECT_STATUS, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:" " %s", GF_CS_OBJECT_STATUS); goto err; } wind: STACK_WIND(frame, cs_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, local->xattr_req); return 0; err: CS_STACK_UNWIND(fstat, frame, -1, errno, NULL, NULL); return 0; } cs_local_t * cs_local_init(xlator_t *this, call_frame_t *frame, loc_t *loc, fd_t *fd, glusterfs_fop_t fop) { cs_local_t *local = NULL; int ret = 0; local = mem_get0(this->local_pool); if (!local) goto out; if (loc) { ret = loc_copy(&local->loc, loc); if (ret) goto out; } if (fd) { local->fd = fd_ref(fd); } local->op_ret = -1; local->op_errno = EUCLEAN; local->fop = fop; local->dloffset = 0; frame->local = local; local->locked = _gf_false; local->call_cnt = 0; out: if (ret) { if (local) mem_put(local); local = NULL; } return local; } call_frame_t * cs_lock_frame(call_frame_t *parent_frame) { call_frame_t *lock_frame = NULL; lock_frame = copy_frame(parent_frame); if (lock_frame == NULL) goto out; set_lk_owner_from_ptr(&lock_frame->root->lk_owner, parent_frame->root); out: return lock_frame; } void cs_lock_wipe(call_frame_t *lock_frame) { CS_STACK_DESTROY(lock_frame); } int32_t cs_inodelk_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { cs_lock_wipe(frame); return 0; } int cs_inodelk_unlock(call_frame_t *main_frame) { xlator_t *this = NULL; struct gf_flock flock = { 0, }; call_frame_t *lock_frame = NULL; cs_local_t *lock_local = NULL; cs_local_t *main_local = NULL; int ret = 0; this = main_frame->this; main_local = main_frame->local; lock_frame = cs_lock_frame(main_frame); if (!lock_frame) goto out; lock_local = cs_local_init(this, lock_frame, NULL, NULL, 0); if (!lock_local) goto out; ret = cs_build_loc(&lock_local->loc, main_frame); if (ret) { goto out; } flock.l_type = F_UNLCK; main_local->locked = _gf_false; STACK_WIND(lock_frame, cs_inodelk_unlock_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, CS_LOCK_DOMAIN, &lock_local->loc, F_SETLKW, &flock, NULL); return 0; out: gf_msg(this->name, GF_LOG_ERROR, 0, 0, "Stale lock would be found on" " server"); if (lock_frame) cs_lock_wipe(lock_frame); return 0; } int cs_download_task(void *arg) { call_frame_t *frame = NULL; xlator_t *this = NULL; cs_private_t *priv = NULL; int ret = -1; char *sign_req = NULL; fd_t *fd = NULL; cs_local_t *local = NULL; dict_t *dict = NULL; frame = (call_frame_t *)arg; this = frame->this; priv = this->private; if (!priv->stores) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "No remote store " "plugins found"); ret = -1; goto out; } local = frame->local; if (local->fd) fd = fd_anonymous(local->fd->inode); else fd = fd_anonymous(local->loc.inode); if (!fd) { gf_msg("CS", GF_LOG_ERROR, 0, 0, "fd creation failed"); ret = -1; goto out; } local->dlfd = fd; local->dloffset = 0; dict = dict_new(); if (!dict) { gf_msg(this->name, GF_LOG_ERROR, 0, ENOMEM, "failed to create " "dict"); ret = -1; goto out; } ret = dict_set_uint32(dict, GF_CS_OBJECT_DOWNLOADING, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "dict_set failed"); ret = -1; goto out; } ret = syncop_fsetxattr(this, local->fd, dict, 0, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "fsetxattr failed " "key %s", GF_CS_OBJECT_DOWNLOADING); ret = -1; goto out; } /*this calling method is for per volume setting */ ret = priv->stores->dlfop(frame, priv->stores->config); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "download failed" ", remotepath: %s", local->remotepath); /*using dlfd as it is anonymous and have RDWR flag*/ ret = syncop_ftruncate(FIRST_CHILD(this), local->dlfd, 0, NULL, NULL, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, -ret, "ftruncate failed"); } else { gf_msg_debug(this->name, 0, "ftruncate succeed"); } ret = -1; goto out; } else { gf_msg(this->name, GF_LOG_INFO, 0, 0, "download success, path" " : %s", local->remotepath); ret = syncop_fremovexattr(this, local->fd, GF_CS_OBJECT_REMOTE, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, -ret, "removexattr failed, remotexattr"); ret = -1; goto out; } else { gf_msg_debug(this->name, 0, "fremovexattr success, " "path : %s", local->remotepath); } ret = syncop_fremovexattr(this, local->fd, GF_CS_OBJECT_DOWNLOADING, NULL, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, -ret, "removexattr failed, downloading xattr, path %s", local->remotepath); ret = -1; goto out; } else { gf_msg_debug(this->name, 0, "fremovexattr success" " path %s", local->remotepath); } } out: GF_FREE(sign_req); if (dict) dict_unref(dict); if (fd) { fd_unref(fd); local->dlfd = NULL; } return ret; } int cs_download(call_frame_t *frame) { int ret = 0; cs_local_t *local = NULL; xlator_t *this = NULL; local = frame->local; this = frame->this; if (!local->remotepath) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, 0, "remote path not" " available. Check posix logs to resolve"); goto out; } ret = cs_download_task((void *)frame); out: return ret; } int cs_set_xattr_req(call_frame_t *frame) { cs_local_t *local = NULL; GF_UNUSED int ret = 0; local = frame->local; /* When remote reads are performed (i.e. reads on remote store), * there needs to be a way to associate a file on gluster volume * with its correspnding file on the remote store. In order to do * that, a unique key can be maintained as an xattr * (GF_CS_XATTR_ARCHIVE_UUID)on the stub file on gluster bricks. * This xattr should be provided to the plugin to * perform the read fop on the correct file. This assumes that the file * hierarchy and name need not be the same on remote store as that of * the gluster volume. */ ret = dict_set_sizen_str_sizen(local->xattr_req, GF_CS_XATTR_ARCHIVE_UUID, "1"); return 0; } int cs_update_xattrs(call_frame_t *frame, dict_t *xdata) { cs_local_t *local = NULL; xlator_t *this = NULL; int size = -1; GF_UNUSED int ret = 0; local = frame->local; this = frame->this; local->xattrinfo.lxattr = GF_CALLOC(1, sizeof(cs_loc_xattr_t), gf_cs_mt_cs_lxattr_t); if (!local->xattrinfo.lxattr) { local->op_ret = -1; local->op_errno = ENOMEM; goto err; } gf_uuid_copy(local->xattrinfo.lxattr->gfid, local->loc.gfid); if (local->remotepath) { local->xattrinfo.lxattr->file_path = gf_strdup(local->remotepath); if (!local->xattrinfo.lxattr->file_path) { local->op_ret = -1; local->op_errno = ENOMEM; goto err; } } ret = dict_get_gfuuid(xdata, GF_CS_XATTR_ARCHIVE_UUID, &(local->xattrinfo.lxattr->uuid)); if (ret) { gf_uuid_clear(local->xattrinfo.lxattr->uuid); } size = strlen(this->name) - strlen("-cloudsync") + 1; local->xattrinfo.lxattr->volname = GF_CALLOC(1, size, gf_common_mt_char); if (!local->xattrinfo.lxattr->volname) { local->op_ret = -1; local->op_errno = ENOMEM; goto err; } strncpy(local->xattrinfo.lxattr->volname, this->name, size - 1); local->xattrinfo.lxattr->volname[size - 1] = '\0'; return 0; err: cs_xattrinfo_wipe(local); return -1; } int cs_serve_readv(call_frame_t *frame, off_t offset, size_t size, uint32_t flags) { xlator_t *this = NULL; cs_private_t *priv = NULL; int ret = -1; fd_t *fd = NULL; cs_local_t *local = NULL; local = frame->local; this = frame->this; priv = this->private; if (!local->remotepath) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, 0, "remote path not" " available. Check posix logs to resolve"); goto out; } if (!priv->stores) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "No remote store " "plugins found"); ret = -1; goto out; } if (local->fd) { fd = fd_anonymous(local->fd->inode); } else { fd = fd_anonymous(local->loc.inode); } local->xattrinfo.size = size; local->xattrinfo.offset = offset; local->xattrinfo.flags = flags; if (!fd) { gf_msg("CS", GF_LOG_ERROR, 0, 0, "fd creation failed"); ret = -1; goto out; } local->dlfd = fd; local->dloffset = offset; /*this calling method is for per volume setting */ ret = priv->stores->rdfop(frame, priv->stores->config); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "read failed" ", remotepath: %s", local->remotepath); ret = -1; goto out; } else { gf_msg(this->name, GF_LOG_INFO, 0, 0, "read success, path" " : %s", local->remotepath); } out: if (fd) { fd_unref(fd); local->dlfd = NULL; } return ret; } int32_t cs_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { cs_local_t *local = NULL; int ret = 0; uint64_t val = 0; fd_t *fd = NULL; local = frame->local; fd = local->fd; local->call_cnt++; if (op_ret == -1) { ret = dict_get_uint64(xdata, GF_CS_OBJECT_STATUS, &val); if (ret == 0) { if (val == GF_CS_ERROR) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "could not get file state, unwinding"); op_ret = -1; op_errno = EIO; goto unwind; } else { __cs_inode_ctx_update(this, fd->inode, val); gf_msg(this->name, GF_LOG_INFO, 0, 0, " state = %" PRIu64, val); if (local->call_cnt == 1 && (val == GF_CS_REMOTE || val == GF_CS_DOWNLOADING)) { gf_msg(this->name, GF_LOG_INFO, 0, 0, " will read from remote : %" PRIu64, val); goto repair; } else { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "second readv, Unwinding"); goto unwind; } } } else { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "file state " "could not be figured, unwinding"); goto unwind; } } else { /* successful readv => file is local */ __cs_inode_ctx_update(this, fd->inode, GF_CS_LOCAL); gf_msg(this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL" ", readv successful"); goto unwind; } repair: ret = locate_and_execute(frame); if (ret) { goto unwind; } return 0; unwind: CS_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, stbuf, iobref, xdata); return 0; } int32_t cs_resume_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { int ret = 0; ret = cs_resume_postprocess(this, frame, fd->inode); if (ret) { goto unwind; } cs_inodelk_unlock(frame); STACK_WIND(frame, cs_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; unwind: cs_inodelk_unlock(frame); cs_common_cbk(frame); return 0; } int32_t cs_resume_remote_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { int ret = 0; cs_local_t *local = NULL; gf_cs_obj_state state = -1; cs_inode_ctx_t *ctx = NULL; cs_inodelk_unlock(frame); local = frame->local; if (!local) { ret = -1; goto unwind; } __cs_inode_ctx_get(this, fd->inode, &ctx); state = __cs_get_file_state(fd->inode, ctx); if (state == GF_CS_ERROR) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "status is GF_CS_ERROR." " Aborting readv"); local->op_ret = -1; local->op_errno = EREMOTE; ret = -1; goto unwind; } /* Serve readv from remote store only if it is remote. */ gf_msg_debug(this->name, 0, "status of file %s is %d", local->remotepath ? local->remotepath : "", state); /* We will reach this condition if local inode ctx had REMOTE * state when the control was in cs_readv but after stat * we got an updated state saying that the file is LOCAL. */ if (state == GF_CS_LOCAL) { STACK_WIND(frame, cs_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); } else if (state == GF_CS_REMOTE) { ret = cs_resume_remote_readv_postprocess(this, frame, fd->inode, offset, size, flags); /* Failed to submit the remote readv fop to plugin */ if (ret) { local->op_ret = -1; local->op_errno = EREMOTE; goto unwind; } /* When the file is in any other intermediate state, * we should not perform remote reads. */ } else { local->op_ret = -1; local->op_errno = EINVAL; goto unwind; } return 0; unwind: cs_common_cbk(frame); return 0; } int32_t cs_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { int op_errno = ENOMEM; cs_local_t *local = NULL; int ret = 0; cs_inode_ctx_t *ctx = NULL; gf_cs_obj_state state = -1; cs_private_t *priv = NULL; VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); priv = this->private; local = cs_local_init(this, frame, NULL, fd, GF_FOP_READ); if (!local) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "local init failed"); goto err; } __cs_inode_ctx_get(this, fd->inode, &ctx); if (ctx) state = __cs_get_file_state(fd->inode, ctx); else state = GF_CS_LOCAL; local->xattr_req = xdata ? dict_ref(xdata) : (xdata = dict_new()); ret = dict_set_uint32(local->xattr_req, GF_CS_OBJECT_STATUS, 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:" " %s", GF_CS_OBJECT_STATUS); goto err; } if (priv->remote_read) { local->stub = fop_readv_stub(frame, cs_resume_remote_readv, fd, size, offset, flags, xdata); } else { local->stub = fop_readv_stub(frame, cs_resume_readv, fd, size, offset, flags, xdata); } if (!local->stub) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insufficient memory"); goto err; } if (state == GF_CS_LOCAL) { STACK_WIND(frame, cs_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); } else { local->call_cnt++; ret = locate_and_execute(frame); if (ret) { goto err; } } return 0; err: CS_STACK_UNWIND(readv, frame, -1, op_errno, NULL, -1, NULL, NULL, NULL); return 0; } int cs_resume_remote_readv_postprocess(xlator_t *this, call_frame_t *frame, inode_t *inode, off_t offset, size_t size, uint32_t flags) { int ret = 0; ret = cs_serve_readv(frame, offset, size, flags); return ret; } int cs_stat_check_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *stbuf, dict_t *xdata) { cs_local_t *local = NULL; call_stub_t *stub = NULL; char *filepath = NULL; int ret = 0; inode_t *inode = NULL; uint64_t val = 0; local = frame->local; if (op_ret == -1) { local->op_ret = op_ret; local->op_errno = op_errno; gf_msg(this->name, GF_LOG_ERROR, 0, op_errno, "stat check failed"); goto err; } else { if (local->fd) inode = local->fd->inode; else inode = local->loc.inode; if (!inode) { local->op_ret = -1; local->op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, 0, 0, "null inode " "returned"); goto err; } ret = dict_get_uint64(xdata, GF_CS_OBJECT_STATUS, &val); if (ret == 0) { if (val == GF_CS_ERROR) { cs_inode_ctx_reset(this, inode); local->op_ret = -1; local->op_errno = EIO; gf_msg(this->name, GF_LOG_ERROR, 0, 0, "status = GF_CS_ERROR. failed to get " " file state"); goto err; } else { ret = __cs_inode_ctx_update(this, inode, val); gf_msg_debug(this->name, 0, "status : %" PRIu64, val); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "ctx update failed"); local->op_ret = -1; local->op_errno = ENOMEM; goto err; } } } else { gf_msg_debug(this->name, 0, "status not found in dict"); local->op_ret = -1; local->op_errno = ENOMEM; goto err; } ret = dict_get_str_sizen(xdata, GF_CS_OBJECT_REMOTE, &filepath); if (filepath) { gf_msg_debug(this->name, 0, "filepath returned %s", filepath); local->remotepath = gf_strdup(filepath); if (!local->remotepath) { local->op_ret = -1; local->op_errno = ENOMEM; goto err; } } else { gf_msg_debug(this->name, 0, "NULL filepath"); } ret = cs_update_xattrs(frame, xdata); if (ret) goto err; local->op_ret = 0; local->xattr_rsp = dict_ref(xdata); memcpy(&local->stbuf, stbuf, sizeof(struct iatt)); } stub = local->stub; local->stub = NULL; call_resume(stub); return 0; err: cs_inodelk_unlock(frame); cs_common_cbk(frame); return 0; } int cs_do_stat_check(call_frame_t *main_frame) { cs_local_t *local = NULL; xlator_t *this = NULL; int ret = 0; local = main_frame->local; this = main_frame->this; ret = dict_set_uint32(local->xattr_req, GF_CS_OBJECT_REPAIR, 256); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "dict_set failed"); goto err; } cs_set_xattr_req(main_frame); if (local->fd) { STACK_WIND(main_frame, cs_stat_check_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, local->fd, local->xattr_req); } else { STACK_WIND(main_frame, cs_stat_check_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, &local->loc, local->xattr_req); } return 0; err: cs_inodelk_unlock(main_frame); cs_common_cbk(main_frame); return 0; } void cs_common_cbk(call_frame_t *frame) { glusterfs_fop_t fop = -1; cs_local_t *local = NULL; local = frame->local; fop = local->fop; /*Note: Only the failure case needs to be handled here. Since for * successful stat check the fop will resume anyway. The unwind can * happen from the fop_cbk and each cbk can unlock the inodelk in case * a lock was taken before. The lock status can be stored in frame */ /* for failure case */ /*TODO: add other fops*/ switch (fop) { case GF_FOP_WRITE: CS_STACK_UNWIND(writev, frame, local->op_ret, local->op_errno, NULL, NULL, NULL); break; case GF_FOP_SETXATTR: CS_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, NULL); break; case GF_FOP_READ: CS_STACK_UNWIND(readv, frame, local->op_ret, local->op_errno, NULL, 0, NULL, NULL, NULL); break; case GF_FOP_FTRUNCATE: CS_STACK_UNWIND(ftruncate, frame, local->op_ret, local->op_errno, NULL, NULL, NULL); break; case GF_FOP_TRUNCATE: CS_STACK_UNWIND(truncate, frame, local->op_ret, local->op_errno, NULL, NULL, NULL); break; default: break; } return; } int cs_blocking_inodelk_cbk(call_frame_t *lock_frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { cs_local_t *main_local = NULL; call_frame_t *main_frame = NULL; cs_local_t *lock_local = NULL; lock_local = lock_frame->local; main_frame = lock_local->main_frame; main_local = main_frame->local; if (op_ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "inodelk failed"); main_local->op_errno = op_errno; main_local->op_ret = op_ret; goto err; } main_local->locked = _gf_true; cs_lock_wipe(lock_frame); cs_do_stat_check(main_frame); return 0; err: cs_common_cbk(main_frame); cs_lock_wipe(lock_frame); return 0; } int cs_build_loc(loc_t *loc, call_frame_t *frame) { cs_local_t *local = NULL; int ret = -1; local = frame->local; if (local->fd) { loc->inode = inode_ref(local->fd->inode); if (loc->inode) { gf_uuid_copy(loc->gfid, loc->inode->gfid); ret = 0; goto out; } else { ret = -1; goto out; } } else { loc->inode = inode_ref(local->loc.inode); if (loc->inode) { gf_uuid_copy(loc->gfid, loc->inode->gfid); ret = 0; goto out; } else { ret = -1; goto out; } } out: return ret; } int cs_blocking_inodelk(call_frame_t *parent_frame) { call_frame_t *lock_frame = NULL; cs_local_t *lock_local = NULL; xlator_t *this = NULL; struct gf_flock flock = { 0, }; int ret = 0; this = parent_frame->this; lock_frame = cs_lock_frame(parent_frame); if (!lock_frame) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insuffcient memory"); goto err; } lock_local = cs_local_init(this, lock_frame, NULL, NULL, 0); if (!lock_local) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "local init failed"); goto err; } lock_local->main_frame = parent_frame; flock.l_type = F_WRLCK; ret = cs_build_loc(&lock_local->loc, parent_frame); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "build_loc failed"); goto err; } STACK_WIND(lock_frame, cs_blocking_inodelk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, CS_LOCK_DOMAIN, &lock_local->loc, F_SETLKW, &flock, NULL); return 0; err: if (lock_frame) cs_lock_wipe(lock_frame); return -1; } int locate_and_execute(call_frame_t *frame) { int ret = 0; ret = cs_blocking_inodelk(frame); if (ret) return -1; else return 0; } int32_t cs_resume_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xattr_req) { cs_local_t *local = NULL; int ret = 0; local = frame->local; ret = cs_resume_postprocess(this, frame, loc->inode); if (ret) { goto unwind; } cs_inodelk_unlock(frame); STACK_WIND(frame, cs_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, local->xattr_req); return 0; unwind: cs_inodelk_unlock(frame); cs_common_cbk(frame); return 0; } int32_t cs_resume_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { cs_local_t *local = NULL; cs_inode_ctx_t *ctx = NULL; gf_cs_obj_state state = GF_CS_ERROR; local = frame->local; __cs_inode_ctx_get(this, loc->inode, &ctx); state = __cs_get_file_state(loc->inode, ctx); if (state == GF_CS_ERROR) { /* file is already remote */ local->op_ret = -1; local->op_errno = EINVAL; gf_msg(this->name, GF_LOG_WARNING, 0, 0, "file %s , could not figure file state", loc->path); goto unwind; } if (state == GF_CS_REMOTE) { /* file is already remote */ local->op_ret = -1; local->op_errno = EINVAL; gf_msg(this->name, GF_LOG_WARNING, 0, EINVAL, "file %s is already remote", loc->path); goto unwind; } if (state == GF_CS_DOWNLOADING) { gf_msg(this->name, GF_LOG_WARNING, 0, 0, " file is in downloading state."); local->op_ret = -1; local->op_errno = EINVAL; goto unwind; } STACK_WIND(frame, cs_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, local->xattr_req); return 0; unwind: cs_inodelk_unlock(frame); cs_common_cbk(frame); return 0; } gf_cs_obj_state __cs_get_file_state(inode_t *inode, cs_inode_ctx_t *ctx) { gf_cs_obj_state state = -1; if (!ctx) return GF_CS_ERROR; LOCK(&inode->lock); { state = ctx->state; } UNLOCK(&inode->lock); return state; } void __cs_inode_ctx_get(xlator_t *this, inode_t *inode, cs_inode_ctx_t **ctx) { uint64_t ctxint = 0; int ret = 0; LOCK(&inode->lock); { ret = __inode_ctx_get(inode, this, &ctxint); } UNLOCK(&inode->lock); if (ret) *ctx = NULL; else *ctx = (cs_inode_ctx_t *)(uintptr_t)ctxint; return; } int __cs_inode_ctx_update(xlator_t *this, inode_t *inode, uint64_t val) { cs_inode_ctx_t *ctx = NULL; uint64_t ctxint = 0; int ret = 0; LOCK(&inode->lock); { ret = __inode_ctx_get(inode, this, &ctxint); if (ret) { ctx = GF_CALLOC(1, sizeof(*ctx), gf_cs_mt_cs_inode_ctx_t); if (!ctx) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "ctx allocation failed"); ret = -1; goto out; } ctx->state = val; ctxint = (uint64_t)(uintptr_t)ctx; ret = __inode_ctx_set(inode, this, &ctxint); if (ret) { GF_FREE(ctx); goto out; } } else { ctx = (cs_inode_ctx_t *)(uintptr_t)ctxint; ctx->state = val; } } out: UNLOCK(&inode->lock); return ret; } int cs_inode_ctx_reset(xlator_t *this, inode_t *inode) { cs_inode_ctx_t *ctx = NULL; uint64_t ctxint = 0; inode_ctx_del(inode, this, &ctxint); if (!ctxint) { return 0; } ctx = (cs_inode_ctx_t *)(uintptr_t)ctxint; GF_FREE(ctx); return 0; } int cs_resume_postprocess(xlator_t *this, call_frame_t *frame, inode_t *inode) { cs_local_t *local = NULL; gf_cs_obj_state state = -1; cs_inode_ctx_t *ctx = NULL; int ret = 0; local = frame->local; if (!local) { ret = -1; goto out; } __cs_inode_ctx_get(this, inode, &ctx); state = __cs_get_file_state(inode, ctx); if (state == GF_CS_ERROR) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "status is GF_CS_ERROR." " Aborting write"); local->op_ret = -1; local->op_errno = EREMOTE; ret = -1; goto out; } if (state == GF_CS_REMOTE || state == GF_CS_DOWNLOADING) { gf_msg_debug(this->name, 0, "status is %d", state); ret = cs_download(frame); if (ret == 0) { gf_msg_debug(this->name, 0, "Winding for Final Write"); } else { gf_msg(this->name, GF_LOG_ERROR, 0, 0, " download failed, unwinding writev"); local->op_ret = -1; local->op_errno = EREMOTE; ret = -1; } } out: return ret; } int32_t cs_fdctx_to_dict(xlator_t *this, fd_t *fd, dict_t *dict) { return 0; } int32_t cs_inode(xlator_t *this) { return 0; } int32_t cs_inode_to_dict(xlator_t *this, dict_t *dict) { return 0; } int32_t cs_history(xlator_t *this) { return 0; } int32_t cs_fd(xlator_t *this) { return 0; } int32_t cs_fd_to_dict(xlator_t *this, dict_t *dict) { return 0; } int32_t cs_fdctx(xlator_t *this, fd_t *fd) { return 0; } int32_t cs_inodectx(xlator_t *this, inode_t *ino) { return 0; } int32_t cs_inodectx_to_dict(xlator_t *this, inode_t *ino, dict_t *dict) { return 0; } int32_t cs_priv_to_dict(xlator_t *this, dict_t *dict, char *brickname) { return 0; } int32_t cs_priv(xlator_t *this) { return 0; } int cs_notify(xlator_t *this, int event, void *data, ...) { return default_notify(this, event, data); } struct xlator_fops cs_fops = { .stat = cs_stat, .readdirp = cs_readdirp, .truncate = cs_truncate, .seek = cs_seek, .statfs = cs_statfs, .fallocate = cs_fallocate, .discard = cs_discard, .getxattr = cs_getxattr, .writev = cs_writev, .setxattr = cs_setxattr, .fgetxattr = cs_fgetxattr, .lookup = cs_lookup, .fsetxattr = cs_fsetxattr, .readv = cs_readv, .ftruncate = cs_ftruncate, .rchecksum = cs_rchecksum, .unlink = cs_unlink, .open = cs_open, .fstat = cs_fstat, .zerofill = cs_zerofill, }; struct xlator_cbks cs_cbks = { .forget = cs_forget, }; struct xlator_dumpops cs_dumpops = { .fdctx_to_dict = cs_fdctx_to_dict, .inode = cs_inode, .inode_to_dict = cs_inode_to_dict, .history = cs_history, .fd = cs_fd, .fd_to_dict = cs_fd_to_dict, .fdctx = cs_fdctx, .inodectx = cs_inodectx, .inodectx_to_dict = cs_inodectx_to_dict, .priv_to_dict = cs_priv_to_dict, .priv = cs_priv, }; struct volume_options cs_options[] = { {.key = {"cloudsync-storetype"}, .type = GF_OPTION_TYPE_STR, .description = "Defines which remote store is enabled"}, {.key = {"cloudsync-remote-read"}, .type = GF_OPTION_TYPE_BOOL, .description = "Defines a remote read fop when on"}, {.key = {"cloudsync-store-id"}, .type = GF_OPTION_TYPE_STR, .description = "Defines a volume wide store id"}, {.key = {"cloudsync-product-id"}, .type = GF_OPTION_TYPE_STR, .description = "Defines a volume wide product id"}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = cs_init, .fini = cs_fini, .notify = cs_notify, .reconfigure = cs_reconfigure, .mem_acct_init = cs_mem_acct_init, .dumpops = &cs_dumpops, .fops = &cs_fops, .cbks = &cs_cbks, .options = cs_options, .identifier = "cloudsync", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync.h0000644000000000000000000000013014522202451024636 xustar000000000000000030 mtime=1699284265.666027429 30 atime=1699284265.666027429 28 ctime=1699284305.4641473 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync.h0000664000175100017510000000705614522202451025127 0ustar00jenkinsjenkins00000000000000/* * Copyright (c) 2018 Red Hat, Inc. * This file is part of GlusterFS. * * This file is licensed to you under your choice of the GNU Lesser * General Public License, version 3 or any later version (LGPLv3 or * later), or the GNU General Public License, version 2 (GPLv2), in all * cases as published by the Free Software Foundation. */ #ifndef __CLOUDSYNC_H__ #define __CLOUDSYNC_H__ #include "cloudsync-common.h" #include "cloudsync-autogen-fops.h" #define ALIGN_SIZE 4096 #define CS_LOCK_DOMAIN "cs.protect.file.stat" typedef struct cs_dlstore { off_t off; struct iovec *vector; int32_t count; struct iobref *iobref; uint32_t flags; } cs_dlstore; typedef struct cs_inode_ctx { cs_loc_xattr_t locxattr; gf_cs_obj_state state; } cs_inode_ctx_t; struct cs_plugin { char *name; /* store name */ char *library; /* library to load for the given store */ char *description; /* description about the store */ }; cs_local_t * cs_local_init(xlator_t *this, call_frame_t *frame, loc_t *loc, fd_t *fd, glusterfs_fop_t fop); int locate_and_execute(call_frame_t *frame); int32_t cs_resume_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata); int32_t cs_inodelk_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata); size_t cs_write_callback(void *lcurlbuf, size_t size, size_t nitems, void *frame); void cs_common_cbk(call_frame_t *frame); gf_boolean_t cs_is_file_remote(struct iatt *stbuf, dict_t *xattr); int32_t cs_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata); int cs_build_loc(loc_t *loc, call_frame_t *frame); int cs_blocking_inodelk_cbk(call_frame_t *lock_frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata); int cs_read_authinfo(xlator_t *this); int __cs_inode_ctx_update(xlator_t *this, inode_t *inode, uint64_t val); int cs_inode_ctx_reset(xlator_t *this, inode_t *inode); void __cs_inode_ctx_get(xlator_t *this, inode_t *inode, cs_inode_ctx_t **ctx); gf_cs_obj_state __cs_get_file_state(inode_t *inode, cs_inode_ctx_t *ctx); int cs_inodelk_unlock(call_frame_t *main_frame); int cs_resume_postprocess(xlator_t *this, call_frame_t *frame, inode_t *inode); int32_t cs_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); int32_t cs_resume_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xattr_req); int32_t cs_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata); int32_t cs_resume_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata); int32_t cs_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata); int cs_resume_remote_readv_postprocess(xlator_t *this, call_frame_t *frame, inode_t *inode, off_t offset, size_t size, uint32_t flags); int cs_serve_readv(call_frame_t *frame, off_t offset, size_t size, uint32_t flags); #endif /* __CLOUDSYNC_H__ */ glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync-fops-h.py0000644000000000000000000000013014522202451026231 xustar000000000000000029 mtime=1699284265.66302742 29 atime=1699284265.66302742 30 ctime=1699284305.462147294 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-fops-h.py0000775000175100017510000000142214522202451026514 0ustar00jenkinsjenkins00000000000000#!/usr/bin/python3 from __future__ import print_function import os import sys curdir = os.path.dirname(sys.argv[0]) gendir = os.path.join(curdir, '../../../../libglusterfs/src') sys.path.append(gendir) from generator import ops, fop_subs, cbk_subs, generate OP_FOP_TEMPLATE = """ int32_t cs_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@); """ def gen_defaults(): for name, value in ops.items(): if name == 'getspec': continue print(generate(OP_FOP_TEMPLATE, name, fop_subs)) for l in open(sys.argv[1], 'r').readlines(): if l.find('#pragma generate') != -1: print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") gen_defaults() print("/* END GENERATED CODE */") else: print(l[:-1]) glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync-fops-c.py0000644000000000000000000000012714522202451026232 xustar000000000000000029 mtime=1699284265.66302742 29 atime=1699284265.66302742 29 ctime=1699284305.46114729 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-fops-c.py0000775000175100017510000002473014522202451026516 0ustar00jenkinsjenkins00000000000000#!/usr/bin/python3 from __future__ import print_function import os import sys curdir = os.path.dirname(sys.argv[0]) gendir = os.path.join(curdir, '../../../../libglusterfs/src') sys.path.append(gendir) from generator import ops, fop_subs, cbk_subs, generate FD_DATA_MODIFYING_OP_FOP_TEMPLATE = """ int32_t cs_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { int op_errno = EINVAL ; cs_local_t *local = NULL; int ret = 0; cs_inode_ctx_t *ctx = NULL; gf_cs_obj_state state = -1; VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (this, err); VALIDATE_OR_GOTO (fd, err); local = cs_local_init (this, frame, NULL, fd, GF_FOP_@UPNAME@); if (!local) { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local init failed"); op_errno = ENOMEM; goto err; } __cs_inode_ctx_get (this, fd->inode, &ctx); if (ctx) state = __cs_get_file_state (fd->inode, ctx); else state = GF_CS_LOCAL; xdata = xdata ? dict_ref (xdata) : dict_new (); if (!xdata) { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory"); op_errno = ENOMEM; goto err; } local->xattr_req = xdata; ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:" " %s", GF_CS_OBJECT_STATUS); goto err; } local->stub = fop_@NAME@_stub (frame, cs_resume_@NAME@, @SHORT_ARGS@); if (!local->stub) { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory"); op_errno = ENOMEM; goto err; } if (state == GF_CS_LOCAL) { STACK_WIND (frame, cs_@NAME@_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); } else { local->call_cnt++; ret = locate_and_execute (frame); if (ret) { op_errno = ENOMEM; goto err; } } return 0; err: CS_STACK_UNWIND (@NAME@, frame, -1, op_errno, @CBK_ERROR_ARGS@); return 0; } """ FD_DATA_MODIFYING_RESUME_OP_FOP_TEMPLATE = """ int32_t cs_resume_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { int ret = 0; ret = cs_resume_postprocess (this, frame, fd->inode); if (ret) { goto unwind; } cs_inodelk_unlock (frame); STACK_WIND (frame, cs_@NAME@_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); return 0; unwind: cs_inodelk_unlock (frame); cs_common_cbk (frame); return 0; } """ FD_DATA_MODIFYING_OP_FOP_CBK_TEMPLATE = """ int32_t cs_@NAME@_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, @LONG_ARGS@) { cs_local_t *local = NULL; int ret = 0; uint64_t val = 0; fd_t *fd = NULL; local = frame->local; fd = local->fd; /* Do we need lock here? */ local->call_cnt++; if (op_ret == -1) { ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val); if (ret == 0) { if (val == GF_CS_ERROR) { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "could not get file state, unwinding"); op_ret = -1; op_errno = EIO; goto unwind; } else { __cs_inode_ctx_update (this, fd->inode, val); gf_msg (this->name, GF_LOG_INFO, 0, 0, " state = %" PRIu64, val); if (local->call_cnt == 1 && (val == GF_CS_REMOTE || val == GF_CS_DOWNLOADING)) { gf_msg (this->name, GF_LOG_INFO, 0, 0, " will repair and download " "the file, current state : %" PRIu64, val); goto repair; } else { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "second @NAME@, Unwinding"); goto unwind; } } } else { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state " "could not be figured, unwinding"); goto unwind; } } else { /* successful @NAME@ => file is local */ __cs_inode_ctx_update (this, fd->inode, GF_CS_LOCAL); gf_msg (this->name, GF_LOG_INFO, 0, 0, "state : GF_CS_LOCAL" ", @NAME@ successful"); goto unwind; } repair: ret = locate_and_execute (frame); if (ret) { goto unwind; } return 0; unwind: CS_STACK_UNWIND (@NAME@, frame, op_ret, op_errno, @SHORT_ARGS@); return 0; } """ LOC_STAT_OP_FOP_TEMPLATE = """ int32_t cs_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { int op_errno = EINVAL; cs_local_t *local = NULL; int ret = 0; local = cs_local_init (this, frame, loc, NULL, GF_FOP_@UPNAME@); if (!local) { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "local is NULL"); op_errno = ENOMEM; goto err; } if (loc->inode->ia_type == IA_IFDIR) goto wind; xdata = xdata ? dict_ref (xdata) : dict_new (); if (!xdata) { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "insufficient memory"); op_errno = ENOMEM; goto err; } local->xattr_req = xdata; ret = dict_set_uint32 (local->xattr_req, GF_CS_OBJECT_STATUS, 1); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "dict_set failed key:" " %s", GF_CS_OBJECT_STATUS); goto err; } wind: STACK_WIND (frame, cs_@NAME@_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); return 0; err: CS_STACK_UNWIND (@NAME@, frame, -1, op_errno, @CBK_ERROR_ARGS@); return 0; } """ LOC_STAT_OP_FOP_CBK_TEMPLATE = """ int32_t cs_@NAME@_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, @LONG_ARGS@) { int ret = 0; uint64_t val = 0; loc_t *loc = NULL; cs_local_t *local = NULL; local = frame->local; loc = &local->loc; if (op_ret == 0) { ret = dict_get_uint64 (xdata, GF_CS_OBJECT_STATUS, &val); if (!ret) { ret = __cs_inode_ctx_update (this, loc->inode, val); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, 0, "ctx update failed"); } } } else { cs_inode_ctx_reset (this, loc->inode); } CS_STACK_UNWIND (@NAME@, frame, op_ret, op_errno, @SHORT_ARGS@); return 0; } """ # All xlator FOPs are covered in the following section just to create a clarity # The lists themselves are not used. entry_ops = ['mknod', 'mkdir', 'unlink', 'rmdir', 'symlink', 'rename', 'link', 'create'] special_ops = ['statfs', 'lookup', 'ipc', 'compound', 'icreate', 'namelink'] ignored_ops = ['getspec'] inode_ops = ['stat', 'readlink', 'truncate', 'open', 'setxattr', 'getxattr', 'removexattr', 'opendir', 'access', 'inodelk', 'entrylk', 'xattrop', 'setattr', 'lease', 'getactivelk', 'setactivelk', 'discover'] fd_ops = ['readv', 'writev', 'flush', 'fsync', 'fsyncdir', 'ftruncate', 'fstat', 'lk', 'readdir', 'finodelk', 'fentrylk', 'fxattrop', 'fsetxattr', 'fgetxattr', 'rchecksum', 'fsetattr', 'readdirp', 'fremovexattr', 'fallocate', 'discard', 'zerofill', 'seek'] # These are the current actual lists used to generate the code # The following list contains fops which are fd based that modifies data fd_data_modify_op_fop_template = ['writev', 'flush', 'fsync', 'ftruncate', 'rchecksum', 'fallocate', 'discard', 'zerofill', 'seek'] # The following list contains fops which are entry based that does not change # data loc_stat_op_fop_template = ['lookup', 'stat', 'discover', 'access', 'setattr', 'getattr'] # These fops need a separate implementation special_fops = ['statfs', 'setxattr', 'unlink', 'getxattr', 'truncate', 'fstat', 'readv', 'readdirp'] def gen_defaults(): for name in ops: if name in fd_data_modify_op_fop_template: print(generate(FD_DATA_MODIFYING_OP_FOP_CBK_TEMPLATE, name, cbk_subs)) print(generate(FD_DATA_MODIFYING_RESUME_OP_FOP_TEMPLATE, name, fop_subs)) print(generate(FD_DATA_MODIFYING_OP_FOP_TEMPLATE, name, fop_subs)) elif name in loc_stat_op_fop_template: print(generate(LOC_STAT_OP_FOP_CBK_TEMPLATE, name, cbk_subs)) print(generate(LOC_STAT_OP_FOP_TEMPLATE, name, fop_subs)) for l in open(sys.argv[1], 'r').readlines(): if l.find('#pragma generate') != -1: print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") gen_defaults() print("/* END GENERATED CODE */") else: print(l[:-1]) glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202463024533 xustar000000000000000030 mtime=1699284275.720057712 29 atime=1699284291.17110425 30 ctime=1699284305.458147282 glusterfs-11.1/xlators/features/cloudsync/src/Makefile.in0000664000175100017510000007607514522202463025032 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/cloudsync/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_PYTHON) \ $(top_srcdir)/py-compile $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) am__DEPENDENCIES_1 = cloudsync_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(am__DEPENDENCIES_1) am__objects_1 = cloudsync.lo am__objects_2 = cloudsync-common.lo am_cloudsync_la_OBJECTS = $(am__objects_1) $(am__objects_2) nodist_cloudsync_la_OBJECTS = cloudsync-autogen-fops.lo cloudsync_la_OBJECTS = $(am_cloudsync_la_OBJECTS) \ $(nodist_cloudsync_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = cloudsync_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(cloudsync_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(cloudsync_la_SOURCES) $(nodist_cloudsync_la_SOURCES) DIST_SOURCES = $(cloudsync_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile) py_compile = $(top_srcdir)/py-compile HEADERS = $(noinst_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = cloudsync-plugins xlator_LTLIBRARIES = cloudsync.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features cloudsync_sources = cloudsync.c CLOUDSYNC_SRC = $(top_srcdir)/xlators/features/cloudsync/src CLOUDSYNC_BLD = $(top_builddir)/xlators/features/cloudsync/src cloudsynccommon_sources = $(CLOUDSYNC_SRC)/cloudsync-common.c noinst_HEADERS = $(CLOUDSYNC_BLD)/cloudsync.h \ $(CLOUDSYNC_BLD)/cloudsync-mem-types.h \ $(CLOUDSYNC_BLD)/cloudsync-messages.h \ $(CLOUDSYNC_BLD)/cloudsync-common.h cloudsync_la_SOURCES = $(cloudsync_sources) $(cloudsynccommon_sources) nodist_cloudsync_la_SOURCES = cloudsync-autogen-fops.c cloudsync-autogen-fops.h BUILT_SOURCES = cloudsync-autogen-fops.h cloudsync_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) cloudsync_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(LIB_DL) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -DCS_PLUGINDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/cloudsync-plugins\" AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) noinst_PYTHON = cloudsync-fops-c.py cloudsync-fops-h.py EXTRA_DIST = cloudsync-autogen-fops-tmpl.c cloudsync-autogen-fops-tmpl.h CLEANFILES = $(nodist_cloudsync_la_SOURCES) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/cloudsync/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/cloudsync/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } cloudsync.la: $(cloudsync_la_OBJECTS) $(cloudsync_la_DEPENDENCIES) $(EXTRA_cloudsync_la_DEPENDENCIES) $(AM_V_CCLD)$(cloudsync_la_LINK) -rpath $(xlatordir) $(cloudsync_la_OBJECTS) $(cloudsync_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cloudsync-autogen-fops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cloudsync-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cloudsync.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< cloudsync-common.lo: $(CLOUDSYNC_SRC)/cloudsync-common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cloudsync-common.lo -MD -MP -MF $(DEPDIR)/cloudsync-common.Tpo -c -o cloudsync-common.lo `test -f '$(CLOUDSYNC_SRC)/cloudsync-common.c' || echo '$(srcdir)/'`$(CLOUDSYNC_SRC)/cloudsync-common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cloudsync-common.Tpo $(DEPDIR)/cloudsync-common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(CLOUDSYNC_SRC)/cloudsync-common.c' object='cloudsync-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cloudsync-common.lo `test -f '$(CLOUDSYNC_SRC)/cloudsync-common.c' || echo '$(srcdir)/'`$(CLOUDSYNC_SRC)/cloudsync-common.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local uninstall-xlatorLTLIBRARIES .MAKE: $(am__recursive_targets) all check install install-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool \ clean-xlatorLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip install-xlatorLTLIBRARIES installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-local \ uninstall-xlatorLTLIBRARIES cloudsync-autogen-fops.c: cloudsync-fops-c.py cloudsync-autogen-fops-tmpl.c $(PYTHON) $(CLOUDSYNC_SRC)/cloudsync-fops-c.py \ $(CLOUDSYNC_SRC)/cloudsync-autogen-fops-tmpl.c > $@ cloudsync-autogen-fops.h: cloudsync-fops-h.py cloudsync-autogen-fops-tmpl.h $(PYTHON) $(CLOUDSYNC_SRC)/cloudsync-fops-h.py \ $(CLOUDSYNC_SRC)/cloudsync-autogen-fops-tmpl.h > $@ uninstall-local: rm -f $(DESTDIR)$(xlatordir)/cloudsync.so # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013014522202451024516 xustar000000000000000029 mtime=1699284265.66302742 29 atime=1699284275.67305757 30 ctime=1699284305.459147285 glusterfs-11.1/xlators/features/cloudsync/src/Makefile.am0000664000175100017510000000326614522202451025006 0ustar00jenkinsjenkins00000000000000SUBDIRS = cloudsync-plugins xlator_LTLIBRARIES = cloudsync.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features cloudsync_sources = cloudsync.c CLOUDSYNC_SRC = $(top_srcdir)/xlators/features/cloudsync/src CLOUDSYNC_BLD = $(top_builddir)/xlators/features/cloudsync/src cloudsynccommon_sources = $(CLOUDSYNC_SRC)/cloudsync-common.c noinst_HEADERS = $(CLOUDSYNC_BLD)/cloudsync.h \ $(CLOUDSYNC_BLD)/cloudsync-mem-types.h \ $(CLOUDSYNC_BLD)/cloudsync-messages.h \ $(CLOUDSYNC_BLD)/cloudsync-common.h cloudsync_la_SOURCES = $(cloudsync_sources) $(cloudsynccommon_sources) nodist_cloudsync_la_SOURCES = cloudsync-autogen-fops.c cloudsync-autogen-fops.h BUILT_SOURCES = cloudsync-autogen-fops.h cloudsync_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) cloudsync_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(LIB_DL) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -DCS_PLUGINDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/cloudsync-plugins\" AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) noinst_PYTHON = cloudsync-fops-c.py cloudsync-fops-h.py EXTRA_DIST = cloudsync-autogen-fops-tmpl.c cloudsync-autogen-fops-tmpl.h cloudsync-autogen-fops.c: cloudsync-fops-c.py cloudsync-autogen-fops-tmpl.c $(PYTHON) $(CLOUDSYNC_SRC)/cloudsync-fops-c.py \ $(CLOUDSYNC_SRC)/cloudsync-autogen-fops-tmpl.c > $@ cloudsync-autogen-fops.h: cloudsync-fops-h.py cloudsync-autogen-fops-tmpl.h $(PYTHON) $(CLOUDSYNC_SRC)/cloudsync-fops-h.py \ $(CLOUDSYNC_SRC)/cloudsync-autogen-fops-tmpl.h > $@ CLEANFILES = $(nodist_cloudsync_la_SOURCES) uninstall-local: rm -f $(DESTDIR)$(xlatordir)/cloudsync.so glusterfs-11.1/xlators/features/cloudsync/src/PaxHeaders.9031/cloudsync-common.c0000644000000000000000000000013014522202451026117 xustar000000000000000029 mtime=1699284265.66302742 29 atime=1699284265.66302742 30 ctime=1699284305.471147321 glusterfs-11.1/xlators/features/cloudsync/src/cloudsync-common.c0000664000175100017510000000246014522202451026402 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "cloudsync-common.h" void cs_xattrinfo_wipe(cs_local_t *local) { if (local->xattrinfo.lxattr) { if (local->xattrinfo.lxattr->file_path) GF_FREE(local->xattrinfo.lxattr->file_path); if (local->xattrinfo.lxattr->volname) GF_FREE(local->xattrinfo.lxattr->volname); GF_FREE(local->xattrinfo.lxattr); } } void cs_local_wipe(xlator_t *this, cs_local_t *local) { if (!local) return; loc_wipe(&local->loc); if (local->fd) { fd_unref(local->fd); local->fd = NULL; } if (local->stub) { call_stub_destroy(local->stub); local->stub = NULL; } if (local->xattr_req) dict_unref(local->xattr_req); if (local->xattr_rsp) dict_unref(local->xattr_rsp); if (local->dlfd) fd_unref(local->dlfd); if (local->remotepath) GF_FREE(local->remotepath); cs_xattrinfo_wipe(local); mem_put(local); } glusterfs-11.1/xlators/features/cloudsync/PaxHeaders.9031/Makefile.in0000644000000000000000000000013014522202463023743 xustar000000000000000029 mtime=1699284275.66305754 29 atime=1699284291.15110419 30 ctime=1699284305.414147149 glusterfs-11.1/xlators/features/cloudsync/Makefile.in0000664000175100017510000005273514522202463024240 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/cloudsync DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/cloudsync/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/cloudsync/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/cloudsync/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023731 xustar000000000000000030 mtime=1699284265.662027417 30 atime=1699284275.639057468 30 ctime=1699284305.416147155 glusterfs-11.1/xlators/features/cloudsync/Makefile.am0000664000175100017510000000003414522202451024205 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/snapview-server0000644000000000000000000000013214522202520022752 xustar000000000000000030 mtime=1699284304.678144932 30 atime=1699284309.686160016 30 ctime=1699284304.678144932 glusterfs-11.1/xlators/features/snapview-server/0002775000175100017510000000000014522202520023310 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/snapview-server/PaxHeaders.9031/src0000644000000000000000000000013214522202520023541 xustar000000000000000030 mtime=1699284304.721145062 30 atime=1699284309.686160016 30 ctime=1699284304.721145062 glusterfs-11.1/xlators/features/snapview-server/src/0002775000175100017510000000000014522202520024077 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/snapview-server/src/PaxHeaders.9031/snapview-server-mem-types.h0000644000000000000000000000013014522202451031046 xustar000000000000000029 mtime=1699284265.69302751 29 atime=1699284265.69302751 30 ctime=1699284304.714145041 glusterfs-11.1/xlators/features/snapview-server/src/snapview-server-mem-types.h0000664000175100017510000000120214522202451031322 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __SNAP_VIEW_MEM_TYPES_H #define __SNAP_VIEW_MEM_TYPES_H #include enum snapview_mem_types { gf_svs_mt_priv_t = gf_common_mt_end + 1, gf_svs_mt_svs_inode_t, gf_svs_mt_dirents_t, gf_svs_mt_svs_fd_t, gf_svs_mt_end }; #endif glusterfs-11.1/xlators/features/snapview-server/src/PaxHeaders.9031/snapview-server.h0000644000000000000000000000013214522202451027132 xustar000000000000000030 mtime=1699284265.694027513 30 atime=1699284265.694027513 30 ctime=1699284304.713145038 glusterfs-11.1/xlators/features/snapview-server/src/snapview-server.h0000664000175100017510000002364514522202451027423 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __SNAP_VIEW_H__ #define __SNAP_VIEW_H__ #include #include #include #include #include #include #include #include #include "glfs-internal.h" #include #include #include #include #include "rpc-clnt.h" #include "protocol-common.h" #include "snapview-server-messages.h" #define DEFAULT_SVD_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs" #define SNAP_VIEW_MAX_GLFS_T 256 #define SNAP_VIEW_MAX_GLFS_FDS 1024 #define SNAP_VIEW_MAX_GLFS_OBJ_HANDLES 1024 #define SVS_STACK_DESTROY(_frame) \ do { \ ((call_frame_t *)_frame)->local = NULL; \ STACK_DESTROY(((call_frame_t *)_frame)->root); \ } while (0) #define SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this) \ do { \ svs_private_t *_private = NULL; \ _private = this->private; \ int i = 0; \ gf_boolean_t found = _gf_false; \ glfs_t *tmp_fs = NULL; \ LOCK(&_private->snaplist_lock); \ { \ for (i = 0; i < _private->num_snaps; i++) { \ tmp_fs = _private->dirents[i].fs; \ gf_log(this->name, GF_LOG_DEBUG, \ "snap name: %s, snap volume: %s," \ "dirent->fs: %p", \ _private->dirents[i].name, \ _private->dirents[i].snap_volname, tmp_fs); \ if (tmp_fs && fs && (tmp_fs == fs)) { \ found = _gf_true; \ gf_msg_debug(this->name, 0, \ "found the fs " \ "instance"); \ break; \ } \ } \ } \ UNLOCK(&_private->snaplist_lock); \ \ if (!found) { \ gf_log(this->name, GF_LOG_WARNING, \ "failed to" \ " find the fs instance %p", \ fs); \ fs = NULL; \ } \ } while (0) #define SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, ret, \ op_errno, label) \ do { \ fs = inode_ctx->fs; \ object = inode_ctx->object; \ SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this); \ if (!fs) \ object = NULL; \ \ if (!fs || !object) { \ int32_t tmp = -1; \ char tmp_uuid[64]; \ \ tmp = svs_get_handle(this, loc, inode_ctx, &op_errno); \ if (tmp) { \ gf_log(this->name, GF_LOG_ERROR, \ "failed to get the handle for %s " \ "(gfid: %s)", \ loc->path, uuid_utoa_r(loc->inode->gfid, tmp_uuid)); \ ret = -1; \ goto label; \ } \ \ fs = inode_ctx->fs; \ object = inode_ctx->object; \ } \ } while (0); #define SVS_STRDUP(dst, src) \ do { \ if (dst && strcmp(src, dst)) { \ GF_FREE(dst); \ dst = NULL; \ } \ \ if (!dst) \ dst = gf_strdup(src); \ } while (0) int svs_mgmt_submit_request(void *req, call_frame_t *frame, glusterfs_ctx_t *ctx, rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc); int svs_get_snapshot_list(xlator_t *this); int mgmt_get_snapinfo_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe); typedef enum { SNAP_VIEW_ENTRY_POINT_INODE = 0, SNAP_VIEW_SNAPSHOT_INODE, SNAP_VIEW_VIRTUAL_INODE } inode_type_t; struct svs_inode { glfs_t *fs; glfs_object_t *object; inode_type_t type; /* used only for entry point directory where gfid of the directory from where the entry point was entered is saved. */ uuid_t pargfid; /* This is used to generate gfid for all sub files/dirs under this * snapshot */ char *snapname; struct iatt buf; }; typedef struct svs_inode svs_inode_t; struct svs_fd { glfs_fd_t *fd; }; typedef struct svs_fd svs_fd_t; struct snap_dirent { char name[NAME_MAX]; char uuid[UUID_CANONICAL_FORM_LEN + 1]; char snap_volname[NAME_MAX]; glfs_t *fs; }; typedef struct snap_dirent snap_dirent_t; struct svs_private { snap_dirent_t *dirents; int num_snaps; char *volname; struct list_head snaplist; gf_lock_t snaplist_lock; struct rpc_clnt *rpc; }; typedef struct svs_private svs_private_t; int __svs_inode_ctx_set(xlator_t *this, inode_t *inode, svs_inode_t *svs_inode); svs_inode_t * __svs_inode_ctx_get(xlator_t *this, inode_t *inode); svs_inode_t * svs_inode_ctx_get(xlator_t *this, inode_t *inode); int32_t svs_inode_ctx_set(xlator_t *this, inode_t *inode, svs_inode_t *svs_inode); svs_inode_t * svs_inode_ctx_get_or_new(xlator_t *this, inode_t *inode); int __svs_fd_ctx_set(xlator_t *this, fd_t *fd, svs_fd_t *svs_fd); svs_fd_t * __svs_fd_ctx_get(xlator_t *this, fd_t *fd); svs_fd_t * svs_fd_ctx_get(xlator_t *this, fd_t *fd); int32_t svs_fd_ctx_set(xlator_t *this, fd_t *fd, svs_fd_t *svs_fd); svs_fd_t * __svs_fd_ctx_get_or_new(xlator_t *this, fd_t *fd); svs_fd_t * svs_fd_ctx_get_or_new(xlator_t *this, fd_t *fd); int svs_uuid_generate(xlator_t *this, uuid_t gfid, char *snapname, uuid_t origin_gfid); void svs_fill_ino_from_gfid(struct iatt *buf); void svs_iatt_fill(uuid_t gfid, struct iatt *buf); snap_dirent_t * svs_get_latest_snap_entry(xlator_t *this); glfs_t * svs_get_latest_snapshot(xlator_t *this); glfs_t * svs_initialise_snapshot_volume(xlator_t *this, const char *name, int32_t *op_errno); glfs_t * __svs_initialise_snapshot_volume(xlator_t *this, const char *name, int32_t *op_errno); snap_dirent_t * __svs_get_snap_dirent(svs_private_t *private, const char *name); int svs_mgmt_init(xlator_t *this); int32_t svs_get_handle(xlator_t *this, loc_t *loc, svs_inode_t *inode_ctx, int32_t *op_errno); glfs_t * svs_inode_glfs_mapping(xlator_t *this, inode_t *inode); glfs_t * svs_inode_ctx_glfs_mapping(xlator_t *this, svs_inode_t *inode_ctx); #endif /* __SNAP_VIEW_H__ */ glusterfs-11.1/xlators/features/snapview-server/src/PaxHeaders.9031/snapview-server-messages.h0000644000000000000000000000013014522202451030735 xustar000000000000000029 mtime=1699284265.69302751 29 atime=1699284265.69302751 30 ctime=1699284304.716145047 glusterfs-11.1/xlators/features/snapview-server/src/snapview-server-messages.h0000664000175100017510000000523714522202451031225 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _SNAPVIEW_SERVER_MESSAGES_H_ #define _SNAPVIEW_SERVER_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(SNAPVIEW_SERVER, SVS_MSG_NO_MEMORY, SVS_MSG_MEM_ACNT_FAILED, SVS_MSG_NULL_GFID, SVS_MSG_GET_LATEST_SNAP_FAILED, SVS_MSG_INVALID_GLFS_CTX, SVS_MSG_LOCK_DESTROY_FAILED, SVS_MSG_SNAPSHOT_LIST_CHANGED, SVS_MSG_MGMT_INIT_FAILED, SVS_MSG_GET_SNAPSHOT_LIST_FAILED, SVS_MSG_GET_GLFS_H_OBJECT_FAILED, SVS_MSG_PARENT_CTX_OR_NAME_NULL, SVS_MSG_SET_INODE_CONTEXT_FAILED, SVS_MSG_GET_INODE_CONTEXT_FAILED, SVS_MSG_NEW_INODE_CTX_FAILED, SVS_MSG_DELETE_INODE_CONTEXT_FAILED, SVS_MSG_SET_FD_CONTEXT_FAILED, SVS_MSG_NEW_FD_CTX_FAILED, SVS_MSG_DELETE_FD_CTX_FAILED, SVS_MSG_GETXATTR_FAILED, SVS_MSG_LISTXATTR_FAILED, SVS_MSG_RELEASEDIR_FAILED, SVS_MSG_RELEASE_FAILED, SVS_MSG_TELLDIR_FAILED, SVS_MSG_STAT_FAILED, SVS_MSG_STATFS_FAILED, SVS_MSG_OPEN_FAILED, SVS_MSG_READ_FAILED, SVS_MSG_READLINK_FAILED, SVS_MSG_ACCESS_FAILED, SVS_MSG_GET_FD_CONTEXT_FAILED, SVS_MSG_DICT_SET_FAILED, SVS_MSG_OPENDIR_FAILED, SVS_MSG_FS_INSTANCE_INVALID, SVS_MSG_SETFSUID_FAIL, SVS_MSG_SETFSGID_FAIL, SVS_MSG_SETFSGRPS_FAIL, SVS_MSG_BUILD_TRNSPRT_OPT_FAILED, SVS_MSG_RPC_INIT_FAILED, SVS_MSG_REG_NOTIFY_FAILED, SVS_MSG_REG_CBK_PRGM_FAILED, SVS_MSG_RPC_CLNT_START_FAILED, SVS_MSG_XDR_PAYLOAD_FAILED, SVS_MSG_NULL_CTX, SVS_MSG_RPC_CALL_FAILED, SVS_MSG_XDR_DECODE_FAILED, SVS_MSG_RSP_DICT_EMPTY, SVS_MSG_DICT_GET_FAILED, SVS_MSG_SNAP_LIST_REFRESH_FAILED, SVS_MSG_RPC_REQ_FAILED, SVS_MSG_CLOSEDIR_FAILED, SVS_MSG_CLOSE_FAILED, SVS_MSG_GFID_GEN_FAILED, SVS_MSG_GLFS_NEW_FAILED, SVS_MSG_SET_VOLFILE_SERVR_FAILED, SVS_MSG_SET_LOGGING_FAILED, SVS_MSG_VOLFILE_SERVER_GET_FAIL, SVS_MSG_GLFS_INIT_FAILED); #endif /* !_SNAPVIEW_CLIENT_MESSAGES_H_ */ glusterfs-11.1/xlators/features/snapview-server/src/PaxHeaders.9031/snapview-server-mgmt.c0000644000000000000000000000013114522202451030066 xustar000000000000000030 mtime=1699284265.694027513 29 atime=1699284265.69302751 30 ctime=1699284304.720145059 glusterfs-11.1/xlators/features/snapview-server/src/snapview-server-mgmt.c0000664000175100017510000003460214522202451030353 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "snapview-server.h" #include "snapview-server-mem-types.h" #include static int mgmt_cbk_snap(struct rpc_clnt *rpc, void *mydata, void *data) { xlator_t *this = NULL; this = mydata; GF_ASSERT(this); gf_msg("mgmt", GF_LOG_INFO, 0, SVS_MSG_SNAPSHOT_LIST_CHANGED, "list of snapshots changed"); svs_get_snapshot_list(this); return 0; } static rpcclnt_cb_actor_t svs_cbk_actors[GF_CBK_MAXVALUE] = { [GF_CBK_GET_SNAPS] = {"GETSNAPS", mgmt_cbk_snap, GF_CBK_GET_SNAPS}, }; static struct rpcclnt_cb_program svs_cbk_prog = { .progname = "GlusterFS Callback", .prognum = GLUSTER_CBK_PROGRAM, .progver = GLUSTER_CBK_VERSION, .actors = svs_cbk_actors, .numactors = GF_CBK_MAXVALUE, }; static char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = { [GF_HNDSK_NULL] = "NULL", [GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY", }; static rpc_clnt_prog_t svs_clnt_handshake_prog = { .progname = "GlusterFS Handshake", .prognum = GLUSTER_HNDSK_PROGRAM, .progver = GLUSTER_HNDSK_VERSION, .procnames = clnt_handshake_procs, }; static int svs_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, void *data) { xlator_t *this = NULL; int ret = 0; this = mydata; switch (event) { case RPC_CLNT_CONNECT: ret = svs_get_snapshot_list(this); if (ret) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, SVS_MSG_GET_SNAPSHOT_LIST_FAILED, "Error in refreshing the snaplist " "infrastructure"); ret = -1; } break; default: break; } return ret; } int svs_mgmt_init(xlator_t *this) { int ret = -1; svs_private_t *priv = NULL; dict_t *options = NULL; int port = GF_DEFAULT_BASE_PORT; char *host = NULL; cmd_args_t *cmd_args = NULL; glusterfs_ctx_t *ctx = NULL; xlator_cmdline_option_t *opt = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, this->ctx, out); priv = this->private; ctx = this->ctx; cmd_args = &ctx->cmd_args; host = "localhost"; if (cmd_args->volfile_server) host = cmd_args->volfile_server; options = dict_new(); if (!options) goto out; opt = find_xlator_option_in_cmd_args_t("address-family", cmd_args); ret = rpc_transport_inet_options_build(options, host, port, (opt != NULL ? opt->value : NULL)); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_BUILD_TRNSPRT_OPT_FAILED, "failed to build the " "transport options"); goto out; } priv->rpc = rpc_clnt_new(options, this, this->name, 8); if (!priv->rpc) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_RPC_INIT_FAILED, "failed to initialize RPC"); goto out; } ret = rpc_clnt_register_notify(priv->rpc, svs_rpc_notify, this); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, SVS_MSG_REG_NOTIFY_FAILED, "failed to register notify function"); goto out; } ret = rpcclnt_cbk_program_register(priv->rpc, &svs_cbk_prog, this); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_REG_CBK_PRGM_FAILED, "failed to register callback program"); goto out; } ret = rpc_clnt_start(priv->rpc); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_RPC_CLNT_START_FAILED, "failed to start the rpc " "client"); goto out; } ret = 0; gf_msg_debug(this->name, 0, "svs mgmt init successful"); out: if (options) dict_unref(options); if (ret) if (priv) { rpc_clnt_connection_cleanup(&priv->rpc->conn); rpc_clnt_unref(priv->rpc); priv->rpc = NULL; } return ret; } int svs_mgmt_submit_request(void *req, call_frame_t *frame, glusterfs_ctx_t *ctx, rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc) { int ret = -1; int count = 0; struct iovec iov = { 0, }; struct iobuf *iobuf = NULL; struct iobref *iobref = NULL; ssize_t xdr_size = 0; GF_VALIDATE_OR_GOTO("snapview-server", frame, out); GF_VALIDATE_OR_GOTO("snapview-server", req, out); GF_VALIDATE_OR_GOTO("snapview-server", ctx, out); GF_VALIDATE_OR_GOTO("snapview-server", prog, out); GF_ASSERT(frame->this); iobref = iobref_new(); if (!iobref) { gf_msg(frame->this->name, GF_LOG_WARNING, ENOMEM, SVS_MSG_NO_MEMORY, "failed to allocate " "new iobref"); goto out; } if (req) { xdr_size = xdr_sizeof(xdrproc, req); iobuf = iobuf_get2(ctx->iobuf_pool, xdr_size); if (!iobuf) { goto out; } iobref_add(iobref, iobuf); iov.iov_base = iobuf->ptr; iov.iov_len = iobuf_pagesize(iobuf); /* Create the xdr payload */ ret = xdr_serialize_generic(iov, req, xdrproc); if (ret == -1) { gf_msg(frame->this->name, GF_LOG_WARNING, 0, SVS_MSG_XDR_PAYLOAD_FAILED, "Failed to create XDR payload"); goto out; } iov.iov_len = ret; count = 1; } ret = rpc_clnt_submit(ctx->mgmt, prog, procnum, cbkfn, &iov, count, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL); out: if (iobref) iobref_unref(iobref); if (iobuf) iobuf_unref(iobuf); return ret; } int mgmt_get_snapinfo_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gf_getsnap_name_uuid_rsp rsp = { 0, }; call_frame_t *frame = NULL; glusterfs_ctx_t *ctx = NULL; int ret = -1; dict_t *dict = NULL; char key[32] = {0}; int len; int snapcount = 0; svs_private_t *priv = NULL; xlator_t *this = NULL; int i = 0; int j = 0; char *value = NULL; snap_dirent_t *dirents = NULL; snap_dirent_t *old_dirents = NULL; int oldcount = 0; GF_VALIDATE_OR_GOTO("snapview-server", req, error_out); GF_VALIDATE_OR_GOTO("snapview-server", myframe, error_out); GF_VALIDATE_OR_GOTO("snapview-server", iov, error_out); frame = myframe; this = frame->this; ctx = frame->this->ctx; priv = this->private; if (!ctx) { errno = EINVAL; gf_msg(frame->this->name, GF_LOG_ERROR, errno, SVS_MSG_NULL_CTX, "NULL context"); goto out; } if (-1 == req->rpc_status) { errno = EINVAL; gf_msg(frame->this->name, GF_LOG_ERROR, errno, SVS_MSG_RPC_CALL_FAILED, "RPC call is not successful"); goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_getsnap_name_uuid_rsp); if (ret < 0) { gf_msg(frame->this->name, GF_LOG_ERROR, 0, SVS_MSG_XDR_DECODE_FAILED, "Failed to decode xdr response, rsp.op_ret = %d", rsp.op_ret); goto out; } if (rsp.op_ret == -1) { errno = rsp.op_errno; ret = -1; goto out; } if (!rsp.dict.dict_len) { ret = -1; errno = EINVAL; gf_msg(frame->this->name, GF_LOG_ERROR, errno, SVS_MSG_RSP_DICT_EMPTY, "Response dict is not populated"); goto out; } dict = dict_new(); if (!dict) { ret = -1; errno = ENOMEM; goto out; } ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict); if (ret) { errno = EINVAL; gf_msg(frame->this->name, GF_LOG_ERROR, errno, LG_MSG_DICT_UNSERIAL_FAILED, "Failed to unserialize dictionary"); goto out; } ret = dict_get_int32(dict, "snap-count", (int32_t *)&snapcount); if (ret) { errno = EINVAL; ret = -1; gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_DICT_GET_FAILED, "Error retrieving snapcount"); goto out; } if (snapcount > 0) { /* first time we are fetching snap list */ dirents = GF_CALLOC(snapcount, sizeof(snap_dirent_t), gf_svs_mt_dirents_t); if (!dirents) { errno = ENOMEM; ret = -1; gf_msg(frame->this->name, GF_LOG_ERROR, errno, SVS_MSG_NO_MEMORY, "Unable to allocate memory"); goto out; } } for (i = 0; i < snapcount; i++) { len = snprintf(key, sizeof(key), "snap-volname.%d", i + 1); ret = dict_get_strn(dict, key, len, &value); if (ret) { errno = EINVAL; ret = -1; gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_DICT_GET_FAILED, "Error retrieving snap volname %d", i + 1); goto out; } strncpy(dirents[i].snap_volname, value, sizeof(dirents[i].snap_volname)); len = snprintf(key, sizeof(key), "snap-id.%d", i + 1); ret = dict_get_strn(dict, key, len, &value); if (ret) { errno = EINVAL; ret = -1; gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_DICT_GET_FAILED, "Error retrieving snap uuid %d", i + 1); goto out; } strncpy(dirents[i].uuid, value, sizeof(dirents[i].uuid)); len = snprintf(key, sizeof(key), "snapname.%d", i + 1); ret = dict_get_strn(dict, key, len, &value); if (ret) { errno = EINVAL; ret = -1; gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_DICT_GET_FAILED, "Error retrieving snap name %d", i + 1); goto out; } strncpy(dirents[i].name, value, sizeof(dirents[i].name)); } /* * Got the new snap list populated in dirents * The new snap list is either a subset or a superset of * the existing snaplist old_dirents which has priv->num_snaps * number of entries. * * If subset, then clean up the fs for entries which are * no longer relevant. * * For other overlapping entries set the fs for new dirents * entries which have a fs assigned already in old_dirents * * We do this as we don't want to do new glfs_init()s repeatedly * as the dirents entries for snapshot volumes get repatedly * cleaned up and allocated. And if we don't then that will lead * to memleaks */ LOCK(&priv->snaplist_lock); { oldcount = priv->num_snaps; old_dirents = priv->dirents; for (i = 0; i < priv->num_snaps; i++) { for (j = 0; j < snapcount; j++) { if ((!strcmp(old_dirents[i].name, dirents[j].name)) && (!strcmp(old_dirents[i].uuid, dirents[j].uuid))) { dirents[j].fs = old_dirents[i].fs; old_dirents[i].fs = NULL; break; } } } priv->dirents = dirents; priv->num_snaps = snapcount; } UNLOCK(&priv->snaplist_lock); if (old_dirents) { for (i = 0; i < oldcount; i++) { if (old_dirents[i].fs) gf_msg_debug(this->name, 0, "calling glfs_fini on " "name: %s, snap_volname: %s, uuid: %s", old_dirents[i].name, old_dirents[i].snap_volname, old_dirents[i].uuid); glfs_fini(old_dirents[i].fs); } } GF_FREE(old_dirents); ret = 0; out: if (dict) { dict_unref(dict); } free(rsp.dict.dict_val); free(rsp.op_errstr); if (ret && dirents) { gf_msg(this->name, GF_LOG_WARNING, 0, SVS_MSG_SNAP_LIST_REFRESH_FAILED, "Could not update dirents with refreshed snap list"); GF_FREE(dirents); } if (myframe) SVS_STACK_DESTROY(myframe); error_out: return ret; } int svs_get_snapshot_list(xlator_t *this) { gf_getsnap_name_uuid_req req = {{ 0, }}; int ret = -1; dict_t *dict = NULL; glusterfs_ctx_t *ctx = NULL; call_frame_t *frame = NULL; svs_private_t *priv = NULL; gf_boolean_t frame_cleanup = _gf_true; GF_VALIDATE_OR_GOTO("snapview-server", this, out); ctx = this->ctx; if (!ctx) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_NULL_CTX, "ctx is NULL"); goto out; } frame = create_frame(this, ctx->pool); if (!frame) { gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_FRAME_ERROR, "Error allocating frame"); goto out; } priv = this->private; dict = dict_new(); if (!dict) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, SVS_MSG_NO_MEMORY, "Error allocating dictionary"); goto out; } ret = dict_set_str(dict, "volname", priv->volname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_DICT_SET_FAILED, "Error setting volname in dict"); goto out; } ret = dict_allocate_and_serialize(dict, &req.dict.dict_val, &req.dict.dict_len); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_DICT_UNSERIAL_FAILED, "Failed to serialize dictionary"); ret = -1; goto out; } ret = svs_mgmt_submit_request( &req, frame, ctx, &svs_clnt_handshake_prog, GF_HNDSK_GET_SNAPSHOT_INFO, mgmt_get_snapinfo_cbk, (xdrproc_t)xdr_gf_getsnap_name_uuid_req); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_RPC_REQ_FAILED, "Error sending snapshot names RPC request"); } frame_cleanup = _gf_false; out: if (dict) { dict_unref(dict); } GF_FREE(req.dict.dict_val); if (frame_cleanup && frame) { /* * Destroy the frame if we encountered an error * Else we need to clean it up in * mgmt_get_snapinfo_cbk */ SVS_STACK_DESTROY(frame); } return ret; } glusterfs-11.1/xlators/features/snapview-server/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465025673 xustar000000000000000030 mtime=1699284277.379062709 30 atime=1699284290.880103374 30 ctime=1699284304.710145029 glusterfs-11.1/xlators/features/snapview-server/src/Makefile.in0000664000175100017510000006127614522202465026166 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/snapview-server/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) am__DEPENDENCIES_1 = snapview_server_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/api/src/libgfapi.la $(am__DEPENDENCIES_1) \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la am_snapview_server_la_OBJECTS = snapview-server.lo \ snapview-server-mgmt.lo snapview-server-helpers.lo snapview_server_la_OBJECTS = $(am_snapview_server_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = snapview_server_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(snapview_server_la_LDFLAGS) \ $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_snapview_server_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(snapview_server_la_SOURCES) DIST_SOURCES = $(snapview_server_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = snapview-server.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features snapview_server_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) snapview_server_la_SOURCES = snapview-server.c snapview-server-mgmt.c \ snapview-server-helpers.c snapview_server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/api/src/libgfapi.la \ $(RLLIBS) $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la noinst_HEADERS = snapview-server.h snapview-server-mem-types.h snapview-server-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/api/src -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -DDATADIR=\"$(localstatedir)\" AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/snapview-server/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/snapview-server/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } snapview-server.la: $(snapview_server_la_OBJECTS) $(snapview_server_la_DEPENDENCIES) $(EXTRA_snapview_server_la_DEPENDENCIES) $(AM_V_CCLD)$(snapview_server_la_LINK) $(am_snapview_server_la_rpath) $(snapview_server_la_OBJECTS) $(snapview_server_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snapview-server-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snapview-server-mgmt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snapview-server.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/snapview-server/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451025654 xustar000000000000000029 mtime=1699284265.69302751 30 atime=1699284277.341062595 30 ctime=1699284304.711145032 glusterfs-11.1/xlators/features/snapview-server/src/Makefile.am0000664000175100017510000000154214522202451026136 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = snapview-server.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features snapview_server_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) snapview_server_la_SOURCES = snapview-server.c snapview-server-mgmt.c \ snapview-server-helpers.c snapview_server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/api/src/libgfapi.la \ $(RLLIBS) $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la noinst_HEADERS = snapview-server.h snapview-server-mem-types.h snapview-server-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/api/src -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -DDATADIR=\"$(localstatedir)\" AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/snapview-server/src/PaxHeaders.9031/snapview-server.c0000644000000000000000000000013214522202451027125 xustar000000000000000030 mtime=1699284265.694027513 30 atime=1699284265.694027513 30 ctime=1699284304.718145053 glusterfs-11.1/xlators/features/snapview-server/src/snapview-server.c0000664000175100017510000025026614522202451027417 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "snapview-server.h" #include "snapview-server-mem-types.h" #include #include "rpc-clnt.h" #include "protocol-common.h" #include #include #include "glfs-internal.h" static int gf_setcredentials(uid_t *uid, gid_t *gid, uint16_t ngrps, uint32_t *groups) { int ret = 0; if (uid) { ret = glfs_setfsuid(*uid); if (ret != 0) { gf_msg("snapview-server", GF_LOG_ERROR, 0, SVS_MSG_SETFSUID_FAIL, "failed to set uid " "%u in thread context", *uid); return ret; } } if (gid) { ret = glfs_setfsgid(*gid); if (ret != 0) { gf_msg("snapview-server", GF_LOG_ERROR, 0, SVS_MSG_SETFSGID_FAIL, "failed to set gid " "%u in thread context", *gid); return ret; } } if (ngrps != 0 && groups) { ret = glfs_setfsgroups(ngrps, groups); if (ret != 0) { gf_msg("snapview-server", GF_LOG_ERROR, 0, SVS_MSG_SETFSGRPS_FAIL, "failed to set " "groups in thread context"); return ret; } } return 0; } static int32_t svs_lookup_entry_point(xlator_t *this, loc_t *loc, inode_t *parent, struct iatt *buf, struct iatt *postparent, int32_t *op_errno) { uuid_t gfid; svs_inode_t *inode_ctx = NULL; int op_ret = -1; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); GF_VALIDATE_OR_GOTO(this->name, buf, out); GF_VALIDATE_OR_GOTO(this->name, postparent, out); if (gf_uuid_is_null(loc->inode->gfid)) { gf_uuid_generate(gfid); svs_iatt_fill(gfid, buf); /* Here the inode context of the entry point directory is filled with just the type of the inode and the gfid of the parent from where the entry point was entered. The glfs object and the fs instance will be NULL. */ if (parent) svs_iatt_fill(parent->gfid, postparent); else { svs_iatt_fill(buf->ia_gfid, postparent); } inode_ctx = svs_inode_ctx_get_or_new(this, loc->inode); if (!inode_ctx) { op_ret = -1; *op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, *op_errno, SVS_MSG_NEW_INODE_CTX_FAILED, "failed to " "allocate inode context for entry point " "directory"); goto out; } gf_uuid_copy(inode_ctx->pargfid, loc->pargfid); memcpy(&inode_ctx->buf, buf, sizeof(*buf)); inode_ctx->type = SNAP_VIEW_ENTRY_POINT_INODE; } else { inode_ctx = svs_inode_ctx_get(this, loc->inode); if (inode_ctx) { memcpy(buf, &inode_ctx->buf, sizeof(*buf)); svs_iatt_fill(inode_ctx->pargfid, postparent); } else { svs_iatt_fill(loc->inode->gfid, buf); if (parent) svs_iatt_fill(parent->gfid, postparent); else { svs_iatt_fill(loc->inode->gfid, postparent); } } } op_ret = 0; out: return op_ret; } /* When lookup comes from client and the protocol/server tries to resolve the pargfid via just sending the gfid as part of lookup, if the inode for the parent gfid is not found. But since that gfid has not yet been looked up yet, inode will not be having inode context and parent is not there (as it is the parent of the entry that is being resolved). So without parent and inode context, svs cannot know which snapshot to look into. In such cases, the amguity is handled by looking into the latest snapshot. If the directory is there in the latest snapshot, lookup is successful, otherwise it is a failure. So for any directory created after taking the latest snapshot, entry into snapshot world is denied. i.e you have to be part of snapshot world to enter it. If the gfid is not found there, then unwind with ESTALE This gets executed mainly in the situation where the snapshot entry point is entered from a non-root directory and that non-root directory's inode (or gfid) is not yet looked up. And in each case when a gfid has to be looked up (without any inode contex and parent context present), last snapshot is referred and a random gfid is not generated. */ int32_t svs_lookup_gfid(xlator_t *this, loc_t *loc, struct iatt *buf, struct iatt *postparent, int32_t *op_errno) { int32_t op_ret = -1; unsigned char handle_obj[GFAPI_HANDLE_LENGTH] = { 0, }; glfs_t *fs = NULL; glfs_object_t *object = NULL; struct stat statbuf = { 0, }; svs_inode_t *inode_ctx = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); GF_VALIDATE_OR_GOTO(this->name, buf, out); GF_VALIDATE_OR_GOTO(this->name, postparent, out); if (gf_uuid_is_null(loc->gfid) && gf_uuid_is_null(loc->inode->gfid)) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_NULL_GFID, "gfid is NULL"); goto out; } if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(handle_obj, loc->inode->gfid, GFAPI_HANDLE_LENGTH); else memcpy(handle_obj, loc->gfid, GFAPI_HANDLE_LENGTH); fs = svs_get_latest_snapshot(this); if (!fs) { op_ret = -1; *op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, *op_errno, SVS_MSG_GET_LATEST_SNAP_FAILED, "failed to get the latest " "snapshot"); goto out; } object = glfs_h_create_from_handle(fs, handle_obj, GFAPI_HANDLE_LENGTH, &statbuf); if (!object) { op_ret = -1; *op_errno = ESTALE; gf_msg(this->name, GF_LOG_ERROR, *op_errno, SVS_MSG_GET_GLFS_H_OBJECT_FAILED, "failed to do lookup and get " "the handle on the snapshot %s (path: %s, gfid: %s)", loc->name, loc->path, uuid_utoa(loc->gfid)); goto out; } inode_ctx = svs_inode_ctx_get_or_new(this, loc->inode); if (!inode_ctx) { op_ret = -1; *op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, *op_errno, SVS_MSG_NEW_INODE_CTX_FAILED, "failed to allocate inode " "context"); goto out; } iatt_from_stat(buf, &statbuf); if (!gf_uuid_is_null(loc->gfid)) gf_uuid_copy(buf->ia_gfid, loc->gfid); else gf_uuid_copy(buf->ia_gfid, loc->inode->gfid); inode_ctx->type = SNAP_VIEW_VIRTUAL_INODE; inode_ctx->fs = fs; inode_ctx->object = object; memcpy(&inode_ctx->buf, buf, sizeof(*buf)); svs_iatt_fill(buf->ia_gfid, postparent); op_ret = 0; out: return op_ret; } /* If the parent is an entry point inode, then create the handle for the snapshot on which lookup came. i.e in reality lookup came on the directory from which the entry point directory was entered, but lookup is into the past. So create the handle for it by doing the name-less lookup on the gfid (which can be obtained from parent's context */ static int32_t svs_lookup_snapshot(xlator_t *this, loc_t *loc, struct iatt *buf, struct iatt *postparent, inode_t *parent, svs_inode_t *parent_ctx, int32_t *op_errno) { int32_t op_ret = -1; unsigned char handle_obj[GFAPI_HANDLE_LENGTH] = { 0, }; glfs_t *fs = NULL; glfs_object_t *object = NULL; struct stat statbuf = { 0, }; svs_inode_t *inode_ctx = NULL; uuid_t gfid; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); GF_VALIDATE_OR_GOTO(this->name, buf, out); GF_VALIDATE_OR_GOTO(this->name, postparent, out); GF_VALIDATE_OR_GOTO(this->name, parent_ctx, out); GF_VALIDATE_OR_GOTO(this->name, parent, out); fs = svs_initialise_snapshot_volume(this, loc->name, op_errno); if (!fs) { gf_msg_debug(this->name, 0, "failed to create " "the fs instance for snap %s", loc->name); *op_errno = ENOENT; op_ret = -1; goto out; } memcpy(handle_obj, parent_ctx->pargfid, GFAPI_HANDLE_LENGTH); object = glfs_h_create_from_handle(fs, handle_obj, GFAPI_HANDLE_LENGTH, &statbuf); if (!object) { op_ret = -1; *op_errno = errno; /* Should this be in warning or error mode? */ gf_msg_debug(this->name, 0, "failed to do lookup and " "get the handle on the snapshot %s", loc->name); goto out; } inode_ctx = svs_inode_ctx_get_or_new(this, loc->inode); if (!inode_ctx) { op_ret = -1; *op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, *op_errno, SVS_MSG_NEW_INODE_CTX_FAILED, "failed to allocate " "inode context"); goto out; } if (gf_uuid_is_null(loc->gfid) && gf_uuid_is_null(loc->inode->gfid)) gf_uuid_generate(gfid); else { if (!gf_uuid_is_null(loc->inode->gfid)) gf_uuid_copy(gfid, loc->inode->gfid); else gf_uuid_copy(gfid, loc->gfid); } iatt_from_stat(buf, &statbuf); gf_uuid_copy(buf->ia_gfid, gfid); svs_fill_ino_from_gfid(buf); inode_ctx->type = SNAP_VIEW_SNAPSHOT_INODE; inode_ctx->fs = fs; inode_ctx->object = object; memcpy(&inode_ctx->buf, buf, sizeof(*buf)); svs_iatt_fill(parent->gfid, postparent); SVS_STRDUP(inode_ctx->snapname, loc->name); if (!inode_ctx->snapname) { op_ret = -1; *op_errno = ENOMEM; goto out; } op_ret = 0; out: if (op_ret) { if (object) glfs_h_close(object); if (inode_ctx) inode_ctx->object = NULL; } return op_ret; } /* Both parent and entry are from snapshot world */ int32_t svs_lookup_entry(xlator_t *this, loc_t *loc, struct iatt *buf, struct iatt *postparent, inode_t *parent, svs_inode_t *parent_ctx, int32_t *op_errno) { int32_t op_ret = -1; glfs_t *fs = NULL; glfs_object_t *object = NULL; struct stat statbuf = { 0, }; svs_inode_t *inode_ctx = NULL; glfs_object_t *parent_object = NULL; uuid_t gfid = { 0, }; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); GF_VALIDATE_OR_GOTO(this->name, buf, out); GF_VALIDATE_OR_GOTO(this->name, postparent, out); GF_VALIDATE_OR_GOTO(this->name, parent_ctx, out); GF_VALIDATE_OR_GOTO(this->name, parent, out); parent_object = parent_ctx->object; fs = parent_ctx->fs; object = glfs_h_lookupat(fs, parent_object, loc->name, &statbuf, 0); if (!object) { /* should this be in WARNING or ERROR mode? */ gf_msg_debug(this->name, 0, "failed to do lookup and " "get the handle for entry %s (path: %s)", loc->name, loc->path); op_ret = -1; *op_errno = errno; goto out; } if (gf_uuid_is_null(object->gfid)) { /* should this be in WARNING or ERROR mode? */ gf_msg_debug(this->name, 0, "gfid from glfs handle is " "NULL for entry %s (path: %s)", loc->name, loc->path); op_ret = -1; *op_errno = errno; goto out; } inode_ctx = svs_inode_ctx_get_or_new(this, loc->inode); if (!inode_ctx) { op_ret = -1; *op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, *op_errno, SVS_MSG_NEW_INODE_CTX_FAILED, "failed to allocate " "inode context"); goto out; } if (gf_uuid_is_null(loc->gfid) && gf_uuid_is_null(loc->inode->gfid)) { if (svs_uuid_generate(this, gfid, parent_ctx->snapname, object->gfid)) { /* * should op_errno be something else such as * EINVAL or ESTALE? */ op_ret = -1; *op_errno = EIO; goto out; } } else { if (!gf_uuid_is_null(loc->inode->gfid)) gf_uuid_copy(gfid, loc->inode->gfid); else gf_uuid_copy(gfid, loc->gfid); } iatt_from_stat(buf, &statbuf); gf_uuid_copy(buf->ia_gfid, gfid); svs_fill_ino_from_gfid(buf); inode_ctx->type = SNAP_VIEW_VIRTUAL_INODE; inode_ctx->fs = fs; inode_ctx->object = object; memcpy(&inode_ctx->buf, buf, sizeof(*buf)); svs_iatt_fill(parent->gfid, postparent); if (IA_ISDIR(buf->ia_type)) { SVS_STRDUP(inode_ctx->snapname, parent_ctx->snapname); if (!inode_ctx->snapname) { op_ret = -1; *op_errno = ENOMEM; goto out; } } op_ret = 0; out: if (op_ret) { if (object) glfs_h_close(object); if (inode_ctx) inode_ctx->object = NULL; } return op_ret; } /* inode context is there means lookup has come on an object which was built either as part of lookup or as part of readdirp. But in readdirp we would not have got the handle to access the object in the gfapi world. So if inode context contains glfs_t instance for the right gfapi world and glfs_object_t handle for accessing it in the gfapi world, then unwind with success as the snapshots as of now are read-only. If the above condition is not met, then send lookup call again to the gfapi world. It can happen only if both parent context and the name of the entry are present. If parent is an entry point to snapshot world: * parent is needed for getting the gfid on which lookup has to be done (the gfid present in the inode is a virtual gfid) in the snapshot world. * name is required to get the right glfs_t instance on which lookup has to be done If parent is a directory from snapshot world: * parent context is needed to get the glfs_t instance and to get the handle to parent directory in the snapshot world. * name is needed to do the lookup on the right entry in the snapshot world */ int32_t svs_revalidate(xlator_t *this, loc_t *loc, inode_t *parent, svs_inode_t *inode_ctx, svs_inode_t *parent_ctx, struct iatt *buf, struct iatt *postparent, int32_t *op_errno) { int32_t op_ret = -1; int ret = -1; char tmp_uuid[64] = { 0, }; glfs_t *fs = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, buf, out); GF_VALIDATE_OR_GOTO(this->name, postparent, out); GF_VALIDATE_OR_GOTO(this->name, inode_ctx, out); if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { svs_iatt_fill(loc->inode->gfid, buf); if (parent) svs_iatt_fill(parent->gfid, postparent); else svs_iatt_fill(loc->inode->gfid, postparent); op_ret = 0; goto out; } else { /* Though fs and object are present in the inode context, its * better to check if fs is valid or not before doing anything. * Its for the protection from the following operations. * 1) Create a file on the glusterfs mount point * 2) Create a snapshot (say "snap1") * 3) Access the contents of the snapshot * 4) Delete the file from the mount point * 5) Delete the snapshot "snap1" * 6) Create a new snapshot "snap1" * * Now accessing the new snapshot "snap1" gives problems. * Because the inode and dentry created for snap1 would not be * deleted upon the deletion of the snapshot (as deletion of * snapshot is a gluster cli operation, not a fop). So next time * upon creation of a new snap with same name, the previous * inode and dentry itself will be used. But the inode context * contains old information about the glfs_t instance and the * handle in the gfapi world. Thus the glfs_t instance should * be checked before accessing. If its wrong, then right * instance should be obtained by doing the lookup. */ if (inode_ctx->fs && inode_ctx->object) { fs = inode_ctx->fs; SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this); if (fs) { memcpy(buf, &inode_ctx->buf, sizeof(*buf)); if (parent) svs_iatt_fill(parent->gfid, postparent); else svs_iatt_fill(buf->ia_gfid, postparent); op_ret = 0; goto out; } else { inode_ctx->fs = NULL; inode_ctx->object = NULL; ret = svs_get_handle(this, loc, inode_ctx, op_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, *op_errno, SVS_MSG_GET_GLFS_H_OBJECT_FAILED, "failed to get the handle for " "%s (gfid %s)", loc->path, uuid_utoa_r(loc->inode->gfid, tmp_uuid)); op_ret = -1; goto out; } } } /* To send the lookup to gfapi world, both the name of the entry as well as the parent context is needed. */ if (!loc->name || !parent_ctx) { *op_errno = ESTALE; gf_msg(this->name, GF_LOG_ERROR, *op_errno, SVS_MSG_PARENT_CTX_OR_NAME_NULL, "%s is NULL", loc->name ? "parent context" : "loc->name"); goto out; } if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { inode_ref(parent); op_ret = svs_lookup_snapshot(this, loc, buf, postparent, parent, parent_ctx, op_errno); } else op_ret = svs_lookup_entry(this, loc, buf, postparent, parent, parent_ctx, op_errno); goto out; } out: return op_ret; } int32_t svs_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { struct iatt buf = { 0, }; int32_t op_ret = -1; int32_t op_errno = EINVAL; struct iatt postparent = { 0, }; svs_inode_t *inode_ctx = NULL; svs_inode_t *parent_ctx = NULL; int32_t ret = -1; inode_t *parent = NULL; gf_boolean_t entry_point_key = _gf_false; gf_boolean_t entry_point = _gf_false; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("svs", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } /* For lookups sent on inodes (i.e not parent inode + basename, but direct inode itself which usually is a nameless lookup or revalidate on the inode), loc->name will not be there. Get it from path if it is there. This is the difference between nameless lookup and revalidate lookup on an inode: nameless lookup: loc->path contains gfid and strrchr on it fails revalidate lookup: loc->path contains the entry name of the inode and strrchr gives the name of the entry from path */ if (loc->path) { if (!loc->name || (loc->name && !strcmp(loc->name, ""))) { loc->name = strrchr(loc->path, '/'); if (loc->name) loc->name++; } } if (loc->parent) parent = inode_ref(loc->parent); else { parent = inode_find(loc->inode->table, loc->pargfid); if (!parent) parent = inode_parent(loc->inode, NULL, NULL); } if (parent) parent_ctx = svs_inode_ctx_get(this, parent); inode_ctx = svs_inode_ctx_get(this, loc->inode); if (xdata && !inode_ctx) { ret = dict_get_str_boolean(xdata, "entry-point", _gf_false); if (ret == -1) { gf_msg_debug(this->name, 0, "failed to get the " "entry point info"); entry_point_key = _gf_false; } else { entry_point_key = ret; } if (loc->name && strlen(loc->name)) { /* lookup can come with the entry-point set in the dict * for the parent directory of the entry-point as well. * So consider entry_point only for named lookup */ entry_point = entry_point_key; } } if (inode_ctx && inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { /* entry-point may not be set in the dictonary. * This can happen if snap-view client is restarted where * inode-ctx not available and a nameless lookup has come */ entry_point = _gf_true; } /* lookup is on the entry point to the snapshot world */ if (entry_point) { op_ret = svs_lookup_entry_point(this, loc, parent, &buf, &postparent, &op_errno); goto out; } /* revalidate */ if (inode_ctx) { op_ret = svs_revalidate(this, loc, parent, inode_ctx, parent_ctx, &buf, &postparent, &op_errno); goto out; } /* This can happen when entry point directory is entered from non-root directory. (ex: if /mnt/glusterfs is the mount point, then entry point (say .snaps) is entered from /mnt/glusterfs/dir/.snaps). Also it can happen when client sends a nameless lookup on just a gfid and the server does not have the inode in the inode table. */ if (!inode_ctx && !parent_ctx) { if (gf_uuid_is_null(loc->gfid) && gf_uuid_is_null(loc->inode->gfid)) { op_ret = -1; op_errno = ESTALE; gf_msg_debug(this->name, 0, "gfid is NULL. Either the lookup " "came on missing entry or the " "entry is stale"); goto out; } if (!entry_point_key) { /* This can happen when there is no inode_ctx available. * snapview-server might have restarted or * graph change might have happened */ op_ret = -1; op_errno = ESTALE; goto out; } /* lookup is on the parent directory of entry-point. * this would have already looked up by snap-view client * so return success */ if (!gf_uuid_is_null(loc->gfid)) gf_uuid_copy(buf.ia_gfid, loc->gfid); else gf_uuid_copy(buf.ia_gfid, loc->inode->gfid); svs_iatt_fill(buf.ia_gfid, &buf); svs_iatt_fill(buf.ia_gfid, &postparent); op_ret = 0; goto out; } if (parent_ctx) { if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { inode_ref(parent); op_ret = svs_lookup_snapshot(this, loc, &buf, &postparent, parent, parent_ctx, &op_errno); } else op_ret = svs_lookup_entry(this, loc, &buf, &postparent, parent, parent_ctx, &op_errno); goto out; } out: STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, loc ? loc->inode : NULL, &buf, xdata, &postparent); if (parent) inode_unref(parent); return 0; } int32_t svs_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { svs_inode_t *inode_ctx = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; svs_fd_t *svs_fd = NULL; glfs_fd_t *glfd = NULL; glfs_t *fs = NULL; glfs_object_t *object = NULL; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } inode_ctx = svs_inode_ctx_get(this, loc->inode); if (!inode_ctx) { op_ret = -1; op_errno = ESTALE; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found " "for the inode %s", uuid_utoa(loc->inode->gfid)); goto out; } /* Fake success is sent if the opendir is on the entry point directory or the inode is SNAP_VIEW_ENTRY_POINT_INODE */ if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { op_ret = 0; op_errno = 0; goto out; } else { SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret, op_errno, out); glfd = glfs_h_opendir(fs, object); if (!glfd) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_OPENDIR_FAILED, "opendir on %s failed " "(gfid: %s)", loc->name, uuid_utoa(loc->inode->gfid)); goto out; } svs_fd = svs_fd_ctx_get_or_new(this, fd); if (!svs_fd) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NEW_FD_CTX_FAILED, "failed to allocate fd context " "for %s (gfid: %s)", loc->name, uuid_utoa(fd->inode->gfid)); glfs_closedir(glfd); goto out; } svs_fd->fd = glfd; op_ret = 0; op_errno = 0; } out: STACK_UNWIND_STRICT(opendir, frame, op_ret, op_errno, fd, NULL); return 0; } /* * This function adds the xattr keys present in the list (@list) to the dict. * But the list contains only the names of the xattrs (and no value, as * the gfapi functions for the listxattr operations would return only the * names of the xattrs in the buffer provided by the caller, though they had * got the values of those xattrs from posix) as described in the man page of * listxattr. But before unwinding snapview-server has to put those names * back into the dict. But to get the values for those xattrs it has to do the * getxattr operation on each xattr which might turn out to be a costly * operation. So for each of the xattrs present in the list, a 0 byte value * ("") is set into the dict before unwinding. Since ("") is also a valid xattr * value(in a file system) we use an extra key in the same dictionary as an * indicator to other xlators which want to cache the xattrs (as of now, * md-cache which caches acl and selinux related xattrs) to not to cache the * values of the xattrs present in the dict. */ int32_t svs_add_xattrs_to_dict(xlator_t *this, dict_t *dict, char *list, ssize_t size) { char keybuffer[4096] = { 0, }; size_t remaining_size = 0; int32_t list_offset = 0; int32_t ret = -1; GF_VALIDATE_OR_GOTO("snapview-daemon", this, out); GF_VALIDATE_OR_GOTO(this->name, dict, out); GF_VALIDATE_OR_GOTO(this->name, list, out); remaining_size = size; list_offset = 0; while (remaining_size > 0) { strncpy(keybuffer, list + list_offset, sizeof(keybuffer) - 1); #ifdef GF_DARWIN_HOST_OS /* The protocol expect namespace for now */ char *newkey = NULL; gf_add_prefix(XATTR_USER_PREFIX, keybuffer, &newkey); strcpy(keybuffer, newkey); GF_FREE(newkey); #endif ret = dict_set_str(dict, keybuffer, ""); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_DICT_SET_FAILED, "dict set operation " "for the key %s failed.", keybuffer); goto out; } remaining_size -= strlen(keybuffer) + 1; list_offset += strlen(keybuffer) + 1; } /* while (remaining_size > 0) */ /* Add an additional key to indicate that we don't need to cache these * xattrs(with value "") */ ret = dict_set_str(dict, "glusterfs.skip-cache", ""); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_DICT_SET_FAILED, "dict set operation for the key glusterfs.skip-cache failed."); goto out; } ret = 0; out: return ret; } static int32_t svs_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { svs_inode_t *inode_ctx = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; glfs_t *fs = NULL; glfs_object_t *object = NULL; char *value = 0; ssize_t size = 0; dict_t *dict = NULL; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO("snap-view-daemon", frame, out); GF_VALIDATE_OR_GOTO("snap-view-daemon", loc, out); GF_VALIDATE_OR_GOTO("snap-view-daemon", loc->inode, out); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } inode_ctx = svs_inode_ctx_get(this, loc->inode); if (!inode_ctx) { op_ret = -1; op_errno = ESTALE; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found " "for the inode %s", uuid_utoa(loc->inode->gfid)); goto out; } /* ENODATA is sent if the getxattr is on entry point directory or the inode is SNAP_VIEW_ENTRY_POINT_INODE. Entry point is a virtual directory on which setxattr operations are not allowed. If getxattr has to be faked as success, then a value for the name of the xattr has to be sent which we don't have. */ if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { op_ret = -1; op_errno = ENODATA; goto out; } else { SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret, op_errno, out); dict = dict_new(); if (!dict) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NO_MEMORY, "failed to allocate dict"); goto out; } size = glfs_h_getxattrs(fs, object, name, NULL, 0); if (size == -1) { op_ret = -1; op_errno = errno; if (errno == ENODATA) { gf_msg_debug(this->name, errno, "getxattr on %s failed (ket: %s)", loc->path, name); } else { gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GETXATTR_FAILED, "getxattr on %s failed (key: %s) with %s", loc->path, name, strerror(errno)); } goto out; } value = GF_CALLOC(size + 1, sizeof(char), gf_common_mt_char); if (!value) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NO_MEMORY, "failed to allocate memory for getxattr " "on %s (key: %s)", loc->name, name); goto out; } size = glfs_h_getxattrs(fs, object, name, value, size); if (size == -1) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GETXATTR_FAILED, "failed to get the xattr %s for " "entry %s", name, loc->name); goto out; } value[size] = '\0'; if (name) { op_ret = dict_set_dynptr(dict, (char *)name, value, size); if (op_ret < 0) { op_errno = -op_ret; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_DICT_SET_FAILED, "dict set operation for %s for " "the key %s failed.", loc->path, name); GF_FREE(value); value = NULL; goto out; } } else { op_ret = svs_add_xattrs_to_dict(this, dict, value, size); if (op_ret == -1) { op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NO_MEMORY, "failed to add xattrs from the list to " "dict for %s (gfid: %s)", loc->path, uuid_utoa(loc->inode->gfid)); goto out; } GF_FREE(value); value = NULL; } } out: if (op_ret && value) GF_FREE(value); STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, NULL); if (dict) dict_unref(dict); return 0; } int32_t svs_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { svs_inode_t *inode_ctx = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; char *value = 0; ssize_t size = 0; dict_t *dict = NULL; svs_fd_t *sfd = NULL; glfs_fd_t *glfd = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO("snap-view-daemon", frame, out); GF_VALIDATE_OR_GOTO("snap-view-daemon", fd, out); GF_VALIDATE_OR_GOTO("snap-view-daemon", fd->inode, out); inode_ctx = svs_inode_ctx_get(this, fd->inode); if (!inode_ctx) { op_ret = -1; op_errno = ESTALE; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found " "for the inode %s", uuid_utoa(fd->inode->gfid)); goto out; } if (!(svs_inode_ctx_glfs_mapping(this, inode_ctx))) { op_ret = -1; op_errno = EBADF; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_FS_INSTANCE_INVALID, "glfs instance %p to which the inode %s " "belongs to does not exist. The snapshot " "corresponding to the instance might have" "been deleted or deactivated", inode_ctx->fs, uuid_utoa(fd->inode->gfid)); goto out; } sfd = svs_fd_ctx_get_or_new(this, fd); if (!sfd) { op_ret = -1; op_errno = EBADFD; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_FD_CONTEXT_FAILED, "failed to get the fd " "context for %s", uuid_utoa(fd->inode->gfid)); goto out; } glfd = sfd->fd; /* EINVAL is sent if the getxattr is on entry point directory or the inode is SNAP_VIEW_ENTRY_POINT_INODE. Entry point is a virtual directory on which setxattr operations are not allowed. If getxattr has to be faked as success, then a value for the name of the xattr has to be sent which we don't have. */ if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { op_ret = -1; op_errno = EINVAL; goto out; } else { dict = dict_new(); if (!dict) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NO_MEMORY, "failed to allocate dict " "(gfid: %s, key: %s)", uuid_utoa(fd->inode->gfid), name); goto out; } if (name) { size = glfs_fgetxattr(glfd, name, NULL, 0); if (size == -1) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GETXATTR_FAILED, "getxattr on %s failed " "(key: %s)", uuid_utoa(fd->inode->gfid), name); goto out; } value = GF_CALLOC(size + 1, sizeof(char), gf_common_mt_char); if (!value) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NO_MEMORY, "failed to " "allocate memory for getxattr on %s " "(key: %s)", uuid_utoa(fd->inode->gfid), name); goto out; } size = glfs_fgetxattr(glfd, name, value, size); if (size == -1) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GETXATTR_FAILED, "failed to get the xattr %s " "for inode %s", name, uuid_utoa(fd->inode->gfid)); goto out; } value[size] = '\0'; op_ret = dict_set_dynptr(dict, (char *)name, value, size); if (op_ret < 0) { op_errno = -op_ret; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_DICT_SET_FAILED, "dict set operation for gfid %s " "for the key %s failed.", uuid_utoa(fd->inode->gfid), name); goto out; } } else { size = glfs_flistxattr(glfd, NULL, 0); if (size == -1) { op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_LISTXATTR_FAILED, "listxattr on %s failed", uuid_utoa(fd->inode->gfid)); goto out; } value = GF_CALLOC(size + 1, sizeof(char), gf_common_mt_char); if (!value) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NO_MEMORY, "failed to " "allocate buffer for xattr " "list (%s)", uuid_utoa(fd->inode->gfid)); goto out; } size = glfs_flistxattr(glfd, value, size); if (size == -1) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_LISTXATTR_FAILED, "listxattr on %s failed", uuid_utoa(fd->inode->gfid)); goto out; } op_ret = svs_add_xattrs_to_dict(this, dict, value, size); if (op_ret == -1) { op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NO_MEMORY, "failed to add xattrs from the list " "to dict (gfid: %s)", uuid_utoa(fd->inode->gfid)); goto out; } GF_FREE(value); } op_ret = 0; op_errno = 0; } out: if (op_ret) GF_FREE(value); STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, NULL); if (dict) dict_unref(dict); return 0; } static int32_t svs_releasedir(xlator_t *this, fd_t *fd) { svs_fd_t *sfd = NULL; int ret = 0; svs_inode_t *svs_inode = NULL; glfs_t *fs = NULL; inode_t *inode = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); sfd = fd_ctx_del_ptr(fd, this); if (!sfd) { gf_msg_debug(this->name, 0, "pfd from fd=%p is NULL", fd); ret = -1; goto out; } inode = fd->inode; svs_inode = svs_inode_ctx_get(this, inode); if (svs_inode) { fs = svs_inode->fs; /* should inode->lock be held for this? */ SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this); if (fs) { if (sfd->fd) { ret = glfs_close(sfd->fd); if (ret) gf_msg(this->name, GF_LOG_WARNING, errno, SVS_MSG_RELEASEDIR_FAILED, "failed to close the glfd for " "directory %s", uuid_utoa(fd->inode->gfid)); } } } GF_FREE(sfd); out: return 0; } static int32_t svs_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int32_t op_ret = -1; int32_t op_errno = 0; uint64_t value = 0; svs_inode_t *inode_ctx = NULL; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } inode_ctx = svs_inode_ctx_get(this, fd->inode); if (!inode_ctx) { op_ret = -1; op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found for" " the inode %s", uuid_utoa(fd->inode->gfid)); goto out; } if (inode_ctx->type != SNAP_VIEW_ENTRY_POINT_INODE) { value = fd_ctx_get(fd, this); if (!value) { op_errno = EINVAL; gf_msg(this->name, GF_LOG_WARNING, op_errno, SVS_MSG_GET_FD_CONTEXT_FAILED, "pfd is NULL on fd=%p", fd); goto out; } } op_ret = 0; out: STACK_UNWIND_STRICT(flush, frame, op_ret, op_errno, NULL); return 0; } static int32_t svs_release(xlator_t *this, fd_t *fd) { svs_fd_t *sfd = NULL; int ret = 0; inode_t *inode = NULL; svs_inode_t *svs_inode = NULL; glfs_t *fs = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); sfd = fd_ctx_del_ptr(fd, this); if (!sfd) { gf_msg_debug(this->name, 0, "pfd from fd=%p is NULL", fd); ret = -1; goto out; } inode = fd->inode; svs_inode = svs_inode_ctx_get(this, inode); if (svs_inode) { fs = svs_inode->fs; /* should inode->lock be held for this? */ SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this); if (fs) { if (sfd->fd) { ret = glfs_close(sfd->fd); if (ret) gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_RELEASE_FAILED, "failed to close " "the glfd for %s", uuid_utoa(fd->inode->gfid)); } } } GF_FREE(sfd); out: return 0; } static int32_t svs_forget(xlator_t *this, inode_t *inode) { int ret = -1; uint64_t value = 0; svs_inode_t *inode_ctx = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); ret = inode_ctx_del(inode, this, &value); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_DELETE_INODE_CONTEXT_FAILED, "failed to delete the inode " "context of %s", uuid_utoa(inode->gfid)); goto out; } inode_ctx = (svs_inode_t *)(uintptr_t)value; if (!inode_ctx) goto out; if (inode_ctx->snapname) GF_FREE(inode_ctx->snapname); /* * glfs_h_close leads to unref and forgetting of the * underlying inode in the gfapi world. i.e. the inode * which inode_ctx->object points to. * As of now the only possibility is, this forget came as a * result of snapdaemon's inode table reaching the lru * limit and receiving forget as a result of purging of * extra inodes that exceeded the limit. But, care must * be taken to ensure that, the gfapi instance to which * the glfs_h_object belongs to is not deleted. Otherwise * this might result in access of a freed pointer. * This will still be helpful in reducing the memory * footprint of snapdaemon when the fs instance itself is * valid (i.e. present and not destroyed due to either snap * deactivate or snap delete), but the lru limit is reached. * The forget due to lru limit will make the underlying inode * being unrefed and forgotten. */ if (svs_inode_ctx_glfs_mapping(this, inode_ctx)) { glfs_h_close(inode_ctx->object); inode_ctx->object = NULL; } GF_FREE(inode_ctx); out: return 0; } static int svs_fill_readdir(xlator_t *this, gf_dirent_t *entries, int32_t *op_errno, size_t size, off_t off) { gf_dirent_t *entry = NULL; svs_private_t *priv = NULL; int i = 0; snap_dirent_t *dirents = NULL; int this_size = 0; int filled_size = 0; int count = 0; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO("snap-view-daemon", entries, out); priv = this->private; GF_ASSERT(priv); /* create the dir entries */ LOCK(&priv->snaplist_lock); { dirents = priv->dirents; for (i = off; i < priv->num_snaps;) { this_size = sizeof(gf_dirent_t) + strlen(dirents[i].name) + 1; if (this_size + filled_size > size) goto unlock; entry = gf_dirent_for_name(dirents[i].name); if (!entry) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, SVS_MSG_NO_MEMORY, "failed to allocate dentry for %s", dirents[i].name); goto unlock; } entry->d_off = i + 1; /* * readdir on the entry-point directory to the snapshot * world, will return elements in the list of the * snapshots as the directory entries. Since the entries * returned are virtual entries which does not exist * physically on the disk, pseudo inode numbers are * generated. */ entry->d_ino = i + 2 * 42; entry->d_type = DT_DIR; list_add_tail(&entry->list, &entries->list); ++i; count++; filled_size += this_size; } } unlock: UNLOCK(&priv->snaplist_lock); if (count == 0) { *op_errno = ENOENT; } out: return count; } static int32_t svs_glfs_readdir(xlator_t *this, glfs_fd_t *glfd, gf_dirent_t *entries, int32_t *op_errno, struct iatt *buf, gf_boolean_t readdirplus, size_t size) { int filled_size = 0; int this_size = 0; int32_t ret = -1; int32_t count = 0; gf_dirent_t *entry = NULL; struct dirent *dirents = NULL; struct dirent de = { 0, }; struct stat statbuf = { 0, }; off_t in_case = -1; GF_VALIDATE_OR_GOTO("svs", this, out); GF_VALIDATE_OR_GOTO(this->name, glfd, out); GF_VALIDATE_OR_GOTO(this->name, entries, out); while (filled_size < size) { in_case = glfs_telldir(glfd); if (in_case == -1) { gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_TELLDIR_FAILED, "telldir failed"); break; } if (readdirplus) ret = glfs_readdirplus_r(glfd, &statbuf, &de, &dirents); else ret = glfs_readdir_r(glfd, &de, &dirents); if (ret == 0 && dirents != NULL) { if (readdirplus) this_size = max(sizeof(gf_dirent_t), sizeof(gfx_dirplist)) + strlen(de.d_name) + 1; else this_size = sizeof(gf_dirent_t) + strlen(de.d_name) + 1; if (this_size + filled_size > size) { glfs_seekdir(glfd, in_case); break; } entry = gf_dirent_for_name(de.d_name); if (!entry) { /* * Since gf_dirent_for_name can return * NULL only when it fails to allocate * memory for the directory entry, * SVS_MSG_NO_MEMORY is used as the * message-id. */ gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_NO_MEMORY, "could not create gf_dirent " "for entry %s: (%s)", entry->d_name, strerror(errno)); break; } entry->d_off = glfs_telldir(glfd); entry->d_ino = de.d_ino; entry->d_type = de.d_type; if (readdirplus) { iatt_from_stat(buf, &statbuf); entry->d_stat = *buf; } list_add_tail(&entry->list, &entries->list); filled_size += this_size; count++; } else if (ret == 0 && dirents == NULL) { *op_errno = ENOENT; break; } else if (ret != 0) { *op_errno = errno; break; } dirents = NULL; } out: return count; } /* readdirp can be of 2 types. 1) It can come on entry point directory where the list of snapshots is sent as dirents. In this case, the iatt structure is filled on the fly if the inode is not found for the entry or the inode context is NULL. Other wise if inode is found and inode context is there the iatt structure saved in the context is used. 2) It can be on a directory in one of the snapshots. In this case, the readdirp call would have sent us a iatt structure. So the same structure is used with the exception that the gfid and the inode numbers will be newly generated and filled in. */ static void svs_readdirp_fill(xlator_t *this, inode_t *parent, svs_inode_t *parent_ctx, gf_dirent_t *entry) { inode_t *inode = NULL; uuid_t random_gfid = { 0, }; struct iatt buf = { 0, }; svs_inode_t *inode_ctx = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, parent, out); GF_VALIDATE_OR_GOTO(this->name, parent_ctx, out); GF_VALIDATE_OR_GOTO(this->name, entry, out); /* skip . and .. */ if (inode_dir_or_parentdir(entry)) goto out; inode = inode_grep(parent->table, parent, entry->d_name); if (inode) { entry->inode = inode; inode_ctx = svs_inode_ctx_get(this, inode); if (!inode_ctx) { gf_uuid_copy(buf.ia_gfid, inode->gfid); svs_iatt_fill(inode->gfid, &buf); buf.ia_type = inode->ia_type; } else { buf = inode_ctx->buf; } entry->d_ino = buf.ia_ino; if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) entry->d_stat = buf; else { entry->d_stat.ia_ino = buf.ia_ino; gf_uuid_copy(entry->d_stat.ia_gfid, buf.ia_gfid); } } else { if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { inode = inode_new(parent->table); /* If inode context allocation fails, then do not send * the inode for that particular entry as part of * readdirp response. Fuse and protocol/server will link * the inodes in readdirp only if the entry contains * inode in it. */ inode_ctx = svs_inode_ctx_get_or_new(this, inode); if (!inode_ctx) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, SVS_MSG_NO_MEMORY, "failed to allocate inode " "context for %s", entry->d_name); inode_unref(inode); goto out; } entry->inode = inode; /* Generate virtual gfid for SNAPSHOT dir and * update the statbuf */ gf_uuid_generate(random_gfid); gf_uuid_copy(buf.ia_gfid, random_gfid); svs_fill_ino_from_gfid(&buf); buf.ia_type = IA_IFDIR; entry->d_ino = buf.ia_ino; entry->d_stat = buf; inode_ctx->buf = buf; inode_ctx->type = SNAP_VIEW_SNAPSHOT_INODE; } else { /* For files under snapshot world do not set * entry->inode and reset statbuf (except ia_ino), * so that FUSE/Kernel will send an explicit lookup. * entry->d_stat contains the statbuf information * of original file, so for NFS not to cache this * information and to send explicit lookup, it is * required to reset the statbuf. * Virtual gfid for these files will be generated in the * first lookup. */ buf.ia_ino = entry->d_ino; entry->d_stat = buf; } } out: return; } /* In readdirp, though new inode is created along with the generation of new gfid, the inode context created will not contain the glfs_t instance for the filesystem it belongs to and the handle for it in the gfapi world. (handle is obtained only by doing the lookup call on the entry and doing lookup on each entry received as part of readdir call is a costly operation. So the fs and handle is NULL in the inode context and is filled in when lookup comes on that object. */ static int32_t svs_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *dict) { gf_dirent_t entries; gf_dirent_t *entry = NULL; struct iatt buf = { 0, }; int count = 0; int op_ret = -1; int op_errno = EINVAL; svs_inode_t *parent_ctx = NULL; svs_fd_t *svs_fd = NULL; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, unwind); GF_VALIDATE_OR_GOTO(this->name, frame, unwind); GF_VALIDATE_OR_GOTO(this->name, fd, unwind); GF_VALIDATE_OR_GOTO(this->name, fd->inode, unwind); INIT_LIST_HEAD(&entries.list); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto unwind; } parent_ctx = svs_inode_ctx_get(this, fd->inode); if (!parent_ctx) { op_ret = -1; op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "failed to get the inode " "context for %s", uuid_utoa(fd->inode->gfid)); goto unwind; } if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { LOCK(&fd->lock); { count = svs_fill_readdir(this, &entries, &op_errno, size, off); } UNLOCK(&fd->lock); op_ret = count; list_for_each_entry(entry, &entries.list, list) { svs_readdirp_fill(this, fd->inode, parent_ctx, entry); } goto unwind; } else { svs_fd = svs_fd_ctx_get_or_new(this, fd); if (!svs_fd) { op_ret = -1; op_errno = EBADFD; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_FD_CONTEXT_FAILED, "failed to get the fd context " "for the inode %s", uuid_utoa(fd->inode->gfid)); goto unwind; } glfs_seekdir(svs_fd->fd, off); LOCK(&fd->lock); { count = svs_glfs_readdir(this, svs_fd->fd, &entries, &op_errno, &buf, _gf_true, size); } UNLOCK(&fd->lock); op_ret = count; list_for_each_entry(entry, &entries.list, list) { svs_readdirp_fill(this, fd->inode, parent_ctx, entry); } goto unwind; } unwind: STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, &entries, dict); gf_dirent_free(&entries); return 0; } static int32_t svs_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { gf_dirent_t entries = { { { 0, }, }, }; int count = 0; svs_inode_t *inode_ctx = NULL; int op_errno = EINVAL; int op_ret = -1; svs_fd_t *svs_fd = NULL; glfs_fd_t *glfd = NULL; INIT_LIST_HEAD(&entries.list); GF_VALIDATE_OR_GOTO("snap-view-server", this, unwind); GF_VALIDATE_OR_GOTO(this->name, frame, unwind); GF_VALIDATE_OR_GOTO(this->name, fd, unwind); GF_VALIDATE_OR_GOTO(this->name, fd->inode, unwind); inode_ctx = svs_inode_ctx_get(this, fd->inode); if (!inode_ctx) { op_ret = -1; op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found in " "the inode %s", uuid_utoa(fd->inode->gfid)); goto unwind; } if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { LOCK(&fd->lock); { count = svs_fill_readdir(this, &entries, &op_errno, size, off); } UNLOCK(&fd->lock); } else { svs_fd = svs_fd_ctx_get_or_new(this, fd); if (!svs_fd) { op_ret = -1; op_errno = EBADFD; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_FD_CONTEXT_FAILED, "failed to get the fd " "context for %s", uuid_utoa(fd->inode->gfid)); goto unwind; } glfd = svs_fd->fd; LOCK(&fd->lock); { count = svs_glfs_readdir(this, glfd, &entries, &op_errno, NULL, _gf_false, size); } UNLOCK(&fd->lock); } op_ret = count; unwind: STACK_UNWIND_STRICT(readdir, frame, op_ret, op_errno, &entries, xdata); gf_dirent_free(&entries); return 0; } /* * This function is mainly helpful for NFS. Till now NFS server was not linking * the inodes in readdirp, which caused problems when below operations were * performed. * * 1) ls -l in one of the snaopshots (snapview-server would generate gfids for * each entry on the fly and link the inodes associated with those entries) * 2) NFS server upon getting readdirp reply would not link the inodes of the * entries. But it used to generate filehandles for each entry and associate * the gfid of that entry with the filehandle and send it as part of the * reply to nfs client. * 3) NFS client would send the filehandle of one of those entries when some * activity is done on it. * 4) NFS server would not be able to find the inode for the gfid present in the * filehandle (as the inode was not linked) and would go for hard resolution * by sending a lookup on the gfid by creating a new inode. * 5) snapview-client will not able to identify whether the inode is a real * inode existing in the main volume or a virtual inode existing in the * snapshots as there would not be any inode context. * 6) Since the gfid upon which lookup is sent is a virtual gfid which is not * present in the disk, lookup would fail and the application would get an * error. * * The above problem is fixed by the below commit which makes snapview server * more compatible with nfs server (1dea949cb60c3814c9206df6ba8dddec8d471a94). * But now because NFS server does inode linking in readdirp has introduced * the below issue. * In readdirp though snapview-server allocates inode contexts it does not * actually perform lookup on each entry it obtained in readdirp (as doing * a lookup via gfapi over the network for each entry would be costly). * * Till now it was not a problem with NFS server, as NFS was sending a lookup on * the gfid it got from NFS client, for which it was not able to find the right * inode. So snapview-server was able to get the fs instance (glfs_t) of the * snapshot volume to which the entry belongs to, and the handle for the entry * from the corresponding snapshot volume and fill those information in the * inode context. * * But now, since NFS server is able to find the inode from the inode table for * the gfid it got from the NFS client, it won't send lookup. Rather it directly * sends the fop it received from the client. Now this causes problems for * snapview-server. Because for each fop snapview-server assumes that lookup has * been performed on that entry and the entry's inode context contains the * pointers for the fs instance and the handle to the entry in that fs. When NFS * server sends the fop and snapview-server finds that the fs instance and the * handle within the inode context are NULL it unwinds with EINVAL. * * So to handle this, if fs instance or handle within the inode context are * NULL, then do a lookup based on parent inode context's fs instance. And * unwind the results obtained as part of lookup */ int32_t svs_get_handle(xlator_t *this, loc_t *loc, svs_inode_t *inode_ctx, int32_t *op_errno) { svs_inode_t *parent_ctx = NULL; int ret = -1; inode_t *parent = NULL; struct iatt postparent = { 0, }; struct iatt buf = { 0, }; char uuid1[64]; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); if (loc->path) { if (!loc->name || (loc->name && !strcmp(loc->name, ""))) { loc->name = strrchr(loc->path, '/'); if (loc->name) loc->name++; } } if (loc->parent) parent = inode_ref(loc->parent); else { parent = inode_find(loc->inode->table, loc->pargfid); if (!parent) parent = inode_parent(loc->inode, NULL, NULL); } if (parent) parent_ctx = svs_inode_ctx_get(this, parent); if (!parent_ctx) { *op_errno = EINVAL; gf_msg(this->name, GF_LOG_WARNING, *op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "failed to get the parent " "context for %s (%s)", loc->path, uuid_utoa_r(loc->inode->gfid, uuid1)); goto out; } if (parent_ctx) { if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { inode_ref(parent); ret = svs_lookup_snapshot(this, loc, &buf, &postparent, parent, parent_ctx, op_errno); } else ret = svs_lookup_entry(this, loc, &buf, &postparent, parent, parent_ctx, op_errno); } out: if (parent) inode_unref(parent); return ret; } int32_t svs_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { struct iatt buf = { 0, }; int32_t op_errno = EINVAL; int32_t op_ret = -1; svs_inode_t *inode_ctx = NULL; glfs_t *fs = NULL; glfs_object_t *object = NULL; struct stat stat = { 0, }; int ret = -1; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } /* Instead of doing the check of whether it is a entry point directory or not by checking the name of the entry and then deciding what to do, just check the inode context and decide what to be done. */ inode_ctx = svs_inode_ctx_get(this, loc->inode); if (!inode_ctx) { op_ret = -1; op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found for %s", uuid_utoa(loc->inode->gfid)); goto out; } if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { svs_iatt_fill(loc->inode->gfid, &buf); op_ret = 0; } else { SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret, op_errno, out); ret = glfs_h_stat(fs, object, &stat); if (ret) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_STAT_FAILED, "glfs_h_stat on %s (gfid: %s) " "failed", loc->name, uuid_utoa(loc->inode->gfid)); goto out; } else gf_msg_debug(this->name, 0, "stat on %s (%s) successful", loc->path, uuid_utoa(loc->inode->gfid)); iatt_from_stat(&buf, &stat); gf_uuid_copy(buf.ia_gfid, loc->inode->gfid); svs_fill_ino_from_gfid(&buf); op_ret = ret; } out: STACK_UNWIND_STRICT(stat, frame, op_ret, op_errno, &buf, xdata); return 0; } int32_t svs_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { struct iatt buf = { 0, }; int32_t op_errno = EINVAL; int32_t op_ret = -1; svs_inode_t *inode_ctx = NULL; struct stat stat = { 0, }; int ret = -1; glfs_fd_t *glfd = NULL; svs_fd_t *sfd = NULL; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); /* Instead of doing the check of whether it is a entry point directory or not by checking the name of the entry and then deciding what to do, just check the inode context and decide what to be done. */ root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } inode_ctx = svs_inode_ctx_get(this, fd->inode); if (!inode_ctx) { op_ret = -1; op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found for" " the inode %s", uuid_utoa(fd->inode->gfid)); goto out; } if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { svs_iatt_fill(fd->inode->gfid, &buf); op_ret = 0; } else { if (!(svs_inode_ctx_glfs_mapping(this, inode_ctx))) { op_ret = -1; op_errno = EBADF; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_FS_INSTANCE_INVALID, "glfs instance %p to which the inode %s " "belongs to does not exist. That snapshot " "corresponding to the fs instance " "might have been deleted or deactivated.", inode_ctx->fs, uuid_utoa(fd->inode->gfid)); goto out; } sfd = svs_fd_ctx_get_or_new(this, fd); if (!sfd) { op_ret = -1; op_errno = EBADFD; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_FD_CONTEXT_FAILED, "failed to get the fd context " "for %s", uuid_utoa(fd->inode->gfid)); goto out; } glfd = sfd->fd; ret = glfs_fstat(glfd, &stat); if (ret) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_STAT_FAILED, "glfs_fstat on gfid: %s failed", uuid_utoa(fd->inode->gfid)); goto out; } iatt_from_stat(&buf, &stat); gf_uuid_copy(buf.ia_gfid, fd->inode->gfid); svs_fill_ino_from_gfid(&buf); op_ret = ret; } out: STACK_UNWIND_STRICT(fstat, frame, op_ret, op_errno, &buf, xdata); return 0; } static int32_t svs_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { struct statvfs buf = { 0, }; int32_t op_errno = EINVAL; int32_t op_ret = -1; svs_inode_t *inode_ctx = NULL; glfs_t *fs = NULL; glfs_object_t *object = NULL; int ret = -1; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } /* Instead of doing the check of whether it is a entry point directory or not by checking the name of the entry and then deciding what to do, just check the inode context and decide what to be done. */ inode_ctx = svs_inode_ctx_get(this, loc->inode); if (!inode_ctx) { op_ret = -1; op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found for %s", uuid_utoa(loc->inode->gfid)); goto out; } SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret, op_errno, out); ret = glfs_h_statfs(fs, object, &buf); if (ret) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_STATFS_FAILED, "glfs_h_statvfs on %s (gfid: %s) " "failed", loc->name, uuid_utoa(loc->inode->gfid)); goto out; } op_ret = ret; out: STACK_UNWIND_STRICT(statfs, frame, op_ret, op_errno, &buf, xdata); return 0; } static int32_t svs_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { svs_inode_t *inode_ctx = NULL; svs_fd_t *sfd = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; glfs_fd_t *glfd = NULL; glfs_t *fs = NULL; glfs_object_t *object = NULL; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); root = frame->root; inode_ctx = svs_inode_ctx_get(this, loc->inode); if (!inode_ctx) { gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context for %s (gfid: %s) " "not found", loc->name, uuid_utoa(loc->inode->gfid)); goto out; } if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { op_ret = 0; op_errno = 0; goto out; } else { SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret, op_errno, out); op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } glfd = glfs_h_open(fs, object, flags); if (!glfd) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_OPEN_FAILED, "glfs_h_open on %s failed (gfid: %s)", loc->name, uuid_utoa(loc->inode->gfid)); goto out; } sfd = svs_fd_ctx_get_or_new(this, fd); if (!sfd) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NO_MEMORY, "failed to allocate fd context " "for %s (gfid: %s)", loc->name, uuid_utoa(loc->inode->gfid)); glfs_close(glfd); goto out; } sfd->fd = glfd; op_ret = 0; } out: STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, NULL); return 0; } static int32_t svs_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { int32_t op_ret = -1; int32_t op_errno = 0; svs_private_t *priv = NULL; struct iobuf *iobuf = NULL; struct iobref *iobref = NULL; struct iovec vec = { 0, }; svs_fd_t *sfd = NULL; int ret = -1; struct glfs_stat fstatbuf = { 0, }; glfs_fd_t *glfd = NULL; struct iatt stbuf = { 0, }; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); priv = this->private; VALIDATE_OR_GOTO(priv, out); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } if (!svs_inode_glfs_mapping(this, fd->inode)) { op_ret = -1; op_errno = EBADF; /* should this be some other error? */ gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_FS_INSTANCE_INVALID, "glfs instance to which the inode " "%s receiving read request belongs, " "does not exist anymore", uuid_utoa(fd->inode->gfid)); goto out; } sfd = svs_fd_ctx_get_or_new(this, fd); if (!sfd) { op_ret = -1; op_errno = EBADFD; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "failed to get the fd " "context for %s", uuid_utoa(fd->inode->gfid)); goto out; } glfd = sfd->fd; iobuf = iobuf_get2(this->ctx->iobuf_pool, size); if (!iobuf) { op_ret = -1; op_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_NO_MEMORY, "failed to " "allocate iobuf while reading the " "file with gfid %s", uuid_utoa(fd->inode->gfid)); goto out; } ret = glfs_pread(glfd, iobuf->ptr, size, offset, 0, &fstatbuf); if (ret < 0) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_READ_FAILED, "glfs_read failed on %s (%s)", uuid_utoa(fd->inode->gfid), strerror(op_errno)); goto out; } vec.iov_base = iobuf->ptr; vec.iov_len = ret; iobref = iobref_new(); iobref_add(iobref, iobuf); glfs_iatt_from_statx(&stbuf, &fstatbuf); gf_uuid_copy(stbuf.ia_gfid, fd->inode->gfid); svs_fill_ino_from_gfid(&stbuf); /* Hack to notify higher layers of EOF. */ if (!stbuf.ia_size || (offset + vec.iov_len) >= stbuf.ia_size) op_errno = ENOENT; op_ret = vec.iov_len; out: STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, &vec, 1, &stbuf, iobref, NULL); if (iobref) iobref_unref(iobref); if (iobuf) iobuf_unref(iobuf); return 0; } static int32_t svs_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { svs_inode_t *inode_ctx = NULL; glfs_t *fs = NULL; glfs_object_t *object = NULL; int op_ret = -1; int op_errno = EINVAL; char *buf = NULL; struct iatt stbuf = { 0, }; int ret = -1; struct stat stat = { 0, }; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } inode_ctx = svs_inode_ctx_get(this, loc->inode); if (!inode_ctx) { op_ret = -1; op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "failed to get inode context " "for %s (gfid: %s)", loc->name, uuid_utoa(loc->inode->gfid)); goto out; } SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret, op_errno, out); ret = glfs_h_stat(fs, object, &stat); if (ret) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_STAT_FAILED, "glfs_h_stat on %s (gfid: %s) " "failed", loc->name, uuid_utoa(loc->inode->gfid)); goto out; } iatt_from_stat(&stbuf, &stat); gf_uuid_copy(stbuf.ia_gfid, loc->inode->gfid); svs_fill_ino_from_gfid(&stbuf); buf = alloca(size + 1); op_ret = glfs_h_readlink(fs, object, buf, size); if (op_ret == -1) { op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_READLINK_FAILED, "readlink on %s failed (gfid: %s)", loc->name, uuid_utoa(loc->inode->gfid)); goto out; } buf[op_ret] = 0; out: STACK_UNWIND_STRICT(readlink, frame, op_ret, op_errno, buf, &stbuf, NULL); return 0; } int32_t svs_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int mask, dict_t *xdata) { int ret = -1; int32_t op_ret = -1; int32_t op_errno = EINVAL; glfs_t *fs = NULL; glfs_object_t *object = NULL; svs_inode_t *inode_ctx = NULL; gf_boolean_t is_fuse_call = 0; int mode = 0; call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO("svs", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); root = frame->root; op_ret = gf_setcredentials(&root->uid, &root->gid, root->ngrps, root->groups); if (op_ret != 0) { goto out; } inode_ctx = svs_inode_ctx_get(this, loc->inode); if (!inode_ctx) { op_ret = -1; op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found for %s", uuid_utoa(loc->inode->gfid)); goto out; } is_fuse_call = __is_fuse_call(frame); /* * For entry-point directory, set read and execute bits. But not write * permissions. */ if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { if (is_fuse_call) { op_ret = 0; op_errno = 0; } else { op_ret = 0; mode |= POSIX_ACL_READ; mode |= POSIX_ACL_EXECUTE; op_errno = mode; } goto out; } SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret, op_errno, out); /* The actual posix_acl xlator does acl checks differently for fuse and nfs. So set frame->root->pid as fspid of the syncop if the call came from nfs */ if (!is_fuse_call) { syncopctx_setfspid(&frame->root->pid); syncopctx_setfsuid(&frame->root->uid); syncopctx_setfsgid(&frame->root->gid); syncopctx_setfsgroups(frame->root->ngrps, frame->root->groups); } ret = glfs_h_access(fs, object, mask); if (ret < 0) { op_ret = -1; op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, SVS_MSG_ACCESS_FAILED, "failed to access %s (gfid: %s)", loc->path, uuid_utoa(loc->inode->gfid)); goto out; } op_ret = 0; op_errno = ret; out: STACK_UNWIND_STRICT(access, frame, op_ret, op_errno, NULL); return 0; } int32_t notify(xlator_t *this, int32_t event, void *data, ...) { switch (event) { case GF_EVENT_PARENT_UP: { /* Tell the parent that snapview-server xlator is up */ default_notify(this, GF_EVENT_CHILD_UP, data); } break; default: break; } return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_svs_mt_end); if (ret != 0) { gf_msg(this->name, GF_LOG_WARNING, 0, SVS_MSG_MEM_ACNT_FAILED, "Memory accounting" " init failed"); return ret; } return ret; } int32_t init(xlator_t *this) { svs_private_t *priv = NULL; int ret = -1; /* This can be the top of graph in certain cases */ if (!this->parents) { gf_msg_debug(this->name, 0, "dangling volume. check volfile "); } priv = GF_CALLOC(1, sizeof(*priv), gf_svs_mt_priv_t); if (!priv) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, SVS_MSG_NO_MEMORY, "failed to " "allocate memory for this->private "); goto out; } this->private = priv; GF_OPTION_INIT("volname", priv->volname, str, out); LOCK_INIT(&priv->snaplist_lock); LOCK(&priv->snaplist_lock); { priv->num_snaps = 0; } UNLOCK(&priv->snaplist_lock); /* What to do here upon failure? should init be failed or succeed? */ /* If succeeded, then dynamic management of snapshots will not */ /* happen.*/ ret = svs_mgmt_init(this); if (ret) { gf_msg(this->name, GF_LOG_WARNING, EINVAL, SVS_MSG_MGMT_INIT_FAILED, "failed to initiate the " "mgmt rpc callback for svs. Dymamic management of the" "snapshots will not happen"); goto out; } /* get the list of snaps first to return to client xlator */ ret = svs_get_snapshot_list(this); if (ret) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, SVS_MSG_GET_SNAPSHOT_LIST_FAILED, "Error initializing snaplist infrastructure"); ret = -1; goto out; } ret = 0; out: if (ret && priv) { LOCK_DESTROY(&priv->snaplist_lock); GF_FREE(priv->dirents); GF_FREE(priv); } return ret; } void fini(xlator_t *this) { svs_private_t *priv = NULL; glusterfs_ctx_t *ctx = NULL; int ret = 0; GF_ASSERT(this); priv = this->private; this->private = NULL; ctx = this->ctx; if (!ctx) gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_INVALID_GLFS_CTX, "Invalid ctx found"); if (priv) { ret = LOCK_DESTROY(&priv->snaplist_lock); if (ret != 0) { gf_msg(this->name, GF_LOG_WARNING, errno, SVS_MSG_LOCK_DESTROY_FAILED, "Could not destroy mutex snaplist_lock"); } if (priv->dirents) { GF_FREE(priv->dirents); } if (priv->rpc) { /* cleanup the saved-frames before last unref */ rpc_clnt_connection_cleanup(&priv->rpc->conn); rpc_clnt_unref(priv->rpc); } GF_FREE(priv); } return; } struct xlator_fops fops = { .lookup = svs_lookup, .stat = svs_stat, .statfs = svs_statfs, .opendir = svs_opendir, .readdirp = svs_readdirp, .readdir = svs_readdir, .open = svs_open, .readv = svs_readv, .flush = svs_flush, .fstat = svs_fstat, .getxattr = svs_getxattr, .access = svs_access, .readlink = svs_readlink, /* entry fops */ }; struct xlator_cbks cbks = { .release = svs_release, .releasedir = svs_releasedir, .forget = svs_forget, }; struct volume_options options[] = { { .key = {"volname"}, .type = GF_OPTION_TYPE_STR, }, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .mem_acct_init = mem_acct_init, .op_version = {1}, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "snapview-server", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/snapview-server/src/PaxHeaders.9031/snapview-server-helpers.c0000644000000000000000000000013014522202451030563 xustar000000000000000029 mtime=1699284265.69302751 29 atime=1699284265.69302751 30 ctime=1699284304.721145062 glusterfs-11.1/xlators/features/snapview-server/src/snapview-server-helpers.c0000664000175100017510000004142014522202451031045 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "snapview-server.h" #include "snapview-server-mem-types.h" #include "rpc-clnt.h" #include "protocol-common.h" #include int __svs_inode_ctx_set(xlator_t *this, inode_t *inode, svs_inode_t *svs_inode) { uint64_t value = 0; int ret = -1; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); GF_VALIDATE_OR_GOTO(this->name, svs_inode, out); value = (uint64_t)(long)svs_inode; ret = __inode_ctx_set(inode, this, &value); out: return ret; } svs_inode_t * __svs_inode_ctx_get(xlator_t *this, inode_t *inode) { svs_inode_t *svs_inode = NULL; uint64_t value = 0; int ret = -1; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); ret = __inode_ctx_get(inode, this, &value); if (ret) goto out; svs_inode = (svs_inode_t *)((long)value); out: return svs_inode; } svs_inode_t * svs_inode_ctx_get(xlator_t *this, inode_t *inode) { svs_inode_t *svs_inode = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { svs_inode = __svs_inode_ctx_get(this, inode); } UNLOCK(&inode->lock); out: return svs_inode; } int32_t svs_inode_ctx_set(xlator_t *this, inode_t *inode, svs_inode_t *svs_inode) { int32_t ret = -1; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); GF_VALIDATE_OR_GOTO(this->name, svs_inode, out); LOCK(&inode->lock); { ret = __svs_inode_ctx_set(this, inode, svs_inode); } UNLOCK(&inode->lock); out: return ret; } svs_inode_t * svs_inode_new(void) { svs_inode_t *svs_inode = NULL; svs_inode = GF_CALLOC(1, sizeof(*svs_inode), gf_svs_mt_svs_inode_t); return svs_inode; } svs_inode_t * svs_inode_ctx_get_or_new(xlator_t *this, inode_t *inode) { svs_inode_t *svs_inode = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { svs_inode = __svs_inode_ctx_get(this, inode); if (!svs_inode) { svs_inode = svs_inode_new(); if (svs_inode) { ret = __svs_inode_ctx_set(this, inode, svs_inode); if (ret) { GF_FREE(svs_inode); svs_inode = NULL; } } } } UNLOCK(&inode->lock); out: return svs_inode; } svs_fd_t * svs_fd_new(void) { svs_fd_t *svs_fd = NULL; svs_fd = GF_CALLOC(1, sizeof(*svs_fd), gf_svs_mt_svs_fd_t); return svs_fd; } int __svs_fd_ctx_set(xlator_t *this, fd_t *fd, svs_fd_t *svs_fd) { uint64_t value = 0; int ret = -1; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, svs_fd, out); value = (uint64_t)(long)svs_fd; ret = __fd_ctx_set(fd, this, value); out: return ret; } svs_fd_t * __svs_fd_ctx_get(xlator_t *this, fd_t *fd) { svs_fd_t *svs_fd = NULL; svs_fd = __fd_ctx_get_ptr(fd, this); if (!svs_fd) { GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); } out: return svs_fd; } svs_fd_t * svs_fd_ctx_get(xlator_t *this, fd_t *fd) { svs_fd_t *svs_fd = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); LOCK(&fd->lock); { svs_fd = __svs_fd_ctx_get(this, fd); } UNLOCK(&fd->lock); out: return svs_fd; } int32_t svs_fd_ctx_set(xlator_t *this, fd_t *fd, svs_fd_t *svs_fd) { int32_t ret = -1; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, svs_fd, out); LOCK(&fd->lock); { ret = __svs_fd_ctx_set(this, fd, svs_fd); } UNLOCK(&fd->lock); out: return ret; } svs_fd_t * __svs_fd_ctx_get_or_new(xlator_t *this, fd_t *fd) { svs_fd_t *svs_fd = NULL; int ret = -1; glfs_t *fs = NULL; glfs_object_t *object = NULL; svs_inode_t *inode_ctx = NULL; glfs_fd_t *glfd = NULL; inode_t *inode = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); inode = fd->inode; svs_fd = __svs_fd_ctx_get(this, fd); if (svs_fd) { ret = 0; goto out; } svs_fd = svs_fd_new(); if (!svs_fd) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_NEW_FD_CTX_FAILED, "failed to allocate new fd " "context for gfid %s", uuid_utoa(inode->gfid)); goto out; } if (fd_is_anonymous(fd)) { inode_ctx = svs_inode_ctx_get(this, inode); if (!inode_ctx) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_GET_INODE_CONTEXT_FAILED, "failed to get inode " "context for %s", uuid_utoa(inode->gfid)); goto out; } fs = inode_ctx->fs; object = inode_ctx->object; if (inode->ia_type == IA_IFDIR) { glfd = glfs_h_opendir(fs, object); if (!glfd) { gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_OPENDIR_FAILED, "failed to " "open the directory %s", uuid_utoa(inode->gfid)); goto out; } } if (inode->ia_type == IA_IFREG) { glfd = glfs_h_open(fs, object, O_RDONLY | O_LARGEFILE); if (!glfd) { gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_OPEN_FAILED, "failed to " "open the file %s", uuid_utoa(inode->gfid)); goto out; } } svs_fd->fd = glfd; } ret = __svs_fd_ctx_set(this, fd, svs_fd); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_SET_FD_CONTEXT_FAILED, "failed to set fd context " "for gfid %s", uuid_utoa(inode->gfid)); if (svs_fd->fd) { if (inode->ia_type == IA_IFDIR) { ret = glfs_closedir(svs_fd->fd); if (ret) gf_msg(this->name, GF_LOG_ERROR, errno, SVS_MSG_CLOSEDIR_FAILED, "failed to close the fd for %s", uuid_utoa(inode->gfid)); } if (inode->ia_type == IA_IFREG) { ret = glfs_close(svs_fd->fd); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_CLOSE_FAILED, "failed to close the fd for %s", uuid_utoa(inode->gfid)); } } ret = -1; } out: if (ret) { GF_FREE(svs_fd); svs_fd = NULL; } return svs_fd; } svs_fd_t * svs_fd_ctx_get_or_new(xlator_t *this, fd_t *fd) { svs_fd_t *svs_fd = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); LOCK(&fd->lock); { svs_fd = __svs_fd_ctx_get_or_new(this, fd); } UNLOCK(&fd->lock); out: return svs_fd; } int svs_uuid_generate(xlator_t *this, uuid_t gfid, char *snapname, uuid_t origin_gfid) { char ino_string[NAME_MAX + 32] = ""; uuid_t tmp = { 0, }; int ret = -1; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, snapname, out); (void)snprintf(ino_string, sizeof(ino_string), "%s%s", snapname, uuid_utoa(origin_gfid)); if (gf_gfid_generate_from_xxh64(tmp, ino_string)) { gf_msg(this->name, GF_LOG_WARNING, 0, SVS_MSG_GFID_GEN_FAILED, "failed to generate " "gfid for object with actual gfid of %s " "(snapname: %s, key: %s)", uuid_utoa(origin_gfid), snapname, ino_string); goto out; } gf_uuid_copy(gfid, tmp); ret = 0; gf_msg_debug(this->name, 0, "gfid generated is %s ", uuid_utoa(gfid)); out: return ret; } void svs_fill_ino_from_gfid(struct iatt *buf) { xlator_t *this = NULL; this = THIS; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, buf, out); /* consider least significant 8 bytes of value out of gfid */ if (gf_uuid_is_null(buf->ia_gfid)) { buf->ia_ino = -1; goto out; } buf->ia_ino = gfid_to_ino(buf->ia_gfid); out: return; } void svs_iatt_fill(uuid_t gfid, struct iatt *buf) { xlator_t *this = NULL; this = THIS; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, buf, out); buf->ia_type = IA_IFDIR; buf->ia_uid = 0; buf->ia_gid = 0; buf->ia_size = 0; buf->ia_nlink = 2; buf->ia_blocks = 8; buf->ia_size = 4096; gf_uuid_copy(buf->ia_gfid, gfid); svs_fill_ino_from_gfid(buf); buf->ia_prot = ia_prot_from_st_mode(0755); /* TODO: it would be better to use real times, but they need to be stable * once created (i.e. mtime should only change when an entry has * been added or removed for example. Otherwise the returned time * should always be the same). */ buf->ia_mtime = buf->ia_atime = buf->ia_ctime = 0; buf->ia_mtime_nsec = buf->ia_atime_nsec = buf->ia_ctime_nsec = 0; out: return; } /* priv->snaplist_lock should be held before calling this function */ snap_dirent_t * __svs_get_snap_dirent(svs_private_t *private, const char *name) { int i = 0; snap_dirent_t *dirents = NULL; snap_dirent_t *tmp_dirent = NULL; snap_dirent_t *dirent = NULL; dirents = private->dirents; if (!dirents) { goto out; } tmp_dirent = dirents; for (i = 0; i < private->num_snaps; i++) { if (!strcmp(tmp_dirent->name, name)) { dirent = tmp_dirent; break; } tmp_dirent++; } out: return dirent; } glfs_t * __svs_initialise_snapshot_volume(xlator_t *this, const char *name, int32_t *op_errno) { svs_private_t *priv = NULL; int32_t ret = -1; int32_t local_errno = ESTALE; snap_dirent_t *dirent = NULL; char volname[PATH_MAX] = { 0, }; glfs_t *fs = NULL; int loglevel = GF_LOG_INFO; char logfile[PATH_MAX] = { 0, }; char *volfile_server = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, name, out); priv = this->private; dirent = __svs_get_snap_dirent(priv, name); if (!dirent) { gf_msg_debug(this->name, 0, "snap entry for " "name %s not found", name); local_errno = ENOENT; goto out; } if (dirent->fs) { ret = 0; fs = dirent->fs; goto out; } snprintf(volname, sizeof(volname), "/snaps/%s/%s/%s", dirent->name, dirent->snap_volname, dirent->snap_volname); fs = glfs_new(volname); if (!fs) { local_errno = ENOMEM; gf_msg(this->name, GF_LOG_ERROR, local_errno, SVS_MSG_GLFS_NEW_FAILED, "glfs instance for snap volume %s " "failed", dirent->name); goto out; } /* * Before, localhost was used as the volfile server. But, with that * method, accessing snapshots started giving ENOENT error if a * specific bind address is mentioned in the glusterd volume file. * Check the bug https://bugzilla.redhat.com/show_bug.cgi?id=1725211. * So, the new method is tried below, where, snapview-server first * uses the volfile server used by the snapd (obtained from the * command line arguments saved in the global context of the process). * If the volfile server in global context is NULL, then localhost * is tried (like before). */ if (this->ctx->cmd_args.volfile_server) { volfile_server = gf_strdup(this->ctx->cmd_args.volfile_server); if (!volfile_server) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SVS_MSG_VOLFILE_SERVER_GET_FAIL, "failed to copy volfile server %s. ", this->ctx->cmd_args.volfile_server); ret = -1; goto out; } } else { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SVS_MSG_VOLFILE_SERVER_GET_FAIL, "volfile server is NULL in cmd args. " "Trying with localhost"); volfile_server = gf_strdup("localhost"); if (!volfile_server) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, SVS_MSG_VOLFILE_SERVER_GET_FAIL, "failed to copy volfile server localhost."); ret = -1; goto out; } } ret = glfs_set_volfile_server(fs, "tcp", volfile_server, 24007); if (ret) { gf_msg(this->name, GF_LOG_ERROR, local_errno, SVS_MSG_SET_VOLFILE_SERVR_FAILED, "setting the " "volfile server %s for snap volume %s " "failed", volfile_server, dirent->name); goto out; } snprintf(logfile, sizeof(logfile), DEFAULT_SVD_LOG_FILE_DIRECTORY "/snaps/%s/%s-%s.log", priv->volname, name, dirent->uuid); ret = glfs_set_logging(fs, logfile, loglevel); if (ret) { gf_msg(this->name, GF_LOG_ERROR, local_errno, SVS_MSG_SET_LOGGING_FAILED, "failed to set the " "log file path"); goto out; } ret = glfs_init(fs); if (ret) { gf_msg(this->name, GF_LOG_ERROR, local_errno, SVS_MSG_GLFS_INIT_FAILED, "initing the " "fs for %s failed", dirent->name); goto out; } ret = 0; out: if (ret) { if (op_errno) *op_errno = local_errno; if (fs) glfs_fini(fs); fs = NULL; } if (fs) { dirent->fs = fs; } GF_FREE(volfile_server); return fs; } glfs_t * svs_initialise_snapshot_volume(xlator_t *this, const char *name, int32_t *op_errno) { glfs_t *fs = NULL; svs_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("snapview-server", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, name, out); priv = this->private; LOCK(&priv->snaplist_lock); { fs = __svs_initialise_snapshot_volume(this, name, op_errno); } UNLOCK(&priv->snaplist_lock); out: return fs; } snap_dirent_t * svs_get_latest_snap_entry(xlator_t *this) { svs_private_t *priv = NULL; snap_dirent_t *dirents = NULL; snap_dirent_t *dirent = NULL; GF_VALIDATE_OR_GOTO("svs", this, out); priv = this->private; LOCK(&priv->snaplist_lock); { dirents = priv->dirents; if (!dirents) { goto unlock; } if (priv->num_snaps) dirent = &dirents[priv->num_snaps - 1]; } unlock: UNLOCK(&priv->snaplist_lock); out: return dirent; } glfs_t * svs_get_latest_snapshot(xlator_t *this) { glfs_t *fs = NULL; snap_dirent_t *dirent = NULL; svs_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("svs", this, out); priv = this->private; dirent = svs_get_latest_snap_entry(this); if (dirent) { LOCK(&priv->snaplist_lock); { fs = dirent->fs; } UNLOCK(&priv->snaplist_lock); } out: return fs; } glfs_t * svs_inode_ctx_glfs_mapping(xlator_t *this, svs_inode_t *inode_ctx) { glfs_t *fs = NULL; GF_VALIDATE_OR_GOTO("svs", this, out); GF_VALIDATE_OR_GOTO(this->name, inode_ctx, out); fs = inode_ctx->fs; SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this); out: return fs; } glfs_t * svs_inode_glfs_mapping(xlator_t *this, inode_t *inode) { svs_inode_t *inode_ctx = NULL; glfs_t *fs = NULL; inode_ctx = svs_inode_ctx_get(this, inode); if (!inode_ctx) { gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_GET_INODE_CONTEXT_FAILED, "inode context not found for" " the inode %s", uuid_utoa(inode->gfid)); goto out; } fs = svs_inode_ctx_glfs_mapping(this, inode_ctx); out: return fs; } glusterfs-11.1/xlators/features/snapview-server/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465025104 xustar000000000000000030 mtime=1699284277.330062561 30 atime=1699284290.860103314 30 ctime=1699284304.673144917 glusterfs-11.1/xlators/features/snapview-server/Makefile.in0000664000175100017510000005266014522202465025374 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/snapview-server DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/snapview-server/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/snapview-server/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/snapview-server/PaxHeaders.9031/Makefile.am0000644000000000000000000000013014522202451025064 xustar000000000000000029 mtime=1699284265.69302751 30 atime=1699284277.306062489 29 ctime=1699284304.67414492 glusterfs-11.1/xlators/features/snapview-server/Makefile.am0000664000175100017510000000001614522202451025342 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/features/PaxHeaders.9031/metadisp0000644000000000000000000000013214522202521021421 xustar000000000000000030 mtime=1699284305.935148718 30 atime=1699284309.686160016 30 ctime=1699284305.935148718 glusterfs-11.1/xlators/features/metadisp/0002775000175100017510000000000014522202521021757 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/metadisp/PaxHeaders.9031/src0000644000000000000000000000013214522202521022210 xustar000000000000000030 mtime=1699284305.991148887 30 atime=1699284309.686160016 30 ctime=1699284305.991148887 glusterfs-11.1/xlators/features/metadisp/src/0002775000175100017510000000000014522202521022546 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/backend.c0000644000000000000000000000013214522202451024022 xustar000000000000000030 mtime=1699284265.679027468 30 atime=1699284265.679027468 30 ctime=1699284305.989148881 glusterfs-11.1/xlators/features/metadisp/src/backend.c0000664000175100017510000000216714522202451024307 0ustar00jenkinsjenkins00000000000000#include "metadisp.h" /* * backend.c * * functions responsible for converting user-facing paths to backend-style * "/$GFID" paths. */ int32_t build_backend_loc(uuid_t gfid, loc_t *src_loc, loc_t *dst_loc) { static uuid_t root = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; char gfid_buf[GF_UUID_BUF_SIZE + 1] = { 0, }; char *path = NULL; GF_VALIDATE_OR_GOTO("metadisp", src_loc, out); GF_VALIDATE_OR_GOTO("metadisp", dst_loc, out); loc_copy(dst_loc, src_loc); memcpy(dst_loc->pargfid, root, sizeof(root)); GF_FREE((char *)dst_loc->path); // we are overwriting path so nuke // whatever loc_copy gave us uuid_utoa_r(gfid, gfid_buf); path = GF_CALLOC(GF_UUID_BUF_SIZE + 1, sizeof(char), gf_common_mt_char); // freed via loc_wipe path[0] = '/'; strncpy(path + 1, gfid_buf, GF_UUID_BUF_SIZE); path[GF_UUID_BUF_SIZE] = 0; dst_loc->path = path; if (src_loc->name) dst_loc->name = strrchr(dst_loc->path, '/'); if (dst_loc->name) dst_loc->name++; return 0; out: return -1; } glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp-lookup.c0000644000000000000000000000013214522202451025550 xustar000000000000000030 mtime=1699284265.679027468 30 atime=1699284265.679027468 30 ctime=1699284305.981148857 glusterfs-11.1/xlators/features/metadisp/src/metadisp-lookup.c0000664000175100017510000000502014522202451026024 0ustar00jenkinsjenkins00000000000000#include "metadisp.h" #include /** * Lookup, like stat, is a two-step process for grabbing the metadata details * as well as the data details. */ int32_t metadisp_backend_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { METADISP_TRACE("backend_lookup_cbk"); if (op_errno == ENOENT) { op_errno = ENODATA; op_ret = -1; } STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata, postparent); return 0; } int32_t metadisp_backend_lookup_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { METADISP_TRACE("backend_lookup_resume"); loc_t backend_loc = { 0, }; if (build_backend_loc(loc->gfid, loc, &backend_loc)) { goto unwind; } STACK_WIND(frame, metadisp_backend_lookup_cbk, DATA_CHILD(this), DATA_CHILD(this)->fops->lookup, &backend_loc, xdata); return 0; unwind: STACK_UNWIND_STRICT(lookup, frame, -1, EINVAL, NULL, NULL, NULL, NULL); return 0; } int32_t metadisp_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { METADISP_TRACE("%d %d", op_ret, op_errno); call_stub_t *stub = NULL; stub = cookie; if (op_ret != 0) { goto unwind; } if (!IA_ISREG(buf->ia_type)) { goto unwind; } else if (!stub) { op_errno = EINVAL; goto unwind; } METADISP_TRACE("resuming stub"); // memcpy(stub->args.loc.gfid, buf->ia_gfid, sizeof(uuid_t)); call_resume(stub); return 0; unwind: METADISP_TRACE("unwinding %d %d", op_ret, op_errno); STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata, postparent); if (stub) { call_stub_destroy(stub); } return 0; } int32_t metadisp_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { METADISP_TRACE("lookup"); call_stub_t *stub = NULL; stub = fop_lookup_stub(frame, metadisp_backend_lookup_resume, loc, xdata); STACK_WIND_COOKIE(frame, metadisp_lookup_cbk, stub, METADATA_CHILD(this), METADATA_CHILD(this)->fops->lookup, loc, xdata); return 0; } glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp-setattr.c0000644000000000000000000000013214522202451025725 xustar000000000000000030 mtime=1699284265.680027471 30 atime=1699284265.680027471 30 ctime=1699284305.988148878 glusterfs-11.1/xlators/features/metadisp/src/metadisp-setattr.c0000664000175100017510000000505114522202451026205 0ustar00jenkinsjenkins00000000000000#include "metadisp.h" #include int32_t metadisp_backend_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { METADISP_TRACE("backend_setattr_cbk"); if (op_errno == ENOENT) { op_errno = ENODATA; op_ret = -1; } STACK_UNWIND_STRICT(setattr, frame, op_ret, op_errno, statpre, statpost, xdata); return 0; } int32_t metadisp_backend_setattr_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { METADISP_TRACE("backend_setattr_resume"); loc_t backend_loc = { 0, }; if (build_backend_loc(loc->gfid, loc, &backend_loc)) { goto unwind; } STACK_WIND(frame, metadisp_backend_setattr_cbk, DATA_CHILD(this), DATA_CHILD(this)->fops->setattr, &backend_loc, stbuf, valid, xdata); return 0; unwind: STACK_UNWIND_STRICT(setattr, frame, -1, EINVAL, NULL, NULL, NULL); return 0; } int32_t metadisp_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { METADISP_TRACE("%d %d", op_ret, op_errno); call_stub_t *stub = NULL; stub = cookie; if (op_ret != 0) { goto unwind; } if (!IA_ISREG(statpost->ia_type)) { goto unwind; } else if (!stub) { op_errno = EINVAL; goto unwind; } METADISP_TRACE("resuming stub"); call_resume(stub); return 0; unwind: METADISP_TRACE("unwinding %d %d", op_ret, op_errno); STACK_UNWIND_STRICT(setattr, frame, op_ret, op_errno, statpre, statpost, xdata); if (stub) { call_stub_destroy(stub); } return 0; } int32_t metadisp_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { METADISP_TRACE("setattr"); call_stub_t *stub = NULL; stub = fop_setattr_stub(frame, metadisp_backend_setattr_resume, loc, stbuf, valid, xdata); STACK_WIND_COOKIE(frame, metadisp_setattr_cbk, stub, METADATA_CHILD(this), METADATA_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp-unlink.c0000644000000000000000000000013214522202451025537 xustar000000000000000030 mtime=1699284265.680027471 30 atime=1699284265.680027471 30 ctime=1699284305.978148848 glusterfs-11.1/xlators/features/metadisp/src/metadisp-unlink.c0000664000175100017510000001033014522202451026013 0ustar00jenkinsjenkins00000000000000 #include "metadisp.h" #include /** * The unlink flow in metadisp is complicated because we must * do ensure that UNLINK causes both the metadata objects * to get removed and the data objects to get removed. */ int32_t metadisp_unlink_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { METADISP_TRACE("winding backend unlink to path %s", loc->path); STACK_WIND(frame, default_unlink_cbk, DATA_CHILD(this), DATA_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; } int32_t metadisp_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { METADISP_TRACE(". %d %d", op_ret, op_errno); int ret = 0; call_stub_t *stub = NULL; int nlink = 0; if (cookie) { stub = cookie; } if (op_ret != 0) { goto unwind; } if (stub->poison) { call_stub_destroy(stub); stub = NULL; return 0; } ret = dict_get_uint32(xdata, GF_RESPONSE_LINK_COUNT_XDATA, &nlink); if (ret != 0) { op_errno = EINVAL; op_ret = -1; goto unwind; } METADISP_TRACE("frontend hardlink count %d %d", ret, nlink); if (nlink > 1) { goto unwind; } call_resume(stub); return 0; unwind: if (stub) { call_stub_destroy(stub); } STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int32_t metadisp_unlink_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { call_stub_t *stub = NULL; if (cookie) { stub = cookie; } if (op_ret != 0) { goto unwind; } // fail fast on empty gfid so we don't loop forever if (gf_uuid_is_null(buf->ia_gfid)) { op_ret = -1; op_errno = ENODATA; goto unwind; } // fill gfid since the stub is incomplete memcpy(stub->args.loc.gfid, buf->ia_gfid, sizeof(uuid_t)); memcpy(stub->args.loc.pargfid, postparent->ia_gfid, sizeof(uuid_t)); if (stub->poison) { call_stub_destroy(stub); stub = NULL; return 0; } call_resume(stub); return 0; unwind: if (stub) { call_stub_destroy(stub); } STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } int32_t metadisp_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { call_stub_t *stub = NULL; loc_t backend_loc = { 0, }; if (gf_uuid_is_null(loc->gfid)) { METADISP_TRACE("winding lookup for unlink to path %s", loc->path); // loop back to ourselves after a lookup stub = fop_unlink_stub(frame, metadisp_unlink, loc, xflag, xdata); STACK_WIND_COOKIE(frame, metadisp_unlink_lookup_cbk, stub, METADATA_CHILD(this), METADATA_CHILD(this)->fops->lookup, loc, xdata); return 0; } if (build_backend_loc(loc->gfid, loc, &backend_loc)) { goto unwind; } // // ensure we get the link count on the unlink response, so we can // account for hardlinks before winding to the backend. // NOTE: // multiple xlators use GF_REQUEST_LINK_COUNT_XDATA. confirmation // is needed to ensure that multiple requests will work in the same // xlator stack. // if (!xdata) { xdata = dict_new(); } dict_set_int32(xdata, GF_REQUEST_LINK_COUNT_XDATA, 1); METADISP_TRACE("winding frontend unlink to path %s", loc->path); stub = fop_unlink_stub(frame, metadisp_unlink_resume, &backend_loc, xflag, xdata); STACK_WIND_COOKIE(frame, metadisp_unlink_cbk, stub, METADATA_CHILD(this), METADATA_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; unwind: STACK_UNWIND_STRICT(unlink, frame, -1, EINVAL, NULL, NULL, NULL); return 0; } glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp-create.c0000644000000000000000000000013214522202451025502 xustar000000000000000030 mtime=1699284265.679027468 30 atime=1699284265.679027468 30 ctime=1699284305.984148866 glusterfs-11.1/xlators/features/metadisp/src/metadisp-create.c0000664000175100017510000000563114522202451025766 0ustar00jenkinsjenkins00000000000000#include "metadisp.h" #include /** * Create, like stat, is a two-step process. We send a create * to the METADATA_CHILD, then send another create to the DATA_CHILD. * * We do the metadata child first to ensure that the ACLs are enforced. */ int32_t metadisp_create_dentry_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent, xdata); return 0; } int32_t metadisp_create_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { // create the backend data inode STACK_WIND(frame, metadisp_create_dentry_cbk, DATA_CHILD(this), DATA_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; } int32_t metadisp_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { METADISP_TRACE("%d %d", op_ret, op_errno); call_stub_t *stub = cookie; if (op_ret != 0) { STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent, xdata); return 0; } if (stub == NULL) { goto unwind; } if (stub->poison) { call_stub_destroy(stub); return 0; } call_resume(stub); return 0; unwind: STACK_UNWIND_STRICT(create, frame, -1, EINVAL, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t metadisp_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { METADISP_TRACE("."); loc_t backend_loc = { 0, }; call_stub_t *stub = NULL; uuid_t *gfid_req = NULL; RESOLVE_GFID_REQ(xdata, gfid_req, out); if (build_backend_loc(*gfid_req, loc, &backend_loc)) { goto unwind; } frame->local = loc; stub = fop_create_stub(frame, metadisp_create_resume, &backend_loc, flags, mode, umask, fd, xdata); STACK_WIND_COOKIE(frame, metadisp_create_cbk, stub, METADATA_CHILD(this), METADATA_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; unwind: STACK_UNWIND_STRICT(create, frame, -1, EINVAL, NULL, NULL, NULL, NULL, NULL, NULL); return 0; out: return -1; } glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/gen-fops.py0000644000000000000000000000013214522202451024357 xustar000000000000000030 mtime=1699284265.679027468 30 atime=1699284265.679027468 30 ctime=1699284305.973148833 glusterfs-11.1/xlators/features/metadisp/src/gen-fops.py0000664000175100017510000000752614522202451024650 0ustar00jenkinsjenkins00000000000000#!/usr/bin/python import sys from generator import fop_subs, generate FN_METADATA_CHILD_GENERIC = """ int32_t metadisp_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { METADISP_TRACE("@NAME@ metadata"); STACK_WIND (frame, default_@NAME@_cbk, METADATA_CHILD(this), METADATA_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); return 0; } """ FN_GENERIC_TEMPLATE = """ int32_t metadisp_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { METADISP_TRACE("@NAME@ generic"); STACK_WIND (frame, default_@NAME@_cbk, DATA_CHILD(this), DATA_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); return 0; } """ FN_DATAFD_TEMPLATE = """ int32_t metadisp_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { METADISP_TRACE("@NAME@ datafd"); xlator_t *child = NULL; child = DATA_CHILD(this); STACK_WIND (frame, default_@NAME@_cbk, child, child->fops->@NAME@, @SHORT_ARGS@); return 0; } """ FN_DATALOC_TEMPLATE = """ int32_t metadisp_@NAME@ (call_frame_t *frame, xlator_t *this, @LONG_ARGS@) { METADISP_TRACE("@NAME@ dataloc"); loc_t backend_loc = { 0, }; if (build_backend_loc(loc->gfid, loc, &backend_loc)) { goto unwind; } xlator_t *child = NULL; child = DATA_CHILD(this); STACK_WIND (frame, default_@NAME@_cbk, child, child->fops->@NAME@, @SHORT_ARGS@); return 0; unwind: STACK_UNWIND_STRICT(lookup, frame, -1, EINVAL, NULL, NULL, NULL, NULL); return 0; } """ FOPS_LINE_TEMPLATE = "\t.@NAME@ = metadisp_@NAME@," skipped = [ "readdir", "readdirp", "lookup", "fsync", "stat", "open", "create", "unlink", "setattr", # TODO: implement "inodelk", ] def gen_fops(): done = skipped # # these are fops that wind to the DATA_CHILD # # NOTE: re-written in order from google doc: # https://docs.google.com/document/d/1KEwVtSNvDhs4qb63gWx2ulCp5GJjge77NGJk4p_Ms4Q for name in [ "writev", "readv", "ftruncate", "zerofill", "discard", "seek", "fstat", ]: done = done + [name] print(generate(FN_DATAFD_TEMPLATE, name, fop_subs)) for name in ["truncate"]: done = done + [name] print(generate(FN_DATALOC_TEMPLATE, name, fop_subs)) # these are fops that operate solely on dentries, folders, # or extended attributes. Therefore, they must always # wind to METADATA_CHILD and should never perform # any path rewriting # # NOTE: re-written in order from google doc: # https://docs.google.com/document/d/1KEwVtSNvDhs4qb63gWx2ulCp5GJjge77NGJk4p_Ms4Q for name in [ "mkdir", "symlink", "link", "rename", "mknod", "opendir", # "readdir, # special-cased # "readdirp, # special-cased "fsyncdir", # "setattr", # special-cased "readlink", "fentrylk", "access", # TODO: these wind to both, # data for backend-attributes and metadata for the rest "xattrop", "setxattr", "getxattr", "removexattr", "fgetxattr", "fsetxattr", "fremovexattr", ]: done = done + [name] print(generate(FN_METADATA_CHILD_GENERIC, name, fop_subs)) print("struct xlator_fops fops = {") for name in done: print(generate(FOPS_LINE_TEMPLATE, name, fop_subs)) print("};") for l in open(sys.argv[1], "r").readlines(): if l.find("#pragma generate") != -1: print("/* BEGIN GENERATED CODE - DO NOT MODIFY */") gen_fops() print("/* END GENERATED CODE */") else: print(l[:-1]) glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp-open.c0000644000000000000000000000013214522202451025200 xustar000000000000000030 mtime=1699284265.679027468 30 atime=1699284265.679027468 30 ctime=1699284305.985148869 glusterfs-11.1/xlators/features/metadisp/src/metadisp-open.c0000664000175100017510000000324614522202451025464 0ustar00jenkinsjenkins00000000000000#include #include "metadisp.h" int32_t metadisp_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { METADISP_TRACE("got open results %d %d", op_ret, op_errno); call_stub_t *stub = NULL; if (cookie) { stub = cookie; } if (op_ret != 0) { goto unwind; } if (!stub) { goto unwind; } if (stub->poison) { call_stub_destroy(stub); stub = NULL; return 0; } call_resume(stub); return 0; unwind: if (stub) { call_stub_destroy(stub); } STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, xdata); return 0; } int32_t metadisp_open_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { STACK_WIND_COOKIE(frame, metadisp_open_cbk, NULL, DATA_CHILD(this), DATA_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; } int32_t metadisp_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { call_stub_t *stub = NULL; loc_t backend_loc = { 0, }; if (build_backend_loc(loc->gfid, loc, &backend_loc)) { goto unwind; } stub = fop_open_stub(frame, metadisp_open_resume, &backend_loc, flags, fd, xdata); STACK_WIND_COOKIE(frame, metadisp_open_cbk, stub, METADATA_CHILD(this), METADATA_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; unwind: STACK_UNWIND_STRICT(open, frame, -1, EINVAL, NULL, NULL); return 0; } glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp-fsync.c0000644000000000000000000000013214522202451025361 xustar000000000000000030 mtime=1699284265.679027468 30 atime=1699284265.679027468 30 ctime=1699284305.987148875 glusterfs-11.1/xlators/features/metadisp/src/metadisp-fsync.c0000664000175100017510000000252114522202451025640 0ustar00jenkinsjenkins00000000000000 #include "metadisp.h" #include int32_t metadisp_fsync_resume(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { STACK_WIND(frame, default_fsync_cbk, DATA_CHILD(this), DATA_CHILD(this)->fops->fsync, fd, flags, xdata); return 0; } int32_t metadisp_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { call_stub_t *stub = NULL; if (cookie) { stub = cookie; } if (op_ret != 0) { goto unwind; } if (stub->poison) { call_stub_destroy(stub); stub = NULL; return 0; } call_resume(stub); return 0; unwind: if (stub) { call_stub_destroy(stub); } STACK_UNWIND_STRICT(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t metadisp_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { call_stub_t *stub = NULL; stub = fop_fsync_stub(frame, metadisp_fsync_resume, fd, flags, xdata); STACK_WIND_COOKIE(frame, metadisp_fsync_cbk, stub, METADATA_CHILD(this), METADATA_CHILD(this)->fops->fsync, fd, flags, xdata); return 0; } glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp-stat.c0000644000000000000000000000013214522202451025212 xustar000000000000000030 mtime=1699284265.680027471 30 atime=1699284265.680027471 30 ctime=1699284305.980148854 glusterfs-11.1/xlators/features/metadisp/src/metadisp-stat.c0000664000175100017510000000716714522202451025504 0ustar00jenkinsjenkins00000000000000#include "metadisp.h" #include /** * The stat flow in METADISP is complicated because we must * do ensure a few things: * 1. stat, on the path within the metadata layer, * MUST get the backend FD of the data layer. * --- we wind to the metadata layer, then the data layer. * * 2. the metadata layer MUST be able to ask the data * layer for stat information. * --- this is 'syncop-internal-from-posix' * * 3. when the metadata exists BUT the data is missing, * we MUST mark the backend file as bad and heal it. */ int32_t metadisp_stat_backend_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { METADISP_TRACE("got backend stat results %d %d", op_ret, op_errno); if (op_errno == ENOENT) { STACK_UNWIND_STRICT(open, frame, -1, ENODATA, NULL, NULL); return 0; } STACK_UNWIND_STRICT(stat, frame, op_ret, op_errno, buf, xdata); return 0; } int32_t metadisp_stat_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { METADISP_TRACE("winding stat to path %s", loc->path); if (gf_uuid_is_null(loc->gfid)) { METADISP_TRACE("bad object, sending EUCLEAN"); STACK_UNWIND_STRICT(open, frame, -1, EUCLEAN, NULL, NULL); return 0; } STACK_WIND(frame, metadisp_stat_backend_cbk, SECOND_CHILD(this), SECOND_CHILD(this)->fops->stat, loc, xdata); return 0; } int32_t metadisp_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { call_stub_t *stub = NULL; METADISP_TRACE("got stat results %d %d", op_ret, op_errno); if (cookie) { stub = cookie; } if (op_ret != 0) { goto unwind; } // only use the stub for the files if (!IA_ISREG(buf->ia_type)) { goto unwind; } if (stub->poison) { call_stub_destroy(stub); stub = NULL; return 0; } call_resume(stub); return 0; unwind: if (stub) { call_stub_destroy(stub); } STACK_UNWIND_STRICT(stat, frame, op_ret, op_errno, buf, xdata); return 0; } int32_t metadisp_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { call_stub_t *stub = NULL; int32_t ret = 0; loc_t backend_loc = { 0, }; METADISP_FILTER_ROOT(stat, loc, xdata); if (build_backend_loc(loc->gfid, loc, &backend_loc)) { goto unwind; } if (dict_get_int32(xdata, "syncop-internal-from-posix", &ret) == 0) { // if we've just been sent a stat from posix, then we know // that we must send down a stat for a file to the second child. // // that means we can skip the stat for the first child and just // send to the data disk. METADISP_TRACE("got syncop-internal-from-posix"); STACK_WIND(frame, default_stat_cbk, DATA_CHILD(this), DATA_CHILD(this)->fops->stat, &backend_loc, xdata); return 0; } // we do not know if the request is for a file, folder, etc. wind // to first child to find out. stub = fop_stat_stub(frame, metadisp_stat_resume, &backend_loc, xdata); METADISP_TRACE("winding stat to first child %s", loc->path); STACK_WIND_COOKIE(frame, metadisp_stat_cbk, stub, METADATA_CHILD(this), METADATA_CHILD(this)->fops->stat, loc, xdata); return 0; unwind: STACK_UNWIND_STRICT(stat, frame, -1, EINVAL, NULL, NULL); return 0; } glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464024340 xustar000000000000000030 mtime=1699284276.543060191 30 atime=1699284291.381104883 30 ctime=1699284305.970148823 glusterfs-11.1/xlators/features/metadisp/src/Makefile.in0000664000175100017510000006307114522202464024626 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/metadisp/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_PYTHON) \ $(top_srcdir)/py-compile $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) metadisp_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_metadisp_la_OBJECTS = metadisp.lo metadisp-unlink.lo \ metadisp-stat.lo metadisp-lookup.lo metadisp-readdir.lo \ metadisp-create.lo metadisp-open.lo metadisp-fsync.lo \ metadisp-setattr.lo backend.lo nodist_metadisp_la_OBJECTS = fops.lo metadisp_la_OBJECTS = $(am_metadisp_la_OBJECTS) \ $(nodist_metadisp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = metadisp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(metadisp_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(metadisp_la_SOURCES) $(nodist_metadisp_la_SOURCES) DIST_SOURCES = $(metadisp_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile) py_compile = $(top_srcdir)/py-compile HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_PYTHON = gen-fops.py EXTRA_DIST = fops-tmpl.c xlator_LTLIBRARIES = metadisp.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features nodist_metadisp_la_SOURCES = fops.c BUILT_SOURCES = fops.c metadisp_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) metadisp_la_SOURCES = metadisp.c \ metadisp-unlink.c \ metadisp-stat.c \ metadisp-lookup.c \ metadisp-readdir.c \ metadisp-create.c \ metadisp-open.c \ metadisp-fsync.c \ metadisp-setattr.c \ backend.c metadisp_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = metadisp.h metadisp-fops.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = $(nodist_metadisp_la_SOURCES) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/metadisp/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/metadisp/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } metadisp.la: $(metadisp_la_OBJECTS) $(metadisp_la_DEPENDENCIES) $(EXTRA_metadisp_la_DEPENDENCIES) $(AM_V_CCLD)$(metadisp_la_LINK) -rpath $(xlatordir) $(metadisp_la_OBJECTS) $(metadisp_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadisp-create.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadisp-fsync.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadisp-lookup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadisp-open.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadisp-readdir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadisp-setattr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadisp-stat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadisp-unlink.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadisp.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES fops.c: fops-tmpl.c $(top_srcdir)/libglusterfs/src/generator.py gen-fops.py PYTHONPATH=$(top_srcdir)/libglusterfs/src \ $(PYTHON) $(srcdir)/gen-fops.py $(srcdir)/fops-tmpl.c > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp.c0000644000000000000000000000013214522202451024241 xustar000000000000000030 mtime=1699284265.680027471 30 atime=1699284265.680027471 30 ctime=1699284305.977148845 glusterfs-11.1/xlators/features/metadisp/src/metadisp.c0000664000175100017510000000143314522202451024521 0ustar00jenkinsjenkins00000000000000#include #include "metadisp.h" #include "metadisp-fops.h" int32_t init(xlator_t *this) { if (!this->children) { gf_log(this->name, GF_LOG_ERROR, "not configured with children. exiting"); return -1; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); } return 0; } void fini(xlator_t *this) { return; } /* defined in fops.c */ struct xlator_fops fops; struct xlator_cbks cbks = {}; struct volume_options options[] = { {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .fops = &fops, .cbks = &cbks, .options = options, .op_version = {1}, .identifier = "metadisp", .category = GF_EXPERIMENTAL, }; glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp-readdir.c0000644000000000000000000000013114522202451025650 xustar000000000000000030 mtime=1699284265.680027471 30 atime=1699284265.680027471 29 ctime=1699284305.98214886 glusterfs-11.1/xlators/features/metadisp/src/metadisp-readdir.c0000664000175100017510000000413414522202451026132 0ustar00jenkinsjenkins00000000000000#include "metadisp.h" /** * With a change to the posix xlator, readdir and readdirp are shockingly * simple. * * The issue with separating the backend data of the files * with the metadata is that readdirs must now read from multiple sources * to coalesce the directory entries. * * The way we do this is to tell the METADATA_CHILD that when it's * running readdirp, each file entry should have a stat wound to * 'stat-source-of-truth'. * * see metadisp_stat for how it handles winds _from_posix. */ int32_t metadisp_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { METADISP_TRACE("."); /* * Always use readdirp, even if the original was readdir. Why? Because NFS. * There are multiple translations between Gluster, UNIX, and NFS stat * structures in that path. One of them uses the type etc. from the stat * structure, which is only filled in by readdirp. If we use readdir, the * entries do actually go all the way back to the client and are visible in * getdents, but then the readdir throws them away because of the * uninitialized type. */ GF_UNUSED int32_t ret; if (!xdata) { xdata = dict_new(); } // ret = dict_set_int32 (xdata, "list-xattr", 1); // I'm my own source of truth! ret = dict_set_static_ptr(xdata, "stat-source-of-truth", (void *)this); STACK_WIND(frame, default_readdirp_cbk, METADATA_CHILD(this), METADATA_CHILD(this)->fops->readdirp, fd, size, off, xdata); return 0; } int32_t metadisp_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { METADISP_TRACE("."); if (!xdata) { xdata = dict_new(); } GF_UNUSED int32_t ret; // ret = dict_set_int32 (xdata, "list-xattr", 1); // I'm my own source of truth! ret = dict_set_static_ptr(xdata, "stat-source-of-truth", (void *)this); STACK_WIND(frame, default_readdirp_cbk, METADATA_CHILD(this), METADATA_CHILD(this)->fops->readdirp, fd, size, off, xdata); return 0; } glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024323 xustar000000000000000030 mtime=1699284265.679027468 30 atime=1699284276.501060064 30 ctime=1699284305.971148827 glusterfs-11.1/xlators/features/metadisp/src/Makefile.am0000664000175100017510000000174314522202451024607 0ustar00jenkinsjenkins00000000000000noinst_PYTHON = gen-fops.py EXTRA_DIST = fops-tmpl.c xlator_LTLIBRARIES = metadisp.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features nodist_metadisp_la_SOURCES = fops.c BUILT_SOURCES = fops.c metadisp_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) metadisp_la_SOURCES = metadisp.c \ metadisp-unlink.c \ metadisp-stat.c \ metadisp-lookup.c \ metadisp-readdir.c \ metadisp-create.c \ metadisp-open.c \ metadisp-fsync.c \ metadisp-setattr.c \ backend.c metadisp_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = metadisp.h metadisp-fops.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) fops.c: fops-tmpl.c $(top_srcdir)/libglusterfs/src/generator.py gen-fops.py PYTHONPATH=$(top_srcdir)/libglusterfs/src \ $(PYTHON) $(srcdir)/gen-fops.py $(srcdir)/fops-tmpl.c > $@ CLEANFILES = $(nodist_metadisp_la_SOURCES) glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/fops-tmpl.c0000644000000000000000000000013214522202451024354 xustar000000000000000030 mtime=1699284265.679027468 30 atime=1699284265.679027468 30 ctime=1699284305.991148887 glusterfs-11.1/xlators/features/metadisp/src/fops-tmpl.c0000664000175100017510000000020314522202451024626 0ustar00jenkinsjenkins00000000000000#ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include "metadisp.h" #include "metadisp-fops.h" #pragma generate glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp.h0000644000000000000000000000013214522202451024246 xustar000000000000000030 mtime=1699284265.680027471 30 atime=1699284265.680027471 30 ctime=1699284305.974148836 glusterfs-11.1/xlators/features/metadisp/src/metadisp.h0000664000175100017510000000333514522202451024531 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef GF_METADISP_H_ #define GF_METADISP_H_ #include #include #define METADATA_CHILD(_this) FIRST_CHILD(_this) #define DATA_CHILD(_this) SECOND_CHILD(_this) int32_t build_backend_loc(uuid_t gfid, loc_t *src_loc, loc_t *dst_loc); #define METADISP_TRACE(_args...) gf_log("metadisp", GF_LOG_INFO, _args) #define METADISP_FILTER_ROOT(_op, _args...) \ if (strcmp(loc->path, "/") == 0) { \ STACK_WIND(frame, default_##_op##_cbk, METADATA_CHILD(this), \ METADATA_CHILD(this)->fops->_op, _args); \ return 0; \ } #define METADISP_FILTER_ROOT_BY_GFID(_op, _gfid, _args...) \ if (__is_root_gfid(_gfid)) { \ STACK_WIND(frame, default_##_op##_cbk, METADATA_CHILD(this), \ METADATA_CHILD(this)->fops->_op, _args); \ return 0; \ } #define RESOLVE_GFID_REQ(_dict, _dest, _lbl) \ VALIDATE_OR_GOTO(dict_get_ptr(_dict, "gfid-req", (void **)&_dest) == 0, \ _lbl) #endif /* __TEMPLATE_H__ */ glusterfs-11.1/xlators/features/metadisp/src/PaxHeaders.9031/metadisp-fops.h0000644000000000000000000000013214522202451025213 xustar000000000000000030 mtime=1699284265.679027468 30 atime=1699284265.679027468 30 ctime=1699284305.976148842 glusterfs-11.1/xlators/features/metadisp/src/metadisp-fops.h0000664000175100017510000000270614522202451025477 0ustar00jenkinsjenkins00000000000000#ifndef GF_METADISP_FOPS_H_ #define GF_METADISP_FOPS_H_ #include #include #include /* fops in here are defined in their own file. Every other fop is just defined * inline of fops.c */ int metadisp_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata); int metadisp_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *dict); int metadisp_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata); int metadisp_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata); int metadisp_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata); int metadisp_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata); int metadisp_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata); int metadisp_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata); int metadisp_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata); int metadisp_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata); #endif glusterfs-11.1/xlators/features/metadisp/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023551 xustar000000000000000030 mtime=1699284276.490060031 30 atime=1699284291.361104823 30 ctime=1699284305.930148703 glusterfs-11.1/xlators/features/metadisp/Makefile.in0000664000175100017510000005273214522202464024041 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/metadisp DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/metadisp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/metadisp/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/metadisp/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023534 xustar000000000000000030 mtime=1699284265.678027465 30 atime=1699284276.466059959 30 ctime=1699284305.931148706 glusterfs-11.1/xlators/features/metadisp/Makefile.am0000664000175100017510000000003414522202451024010 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/upcall0000644000000000000000000000013214522202520021072 xustar000000000000000030 mtime=1699284304.075143116 30 atime=1699284309.686160016 30 ctime=1699284304.075143116 glusterfs-11.1/xlators/features/upcall/0002775000175100017510000000000014522202520021430 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/upcall/PaxHeaders.9031/src0000644000000000000000000000013214522202520021661 xustar000000000000000030 mtime=1699284304.131143285 30 atime=1699284309.686160016 30 ctime=1699284304.131143285 glusterfs-11.1/xlators/features/upcall/src/0002775000175100017510000000000014522202520022217 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/upcall/src/PaxHeaders.9031/upcall.h0000644000000000000000000000013214522202451023372 xustar000000000000000030 mtime=1699284265.698027525 30 atime=1699284265.698027525 30 ctime=1699284304.122143258 glusterfs-11.1/xlators/features/upcall/src/upcall.h0000664000175100017510000001072414522202451023655 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __UPCALL_H__ #define __UPCALL_H__ #include #include "upcall-mem-types.h" #include #include "upcall-messages.h" #include #define EXIT_IF_UPCALL_OFF(this, label) \ do { \ if (!is_upcall_enabled(this)) \ goto label; \ } while (0) #define UPCALL_STACK_UNWIND(fop, frame, params...) \ do { \ upcall_local_t *__local = NULL; \ if (frame) { \ __local = frame->local; \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ upcall_local_wipe(__local); \ } while (0) #define UPCALL_STACK_DESTROY(frame) \ do { \ upcall_local_t *__local = NULL; \ __local = frame->local; \ frame->local = NULL; \ STACK_DESTROY(frame->root); \ upcall_local_wipe(__local); \ } while (0) struct _upcall_private { time_t cache_invalidation_timeout; struct list_head inode_ctx_list; gf_lock_t inode_ctx_lk; pthread_t reaper_thr; dict_t *xattrs; /* list of xattrs registered by clients for receiving invalidation */ int32_t fini; gf_boolean_t cache_invalidation_enabled; gf_boolean_t reaper_init_done; }; typedef struct _upcall_private upcall_private_t; struct _upcall_client { struct list_head client_list; /* strdup to store client_uid, strdup. Free it explicitly */ char *client_uid; time_t access_time; /* time last accessed */ /* the amount of time which client can cache this entry */ uint32_t expire_time_attr; }; typedef struct _upcall_client upcall_client_t; /* Upcall entries are maintained in inode_ctx */ struct _upcall_inode_ctx { struct list_head inode_ctx_list; struct list_head client_list; pthread_mutex_t client_list_lock; /* mutex for clients list of this upcall entry */ uuid_t gfid; /* gfid of the entry */ int destroy; }; typedef struct _upcall_inode_ctx upcall_inode_ctx_t; struct upcall_local { /* XXX: need to check if we can store * pointers in 'local' which may get freed * in future by other thread */ inode_t *inode; loc_t rename_oldloc; loc_t loc; /* required for stat in *xattr_cbk */ fd_t *fd; /* required for fstat in *xattr_cbk */ dict_t *xattr; }; typedef struct upcall_local upcall_local_t; void upcall_local_wipe(upcall_local_t *local); int upcall_cleanup_inode_ctx(xlator_t *this, inode_t *inode); void * upcall_reaper_thread(void *data); int upcall_reaper_thread_init(xlator_t *this); /* Xlator options */ gf_boolean_t is_upcall_enabled(xlator_t *this); /* Cache invalidation specific */ void upcall_cache_invalidate(call_frame_t *frame, xlator_t *this, client_t *client, inode_t *inode, uint32_t flags, struct iatt *stbuf, struct iatt *p_stbuf, struct iatt *oldp_stbuf, dict_t *xattr); int up_filter_xattr(dict_t *xattr, dict_t *regd_xattrs); int up_compare_afr_xattr(dict_t *d, char *k, data_t *v, void *tmp); gf_boolean_t up_invalidate_needed(dict_t *xattrs); #endif /* __UPCALL_H__ */ glusterfs-11.1/xlators/features/upcall/src/PaxHeaders.9031/upcall-mem-types.h0000644000000000000000000000013214522202451025310 xustar000000000000000030 mtime=1699284265.697027522 30 atime=1699284265.697027522 30 ctime=1699284304.124143264 glusterfs-11.1/xlators/features/upcall/src/upcall-mem-types.h0000664000175100017510000000124414522202451025570 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __UPCALL_MEM_TYPES_H__ #define __UPCALL_MEM_TYPES_H__ #include enum gf_upcall_mem_types_ { gf_upcall_mt_conf_t = gf_common_mt_end + 1, gf_upcall_mt_private_t, gf_upcall_mt_upcall_inode_ctx_t, gf_upcall_mt_upcall_client_entry_t, gf_upcall_mt_end }; #endif glusterfs-11.1/xlators/features/upcall/src/PaxHeaders.9031/upcall-messages.h0000644000000000000000000000013114522202451025176 xustar000000000000000030 mtime=1699284265.697027522 30 atime=1699284265.697027522 29 ctime=1699284304.12614327 glusterfs-11.1/xlators/features/upcall/src/upcall-messages.h0000664000175100017510000000166014522202451025461 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _UPCALL_MESSAGES_H_ #define _UPCALL_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(UPCALL, UPCALL_MSG_NO_MEMORY, UPCALL_MSG_INTERNAL_ERROR, UPCALL_MSG_NOTIFY_FAILED); #endif /* !_UPCALL_MESSAGES_H_ */ glusterfs-11.1/xlators/features/upcall/src/PaxHeaders.9031/upcall.c0000644000000000000000000000013214522202451023365 xustar000000000000000030 mtime=1699284265.698027525 30 atime=1699284265.697027522 30 ctime=1699284304.129143279 glusterfs-11.1/xlators/features/upcall/src/upcall.c0000664000175100017510000017141514522202451023655 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include "upcall.h" #include "upcall-mem-types.h" #include #include "upcall-cache-invalidation.h" static upcall_local_t * upcall_local_init(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, inode_t *inode, dict_t *xattr); static int32_t up_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(open, frame, op_ret, op_errno, fd, xdata); return 0; } static int32_t up_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; err: UPCALL_STACK_UNWIND(open, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_WRITE_FLAGS, postbuf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } static int32_t up_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, iobref, xdata); return 0; err: UPCALL_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iovec *vector, int count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, stbuf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, stbuf, iobref, xdata); return 0; } static int32_t up_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; err: UPCALL_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); return 0; } static int32_t up_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(lk, frame, op_ret, op_errno, lock, xdata); return 0; } static int32_t up_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_lk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lk, fd, cmd, flock, xdata); return 0; err: UPCALL_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_WRITE_FLAGS, postbuf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } static int32_t up_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; err: UPCALL_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { client_t *client = NULL; uint32_t flags = 0; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } /* XXX: setattr -> UP_SIZE or UP_OWN or UP_MODE or UP_TIMES * or INODE_UPDATE (or UP_PERM esp in case of ACLs -> INODE_INVALIDATE) * Need to check what attr is changed and accordingly pass UP_FLAGS. * Bug1200271. */ flags = UP_ATTR_FLAGS; /* If mode bits have changed invalidate the xattrs, as posix-acl and * others store permission related information in xattrs. With changing * of permissions/mode, we need to make clients to forget all the * xattrs related to permissions. * TODO: Invalidate the xattr system.posix_acl_access alone. */ if (is_same_mode(statpre->ia_prot, statpost->ia_prot) != 0) flags |= UP_XATTR; upcall_cache_invalidate(frame, this, client, local->inode, flags, statpost, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(setattr, frame, op_ret, op_errno, statpre, statpost, xdata); return 0; } static int32_t up_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; err: UPCALL_STACK_UNWIND(setattr, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, (UP_RENAME_FLAGS | UP_PARENT_DENTRY_FLAGS), stbuf, postnewparent, postoldparent, NULL); upcall_cache_invalidate(frame, this, client, local->rename_oldloc.parent, UP_UPDATE_CLIENT, postoldparent, NULL, NULL, NULL); if (local->rename_oldloc.parent == local->loc.parent) goto out; upcall_cache_invalidate(frame, this, client, local->loc.parent, UP_UPDATE_CLIENT, postnewparent, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(rename, frame, op_ret, op_errno, stbuf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); return 0; } static int32_t up_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, newloc, NULL, oldloc->inode, NULL); if (!local) { goto err; } /* copy oldloc */ loc_copy(&local->rename_oldloc, oldloc); out: STACK_WIND(frame, up_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; err: UPCALL_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t up_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, (UP_NLINK_FLAGS | UP_PARENT_DENTRY_FLAGS), NULL, postparent, NULL, NULL); upcall_cache_invalidate(frame, this, client, local->loc.parent, UP_UPDATE_CLIENT, postparent, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } static int32_t up_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, loc, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; err: UPCALL_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, (UP_NLINK_FLAGS | UP_PARENT_DENTRY_FLAGS), stbuf, postparent, NULL, NULL); upcall_cache_invalidate(frame, this, client, local->loc.parent, UP_UPDATE_CLIENT, postparent, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(link, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); return 0; } static int32_t up_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, newloc, NULL, oldloc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; err: UPCALL_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t up_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, (UP_NLINK_FLAGS | UP_PARENT_DENTRY_FLAGS), NULL, postparent, NULL, NULL); upcall_cache_invalidate(frame, this, client, local->loc.parent, UP_UPDATE_CLIENT, postparent, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(rmdir, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } static int32_t up_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, loc, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); return 0; err: UPCALL_STACK_UNWIND(rmdir, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } /* invalidate parent's entry too */ upcall_cache_invalidate(frame, this, client, local->inode, UP_TIMES, postparent, NULL, NULL, NULL); upcall_cache_invalidate(frame, this, client, local->loc.inode, UP_UPDATE_CLIENT, stbuf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(mkdir, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); return 0; } static int32_t up_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *params) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, loc, NULL, loc->parent, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, params); return 0; err: UPCALL_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t up_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } /* As its a new file create, no need of sending notification * However invalidate parent's entry and update that fact that the * client has accessed the newly created entry */ upcall_cache_invalidate(frame, this, client, local->inode, UP_TIMES, postparent, NULL, NULL, NULL); upcall_cache_invalidate(frame, this, client, local->loc.inode, UP_UPDATE_CLIENT, stbuf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, stbuf, preparent, postparent, xdata); return 0; } static int32_t up_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *params) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, loc, NULL, loc->parent, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, params); return 0; err: UPCALL_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t up_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, stbuf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, stbuf, xattr, postparent); return 0; } static int32_t up_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xattr_req); return 0; err: UPCALL_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } static int32_t up_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, buf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(stat, frame, op_ret, op_errno, buf, xdata); return 0; } static int32_t up_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; err: UPCALL_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; err: UPCALL_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; err: UPCALL_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(access, frame, op_ret, op_errno, xdata); return 0; } static int32_t up_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_access_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->access, loc, mask, xdata); return 0; err: UPCALL_STACK_UNWIND(access, frame, -1, op_errno, NULL); return 0; } static int32_t up_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, const char *path, struct iatt *stbuf, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, stbuf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(readlink, frame, op_ret, op_errno, path, stbuf, xdata); return 0; } static int32_t up_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_readlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink, loc, size, xdata); return 0; err: UPCALL_STACK_UNWIND(readlink, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } /* invalidate parent's entry too */ upcall_cache_invalidate(frame, this, client, local->inode, UP_TIMES, postparent, NULL, NULL, NULL); upcall_cache_invalidate(frame, this, client, local->loc.inode, UP_UPDATE_CLIENT, buf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } static int32_t up_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, loc, NULL, loc->parent, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; err: UPCALL_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t up_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } /* invalidate parent's entry too */ upcall_cache_invalidate(frame, this, client, local->inode, UP_TIMES, postparent, NULL, NULL, NULL); upcall_cache_invalidate(frame, this, client, local->loc.inode, UP_UPDATE_CLIENT, buf, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(symlink, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } static int32_t up_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, loc, NULL, loc->parent, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); return 0; err: UPCALL_STACK_UNWIND(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t up_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(opendir, frame, op_ret, op_errno, fd, xdata); return 0; } static int32_t up_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); return 0; err: UPCALL_STACK_UNWIND(opendir, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(statfs, frame, op_ret, op_errno, buf, xdata); return 0; } static int32_t up_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_statfs_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, loc, xdata); return 0; err: UPCALL_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(readdir, frame, op_ret, op_errno, entries, xdata); return 0; } static int32_t up_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, fd, size, off, xdata); return 0; err: UPCALL_STACK_UNWIND(readdir, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; gf_dirent_t *entry = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); list_for_each_entry(entry, &entries->list, list) { if (entry->inode == NULL) { continue; } upcall_cache_invalidate(frame, this, client, entry->inode, UP_UPDATE_CLIENT, &entry->d_stat, NULL, NULL, NULL); } out: UPCALL_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata); return 0; } static int32_t up_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *dict) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, off, dict); return 0; err: UPCALL_STACK_UNWIND(readdirp, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; err: UPCALL_STACK_UNWIND(fsetattr, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_WRITE_FLAGS, post, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(fallocate, frame, op_ret, op_errno, pre, post, xdata); return 0; } static int32_t up_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_fallocate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, xdata); return 0; err: UPCALL_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_WRITE_FLAGS, post, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(discard, frame, op_ret, op_errno, pre, post, xdata); return 0; } static int32_t up_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_discard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); return 0; err: UPCALL_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_WRITE_FLAGS, post, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(zerofill, frame, op_ret, op_errno, pre, post, xdata); return 0; } static int up_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_zerofill_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata); return 0; err: UPCALL_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t up_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, off_t offset, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(seek, frame, op_ret, op_errno, offset, xdata); return 0; } static int32_t up_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_seek_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->seek, fd, offset, what, xdata); return 0; err: UPCALL_STACK_UNWIND(seek, frame, -1, op_errno, 0, NULL); return 0; } static int32_t up_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { client_t *client = NULL; uint32_t flags = 0; upcall_local_t *local = NULL; int ret = 0; struct iatt stbuf = { 0, }; upcall_private_t *priv = NULL; EXIT_IF_UPCALL_OFF(this, out); priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } flags = UP_XATTR; ret = up_filter_xattr(local->xattr, priv->xattrs); if (ret < 0) { op_ret = ret; goto out; } if (!up_invalidate_needed(local->xattr)) goto out; ret = dict_get_iatt(xdata, GF_POSTSTAT, &stbuf); if (ret == 0) flags |= UP_TIMES; upcall_cache_invalidate(frame, this, client, local->inode, flags, &stbuf, NULL, NULL, local->xattr); out: UPCALL_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); return 0; } static int32_t up_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, loc, NULL, loc->inode, dict); if (!local) { goto err; } out: STACK_WIND(frame, up_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; err: UPCALL_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); return 0; } static int32_t up_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { client_t *client = NULL; uint32_t flags = 0; upcall_local_t *local = NULL; int ret = 0; struct iatt stbuf = { 0, }; upcall_private_t *priv = NULL; EXIT_IF_UPCALL_OFF(this, out); priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } flags = UP_XATTR; ret = up_filter_xattr(local->xattr, priv->xattrs); if (ret < 0) { op_ret = ret; goto out; } if (!up_invalidate_needed(local->xattr)) goto out; ret = dict_get_iatt(xdata, GF_POSTSTAT, &stbuf); if (ret == 0) flags |= UP_TIMES; upcall_cache_invalidate(frame, this, client, local->inode, flags, &stbuf, NULL, NULL, local->xattr); out: UPCALL_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, xdata); return 0; } static int32_t up_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, fd, fd->inode, dict); if (!local) { goto err; } out: STACK_WIND(frame, up_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; err: UPCALL_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); return 0; } static int32_t up_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { client_t *client = NULL; uint32_t flags = 0; upcall_local_t *local = NULL; struct iatt stbuf = { 0, }; int ret = 0; upcall_private_t *priv = NULL; EXIT_IF_UPCALL_OFF(this, out); priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } flags = UP_XATTR_RM; ret = up_filter_xattr(local->xattr, priv->xattrs); if (ret < 0) { op_ret = ret; goto out; } if (!up_invalidate_needed(local->xattr)) goto out; ret = dict_get_iatt(xdata, GF_POSTSTAT, &stbuf); if (ret == 0) flags |= UP_TIMES; upcall_cache_invalidate(frame, this, client, local->inode, flags, &stbuf, NULL, NULL, local->xattr); out: UPCALL_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, xdata); return 0; } static int32_t up_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; dict_t *xattr = NULL; EXIT_IF_UPCALL_OFF(this, out); xattr = dict_for_key_value(name, "", 1, _gf_true); if (!xattr) { goto err; } local = upcall_local_init(frame, this, NULL, fd, fd->inode, xattr); if (!local) { goto err; } out: if (xattr) dict_unref(xattr); STACK_WIND(frame, up_fremovexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; err: if (xattr) dict_unref(xattr); UPCALL_STACK_UNWIND(fremovexattr, frame, -1, op_errno, NULL); return 0; } static int32_t up_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { client_t *client = NULL; uint32_t flags = 0; upcall_local_t *local = NULL; struct iatt stbuf = { 0, }; int ret = 0; upcall_private_t *priv = NULL; EXIT_IF_UPCALL_OFF(this, out); priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } flags = UP_XATTR_RM; ret = up_filter_xattr(local->xattr, priv->xattrs); if (ret < 0) { op_ret = ret; goto out; } if (!up_invalidate_needed(local->xattr)) goto out; ret = dict_get_iatt(xdata, GF_POSTSTAT, &stbuf); if (ret == 0) flags |= UP_TIMES; upcall_cache_invalidate(frame, this, client, local->inode, flags, &stbuf, NULL, NULL, local->xattr); out: UPCALL_STACK_UNWIND(removexattr, frame, op_ret, op_errno, xdata); return 0; } static int32_t up_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; dict_t *xattr = NULL; EXIT_IF_UPCALL_OFF(this, out); xattr = dict_for_key_value(name, "", 1, _gf_true); if (!xattr) { goto err; } local = upcall_local_init(frame, this, loc, NULL, loc->inode, xattr); if (!local) { goto err; } out: if (xattr) dict_unref(xattr); STACK_WIND(frame, up_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; err: if (xattr) dict_unref(xattr); UPCALL_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); return 0; } static int32_t up_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, dict, xdata); return 0; } static int32_t up_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); return 0; err: UPCALL_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } upcall_cache_invalidate(frame, this, client, local->inode, UP_UPDATE_CLIENT, NULL, NULL, NULL, NULL); out: UPCALL_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } static int32_t up_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int32_t op_errno = ENOMEM; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL); if (!local) { goto err; } out: STACK_WIND(frame, up_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); return 0; err: UPCALL_STACK_UNWIND(getxattr, frame, -1, op_errno, NULL, NULL); return 0; } /* The xattrops here mainly tracks changes in afr pending xattr. * 1. xattrop doesn't carry info saying post op/pre op. * 2. Pre xattrop will have 0 value for all pending xattrs, * the cbk of pre xattrop carries the on-disk xattr value. * Non zero on-disk xattr indicates pending healing. * 3. Post xattrop will either have 0 or 1 as value of pending xattrs, * 0 on success, 1 on failure. But the post xattrop cbk will have * 0 or 1 or any higher value. * 0 - if no healing required* * 1 - if this is the first time pending xattr is being set. * n - if there is already a pending xattr set, it will increment * the on-disk value and send that in cbk. * Our aim is to send an invalidation, only the first time a pending * xattr was set on a file. Below are some of the exceptions in handling * xattrop: * - Do not filter unregistered xattrs in the cbk, but in the call path. * Else, we will be invalidating on every preop, if the file already has * pending xattr set. Filtering unregistered xattrs on the fop path * ensures we invalidate only in postop, every time a postop comes with * pending xattr value 1. * - Consider a brick is down, and the postop sets pending xattrs as long * as the other brick is down. But we do not want to invalidate every time * a pending xattr is set, but we want to invalidate only the first time * a pending xattr is set on any file. Hence, to identify if its the first * time a pending xattr is set, we compare the value of pending xattrs that * came in postop and postop cbk, if its same then its the first time. */ static int32_t up_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { client_t *client = NULL; upcall_local_t *local = NULL; EXIT_IF_UPCALL_OFF(this, out); client = frame->root->client; local = frame->local; if ((op_ret < 0) || !local) { goto out; } if (up_invalidate_needed(local->xattr)) { if (dict_foreach(local->xattr, up_compare_afr_xattr, dict) < 0) goto out; upcall_cache_invalidate(frame, this, client, local->inode, UP_XATTR, NULL, NULL, NULL, local->xattr); } out: if (frame->root->op == GF_FOP_FXATTROP) { UPCALL_STACK_UNWIND(fxattrop, frame, op_ret, op_errno, dict, xdata); } else { UPCALL_STACK_UNWIND(xattrop, frame, op_ret, op_errno, dict, xdata); } return 0; } static int32_t up_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { int32_t op_errno = EINVAL; upcall_local_t *local = NULL; int ret = 0; upcall_private_t *priv = NULL; EXIT_IF_UPCALL_OFF(this, out); priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); local = upcall_local_init(frame, this, loc, NULL, loc->inode, xattr); if (!local) { op_errno = ENOMEM; goto err; } ret = up_filter_xattr(local->xattr, priv->xattrs); if (ret < 0) { goto err; } out: STACK_WIND(frame, up_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, optype, xattr, xdata); return 0; err: UPCALL_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL); return 0; } static int32_t up_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { int32_t op_errno = EINVAL; upcall_local_t *local = NULL; int ret = 0; upcall_private_t *priv = NULL; EXIT_IF_UPCALL_OFF(this, out); priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); local = upcall_local_init(frame, this, NULL, fd, fd->inode, xattr); if (!local) { op_errno = ENOMEM; goto err; } ret = up_filter_xattr(local->xattr, priv->xattrs); if (ret < 0) { goto err; } out: STACK_WIND(frame, up_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, optype, xattr, xdata); return 0; err: STACK_UNWIND_STRICT(fxattrop, frame, -1, op_errno, NULL, NULL); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_upcall_mt_end); if (ret != 0) { gf_msg("upcall", GF_LOG_WARNING, 0, UPCALL_MSG_NO_MEMORY, "Memory allocation failed"); return ret; } return ret; } void upcall_local_wipe(upcall_local_t *local) { if (local) { inode_unref(local->inode); if (local->xattr) dict_unref(local->xattr); loc_wipe(&local->rename_oldloc); loc_wipe(&local->loc); if (local->fd) fd_unref(local->fd); mem_put(local); } } static upcall_local_t * upcall_local_init(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, inode_t *inode, dict_t *xattr) { upcall_local_t *local = NULL; GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); local = mem_get0(this->local_pool); if (!local) goto out; local->inode = inode_ref(inode); if (xattr) local->xattr = dict_copy_with_ref(xattr, NULL); if (loc) loc_copy(&local->loc, loc); if (fd) local->fd = fd_ref(fd); frame->local = local; out: return local; } static int32_t update_xattrs(dict_t *dict, char *key, data_t *value, void *data) { dict_t *xattrs = data; int ret = 0; ret = dict_set_int8(xattrs, key, 0); return ret; } int32_t up_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) { upcall_private_t *priv = NULL; int ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); if (op != GF_IPC_TARGET_UPCALL) goto wind; /* TODO: Bz-1371622 Along with the xattrs also store list of clients * that are interested in notifications, so that the notification * can be sent to the clients that have registered. * Once this implemented there can be unregister of xattrs for * notifications. Until then there is no unregister of xattrs*/ if (xdata && priv->xattrs) { ret = dict_foreach(xdata, update_xattrs, priv->xattrs); } out: STACK_UNWIND_STRICT(ipc, frame, ret, 0, NULL); return 0; wind: STACK_WIND(frame, default_ipc_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc, op, xdata); return 0; } int reconfigure(xlator_t *this, dict_t *options) { upcall_private_t *priv = NULL; int ret = -1; priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); GF_OPTION_RECONF("cache-invalidation", priv->cache_invalidation_enabled, options, bool, out); GF_OPTION_RECONF("cache-invalidation-timeout", priv->cache_invalidation_timeout, options, time, out); ret = 0; if (priv->cache_invalidation_enabled && !priv->reaper_init_done) { ret = upcall_reaper_thread_init(this); if (ret) { gf_msg("upcall", GF_LOG_WARNING, 0, UPCALL_MSG_INTERNAL_ERROR, "reaper_thread creation failed (%s)." " Disabling cache_invalidation", strerror(errno)); } priv->reaper_init_done = _gf_true; } out: return ret; } int init(xlator_t *this) { int ret = -1; upcall_private_t *priv = NULL; priv = GF_CALLOC(1, sizeof(*priv), gf_upcall_mt_private_t); if (!priv) goto out; priv->xattrs = dict_new(); if (!priv->xattrs) goto out; GF_OPTION_INIT("cache-invalidation", priv->cache_invalidation_enabled, bool, out); GF_OPTION_INIT("cache-invalidation-timeout", priv->cache_invalidation_timeout, time, out); LOCK_INIT(&priv->inode_ctx_lk); INIT_LIST_HEAD(&priv->inode_ctx_list); priv->fini = 0; priv->reaper_init_done = _gf_false; this->private = priv; this->local_pool = mem_pool_new(upcall_local_t, 512); ret = 0; if (priv->cache_invalidation_enabled) { ret = upcall_reaper_thread_init(this); if (ret) { gf_msg("upcall", GF_LOG_WARNING, 0, UPCALL_MSG_INTERNAL_ERROR, "reaper_thread creation failed (%s)." " Disabling cache_invalidation", strerror(errno)); } priv->reaper_init_done = _gf_true; } out: if (ret && priv) { if (priv->xattrs) dict_unref(priv->xattrs); GF_FREE(priv); } return ret; } void fini(xlator_t *this) { upcall_private_t *priv = NULL; priv = this->private; if (!priv) { return; } this->private = NULL; priv->fini = 1; if (priv->reaper_thr) { gf_thread_cleanup_xint(priv->reaper_thr); priv->reaper_thr = 0; priv->reaper_init_done = _gf_false; } dict_unref(priv->xattrs); LOCK_DESTROY(&priv->inode_ctx_lk); /* Do we need to cleanup the inode_ctxs? IMO not required * as inode_forget would have been done on all the inodes * before calling xlator_fini */ GF_FREE(priv); if (this->local_pool) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; } return; } int upcall_forget(xlator_t *this, inode_t *inode) { upcall_private_t *priv = this->private; if (!priv) goto out; upcall_cleanup_inode_ctx(this, inode); out: return 0; } int upcall_release(xlator_t *this, fd_t *fd) { return 0; } int notify(xlator_t *this, int32_t event, void *data, ...) { int ret = -1; struct gf_upcall *up_req = NULL; switch (event) { case GF_EVENT_UPCALL: { gf_log(this->name, GF_LOG_DEBUG, "Upcall Notify event = %d", event); up_req = (struct gf_upcall *)data; GF_VALIDATE_OR_GOTO(this->name, up_req, out); ret = default_notify(this, event, up_req); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, UPCALL_MSG_NOTIFY_FAILED, "Failed to notify cache invalidation" " to client(%s)", up_req->client_uid); goto out; } } break; default: default_notify(this, event, data); break; } ret = 0; out: return ret; } struct xlator_fops fops = { .ipc = up_ipc, /* fops which change only "ATIME" do not result * in any cache invalidation. Hence upcall * notifications are not sent in this case. * But however, we need to store/update the * client info in the upcall state to be able * to notify them in case of any changes done * to the data. * * Below such fops do not trigger upcall * notifications but will add/update * clients info in the upcall inode ctx.*/ .lookup = up_lookup, .open = up_open, .statfs = up_statfs, .opendir = up_opendir, .readdir = up_readdir, .readdirp = up_readdirp, .stat = up_stat, .fstat = up_fstat, .access = up_access, .readlink = up_readlink, .readv = up_readv, .lk = up_lk, .seek = up_seek, /* fops doing write */ .truncate = up_truncate, .ftruncate = up_ftruncate, .writev = up_writev, .zerofill = up_zerofill, .fallocate = up_fallocate, .discard = up_discard, /* fops changing attributes */ .fsetattr = up_fsetattr, .setattr = up_setattr, /* fops affecting parent dirent */ .mknod = up_mknod, .create = up_create, .symlink = up_symlink, .mkdir = up_mkdir, /* fops affecting both file and parent * cache entries */ .unlink = up_unlink, .link = up_link, .rmdir = up_rmdir, .rename = up_rename, .setxattr = up_setxattr, .fsetxattr = up_fsetxattr, .getxattr = up_getxattr, .fgetxattr = up_fgetxattr, .fremovexattr = up_fremovexattr, .removexattr = up_removexattr, .xattrop = up_xattrop, .fxattrop = up_fxattrop, #ifdef NOT_SUPPORTED /* internal lk fops */ .inodelk = up_inodelk, .finodelk = up_finodelk, .entrylk = up_entrylk, .fentrylk = up_fentrylk, /* Below fops follow 'WRITE' which * would have already sent upcall * notifications */ .flush = up_flush, .fsync = up_fsync, .fsyncdir = up_fsyncdir, #endif }; struct xlator_cbks cbks = { .forget = upcall_forget, .release = upcall_release, }; struct volume_options options[] = { { .key = {"cache-invalidation"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "When \"on\", sends cache-invalidation" " notifications.", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"cache", "cacheconsistency", "upcall"}, }, {.key = {"cache-invalidation-timeout"}, .type = GF_OPTION_TYPE_INT, .default_value = CACHE_INVALIDATION_TIMEOUT, .description = "After 'timeout' seconds since the time" " client accessed any file, cache-invalidation" " notifications are no longer sent to that client.", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"cache", "cachetimeout", "upcall"}}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "upcall", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/upcall/src/PaxHeaders.9031/upcall-internal.c0000644000000000000000000000013214522202451025177 xustar000000000000000030 mtime=1699284265.697027522 30 atime=1699284265.697027522 30 ctime=1699284304.131143285 glusterfs-11.1/xlators/features/upcall/src/upcall-internal.c0000664000175100017510000004501214522202451025460 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include "upcall.h" #include "upcall-mem-types.h" /* * Check if any of the upcall options are enabled: * - cache_invalidation */ gf_boolean_t is_upcall_enabled(xlator_t *this) { upcall_private_t *priv = NULL; if (this->private) { priv = (upcall_private_t *)this->private; return priv->cache_invalidation_enabled; } return _gf_false; } /* * Get the cache_invalidation_timeout */ static time_t get_cache_invalidation_timeout(xlator_t *this) { upcall_private_t *priv = NULL; if (this->private) { priv = (upcall_private_t *)this->private; return priv->cache_invalidation_timeout; } return 0; } static upcall_client_t * __add_upcall_client(xlator_t *this, client_t *client, upcall_inode_ctx_t *up_inode_ctx, time_t now, time_t timeout) { upcall_client_t *up_client_entry = GF_MALLOC( sizeof(*up_client_entry), gf_upcall_mt_upcall_client_entry_t); if (!up_client_entry) { gf_msg("upcall", GF_LOG_WARNING, 0, UPCALL_MSG_NO_MEMORY, "Memory allocation failed"); return NULL; } INIT_LIST_HEAD(&up_client_entry->client_list); up_client_entry->client_uid = gf_strdup(client->client_uid); up_client_entry->access_time = now; up_client_entry->expire_time_attr = timeout; list_add_tail(&up_client_entry->client_list, &up_inode_ctx->client_list); gf_log(this->name, GF_LOG_DEBUG, "upcall_entry_t client added - %s", up_client_entry->client_uid); return up_client_entry; } static upcall_inode_ctx_t * __upcall_inode_ctx_set(inode_t *inode, xlator_t *this) { upcall_inode_ctx_t *inode_ctx = NULL; upcall_private_t *priv = NULL; int ret; uint64_t ctx = 0; priv = this->private; GF_ASSERT(priv); inode_ctx = GF_MALLOC(sizeof(upcall_inode_ctx_t), gf_upcall_mt_upcall_inode_ctx_t); if (!inode_ctx) { goto out; } pthread_mutex_init(&inode_ctx->client_list_lock, NULL); INIT_LIST_HEAD(&inode_ctx->inode_ctx_list); INIT_LIST_HEAD(&inode_ctx->client_list); inode_ctx->destroy = 0; gf_uuid_copy(inode_ctx->gfid, inode->gfid); ctx = (long)inode_ctx; ret = __inode_ctx_set(inode, this, &ctx); if (ret) { gf_log(this->name, GF_LOG_WARNING, "failed to set inode ctx (%p)", inode); GF_FREE(inode_ctx); inode_ctx = NULL; goto out; } /* add this inode_ctx to the global list */ LOCK(&priv->inode_ctx_lk); { list_add_tail(&inode_ctx->inode_ctx_list, &priv->inode_ctx_list); } UNLOCK(&priv->inode_ctx_lk); out: return inode_ctx; } static upcall_inode_ctx_t * __upcall_inode_ctx_get(inode_t *inode, xlator_t *this) { upcall_inode_ctx_t *inode_ctx = NULL; uint64_t ctx = 0; int ret = 0; ret = __inode_ctx_get(inode, this, &ctx); if (ret == 0) { inode_ctx = (upcall_inode_ctx_t *)(long)(ctx); } else { inode_ctx = __upcall_inode_ctx_set(inode, this); } return inode_ctx; } static upcall_inode_ctx_t * upcall_inode_ctx_get(inode_t *inode, xlator_t *this) { upcall_inode_ctx_t *inode_ctx = NULL; LOCK(&inode->lock); { inode_ctx = __upcall_inode_ctx_get(inode, this); } UNLOCK(&inode->lock); return inode_ctx; } static void __upcall_cleanup_client_entry(upcall_client_t *up_client) { list_del_init(&up_client->client_list); GF_FREE(up_client->client_uid); GF_FREE(up_client); } static void upcall_cleanup_expired_clients(xlator_t *this, upcall_inode_ctx_t *up_inode_ctx, time_t now, time_t timeout) { upcall_client_t *up_client = NULL; upcall_client_t *tmp = NULL; time_t t_expired = 0; pthread_mutex_lock(&up_inode_ctx->client_list_lock); { list_for_each_entry_safe(up_client, tmp, &up_inode_ctx->client_list, client_list) { t_expired = now - up_client->access_time; if (t_expired > (2 * timeout)) { gf_log(this->name, GF_LOG_TRACE, "Cleaning up client_entry(%s)", up_client->client_uid); __upcall_cleanup_client_entry(up_client); } } } pthread_mutex_unlock(&up_inode_ctx->client_list_lock); } /* * Free Upcall inode_ctx client list */ int __upcall_cleanup_inode_ctx_client_list(upcall_inode_ctx_t *inode_ctx) { upcall_client_t *up_client = NULL; upcall_client_t *tmp = NULL; list_for_each_entry_safe(up_client, tmp, &inode_ctx->client_list, client_list) { __upcall_cleanup_client_entry(up_client); } return 0; } static void upcall_cache_forget(xlator_t *this, inode_t *inode, upcall_inode_ctx_t *up_inode_ctx, time_t timeout); /* * Free upcall_inode_ctx */ int upcall_cleanup_inode_ctx(xlator_t *this, inode_t *inode) { uint64_t ctx = 0; upcall_inode_ctx_t *inode_ctx = NULL; int ret = 0; upcall_private_t *priv = NULL; priv = this->private; GF_ASSERT(priv); ret = inode_ctx_del(inode, this, &ctx); if (ret < 0) { gf_msg("upcall", GF_LOG_WARNING, 0, UPCALL_MSG_INTERNAL_ERROR, "Failed to del upcall_inode_ctx (%p)", inode); goto out; } inode_ctx = (upcall_inode_ctx_t *)(long)ctx; if (inode_ctx) { /* Invalidate all the upcall cache entries */ upcall_cache_forget(this, inode, inode_ctx, priv->cache_invalidation_timeout); /* do we really need lock? yes now reaper thread * may also be trying to cleanup the client entries. */ pthread_mutex_lock(&inode_ctx->client_list_lock); { if (!list_empty(&inode_ctx->client_list)) { __upcall_cleanup_inode_ctx_client_list(inode_ctx); } } pthread_mutex_unlock(&inode_ctx->client_list_lock); /* Mark the inode_ctx to be destroyed */ inode_ctx->destroy = 1; gf_msg_debug("upcall", 0, "set upcall_inode_ctx (%p) to destroy mode", inode_ctx); } out: return ret; } /* * Traverse through the list of upcall_inode_ctx(s), * cleanup the expired client entries and destroy the ctx * which is no longer valid and has destroy bit set. */ void * upcall_reaper_thread(void *data) { upcall_private_t *priv = NULL; upcall_inode_ctx_t *inode_ctx = NULL; upcall_inode_ctx_t *tmp = NULL; xlator_t *this = NULL; time_t timeout = 0; time_t time_now; this = (xlator_t *)data; GF_ASSERT(this); priv = this->private; GF_ASSERT(priv); timeout = priv->cache_invalidation_timeout; time_now = gf_time(); while (!priv->fini) { list_for_each_entry_safe(inode_ctx, tmp, &priv->inode_ctx_list, inode_ctx_list) { /* cleanup expired clients */ upcall_cleanup_expired_clients(this, inode_ctx, time_now, timeout); if (!inode_ctx->destroy) { continue; } /* client list would have been cleaned up*/ gf_msg_debug("upcall", 0, "Freeing upcall_inode_ctx (%p)", inode_ctx); LOCK(&priv->inode_ctx_lk); { list_del_init(&inode_ctx->inode_ctx_list); pthread_mutex_destroy(&inode_ctx->client_list_lock); } UNLOCK(&priv->inode_ctx_lk); GF_FREE(inode_ctx); inode_ctx = NULL; } /* don't do a very busy loop */ timeout = priv->cache_invalidation_timeout; sleep(timeout / 2); time_now = gf_time(); } return NULL; } /* * Initialize upcall reaper thread. */ int upcall_reaper_thread_init(xlator_t *this) { upcall_private_t *priv = NULL; int ret = -1; priv = this->private; GF_ASSERT(priv); ret = gf_thread_create(&priv->reaper_thr, NULL, upcall_reaper_thread, this, "upreaper"); return ret; } int up_compare_afr_xattr(dict_t *d, char *k, data_t *v, void *tmp) { dict_t *dict = tmp; if (!strncmp(k, AFR_XATTR_PREFIX, SLEN(AFR_XATTR_PREFIX)) && (!is_data_equal(v, dict_get(dict, k)))) return -1; return 0; } static void up_filter_afr_xattr(dict_t *xattrs, char *xattr, data_t *v) { /* Filter the afr pending xattrs, with value 0. Ideally this should * be executed only in case of xattrop and not in set and removexattr, * butset and remove xattr fops do not come with keys AFR_XATTR_PREFIX */ if (!strncmp(xattr, AFR_XATTR_PREFIX, SLEN(AFR_XATTR_PREFIX)) && (mem_0filled(v->data, v->len) == 0)) { dict_del(xattrs, xattr); } return; } static gf_boolean_t up_key_is_regd_xattr(dict_t *regd_xattrs, char *regd_xattr, data_t *v, void *xattr) { int ret = _gf_false; char *key = xattr; if (fnmatch(regd_xattr, key, 0) == 0) ret = _gf_true; return ret; } int up_filter_unregd_xattr(dict_t *xattrs, char *xattr, data_t *v, void *regd_xattrs) { int ret = 0; ret = dict_foreach_match(regd_xattrs, up_key_is_regd_xattr, xattr, dict_null_foreach_fn, NULL); if (ret == 0) { /* xattr was not found in the registered xattr, hence do not * send notification for its change */ dict_del(xattrs, xattr); goto out; } up_filter_afr_xattr(xattrs, xattr, v); out: return 0; } int up_filter_xattr(dict_t *xattr, dict_t *regd_xattrs) { int ret = 0; ret = dict_foreach(xattr, up_filter_unregd_xattr, regd_xattrs); return ret; } static void upcall_client_cache_invalidate(xlator_t *this, uuid_t gfid, upcall_client_t *up_client_entry, uint32_t flags, struct iatt *stbuf, struct iatt *p_stbuf, struct iatt *oldp_stbuf, dict_t *xattr, time_t now, time_t timeout); gf_boolean_t up_invalidate_needed(dict_t *xattrs) { if (dict_key_count(xattrs) == 0) { gf_msg_trace("upcall", 0, "None of xattrs requested for" " invalidation, were changed. Nothing to " "invalidate"); return _gf_false; } return _gf_true; } /* * Given a client, first fetch upcall_entry_t from the inode_ctx client list. * Later traverse through the client list of that upcall entry. If this client * is not present in the list, create one client entry with this client info. * Also check if there are other clients which need to be notified of this * op. If yes send notify calls to them. * * Since sending notifications for cache_invalidation is a best effort, * any errors during the process are logged and ignored. * * The function should be called only if upcall is enabled */ void upcall_cache_invalidate(call_frame_t *frame, xlator_t *this, client_t *client, inode_t *inode, const uint32_t flags, struct iatt *stbuf, struct iatt *p_stbuf, struct iatt *oldp_stbuf, dict_t *xattr) { upcall_client_t *up_client_entry = NULL; upcall_client_t *tmp = NULL; upcall_inode_ctx_t *up_inode_ctx = NULL; gf_boolean_t found = _gf_false; time_t time_now, timeout; inode_t *linked_inode = NULL; /* server-side generated fops like quota/marker will not have any * client associated with them. Ignore such fops. */ if (!client) { gf_msg_debug("upcall", 0, "Internal fop - client NULL"); return; } /* For nameless LOOKUPs, inode created shall always be * invalid. Hence check if there is any already linked inode. * If yes, update the inode_ctx of that valid inode */ if (inode && (inode->ia_type == IA_INVAL) && stbuf) { linked_inode = inode_find(inode->table, stbuf->ia_gfid); if (linked_inode) { gf_log("upcall", GF_LOG_DEBUG, "upcall_inode_ctx_get of linked inode (%p)", linked_inode); up_inode_ctx = upcall_inode_ctx_get(linked_inode, this); } } if (inode && !up_inode_ctx) up_inode_ctx = upcall_inode_ctx_get(inode, this); if (!up_inode_ctx) { gf_msg("upcall", GF_LOG_WARNING, 0, UPCALL_MSG_INTERNAL_ERROR, "upcall_inode_ctx_get failed (%p)", inode); return; } /* In case of LOOKUP, if first time, inode created shall be * invalid till it gets linked to inode table. Read gfid from * the stat returned in such cases. */ if (gf_uuid_is_null(up_inode_ctx->gfid) && stbuf) { /* That means inode must have been invalid when this inode_ctx * is created. Copy the gfid value from stbuf instead. */ gf_uuid_copy(up_inode_ctx->gfid, stbuf->ia_gfid); } if (gf_uuid_is_null(up_inode_ctx->gfid)) { gf_msg_debug(this->name, 0, "up_inode_ctx->gfid and " "stbuf->ia_gfid is NULL, fop:%s", gf_fop_list[frame->root->op]); goto out; } timeout = get_cache_invalidation_timeout(this); time_now = gf_time(); pthread_mutex_lock(&up_inode_ctx->client_list_lock); { list_for_each_entry_safe(up_client_entry, tmp, &up_inode_ctx->client_list, client_list) { /* Do not send UPCALL event if same client. */ if (!strcmp(client->client_uid, up_client_entry->client_uid)) { up_client_entry->access_time = time_now; found = _gf_true; continue; } /* * Ignore sending notifications in case of only UP_ATIME */ if (!(flags & ~(UP_ATIME))) { if (found) break; else /* we still need to find current client entry*/ continue; } /* any other client */ /* XXX: Send notifications asynchrounously * instead of in the I/O path - BZ 1200264 * Also if the file is frequently accessed, set * expire_time_attr to 0. */ upcall_client_cache_invalidate( this, up_inode_ctx->gfid, up_client_entry, flags, stbuf, p_stbuf, oldp_stbuf, xattr, time_now, timeout); } if (!found) { up_client_entry = __add_upcall_client(this, client, up_inode_ctx, time_now, timeout); } } pthread_mutex_unlock(&up_inode_ctx->client_list_lock); out: /* release the ref from inode_find */ if (linked_inode) inode_unref(linked_inode); return; } /* * If the upcall_client_t has recently accessed the file (i.e, within * priv->cache_invalidation_timeout), send a upcall notification. */ static void upcall_client_cache_invalidate(xlator_t *this, uuid_t gfid, upcall_client_t *up_client_entry, uint32_t flags, struct iatt *stbuf, struct iatt *p_stbuf, struct iatt *oldp_stbuf, dict_t *xattr, time_t now, time_t timeout) { struct gf_upcall up_req = { 0, }; struct gf_upcall_cache_invalidation ca_req = { 0, }; int ret; time_t t_expired = now - up_client_entry->access_time; if (t_expired < timeout) { /* Send notify call */ up_req.client_uid = up_client_entry->client_uid; gf_uuid_copy(up_req.gfid, gfid); ca_req.flags = flags; ca_req.expire_time_attr = up_client_entry->expire_time_attr; if (stbuf) ca_req.stat = *stbuf; if (p_stbuf) ca_req.p_stat = *p_stbuf; if (oldp_stbuf) ca_req.oldp_stat = *oldp_stbuf; ca_req.dict = xattr; up_req.data = &ca_req; up_req.event_type = GF_UPCALL_CACHE_INVALIDATION; gf_log(this->name, GF_LOG_TRACE, "Cache invalidation notification sent to %s", up_client_entry->client_uid); /* Need to send inode flags */ ret = this->notify(this, GF_EVENT_UPCALL, &up_req); /* * notify may fail as the client could have been * dis(re)connected. Cleanup the client entry. */ if (ret < 0) __upcall_cleanup_client_entry(up_client_entry); } else { gf_log(this->name, GF_LOG_TRACE, "Cache invalidation notification NOT sent to %s", up_client_entry->client_uid); if (t_expired > (2 * timeout)) { /* Cleanup the entry */ __upcall_cleanup_client_entry(up_client_entry); } } } /* * This is called during upcall_inode_ctx cleanup in case of 'inode_forget'. * Send "UP_FORGET" to all the clients so that they invalidate their cache * entry and do a fresh lookup next time when any I/O comes in. */ static void upcall_cache_forget(xlator_t *this, inode_t *inode, upcall_inode_ctx_t *up_inode_ctx, time_t timeout) { upcall_client_t *up_client_entry = NULL; upcall_client_t *tmp = NULL; uint32_t flags = UP_FORGET; time_t time_now; gf_boolean_t is_gfid_valid = _gf_true; if (!up_inode_ctx) { return; } if (gf_uuid_is_null(up_inode_ctx->gfid)) is_gfid_valid = _gf_false; time_now = gf_time(); pthread_mutex_lock(&up_inode_ctx->client_list_lock); { list_for_each_entry_safe(up_client_entry, tmp, &up_inode_ctx->client_list, client_list) { /* Set the access time to gf_time() * to send notify */ up_client_entry->access_time = time_now; if (is_gfid_valid) upcall_client_cache_invalidate( this, up_inode_ctx->gfid, up_client_entry, flags, NULL, NULL, NULL, NULL, time_now, timeout); } } pthread_mutex_unlock(&up_inode_ctx->client_list_lock); } glusterfs-11.1/xlators/features/upcall/src/PaxHeaders.9031/upcall-cache-invalidation.h0000644000000000000000000000013214522202451027112 xustar000000000000000030 mtime=1699284265.697027522 30 atime=1699284265.697027522 30 ctime=1699284304.128143276 glusterfs-11.1/xlators/features/upcall/src/upcall-cache-invalidation.h0000664000175100017510000000120514522202451027367 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __UPCALL_CACHE_INVALIDATION_H__ #define __UPCALL_CACHE_INVALIDATION_H__ /* The time period for which a client will be notified of cache_invalidation * events post its last access */ #define CACHE_INVALIDATION_TIMEOUT "60" #endif /* __UPCALL_CACHE_INVALIDATION_H__ */ glusterfs-11.1/xlators/features/upcall/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465024013 xustar000000000000000030 mtime=1699284277.631063468 30 atime=1699284290.964103627 30 ctime=1699284304.118143246 glusterfs-11.1/xlators/features/upcall/src/Makefile.in0000664000175100017510000006020214522202465024272 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/upcall/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) upcall_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la am_upcall_la_OBJECTS = upcall.lo upcall-internal.lo upcall_la_OBJECTS = $(am_upcall_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = upcall_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(upcall_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_upcall_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(upcall_la_SOURCES) DIST_SOURCES = $(upcall_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = upcall.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features upcall_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) upcall_la_SOURCES = upcall.c upcall-internal.c upcall_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la noinst_HEADERS = upcall.h upcall-mem-types.h upcall-messages.h \ upcall-cache-invalidation.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/upcall/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/upcall/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } upcall.la: $(upcall_la_OBJECTS) $(upcall_la_DEPENDENCIES) $(EXTRA_upcall_la_DEPENDENCIES) $(AM_V_CCLD)$(upcall_la_LINK) $(am_upcall_la_rpath) $(upcall_la_OBJECTS) $(upcall_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upcall-internal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upcall.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/upcall/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023775 xustar000000000000000030 mtime=1699284265.697027522 30 atime=1699284277.593063353 30 ctime=1699284304.120143252 glusterfs-11.1/xlators/features/upcall/src/Makefile.am0000664000175100017510000000130114522202451024247 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = upcall.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features upcall_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) upcall_la_SOURCES = upcall.c upcall-internal.c upcall_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la noinst_HEADERS = upcall.h upcall-mem-types.h upcall-messages.h \ upcall-cache-invalidation.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/upcall/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202465023223 xustar000000000000000029 mtime=1699284277.58206332 30 atime=1699284290.943103564 30 ctime=1699284304.069143098 glusterfs-11.1/xlators/features/upcall/Makefile.in0000664000175100017510000005272414522202465023515 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/upcall DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/upcall/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/upcall/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/upcall/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023206 xustar000000000000000030 mtime=1699284265.697027522 30 atime=1699284277.558063248 30 ctime=1699284304.071143104 glusterfs-11.1/xlators/features/upcall/Makefile.am0000664000175100017510000000003414522202451023462 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/selinux0000644000000000000000000000013214522202521021302 xustar000000000000000030 mtime=1699284305.167146405 30 atime=1699284309.686160016 30 ctime=1699284305.167146405 glusterfs-11.1/xlators/features/selinux/0002775000175100017510000000000014522202521021640 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/selinux/PaxHeaders.9031/src0000644000000000000000000000013214522202521022071 xustar000000000000000030 mtime=1699284305.216146553 30 atime=1699284309.686160016 30 ctime=1699284305.216146553 glusterfs-11.1/xlators/features/selinux/src/0002775000175100017510000000000014522202521022427 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/selinux/src/PaxHeaders.9031/selinux.h0000644000000000000000000000013214522202451024010 xustar000000000000000030 mtime=1699284265.688027495 30 atime=1699284265.688027495 30 ctime=1699284305.211146538 glusterfs-11.1/xlators/features/selinux/src/selinux.h0000664000175100017510000000115714522202451024273 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2017 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __SELINUX_H__ #define __SELINUX_H__ #define SELINUX_XATTR "security.selinux" #define SELINUX_GLUSTER_XATTR "trusted.glusterfs.selinux" struct selinux_priv { gf_boolean_t selinux_enabled; }; typedef struct selinux_priv selinux_priv_t; #endif glusterfs-11.1/xlators/features/selinux/src/PaxHeaders.9031/selinux-mem-types.h0000644000000000000000000000013114522202451025725 xustar000000000000000030 mtime=1699284265.688027495 30 atime=1699284265.688027495 29 ctime=1699284305.21514655 glusterfs-11.1/xlators/features/selinux/src/selinux-mem-types.h0000664000175100017510000000110714522202451026204 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2017 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __SELINUX_MEM_TYPES_H__ #define __SELINUX_MEM_TYPES_H__ #include enum gf_selinux_mem_types_ { gf_selinux_mt_selinux_priv_t = gf_common_mt_end + 1, gf_selinux_mt_end }; #endif glusterfs-11.1/xlators/features/selinux/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202465024221 xustar000000000000000030 mtime=1699284277.047061709 29 atime=1699284290.43410203 30 ctime=1699284305.207146526 glusterfs-11.1/xlators/features/selinux/src/Makefile.in0000664000175100017510000005743614522202465024520 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/selinux/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) selinux_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_selinux_la_OBJECTS = selinux.lo selinux_la_OBJECTS = $(am_selinux_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = selinux_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(selinux_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_selinux_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(selinux_la_SOURCES) DIST_SOURCES = $(selinux_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = selinux.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features selinux_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) selinux_la_SOURCES = selinux.c selinux_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = selinux.h selinux-messages.h selinux-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/selinux/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/selinux/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } selinux.la: $(selinux_la_OBJECTS) $(selinux_la_DEPENDENCIES) $(EXTRA_selinux_la_DEPENDENCIES) $(AM_V_CCLD)$(selinux_la_LINK) $(am_selinux_la_rpath) $(selinux_la_OBJECTS) $(selinux_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selinux.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/selinux/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024204 xustar000000000000000030 mtime=1699284265.688027495 30 atime=1699284277.009061595 30 ctime=1699284305.209146531 glusterfs-11.1/xlators/features/selinux/src/Makefile.am0000664000175100017510000000100714522202451024461 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = selinux.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features selinux_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) selinux_la_SOURCES = selinux.c selinux_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = selinux.h selinux-messages.h selinux-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/selinux/src/PaxHeaders.9031/selinux-messages.h0000644000000000000000000000013214522202451025615 xustar000000000000000030 mtime=1699284265.688027495 30 atime=1699284265.688027495 30 ctime=1699284305.213146544 glusterfs-11.1/xlators/features/selinux/src/selinux-messages.h0000664000175100017510000000177314522202451026104 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2017 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _SELINUX_MESSAGES_H__ #define _SELINUX_MESSAGES_H__ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(SL, SL_MSG_INVALID_VOLFILE, SL_MSG_ENOMEM, SL_MSG_MEM_ACCT_INIT_FAILED, SL_MSG_SELINUX_GLUSTER_XATTR_MISSING, SL_MSG_SELINUX_XATTR_MISSING); #endif /*_SELINUX_MESSAGES_H */ glusterfs-11.1/xlators/features/selinux/src/PaxHeaders.9031/selinux.c0000644000000000000000000000013214522202451024003 xustar000000000000000030 mtime=1699284265.688027495 30 atime=1699284265.688027495 30 ctime=1699284305.216146553 glusterfs-11.1/xlators/features/selinux/src/selinux.c0000664000175100017510000002031714522202451024265 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2017 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "selinux.h" #include "selinux-messages.h" #include "selinux-mem-types.h" #include static int selinux_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *dict, dict_t *xdata) { int ret = 0; char *name = cookie; if (op_errno == 0 && dict && name && (!strcmp(name, SELINUX_GLUSTER_XATTR))) { ret = dict_rename_key(dict, SELINUX_GLUSTER_XATTR, SELINUX_XATTR); if (ret < 0) gf_msg(this->name, GF_LOG_ERROR, op_errno, SL_MSG_SELINUX_GLUSTER_XATTR_MISSING, "getxattr failed for %s", SELINUX_XATTR); } STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, xdata); return ret; } static int selinux_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { selinux_priv_t *priv = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; char *xattr_name = (char *)name; priv = this->private; GF_VALIDATE_OR_GOTO("selinux", priv, err); /* name can be NULL for listxattr calls */ if (!priv->selinux_enabled || !name) goto off; if (strcmp(name, SELINUX_XATTR) == 0) xattr_name = SELINUX_GLUSTER_XATTR; off: STACK_WIND_COOKIE(frame, selinux_fgetxattr_cbk, xattr_name, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, xattr_name, xdata); return 0; err: STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, NULL, xdata); return 0; } static int selinux_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *dict, dict_t *xdata) { int ret = 0; char *name = cookie; if (op_errno == 0 && dict && name && (!strcmp(name, SELINUX_GLUSTER_XATTR))) { ret = dict_rename_key(dict, SELINUX_GLUSTER_XATTR, SELINUX_XATTR); if (ret < 0) gf_msg(this->name, GF_LOG_ERROR, op_errno, SL_MSG_SELINUX_GLUSTER_XATTR_MISSING, "getxattr failed for %s", SELINUX_XATTR); } STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } static int selinux_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { selinux_priv_t *priv = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; char *xattr_name = (char *)name; priv = this->private; GF_VALIDATE_OR_GOTO("selinux", priv, err); /* name can be NULL for listxattr calls */ if (!priv->selinux_enabled || !name) goto off; if (strcmp(name, SELINUX_XATTR) == 0) xattr_name = SELINUX_GLUSTER_XATTR; off: STACK_WIND_COOKIE(frame, selinux_getxattr_cbk, xattr_name, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, xattr_name, xdata); return 0; err: STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, NULL, xdata); return 0; } static int selinux_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); return 0; } static int selinux_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int flags, dict_t *xdata) { selinux_priv_t *priv = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; int32_t ret = -1; priv = this->private; GF_VALIDATE_OR_GOTO("selinux", priv, err); if (!priv->selinux_enabled && !dict) goto off; ret = dict_rename_key(dict, SELINUX_XATTR, SELINUX_GLUSTER_XATTR); if (ret < 0 && ret != -ENODATA) goto err; off: STACK_WIND(frame, selinux_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; err: STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); return 0; } static int selinux_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); return 0; } static int selinux_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int flags, dict_t *xdata) { selinux_priv_t *priv = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; int32_t ret = -1; priv = this->private; GF_VALIDATE_OR_GOTO("selinux", priv, err); if (!priv->selinux_enabled && !dict) goto off; ret = dict_rename_key(dict, SELINUX_XATTR, SELINUX_GLUSTER_XATTR); if (ret < 0 && ret != -ENODATA) goto err; off: STACK_WIND(frame, selinux_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; err: STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; GF_VALIDATE_OR_GOTO("selinux", this, out); ret = xlator_mem_acct_init(this, gf_selinux_mt_end); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SL_MSG_MEM_ACCT_INIT_FAILED, "Memory accounting init failed"); return ret; } out: return ret; } int32_t init(xlator_t *this) { int32_t ret = -1; selinux_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("selinux", this, out); if (!this->children || this->children->next) { gf_msg(this->name, GF_LOG_WARNING, 0, SL_MSG_INVALID_VOLFILE, "Error: SELinux (%s) not configured with exactly one " "child", this->name); return -1; } if (this->parents == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, SL_MSG_INVALID_VOLFILE, "Dangling volume. Please check the volfile"); } priv = GF_CALLOC(1, sizeof(*priv), gf_selinux_mt_selinux_priv_t); if (!priv) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); goto out; } GF_OPTION_INIT("selinux", priv->selinux_enabled, bool, out); this->local_pool = mem_pool_new(selinux_priv_t, 64); if (!this->local_pool) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, SL_MSG_ENOMEM, "Failed to create local_t's memory pool"); goto out; } this->private = (void *)priv; ret = 0; out: if (ret) { GF_FREE(priv); mem_pool_destroy(this->local_pool); this->local_pool = NULL; } return ret; } int reconfigure(xlator_t *this, dict_t *options) { int32_t ret = -1; selinux_priv_t *priv = NULL; priv = this->private; GF_OPTION_RECONF("selinux", priv->selinux_enabled, options, bool, out); ret = 0; out: return ret; } void fini(xlator_t *this) { selinux_priv_t *priv = NULL; priv = this->private; GF_FREE(priv); mem_pool_destroy(this->local_pool); this->local_pool = NULL; return; } struct xlator_fops fops = { .getxattr = selinux_getxattr, .fgetxattr = selinux_fgetxattr, .setxattr = selinux_setxattr, .fsetxattr = selinux_fsetxattr, }; struct xlator_cbks cbks = {}; struct volume_options options[] = { { .key = {"selinux"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "Enable/disable selinux translator", .op_version = {GD_OP_VERSION_3_11_0}, .flags = OPT_FLAG_SETTABLE, .tags = {"security", "linux"}, }, { .key = {NULL}, }}; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "selinux", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/selinux/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023432 xustar000000000000000030 mtime=1699284276.998061561 30 atime=1699284290.412101964 30 ctime=1699284305.161146387 glusterfs-11.1/xlators/features/selinux/Makefile.in0000664000175100017510000005272714522202464023726 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/selinux DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/selinux/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/selinux/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/selinux/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023415 xustar000000000000000030 mtime=1699284265.688027495 30 atime=1699284276.973061486 30 ctime=1699284305.163146393 glusterfs-11.1/xlators/features/selinux/Makefile.am0000664000175100017510000000003414522202451023671 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/marker0000644000000000000000000000013214522202517021101 xustar000000000000000030 mtime=1699284303.660141866 30 atime=1699284309.686160016 30 ctime=1699284303.660141866 glusterfs-11.1/xlators/features/marker/0002775000175100017510000000000014522202517021437 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/marker/PaxHeaders.9031/src0000644000000000000000000000013214522202517021670 xustar000000000000000030 mtime=1699284303.727142068 30 atime=1699284309.686160016 30 ctime=1699284303.727142068 glusterfs-11.1/xlators/features/marker/src/0002775000175100017510000000000014522202517022226 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/marker-quota-helper.c0000644000000000000000000000013214522202451025773 xustar000000000000000030 mtime=1699284265.675027456 30 atime=1699284265.675027456 30 ctime=1699284303.725142062 glusterfs-11.1/xlators/features/marker/src/marker-quota-helper.c0000664000175100017510000002111614522202451026253 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "marker-quota.h" #include "marker-common.h" #include "marker-quota-helper.h" #include "marker-mem-types.h" int mq_loc_fill(loc_t *loc, inode_t *inode, inode_t *parent, char *path) { int ret = -1; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", inode, out); GF_VALIDATE_OR_GOTO("marker", path, out); /* Not checking for parent because while filling * loc of root, parent will be NULL */ if (inode) { loc->inode = inode_ref(inode); } if (parent) loc->parent = inode_ref(parent); if (!gf_uuid_is_null(inode->gfid)) gf_uuid_copy(loc->gfid, inode->gfid); loc->path = gf_strdup(path); if (!loc->path) { gf_log("loc fill", GF_LOG_ERROR, "strdup failed"); goto out; } loc->name = strrchr(loc->path, '/'); if (loc->name) loc->name++; else goto out; ret = 0; out: if (ret < 0) loc_wipe(loc); return ret; } int32_t mq_inode_loc_fill(const char *parent_gfid, inode_t *inode, loc_t *loc) { char *resolvedpath = NULL; inode_t *parent = NULL; quota_inode_ctx_t *ctx = NULL; xlator_t *this = NULL; int ret = -1; this = THIS; if (inode == NULL) { gf_log_callingfn("marker", GF_LOG_ERROR, "loc fill failed, " "inode is NULL"); return ret; } if (loc == NULL) return ret; if ((inode) && __is_root_gfid(inode->gfid)) { loc->parent = NULL; goto ignore_parent; } if (parent_gfid == NULL) parent = inode_parent(inode, 0, NULL); else parent = inode_find(inode->table, (unsigned char *)parent_gfid); if (parent == NULL) { gf_log("marker", GF_LOG_ERROR, "parent is NULL for %s", uuid_utoa(inode->gfid)); goto err; } ignore_parent: ret = inode_path(inode, NULL, &resolvedpath); if (ret < 0) { gf_log("marker", GF_LOG_ERROR, "failed to resolve path for %s", uuid_utoa(inode->gfid)); goto err; } ret = mq_loc_fill(loc, inode, parent, resolvedpath); if (ret < 0) goto err; ret = mq_inode_ctx_get(inode, this, &ctx); if (ret < 0 || ctx == NULL) ctx = mq_inode_ctx_new(inode, this); if (ctx == NULL) { gf_log(this->name, GF_LOG_WARNING, "mq_inode_ctx_new " "failed for %s", uuid_utoa(inode->gfid)); ret = -1; goto err; } ret = 0; err: if (parent) inode_unref(parent); GF_FREE(resolvedpath); return ret; } quota_inode_ctx_t * mq_alloc_inode_ctx(void) { int32_t ret = -1; quota_inode_ctx_t *ctx = NULL; QUOTA_ALLOC(ctx, quota_inode_ctx_t, ret); if (ret == -1) goto out; ctx->size = 0; ctx->dirty = 0; ctx->updation_status = _gf_false; LOCK_INIT(&ctx->lock); INIT_LIST_HEAD(&ctx->contribution_head); out: return ctx; } static void mq_contri_fini(inode_contribution_t *contri) { LOCK_DESTROY(&contri->lock); GF_FREE(contri); } inode_contribution_t * mq_contri_init(inode_t *inode) { inode_contribution_t *contri = NULL; int32_t ret = 0; QUOTA_ALLOC(contri, inode_contribution_t, ret); if (ret == -1) goto out; GF_REF_INIT(contri, mq_contri_fini); contri->contribution = 0; contri->file_count = 0; contri->dir_count = 0; gf_uuid_copy(contri->gfid, inode->gfid); LOCK_INIT(&contri->lock); INIT_LIST_HEAD(&contri->contri_list); out: return contri; } inode_contribution_t * mq_get_contribution_node(inode_t *inode, quota_inode_ctx_t *ctx) { inode_contribution_t *contri = NULL; inode_contribution_t *temp = NULL; if (!inode || !ctx) goto out; LOCK(&ctx->lock); { if (list_empty(&ctx->contribution_head)) goto unlock; list_for_each_entry(temp, &ctx->contribution_head, contri_list) { if (gf_uuid_compare(temp->gfid, inode->gfid) == 0) { contri = temp; GF_REF_GET(contri); break; } } } unlock: UNLOCK(&ctx->lock); out: return contri; } inode_contribution_t * __mq_add_new_contribution_node(xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) { inode_contribution_t *contribution = NULL; if (!loc->parent) { if (!gf_uuid_is_null(loc->pargfid)) loc->parent = inode_find(loc->inode->table, loc->pargfid); if (!loc->parent) loc->parent = inode_parent(loc->inode, loc->pargfid, loc->name); if (!loc->parent) goto out; } list_for_each_entry(contribution, &ctx->contribution_head, contri_list) { if (loc->parent && gf_uuid_compare(contribution->gfid, loc->parent->gfid) == 0) { goto out; } } contribution = mq_contri_init(loc->parent); if (contribution == NULL) goto out; list_add_tail(&contribution->contri_list, &ctx->contribution_head); out: return contribution; } inode_contribution_t * mq_add_new_contribution_node(xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) { inode_contribution_t *contribution = NULL; if ((ctx == NULL) || (loc == NULL)) return NULL; if (((loc->path) && (strcmp(loc->path, "/") == 0)) || (!loc->path && gf_uuid_is_null(loc->pargfid))) return NULL; LOCK(&ctx->lock); { contribution = __mq_add_new_contribution_node(this, ctx, loc); if (contribution) GF_REF_GET(contribution); } UNLOCK(&ctx->lock); return contribution; } int32_t mq_dict_set_contribution(xlator_t *this, dict_t *dict, loc_t *loc, uuid_t gfid, char *contri_key) { int32_t ret = -1; char key[QUOTA_KEY_MAX] = { 0, }; GF_VALIDATE_OR_GOTO("marker", this, out); GF_VALIDATE_OR_GOTO("marker", dict, out); GF_VALIDATE_OR_GOTO("marker", loc, out); if (gfid && !gf_uuid_is_null(gfid)) { GET_CONTRI_KEY(this, key, gfid, ret); } else if (loc->parent) { GET_CONTRI_KEY(this, key, loc->parent->gfid, ret); } else { /* nameless lookup, fetch contributions to all parents */ GET_CONTRI_KEY(this, key, NULL, ret); } if (ret < 0) goto out; ret = dict_set_int64(dict, key, 0); if (ret < 0) goto out; if (contri_key) if (snprintf(contri_key, QUOTA_KEY_MAX, "%s", key) >= QUOTA_KEY_MAX) { ret = -1; goto out; } out: if (ret < 0) gf_log_callingfn(this ? this->name : "Marker", GF_LOG_ERROR, "dict set failed"); return ret; } int32_t mq_inode_ctx_get(inode_t *inode, xlator_t *this, quota_inode_ctx_t **ctx) { int32_t ret = -1; uint64_t ctx_int = 0; marker_inode_ctx_t *mark_ctx = NULL; GF_VALIDATE_OR_GOTO("marker", inode, out); GF_VALIDATE_OR_GOTO("marker", this, out); GF_VALIDATE_OR_GOTO("marker", ctx, out); ret = inode_ctx_get(inode, this, &ctx_int); if (ret < 0) { ret = -1; *ctx = NULL; goto out; } mark_ctx = (marker_inode_ctx_t *)(unsigned long)ctx_int; if (mark_ctx->quota_ctx == NULL) { ret = -1; goto out; } *ctx = mark_ctx->quota_ctx; ret = 0; out: return ret; } quota_inode_ctx_t * __mq_inode_ctx_new(inode_t *inode, xlator_t *this) { int32_t ret = -1; quota_inode_ctx_t *quota_ctx = NULL; marker_inode_ctx_t *mark_ctx = NULL; ret = marker_force_inode_ctx_get(inode, this, &mark_ctx); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "marker_force_inode_ctx_get() failed"); goto out; } LOCK(&inode->lock); { if (mark_ctx->quota_ctx == NULL) { quota_ctx = mq_alloc_inode_ctx(); if (quota_ctx == NULL) { ret = -1; goto unlock; } mark_ctx->quota_ctx = quota_ctx; } else { quota_ctx = mark_ctx->quota_ctx; } ret = 0; } unlock: UNLOCK(&inode->lock); out: return quota_ctx; } quota_inode_ctx_t * mq_inode_ctx_new(inode_t *inode, xlator_t *this) { return __mq_inode_ctx_new(inode, this); } glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/marker-quota.c0000644000000000000000000000013214522202451024516 xustar000000000000000030 mtime=1699284265.676027459 30 atime=1699284265.676027459 30 ctime=1699284303.723142056 glusterfs-11.1/xlators/features/marker/src/marker-quota.c0000664000175100017510000016330014522202451025000 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "marker-quota.h" #include "marker-quota-helper.h" #include #include int mq_loc_copy(loc_t *dst, loc_t *src) { int ret = -1; GF_VALIDATE_OR_GOTO("marker", dst, out); GF_VALIDATE_OR_GOTO("marker", src, out); if (src->inode == NULL || ((src->parent == NULL) && (gf_uuid_is_null(src->pargfid)) && !__is_root_gfid(src->inode->gfid))) { gf_log("marker", GF_LOG_WARNING, "src loc is not valid"); goto out; } ret = loc_copy(dst, src); out: return ret; } static void mq_set_ctx_status(quota_inode_ctx_t *ctx, gf_boolean_t *flag, gf_boolean_t status) { LOCK(&ctx->lock); { *flag = status; } UNLOCK(&ctx->lock); } static void mq_test_and_set_ctx_status(quota_inode_ctx_t *ctx, gf_boolean_t *flag, gf_boolean_t *status) { gf_boolean_t temp = _gf_false; LOCK(&ctx->lock); { temp = *status; *status = *flag; *flag = temp; } UNLOCK(&ctx->lock); } static void mq_get_ctx_status(quota_inode_ctx_t *ctx, gf_boolean_t *flag, gf_boolean_t *status) { LOCK(&ctx->lock); { *status = *flag; } UNLOCK(&ctx->lock); } int32_t mq_get_ctx_updation_status(quota_inode_ctx_t *ctx, gf_boolean_t *status) { GF_VALIDATE_OR_GOTO("marker", ctx, out); GF_VALIDATE_OR_GOTO("marker", status, out); mq_get_ctx_status(ctx, &ctx->updation_status, status); return 0; out: return -1; } int32_t mq_set_ctx_updation_status(quota_inode_ctx_t *ctx, gf_boolean_t status) { GF_VALIDATE_OR_GOTO("marker", ctx, out); mq_set_ctx_status(ctx, &ctx->updation_status, status); return 0; out: return -1; } int32_t mq_test_and_set_ctx_updation_status(quota_inode_ctx_t *ctx, gf_boolean_t *status) { GF_VALIDATE_OR_GOTO("marker", ctx, out); GF_VALIDATE_OR_GOTO("marker", status, out); mq_test_and_set_ctx_status(ctx, &ctx->updation_status, status); return 0; out: return -1; } int32_t mq_set_ctx_create_status(quota_inode_ctx_t *ctx, gf_boolean_t status) { GF_VALIDATE_OR_GOTO("marker", ctx, out); mq_set_ctx_status(ctx, &ctx->create_status, status); return 0; out: return -1; } int32_t mq_test_and_set_ctx_create_status(quota_inode_ctx_t *ctx, gf_boolean_t *status) { GF_VALIDATE_OR_GOTO("marker", ctx, out); GF_VALIDATE_OR_GOTO("marker", status, out); mq_test_and_set_ctx_status(ctx, &ctx->create_status, status); return 0; out: return -1; } static void mq_set_ctx_dirty_status(quota_inode_ctx_t *ctx, gf_boolean_t status) { GF_VALIDATE_OR_GOTO("marker", ctx, out); mq_set_ctx_status(ctx, &ctx->dirty_status, status); out: return; } int mq_build_ancestry(xlator_t *this, loc_t *loc) { int32_t ret = -1; fd_t *fd = NULL; gf_dirent_t entries; gf_dirent_t *entry = NULL; dict_t *xdata = NULL; inode_t *tmp_parent = NULL; inode_t *tmp_inode = NULL; inode_t *linked_inode = NULL; quota_inode_ctx_t *ctx = NULL; INIT_LIST_HEAD(&entries.list); xdata = dict_new(); if (xdata == NULL) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); ret = -ENOMEM; goto out; } ret = dict_set_int8(xdata, GET_ANCESTRY_DENTRY_KEY, 1); if (ret < 0) goto out; fd = fd_anonymous(loc->inode); if (fd == NULL) { gf_log(this->name, GF_LOG_ERROR, "fd creation failed"); ret = -ENOMEM; goto out; } fd_bind(fd); ret = syncop_readdirp(this, fd, 131072, 0, &entries, xdata, NULL); if (ret < 0) { gf_log(this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "readdirp failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } if (list_empty(&entries.list)) { ret = -1; goto out; } list_for_each_entry(entry, &entries.list, list) { if (__is_root_gfid(entry->inode->gfid)) { /* The list contains a sub-list for each possible path * to the target inode. Each sub-list starts with the * root entry of the tree and is followed by the child * entries for a particular path to the target entry. * The root entry is an implied sub-list delimiter, * as it denotes we have started processing a new path. * Reset the parent pointer and continue */ tmp_parent = NULL; } else { linked_inode = inode_link(entry->inode, tmp_parent, entry->d_name, &entry->d_stat); if (linked_inode) { tmp_inode = entry->inode; entry->inode = linked_inode; inode_unref(tmp_inode); } else { gf_log(this->name, GF_LOG_ERROR, "inode link failed"); ret = -EINVAL; goto out; } } ctx = mq_inode_ctx_new(entry->inode, this); if (ctx == NULL) { gf_log(this->name, GF_LOG_WARNING, "mq_inode_ctx_new " "failed for %s", uuid_utoa(entry->inode->gfid)); ret = -ENOMEM; goto out; } /* For non-directory, posix_get_ancestry_non_directory returns * all hard-links that are represented by nodes adjacent to * each other in the dentry-list. * (Unlike the directory case where adjacent nodes either have * a parent/child relationship or belong to different paths). */ if (entry->inode->ia_type == IA_IFDIR) tmp_parent = entry->inode; } if (loc->parent) inode_unref(loc->parent); loc->parent = inode_parent(loc->inode, 0, NULL); if (loc->parent == NULL) { ret = -1; goto out; } ret = 0; out: gf_dirent_free(&entries); if (fd) fd_unref(fd); if (xdata) dict_unref(xdata); return ret; } /* This function should be used only in inspect_directory and inspect_file * function to heal quota xattrs. * Inode quota feature is introduced in 3.7. * If gluster setup is upgraded from 3.6 to 3.7, there can be a * getxattr and setxattr spikes with quota heal as inode quota is missing. * So this wrapper function is to avoid xattrs spikes during upgrade. * This function returns success even is inode-quota xattrs are missing and * hence no healing performed. */ static int32_t _quota_dict_get_meta(xlator_t *this, dict_t *dict, char *key, const int keylen, quota_meta_t *meta, ia_type_t ia_type, gf_boolean_t add_delta) { int32_t ret = 0; marker_conf_t *priv = NULL; priv = this->private; ret = quota_dict_get_inode_meta(dict, key, keylen, meta); if (ret == -2 && (priv->feature_enabled & GF_INODE_QUOTA) == 0) { /* quota_dict_get_inode_meta returns -2 if * inode quota xattrs are not present. * if inode quota self heal is turned off, * then we should skip healing inode quotas */ gf_log(this->name, GF_LOG_DEBUG, "inode quota disabled. " "inode quota self heal will not be performed"); ret = 0; if (add_delta) { if (ia_type == IA_IFDIR) meta->dir_count = 1; else meta->file_count = 1; } } return ret; } int32_t quota_dict_set_size_meta(xlator_t *this, dict_t *dict, const quota_meta_t *meta) { int32_t ret = -ENOMEM; quota_meta_t *value = NULL; char size_key[QUOTA_KEY_MAX] = { 0, }; value = GF_MALLOC(2 * sizeof(quota_meta_t), gf_common_quota_meta_t); if (value == NULL) { goto out; } value[0].size = htobe64(meta->size); value[0].file_count = htobe64(meta->file_count); value[0].dir_count = htobe64(meta->dir_count); value[1].size = 0; value[1].file_count = 0; value[1].dir_count = htobe64(1); GET_SIZE_KEY(this, size_key, ret); if (ret < 0) goto out; ret = dict_set_bin(dict, size_key, value, (sizeof(quota_meta_t) * 2)); if (ret < 0) { gf_log_callingfn("quota", GF_LOG_ERROR, "dict set failed"); GF_FREE(value); } out: return ret; } void mq_compute_delta(quota_meta_t *delta, const quota_meta_t *op1, const quota_meta_t *op2) { delta->size = op1->size - op2->size; delta->file_count = op1->file_count - op2->file_count; delta->dir_count = op1->dir_count - op2->dir_count; } void mq_add_meta(quota_meta_t *dst, const quota_meta_t *src) { dst->size += src->size; dst->file_count += src->file_count; dst->dir_count += src->dir_count; } void mq_sub_meta(quota_meta_t *dst, const quota_meta_t *src) { if (src == NULL) { dst->size = -dst->size; dst->file_count = -dst->file_count; dst->dir_count = -dst->dir_count; } else { dst->size = src->size - dst->size; dst->file_count = src->file_count - dst->file_count; dst->dir_count = src->dir_count - dst->dir_count; } } int32_t mq_are_xattrs_set(xlator_t *this, loc_t *loc, gf_boolean_t *contri_set, gf_boolean_t *size_set) { int32_t ret = -1; char contri_key[QUOTA_KEY_MAX] = { 0, }; char size_key[QUOTA_KEY_MAX] = { 0, }; quota_meta_t meta = { 0, }; dict_t *dict = NULL; dict_t *rsp_dict = NULL; dict = dict_new(); if (dict == NULL) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); goto out; } ret = mq_req_xattr(this, loc, dict, contri_key, size_key); if (ret < 0) goto out; ret = syncop_lookup(FIRST_CHILD(this), loc, NULL, NULL, dict, &rsp_dict); if (ret < 0) { gf_log_callingfn( this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "lookup failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } if (rsp_dict == NULL) goto out; *contri_set = _gf_true; *size_set = _gf_true; if (loc->inode->ia_type == IA_IFDIR) { ret = quota_dict_get_inode_meta(rsp_dict, size_key, strlen(size_key), &meta); if (ret < 0 || meta.dir_count == 0) *size_set = _gf_false; } if (!loc_is_root(loc)) { ret = quota_dict_get_inode_meta(rsp_dict, contri_key, strlen(contri_key), &meta); if (ret < 0) *contri_set = _gf_false; } ret = 0; out: if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); return ret; } int32_t mq_create_size_xattrs(xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) { int32_t ret = -1; quota_meta_t size = { 0, }; dict_t *dict = NULL; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); if (loc->inode->ia_type != IA_IFDIR) { ret = 0; goto out; } dict = dict_new(); if (!dict) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); ret = -1; goto out; } ret = quota_dict_set_size_meta(this, dict, &size); if (ret < 0) goto out; ret = syncop_xattrop(FIRST_CHILD(this), loc, GF_XATTROP_ADD_ARRAY64_WITH_DEFAULT, dict, NULL, NULL, NULL); if (ret < 0) { gf_log_callingfn( this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "xattrop failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } out: if (dict) dict_unref(dict); return ret; } int32_t mq_lock(xlator_t *this, loc_t *loc, short l_type) { struct gf_flock lock = { 0, }; int32_t ret = -1; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); gf_log(this->name, GF_LOG_DEBUG, "set lock type %d on %s", l_type, loc->path); lock.l_len = 0; lock.l_start = 0; lock.l_type = l_type; lock.l_whence = SEEK_SET; ret = syncop_inodelk(FIRST_CHILD(this), this->name, loc, F_SETLKW, &lock, NULL, NULL); if (ret < 0) gf_log_callingfn( this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "inodelk failed " "for %s: %s", loc->path, strerror(-ret)); out: return ret; } int32_t mq_get_dirty(xlator_t *this, loc_t *loc, int32_t *dirty) { int32_t ret = -1; int8_t value = 0; dict_t *dict = NULL; dict_t *rsp_dict = NULL; dict = dict_new(); if (dict == NULL) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); goto out; } ret = dict_set_int64(dict, QUOTA_DIRTY_KEY, 0); if (ret < 0) { gf_log(this->name, GF_LOG_WARNING, "dict set failed"); goto out; } ret = syncop_lookup(FIRST_CHILD(this), loc, NULL, NULL, dict, &rsp_dict); if (ret < 0) { gf_log_callingfn( this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "lookup failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } ret = dict_get_int8(rsp_dict, QUOTA_DIRTY_KEY, &value); if (ret < 0) goto out; *dirty = value; out: if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); return ret; } int32_t mq_get_set_dirty(xlator_t *this, loc_t *loc, int32_t dirty, int32_t *prev_dirty) { int32_t ret = -1; int8_t value = 0; quota_inode_ctx_t *ctx = NULL; dict_t *dict = NULL; dict_t *rsp_dict = NULL; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); GF_VALIDATE_OR_GOTO("marker", prev_dirty, out); ret = mq_inode_ctx_get(loc->inode, this, &ctx); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "failed to get inode ctx for " "%s", loc->path); goto out; } dict = dict_new(); if (!dict) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); ret = -1; goto out; } ret = dict_set_int8(dict, QUOTA_DIRTY_KEY, dirty); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "dict_set failed"); goto out; } ret = syncop_xattrop(FIRST_CHILD(this), loc, GF_XATTROP_GET_AND_SET, dict, NULL, NULL, &rsp_dict); if (ret < 0) { gf_log_callingfn( this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "xattrop failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } *prev_dirty = 0; if (rsp_dict) { ret = dict_get_int8(rsp_dict, QUOTA_DIRTY_KEY, &value); if (ret == 0) *prev_dirty = value; } LOCK(&ctx->lock); { ctx->dirty = dirty; } UNLOCK(&ctx->lock); ret = 0; out: if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); return ret; } void mq_mark_dirty(xlator_t *this, loc_t *loc, int32_t dirty) { int32_t ret = -1; dict_t *dict = NULL; quota_inode_ctx_t *ctx = NULL; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); ret = mq_inode_ctx_get(loc->inode, this, &ctx); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "failed to get inode ctx for " "%s", loc->path); goto out; } dict = dict_new(); if (!dict) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); goto out; } ret = dict_set_int8(dict, QUOTA_DIRTY_KEY, dirty); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "dict_set failed"); goto out; } ret = syncop_setxattr(FIRST_CHILD(this), loc, dict, 0, NULL, NULL); if (ret < 0) { gf_log_callingfn( this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "setxattr dirty = %d " "failed for %s: %s", dirty, loc->path, strerror(-ret)); goto out; } LOCK(&ctx->lock); { ctx->dirty = dirty; } UNLOCK(&ctx->lock); out: if (dict) dict_unref(dict); } int32_t _mq_get_metadata(xlator_t *this, loc_t *loc, quota_meta_t *contri, quota_meta_t *size, uuid_t contri_gfid) { int32_t ret = -1; quota_meta_t meta = { 0, }; char contri_key[QUOTA_KEY_MAX] = { 0, }; char size_key[QUOTA_KEY_MAX] = { 0, }; int keylen = 0; dict_t *dict = NULL; dict_t *rsp_dict = NULL; struct iatt stbuf = { 0, }; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); if (size == NULL && contri == NULL) goto out; dict = dict_new(); if (dict == NULL) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); goto out; } if (size && loc->inode->ia_type == IA_IFDIR) { GET_SIZE_KEY(this, size_key, keylen); if (keylen < 0) goto out; ret = dict_set_int64(dict, size_key, 0); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "dict_set failed."); goto out; } } if (contri && !loc_is_root(loc)) { ret = mq_dict_set_contribution(this, dict, loc, contri_gfid, contri_key); if (ret < 0) goto out; } ret = syncop_lookup(FIRST_CHILD(this), loc, &stbuf, NULL, dict, &rsp_dict); if (ret < 0) { gf_log_callingfn( this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "lookup failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } if (size) { if (loc->inode->ia_type == IA_IFDIR) { ret = quota_dict_get_meta(rsp_dict, size_key, keylen, &meta); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "dict_get failed."); goto out; } size->size = meta.size; size->file_count = meta.file_count; size->dir_count = meta.dir_count; } else { size->size = stbuf.ia_blocks * 512; size->file_count = 1; size->dir_count = 0; } } if (contri && !loc_is_root(loc)) { ret = quota_dict_get_meta(rsp_dict, contri_key, strlen(contri_key), &meta); if (ret < 0) { contri->size = 0; contri->file_count = 0; contri->dir_count = 0; } else { contri->size = meta.size; contri->file_count = meta.file_count; contri->dir_count = meta.dir_count; } } ret = 0; out: if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); return ret; } int32_t mq_get_metadata(xlator_t *this, loc_t *loc, quota_meta_t *contri, quota_meta_t *size, quota_inode_ctx_t *ctx, inode_contribution_t *contribution) { int32_t ret = -1; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); GF_VALIDATE_OR_GOTO("marker", ctx, out); GF_VALIDATE_OR_GOTO("marker", contribution, out); if (size == NULL && contri == NULL) { ret = 0; goto out; } ret = _mq_get_metadata(this, loc, contri, size, contribution->gfid); if (ret < 0) goto out; if (size) { LOCK(&ctx->lock); { ctx->size = size->size; ctx->file_count = size->file_count; ctx->dir_count = size->dir_count; } UNLOCK(&ctx->lock); } if (contri) { LOCK(&contribution->lock); { contribution->contribution = contri->size; contribution->file_count = contri->file_count; contribution->dir_count = contri->dir_count; } UNLOCK(&contribution->lock); } out: return ret; } int32_t mq_get_delta(xlator_t *this, loc_t *loc, quota_meta_t *delta, quota_inode_ctx_t *ctx, inode_contribution_t *contribution) { int32_t ret = -1; quota_meta_t size = { 0, }; quota_meta_t contri = { 0, }; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); GF_VALIDATE_OR_GOTO("marker", ctx, out); GF_VALIDATE_OR_GOTO("marker", contribution, out); ret = mq_get_metadata(this, loc, &contri, &size, ctx, contribution); if (ret < 0) goto out; mq_compute_delta(delta, &size, &contri); out: return ret; } int32_t mq_remove_contri(xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx, inode_contribution_t *contri, quota_meta_t *delta, uint32_t nlink) { int32_t ret = -1; char contri_key[QUOTA_KEY_MAX] = { 0, }; if (nlink == 1) { /*File was a last link and has been deleted */ ret = 0; goto done; } GET_CONTRI_KEY(this, contri_key, contri->gfid, ret); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "get contri_key " "failed for %s", uuid_utoa(contri->gfid)); goto out; } ret = syncop_removexattr(FIRST_CHILD(this), loc, contri_key, 0, NULL); if (ret < 0) { if (-ret == ENOENT || -ret == ESTALE || -ret == ENODATA || -ret == ENOATTR) { /* Remove contri in done when unlink operation is * performed, so return success on ENOENT/ESTSLE * rename operation removes xattr earlier, * so return success on ENODATA */ ret = 0; } else { gf_log_callingfn(this->name, GF_LOG_ERROR, "removexattr %s failed for %s: %s", contri_key, loc->path, strerror(-ret)); goto out; } } done: LOCK(&contri->lock); { contri->contribution += delta->size; contri->file_count += delta->file_count; contri->dir_count += delta->dir_count; } UNLOCK(&contri->lock); ret = 0; out: QUOTA_FREE_CONTRIBUTION_NODE(ctx, contri); return ret; } int32_t mq_update_contri(xlator_t *this, loc_t *loc, inode_contribution_t *contri, quota_meta_t *delta) { int32_t ret = -1; char contri_key[QUOTA_KEY_MAX] = { 0, }; dict_t *dict = NULL; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); GF_VALIDATE_OR_GOTO("marker", delta, out); GF_VALIDATE_OR_GOTO("marker", contri, out); if (quota_meta_is_null(delta)) { ret = 0; goto out; } dict = dict_new(); if (!dict) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); ret = -1; goto out; } GET_CONTRI_KEY(this, contri_key, contri->gfid, ret); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "get contri_key " "failed for %s", uuid_utoa(contri->gfid)); goto out; } ret = quota_dict_set_meta(dict, contri_key, delta, loc->inode->ia_type); if (ret < 0) goto out; ret = syncop_xattrop(FIRST_CHILD(this), loc, GF_XATTROP_ADD_ARRAY64, dict, NULL, NULL, NULL); if (ret < 0) { gf_log_callingfn( this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "xattrop failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } LOCK(&contri->lock); { contri->contribution += delta->size; contri->file_count += delta->file_count; contri->dir_count += delta->dir_count; } UNLOCK(&contri->lock); out: if (dict) dict_unref(dict); return ret; } int32_t mq_update_size(xlator_t *this, loc_t *loc, quota_meta_t *delta) { int32_t ret = -1; quota_inode_ctx_t *ctx = NULL; dict_t *dict = NULL; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); GF_VALIDATE_OR_GOTO("marker", delta, out); ret = mq_inode_ctx_get(loc->inode, this, &ctx); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "failed to get inode ctx for " "%s", loc->path); goto out; } if (quota_meta_is_null(delta) && (ctx->dir_count != 0)) { ret = 0; goto out; } dict = dict_new(); if (!dict) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); ret = -1; goto out; } ret = quota_dict_set_size_meta(this, dict, delta); if (ret < 0) goto out; ret = syncop_xattrop(FIRST_CHILD(this), loc, GF_XATTROP_ADD_ARRAY64_WITH_DEFAULT, dict, NULL, NULL, NULL); if (ret < 0) { gf_log_callingfn( this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "xattrop failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } LOCK(&ctx->lock); { ctx->size += delta->size; ctx->file_count += delta->file_count; if (ctx->dir_count == 0) ctx->dir_count += delta->dir_count + 1; else ctx->dir_count += delta->dir_count; } UNLOCK(&ctx->lock); out: if (dict) dict_unref(dict); return ret; } int mq_synctask_cleanup(int ret, call_frame_t *frame, void *opaque) { quota_synctask_t *args = NULL; GF_ASSERT(opaque); args = (quota_synctask_t *)opaque; loc_wipe(&args->loc); if (args->stub) call_resume(args->stub); if (!args->is_static) GF_FREE(args); return 0; } int mq_synctask1(xlator_t *this, synctask_fn_t task, gf_boolean_t spawn, loc_t *loc, quota_meta_t *contri, uint32_t nlink, call_stub_t *stub) { int32_t ret = -1; quota_synctask_t *args = NULL; quota_synctask_t static_args = { 0, }; if (spawn) { QUOTA_ALLOC_OR_GOTO(args, quota_synctask_t, ret, out); args->is_static = _gf_false; } else { args = &static_args; args->is_static = _gf_true; } args->this = this; args->stub = stub; loc_copy(&args->loc, loc); args->ia_nlink = nlink; if (contri) { args->contri = *contri; } else { args->contri.size = -1; args->contri.file_count = -1; args->contri.dir_count = -1; } if (spawn) { ret = synctask_new1(this->ctx->env, 0, task, mq_synctask_cleanup, NULL, args); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to spawn " "new synctask"); mq_synctask_cleanup(ret, NULL, args); } } else { ret = task(args); mq_synctask_cleanup(ret, NULL, args); } out: return ret; } int mq_synctask(xlator_t *this, synctask_fn_t task, gf_boolean_t spawn, loc_t *loc) { return mq_synctask1(this, task, spawn, loc, NULL, -1, NULL); } int32_t mq_prevalidate_txn(xlator_t *this, loc_t *origin_loc, loc_t *loc, quota_inode_ctx_t **ctx, struct iatt *buf) { int32_t ret = -1; quota_inode_ctx_t *ctxtmp = NULL; if (buf) { if (buf->ia_type == IA_IFREG && IS_DHT_LINKFILE_MODE(buf)) goto out; if (buf->ia_type != IA_IFREG && buf->ia_type != IA_IFLNK && buf->ia_type != IA_IFDIR) goto out; } if (origin_loc == NULL || origin_loc->inode == NULL || gf_uuid_is_null(origin_loc->inode->gfid)) goto out; loc_copy(loc, origin_loc); if (gf_uuid_is_null(loc->gfid)) gf_uuid_copy(loc->gfid, loc->inode->gfid); if (!loc_is_root(loc) && loc->parent == NULL) loc->parent = inode_parent(loc->inode, 0, NULL); ret = mq_inode_ctx_get(loc->inode, this, &ctxtmp); if (ret < 0) { gf_log_callingfn(this->name, GF_LOG_WARNING, "inode ctx for " "is NULL for %s", loc->path); goto out; } if (ctx) *ctx = ctxtmp; ret = 0; out: return ret; } int mq_create_xattrs_task(void *opaque) { int32_t ret = -1; gf_boolean_t locked = _gf_false; gf_boolean_t contri_set = _gf_false; gf_boolean_t size_set = _gf_false; gf_boolean_t need_txn = _gf_false; quota_synctask_t *args = NULL; quota_inode_ctx_t *ctx = NULL; xlator_t *this = NULL; loc_t *loc = NULL; gf_boolean_t status = _gf_false; GF_ASSERT(opaque); args = (quota_synctask_t *)opaque; loc = &args->loc; this = args->this; THIS = this; ret = mq_inode_ctx_get(loc->inode, this, &ctx); if (ret < 0) { gf_log(this->name, GF_LOG_WARNING, "Failed to" "get inode ctx, aborting quota create txn"); goto out; } if (loc->inode->ia_type == IA_IFDIR) { /* lock not required for files */ ret = mq_lock(this, loc, F_WRLCK); if (ret < 0) goto out; locked = _gf_true; } ret = mq_are_xattrs_set(this, loc, &contri_set, &size_set); if (ret < 0 || (contri_set && size_set)) goto out; mq_set_ctx_create_status(ctx, _gf_false); status = _gf_true; if (loc->inode->ia_type == IA_IFDIR && size_set == _gf_false) { ret = mq_create_size_xattrs(this, ctx, loc); if (ret < 0) goto out; } need_txn = _gf_true; out: if (locked) ret = mq_lock(this, loc, F_UNLCK); if (status == _gf_false) mq_set_ctx_create_status(ctx, _gf_false); if (need_txn) ret = mq_initiate_quota_blocking_txn(this, loc, NULL); return ret; } static int _mq_create_xattrs_txn(xlator_t *this, loc_t *origin_loc, struct iatt *buf, gf_boolean_t spawn) { int32_t ret = -1; quota_inode_ctx_t *ctx = NULL; gf_boolean_t status = _gf_true; loc_t loc = { 0, }; inode_contribution_t *contribution = NULL; ret = mq_prevalidate_txn(this, origin_loc, &loc, &ctx, buf); if (ret < 0) goto out; ret = mq_test_and_set_ctx_create_status(ctx, &status); if (ret < 0 || status == _gf_true) goto out; if (!loc_is_root(&loc) && loc.parent) { contribution = mq_add_new_contribution_node(this, ctx, &loc); if (contribution == NULL) { gf_log(this->name, GF_LOG_WARNING, "cannot add a new contribution node " "(%s)", uuid_utoa(loc.gfid)); ret = -1; goto out; } else { GF_REF_PUT(contribution); } } ret = mq_synctask(this, mq_create_xattrs_task, spawn, &loc); out: if (ret < 0 && status == _gf_false) mq_set_ctx_create_status(ctx, _gf_false); loc_wipe(&loc); return ret; } int mq_create_xattrs_txn(xlator_t *this, loc_t *loc, struct iatt *buf) { int32_t ret = -1; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); ret = _mq_create_xattrs_txn(this, loc, buf, _gf_true); out: return ret; } int32_t mq_reduce_parent_size_task(void *opaque) { int32_t ret = -1; int32_t prev_dirty = 0; quota_inode_ctx_t *ctx = NULL; quota_inode_ctx_t *parent_ctx = NULL; inode_contribution_t *contribution = NULL; quota_meta_t delta = { 0, }; quota_meta_t contri = { 0, }; loc_t parent_loc = { 0, }; gf_boolean_t locked = _gf_false; gf_boolean_t dirty = _gf_false; quota_synctask_t *args = NULL; xlator_t *this = NULL; loc_t *loc = NULL; gf_boolean_t remove_xattr = _gf_true; uint32_t nlink = 0; GF_ASSERT(opaque); args = (quota_synctask_t *)opaque; loc = &args->loc; contri = args->contri; nlink = args->ia_nlink; this = args->this; THIS = this; ret = mq_inode_loc_fill(NULL, loc->parent, &parent_loc); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "parent_loc fill failed for " "child inode %s: ", uuid_utoa(loc->inode->gfid)); goto out; } ret = mq_lock(this, &parent_loc, F_WRLCK); if (ret < 0) goto out; locked = _gf_true; if (contri.size >= 0) { /* contri parameter is supplied only for rename operation. * remove xattr is alreday performed, we need to skip * removexattr for rename operation */ remove_xattr = _gf_false; delta.size = contri.size; delta.file_count = contri.file_count; delta.dir_count = contri.dir_count; } else { remove_xattr = _gf_true; ret = mq_inode_ctx_get(loc->inode, this, &ctx); if (ret < 0) { gf_log_callingfn(this->name, GF_LOG_WARNING, "ctx for" " the node %s is NULL", loc->path); goto out; } contribution = mq_get_contribution_node(loc->parent, ctx); if (contribution == NULL) { ret = -1; gf_log(this->name, GF_LOG_DEBUG, "contribution for the node %s is NULL", loc->path); goto out; } LOCK(&contribution->lock); { delta.size = contribution->contribution; delta.file_count = contribution->file_count; delta.dir_count = contribution->dir_count; } UNLOCK(&contribution->lock); } ret = mq_get_set_dirty(this, &parent_loc, 1, &prev_dirty); if (ret < 0) goto out; dirty = _gf_true; mq_sub_meta(&delta, NULL); if (remove_xattr) { ret = mq_remove_contri(this, loc, ctx, contribution, &delta, nlink); if (ret < 0) goto out; } if (quota_meta_is_null(&delta)) goto out; ret = mq_update_size(this, &parent_loc, &delta); if (ret < 0) goto out; out: if (dirty) { if (ret < 0 || prev_dirty) { /* On failure clear dirty status flag. * In the next lookup inspect_directory_xattr * can set the status flag and fix the * dirty directory. * Do the same if dir was dirty before * the txn */ ret = mq_inode_ctx_get(parent_loc.inode, this, &parent_ctx); if (ret == 0) mq_set_ctx_dirty_status(parent_ctx, _gf_false); } else { mq_mark_dirty(this, &parent_loc, 0); } } if (locked) ret = mq_lock(this, &parent_loc, F_UNLCK); if (ret >= 0) ret = mq_initiate_quota_blocking_txn(this, &parent_loc, NULL); loc_wipe(&parent_loc); if (contribution) GF_REF_PUT(contribution); return ret; } int32_t mq_reduce_parent_size_txn(xlator_t *this, loc_t *origin_loc, quota_meta_t *contri, uint32_t nlink, call_stub_t *stub) { int32_t ret = -1; loc_t loc = { 0, }; gf_boolean_t resume_stub = _gf_true; GF_VALIDATE_OR_GOTO("marker", this, out); GF_VALIDATE_OR_GOTO("marker", origin_loc, out); ret = mq_prevalidate_txn(this, origin_loc, &loc, NULL, NULL); if (ret < 0) goto out; if (loc_is_root(&loc)) { ret = 0; goto out; } resume_stub = _gf_false; ret = mq_synctask1(this, mq_reduce_parent_size_task, _gf_true, &loc, contri, nlink, stub); out: loc_wipe(&loc); if (resume_stub && stub) call_resume(stub); if (ret) gf_log_callingfn(this ? this->name : "Marker", GF_LOG_ERROR, "mq_reduce_parent_size_txn failed"); return ret; } int mq_initiate_quota_task(void *opaque) { int32_t ret = -1; int32_t prev_dirty = 0; loc_t child_loc = { 0, }; loc_t parent_loc = { 0, }; gf_boolean_t locked = _gf_false; gf_boolean_t dirty = _gf_false; gf_boolean_t status = _gf_false; quota_meta_t delta = { 0, }; quota_synctask_t *args = NULL; xlator_t *this = NULL; loc_t *loc = NULL; inode_contribution_t *contri = NULL; quota_inode_ctx_t *ctx = NULL; quota_inode_ctx_t *parent_ctx = NULL; inode_t *tmp_parent = NULL; GF_VALIDATE_OR_GOTO("marker", opaque, out); args = (quota_synctask_t *)opaque; loc = &args->loc; this = args->this; GF_VALIDATE_OR_GOTO("marker", this, out); THIS = this; GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = mq_loc_copy(&child_loc, loc); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "loc copy failed"); goto out; } while (!__is_root_gfid(child_loc.gfid)) { ret = mq_inode_ctx_get(child_loc.inode, this, &ctx); if (ret < 0) { gf_log(this->name, GF_LOG_WARNING, "inode ctx get failed for %s, " "aborting update txn", child_loc.path); goto out; } /* To improve performance, abort current transaction * if one is already in progress for same inode */ if (status == _gf_true) { /* status will already set before txn start, * so it should not be set in first * loop iteration */ ret = mq_test_and_set_ctx_updation_status(ctx, &status); if (ret < 0 || status == _gf_true) goto out; } if (child_loc.parent == NULL) { ret = mq_build_ancestry(this, &child_loc); if (ret < 0 || child_loc.parent == NULL) { /* If application performs parallel remove * operations on same set of files/directories * then we may get ENOENT/ESTALE */ gf_log(this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "build ancestry failed for inode %s", uuid_utoa(child_loc.inode->gfid)); ret = -1; goto out; } } ret = mq_inode_loc_fill(NULL, child_loc.parent, &parent_loc); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "parent_loc fill " "failed for child inode %s: ", uuid_utoa(child_loc.inode->gfid)); goto out; } ret = mq_lock(this, &parent_loc, F_WRLCK); if (ret < 0) goto out; locked = _gf_true; mq_set_ctx_updation_status(ctx, _gf_false); status = _gf_true; /* Contribution node can be NULL in below scenarios and create if needed: Scenario 1) In this case create a new contribution node Suppose hard link for a file f1 present in a directory d1 is created in the directory d2 (as f2). Now, since d2's contribution is not there in f1's inode ctx, d2's contribution xattr won't be created and will create problems for quota operations. Don't create contribution if parent has been changed after taking a lock, this can happen when rename is performed and writes is still in-progress for the same file Scenario 2) When a rename operation is performed, contribution node for olp path will be removed. Create contribution node only if oldparent is same as newparent. Consider below example 1) rename FOP invoked on file 'x' 2) write is still in progress for file 'x' 3) rename takes a lock on old-parent 4) write-update txn blocked on old-parent to acquire lock 5) in rename_cbk, contri xattrs are removed and contribution is deleted and lock is released 6) now write-update txn gets the lock and updates the wrong parent as it was holding lock on old parent so validate parent once the lock is acquired For more information on this problem, please see doc for marker_rename in file marker.c */ contri = mq_get_contribution_node(child_loc.parent, ctx); if (contri == NULL) { tmp_parent = inode_parent(child_loc.inode, 0, NULL); if (tmp_parent == NULL) { /* This can happen if application performs * parallel remove operations on same set * of files/directories */ gf_log(this->name, GF_LOG_WARNING, "parent is " "NULL for inode %s", uuid_utoa(child_loc.inode->gfid)); ret = -1; goto out; } if (gf_uuid_compare(tmp_parent->gfid, parent_loc.gfid)) { /* abort txn if parent has changed */ ret = 0; goto out; } inode_unref(tmp_parent); tmp_parent = NULL; contri = mq_add_new_contribution_node(this, ctx, &child_loc); if (contri == NULL) { gf_log(this->name, GF_LOG_ERROR, "Failed to " "create contribution node for %s, " "abort update txn", child_loc.path); ret = -1; goto out; } } ret = mq_get_delta(this, &child_loc, &delta, ctx, contri); if (ret < 0) goto out; if (quota_meta_is_null(&delta)) goto out; ret = mq_get_set_dirty(this, &parent_loc, 1, &prev_dirty); if (ret < 0) goto out; dirty = _gf_true; ret = mq_update_contri(this, &child_loc, contri, &delta); if (ret < 0) goto out; ret = mq_update_size(this, &parent_loc, &delta); if (ret < 0) { gf_log(this->name, GF_LOG_DEBUG, "rollback " "contri updation"); mq_sub_meta(&delta, NULL); mq_update_contri(this, &child_loc, contri, &delta); goto out; } if (prev_dirty == 0) { mq_mark_dirty(this, &parent_loc, 0); } else { ret = mq_inode_ctx_get(parent_loc.inode, this, &parent_ctx); if (ret == 0) mq_set_ctx_dirty_status(parent_ctx, _gf_false); } dirty = _gf_false; prev_dirty = 0; ret = mq_lock(this, &parent_loc, F_UNLCK); locked = _gf_false; if (__is_root_gfid(parent_loc.gfid)) break; /* Repeate above steps upwards till the root */ loc_wipe(&child_loc); ret = mq_loc_copy(&child_loc, &parent_loc); if (ret < 0) goto out; loc_wipe(&parent_loc); GF_REF_PUT(contri); contri = NULL; } out: if ((dirty) && (ret < 0)) { /* On failure clear dirty status flag. * In the next lookup inspect_directory_xattr * can set the status flag and fix the * dirty directory. * Do the same if the dir was dirty before * txn */ ret = mq_inode_ctx_get(parent_loc.inode, this, &parent_ctx); if (ret == 0) mq_set_ctx_dirty_status(parent_ctx, _gf_false); } if (locked) ret = mq_lock(this, &parent_loc, F_UNLCK); if (ctx && status == _gf_false) mq_set_ctx_updation_status(ctx, _gf_false); loc_wipe(&child_loc); loc_wipe(&parent_loc); if (tmp_parent) inode_unref(tmp_parent); if (contri) GF_REF_PUT(contri); return 0; } int _mq_initiate_quota_txn(xlator_t *this, loc_t *origin_loc, struct iatt *buf, gf_boolean_t spawn) { int32_t ret = -1; quota_inode_ctx_t *ctx = NULL; gf_boolean_t status = _gf_true; loc_t loc = { 0, }; ret = mq_prevalidate_txn(this, origin_loc, &loc, &ctx, buf); if (ret < 0) goto out; if (loc_is_root(&loc)) { ret = 0; goto out; } ret = mq_test_and_set_ctx_updation_status(ctx, &status); if (ret < 0 || status == _gf_true) goto out; ret = mq_synctask(this, mq_initiate_quota_task, spawn, &loc); out: if (ret < 0 && status == _gf_false) mq_set_ctx_updation_status(ctx, _gf_false); loc_wipe(&loc); return ret; } int mq_initiate_quota_txn(xlator_t *this, loc_t *loc, struct iatt *buf) { int32_t ret = -1; GF_VALIDATE_OR_GOTO("marker", this, out); GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); ret = _mq_initiate_quota_txn(this, loc, buf, _gf_true); out: return ret; } int mq_initiate_quota_blocking_txn(xlator_t *this, loc_t *loc, struct iatt *buf) { int32_t ret = -1; GF_VALIDATE_OR_GOTO("marker", this, out); GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); ret = _mq_initiate_quota_txn(this, loc, buf, _gf_false); out: return ret; } int mq_update_dirty_inode_task(void *opaque) { int32_t ret = -1; fd_t *fd = NULL; off_t offset = 0; gf_dirent_t entries; gf_dirent_t *entry = NULL; gf_boolean_t locked = _gf_false; gf_boolean_t updated = _gf_false; int32_t dirty = 0; quota_meta_t contri = { 0, }; quota_meta_t size = { 0, }; quota_meta_t contri_sum = { 0, }; quota_meta_t delta = { 0, }; quota_synctask_t *args = NULL; xlator_t *this = NULL; loc_t *loc = NULL; quota_inode_ctx_t *ctx = NULL; dict_t *xdata = NULL; char contri_key[QUOTA_KEY_MAX] = { 0, }; int keylen = 0; GF_ASSERT(opaque); args = (quota_synctask_t *)opaque; loc = &args->loc; this = args->this; THIS = this; INIT_LIST_HEAD(&entries.list); ret = mq_inode_ctx_get(loc->inode, this, &ctx); if (ret < 0) goto out; GET_CONTRI_KEY(this, contri_key, loc->gfid, keylen); if (keylen < 0) { ret = keylen; goto out; } xdata = dict_new(); if (xdata == NULL) { gf_log(this->name, GF_LOG_ERROR, "dict_new failed"); ret = -1; goto out; } ret = dict_set_int64(xdata, contri_key, 0); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "dict_set failed"); goto out; } ret = mq_lock(this, loc, F_WRLCK); if (ret < 0) goto out; locked = _gf_true; ret = mq_get_dirty(this, loc, &dirty); if (ret < 0 || dirty == 0) { ret = 0; goto out; } fd = fd_create(loc->inode, 0); if (!fd) { gf_log(this->name, GF_LOG_ERROR, "Failed to create fd"); ret = -1; goto out; } ret = syncop_opendir(this, loc, fd, NULL, NULL); if (ret < 0) { gf_log(this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "opendir failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } fd_bind(fd); while ((ret = syncop_readdirp(this, fd, 131072, offset, &entries, xdata, NULL)) != 0) { if (ret < 0) { gf_log(this->name, (-ret == ENOENT || -ret == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, "readdirp failed " "for %s: %s", loc->path, strerror(-ret)); goto out; } if (list_empty(&entries.list)) break; list_for_each_entry(entry, &entries.list, list) { offset = entry->d_off; /* skip . and .. */ if (inode_dir_or_parentdir(entry)) continue; memset(&contri, 0, sizeof(contri)); quota_dict_get_meta(entry->dict, contri_key, keylen, &contri); if (quota_meta_is_null(&contri)) continue; mq_add_meta(&contri_sum, &contri); } gf_dirent_free(&entries); } /* Inculde for self */ contri_sum.dir_count++; ret = _mq_get_metadata(this, loc, NULL, &size, 0); if (ret < 0) goto out; mq_compute_delta(&delta, &contri_sum, &size); if (quota_meta_is_null(&delta)) goto out; gf_log(this->name, GF_LOG_INFO, "calculated size = %" PRId64 ", original size = %" PRIu64 ", diff = %" PRIu64 ", path = %s ", contri_sum.size, size.size, delta.size, loc->path); gf_log(this->name, GF_LOG_INFO, "calculated f_count = %" PRId64 ", original f_count = %" PRIu64 ", diff = %" PRIu64 ", path = %s ", contri_sum.file_count, size.file_count, delta.file_count, loc->path); gf_log(this->name, GF_LOG_INFO, "calculated d_count = %" PRId64 ", original d_count = %" PRIu64 ", diff = %" PRIu64 ", path = %s ", contri_sum.dir_count, size.dir_count, delta.dir_count, loc->path); ret = mq_update_size(this, loc, &delta); if (ret < 0) goto out; updated = _gf_true; out: gf_dirent_free(&entries); if (fd) fd_unref(fd); if (xdata) dict_unref(xdata); if (ret < 0) { /* On failure clear dirty status flag. * In the next lookup inspect_directory_xattr * can set the status flag and fix the * dirty directory */ if (ctx) mq_set_ctx_dirty_status(ctx, _gf_false); } else if (dirty) { mq_mark_dirty(this, loc, 0); } if (locked) mq_lock(this, loc, F_UNLCK); if (updated) mq_initiate_quota_blocking_txn(this, loc, NULL); return ret; } int32_t mq_update_dirty_inode_txn(xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx) { int32_t ret = -1; gf_boolean_t status = _gf_true; GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", loc->inode, out); mq_test_and_set_ctx_status(ctx, &ctx->dirty_status, &status); if (status == _gf_true) goto out; ret = mq_synctask(this, mq_update_dirty_inode_task, _gf_true, loc); out: if (ret < 0 && status == _gf_false) mq_set_ctx_dirty_status(ctx, _gf_false); return ret; } int32_t mq_inspect_directory_xattr(xlator_t *this, quota_inode_ctx_t *ctx, inode_contribution_t *contribution, loc_t *loc, dict_t *dict) { int32_t ret = -1; int8_t dirty = -1; quota_meta_t size = { 0, }; quota_meta_t contri = { 0, }; quota_meta_t delta = { 0, }; char contri_key[QUOTA_KEY_MAX] = { 0, }; char size_key[QUOTA_KEY_MAX] = { 0, }; int keylen = 0; gf_boolean_t status = _gf_false; ret = dict_get_int8(dict, QUOTA_DIRTY_KEY, &dirty); if (ret < 0) { /* dirty is set only on the first file write operation * so ignore this error */ ret = 0; dirty = 0; } GET_SIZE_KEY(this, size_key, keylen); if (keylen < 0) { ret = -1; goto out; } ret = _quota_dict_get_meta(this, dict, size_key, keylen, &size, IA_IFDIR, _gf_false); if (ret < 0) goto create_xattr; if (!contribution) goto create_xattr; if (!loc_is_root(loc)) { GET_CONTRI_KEY(this, contri_key, contribution->gfid, keylen); if (keylen < 0) { ret = -1; goto out; } ret = _quota_dict_get_meta(this, dict, contri_key, keylen, &contri, IA_IFDIR, _gf_false); if (ret < 0) goto create_xattr; LOCK(&contribution->lock); { contribution->contribution = contri.size; contribution->file_count = contri.file_count; contribution->dir_count = contri.dir_count; } UNLOCK(&contribution->lock); } LOCK(&ctx->lock); { ctx->size = size.size; ctx->file_count = size.file_count; ctx->dir_count = size.dir_count; ctx->dirty = dirty; } UNLOCK(&ctx->lock); ret = mq_get_ctx_updation_status(ctx, &status); if (ret < 0 || status == _gf_true) { /* If the update txn is in progress abort inspection */ ret = 0; goto out; } mq_compute_delta(&delta, &size, &contri); if (dirty) { ret = mq_update_dirty_inode_txn(this, loc, ctx); goto out; } if (!loc_is_root(loc) && !quota_meta_is_null(&delta)) mq_initiate_quota_txn(this, loc, NULL); ret = 0; goto out; create_xattr: if (ret < 0) ret = mq_create_xattrs_txn(this, loc, NULL); out: return ret; } int32_t mq_inspect_file_xattr(xlator_t *this, quota_inode_ctx_t *ctx, inode_contribution_t *contribution, loc_t *loc, dict_t *dict, struct iatt *buf) { int32_t ret = -1; quota_meta_t size = { 0, }; quota_meta_t contri = { 0, }; quota_meta_t delta = { 0, }; char contri_key[QUOTA_KEY_MAX] = { 0, }; int keylen = 0; gf_boolean_t status = _gf_false; if (!buf || !contribution || !ctx) goto out; LOCK(&ctx->lock); { ctx->size = 512 * buf->ia_blocks; ctx->file_count = 1; ctx->dir_count = 0; size.size = ctx->size; size.file_count = ctx->file_count; size.dir_count = ctx->dir_count; } UNLOCK(&ctx->lock); GET_CONTRI_KEY(this, contri_key, contribution->gfid, keylen); if (keylen < 0) { ret = -1; goto out; } ret = _quota_dict_get_meta(this, dict, contri_key, keylen, &contri, IA_IFREG, _gf_true); if (ret < 0) { ret = mq_create_xattrs_txn(this, loc, NULL); } else { LOCK(&contribution->lock); { contribution->contribution = contri.size; contribution->file_count = contri.file_count; contribution->dir_count = contri.dir_count; } UNLOCK(&contribution->lock); ret = mq_get_ctx_updation_status(ctx, &status); if (ret < 0 || status == _gf_true) { /* If the update txn is in progress abort inspection */ ret = 0; goto out; } mq_compute_delta(&delta, &size, &contri); if (!quota_meta_is_null(&delta)) mq_initiate_quota_txn(this, loc, NULL); } /* TODO: revist this code when fixing hardlinks */ out: return ret; } int32_t mq_xattr_state(xlator_t *this, loc_t *origin_loc, dict_t *dict, struct iatt *buf) { int32_t ret = -1; quota_inode_ctx_t *ctx = NULL; loc_t loc = { 0, }; inode_contribution_t *contribution = NULL; ret = mq_prevalidate_txn(this, origin_loc, &loc, &ctx, buf); if (ret < 0 || loc.parent == NULL) goto out; if (!loc_is_root(&loc)) { contribution = mq_add_new_contribution_node(this, ctx, &loc); if (contribution == NULL) { if (!gf_uuid_is_null(loc.inode->gfid)) gf_log(this->name, GF_LOG_WARNING, "cannot add a new contribution node " "(%s)", uuid_utoa(loc.gfid)); ret = -1; goto out; } if (buf->ia_type == IA_IFDIR) mq_inspect_directory_xattr(this, ctx, contribution, &loc, dict); else mq_inspect_file_xattr(this, ctx, contribution, &loc, dict, buf); } else { mq_inspect_directory_xattr(this, ctx, 0, &loc, dict); } out: loc_wipe(&loc); if (contribution) GF_REF_PUT(contribution); return ret; } int32_t mq_req_xattr(xlator_t *this, loc_t *loc, dict_t *dict, char *contri_key, char *size_key) { int32_t ret = -1; char key[QUOTA_KEY_MAX] = { 0, }; GF_VALIDATE_OR_GOTO("marker", this, out); GF_VALIDATE_OR_GOTO("marker", loc, out); GF_VALIDATE_OR_GOTO("marker", dict, out); if (!loc_is_root(loc)) { ret = mq_dict_set_contribution(this, dict, loc, NULL, contri_key); if (ret < 0) goto out; } GET_SIZE_KEY(this, key, ret); if (ret < 0) goto out; if (size_key) if (snprintf(size_key, QUOTA_KEY_MAX, "%s", key) >= QUOTA_KEY_MAX) { ret = -1; goto out; } ret = dict_set_uint64(dict, key, 0); if (ret < 0) goto out; ret = dict_set_int8(dict, QUOTA_DIRTY_KEY, 0); out: if (ret < 0) gf_log_callingfn(this ? this->name : "Marker", GF_LOG_ERROR, "dict set failed"); return ret; } int32_t mq_forget(xlator_t *this, quota_inode_ctx_t *ctx) { inode_contribution_t *contri = NULL; inode_contribution_t *next = NULL; GF_VALIDATE_OR_GOTO("marker", this, out); GF_VALIDATE_OR_GOTO("marker", ctx, out); list_for_each_entry_safe(contri, next, &ctx->contribution_head, contri_list) { list_del_init(&contri->contri_list); GF_REF_PUT(contri); } LOCK_DESTROY(&ctx->lock); GF_FREE(ctx); out: return 0; } glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/marker.h0000644000000000000000000000013214522202451023374 xustar000000000000000030 mtime=1699284265.678027465 30 atime=1699284265.678027465 30 ctime=1699284303.708142011 glusterfs-11.1/xlators/features/marker/src/marker.h0000664000175100017510000001276114522202451023662 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _MARKER_H #define _MARKER_H #include "marker-quota.h" #include #define MARKER_XATTR_PREFIX "trusted.glusterfs" #define XTIME "xtime" #define VOLUME_MARK "volume-mark" #define VOLUME_UUID "volume-uuid" #define TIMESTAMP_FILE "timestamp-file" enum { GF_QUOTA = 1, GF_XTIME = 2, GF_XTIME_GSYNC_FORCE = 4, GF_INODE_QUOTA = 8, }; /*initialize the local variable*/ #define MARKER_INIT_LOCAL(_frame, _local) \ do { \ _frame->local = _local; \ _local->pid = _frame->root->pid; \ memset(&_local->loc, 0, sizeof(loc_t)); \ _local->ref = 1; \ _local->uid = -1; \ _local->gid = -1; \ LOCK_INIT(&_local->lock); \ _local->oplocal = NULL; \ } while (0) /* try alloc and if it fails, goto label */ #define ALLOCATE_OR_GOTO(var, type, label) \ do { \ var = GF_CALLOC(sizeof(type), 1, gf_marker_mt_##type); \ if (!var) { \ gf_log(this->name, GF_LOG_ERROR, "out of memory :("); \ goto label; \ } \ } while (0) #define _MARKER_SET_UID_GID(dest, src) \ do { \ if (src->uid != -1 && src->gid != -1) { \ dest->uid = src->uid; \ dest->gid = src->gid; \ } \ } while (0) #define MARKER_SET_UID_GID(frame, dest, src) \ do { \ _MARKER_SET_UID_GID(dest, src); \ frame->root->uid = 0; \ frame->root->gid = 0; \ frame->cookie = (void *)_GF_UID_GID_CHANGED; \ } while (0) #define MARKER_RESET_UID_GID(frame, dest, src) \ do { \ _MARKER_SET_UID_GID(dest, src); \ frame->cookie = NULL; \ } while (0) #define MARKER_STACK_UNWIND(fop, frame, params...) \ do { \ quota_local_t *_local = NULL; \ if (frame) { \ _local = frame->local; \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ if (_local) \ marker_local_unref(_local); \ } while (0) struct marker_local { uint32_t timebuf[2]; pid_t pid; loc_t loc; loc_t parent_loc; uid_t uid; gid_t gid; int32_t ref; uint32_t ia_nlink; struct iatt buf; gf_lock_t lock; mode_t mode; int32_t err; call_stub_t *stub; call_frame_t *lk_frame; quota_meta_t contribution; struct marker_local *oplocal; /* marker quota specific */ int64_t delta; int64_t d_off; int64_t sum; int64_t size; int32_t hl_count; int32_t dentry_child_count; fd_t *fd; call_frame_t *frame; quota_inode_ctx_t *ctx; inode_contribution_t *contri; int xflag; dict_t *xdata; gf_boolean_t skip_txn; }; typedef struct marker_local marker_local_t; #define quota_local_t marker_local_t struct marker_inode_ctx { struct quota_inode_ctx *quota_ctx; }; typedef struct marker_inode_ctx marker_inode_ctx_t; struct marker_conf { char feature_enabled; char *size_key; char *dirty_key; char *volume_uuid; uuid_t volume_uuid_bin; char *timestamp_file; char *marker_xattr; uint64_t quota_lk_owner; gf_lock_t lock; int32_t version; }; typedef struct marker_conf marker_conf_t; #endif glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/marker-quota-helper.h0000644000000000000000000000013214522202451026000 xustar000000000000000030 mtime=1699284265.676027459 30 atime=1699284265.675027456 30 ctime=1699284303.714142029 glusterfs-11.1/xlators/features/marker/src/marker-quota-helper.h0000664000175100017510000000524614522202451026266 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _MARKER_QUOTA_HELPER_H #define _MARKER_QUOTA_HELPER_H #include "marker.h" #define QUOTA_FREE_CONTRIBUTION_NODE(ctx, _contribution) \ do { \ LOCK(&ctx->lock); \ { \ list_del_init(&_contribution->contri_list); \ GF_REF_PUT(_contribution); \ } \ UNLOCK(&ctx->lock); \ } while (0) #define QUOTA_SAFE_INCREMENT(lock, var) \ do { \ LOCK(lock); \ var++; \ UNLOCK(lock); \ } while (0) #define QUOTA_SAFE_DECREMENT(lock, var, value) \ do { \ LOCK(lock); \ { \ value = --var; \ } \ UNLOCK(lock); \ } while (0) inode_contribution_t * mq_add_new_contribution_node(xlator_t *, quota_inode_ctx_t *, loc_t *); int32_t mq_dict_set_contribution(xlator_t *, dict_t *, loc_t *, uuid_t, char *); quota_inode_ctx_t * mq_inode_ctx_new(inode_t *, xlator_t *); int32_t mq_inode_ctx_get(inode_t *, xlator_t *, quota_inode_ctx_t **); int32_t mq_delete_contribution_node(dict_t *, char *, inode_contribution_t *); int32_t mq_inode_loc_fill(const char *, inode_t *, loc_t *); inode_contribution_t * mq_contri_init(inode_t *inode); inode_contribution_t * mq_get_contribution_node(inode_t *, quota_inode_ctx_t *); #endif glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/marker-quota.h0000644000000000000000000000013114522202451024522 xustar000000000000000030 mtime=1699284265.677027462 30 atime=1699284265.676027459 29 ctime=1699284303.71114202 glusterfs-11.1/xlators/features/marker/src/marker-quota.h0000664000175100017510000001355514522202451025013 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _MARKER_QUOTA_H #define _MARKER_QUOTA_H #include #include "marker-mem-types.h" #include #include #include #define QUOTA_XATTR_PREFIX "trusted.glusterfs" #define QUOTA_DIRTY_KEY "trusted.glusterfs.quota.dirty" #define CONTRIBUTION "contri" #define QUOTA_KEY_MAX 512 #define READDIR_BUF 4096 #define QUOTA_ALLOC(var, type, ret) \ do { \ ret = 0; \ var = GF_CALLOC(sizeof(type), 1, gf_marker_mt_##type); \ if (!var) { \ ret = -1; \ } \ } while (0); #define QUOTA_ALLOC_OR_GOTO(var, type, ret, label) \ do { \ var = GF_CALLOC(sizeof(type), 1, gf_marker_mt_##type); \ if (!var) { \ gf_log("", GF_LOG_ERROR, "out of memory"); \ ret = -1; \ goto label; \ } \ ret = 0; \ } while (0); #define GET_QUOTA_KEY(_this, var, key, _ret) \ do { \ marker_conf_t *_priv = _this->private; \ if (_priv->version > 0) \ _ret = snprintf(var, QUOTA_KEY_MAX, "%s.%d", key, _priv->version); \ else \ _ret = snprintf(var, QUOTA_KEY_MAX, "%s", key); \ } while (0) #define GET_CONTRI_KEY(_this, var, _gfid, _ret) \ do { \ char _tmp_var[QUOTA_KEY_MAX] = { \ 0, \ }; \ if (_gfid != NULL) { \ char _gfid_unparsed[40]; \ gf_uuid_unparse(_gfid, _gfid_unparsed); \ _ret = snprintf(_tmp_var, QUOTA_KEY_MAX, \ QUOTA_XATTR_PREFIX ".%s.%s." CONTRIBUTION, \ "quota", _gfid_unparsed); \ } else { \ _ret = snprintf(_tmp_var, QUOTA_KEY_MAX, \ QUOTA_XATTR_PREFIX ".%s.." CONTRIBUTION, "quota"); \ } \ GET_QUOTA_KEY(_this, var, _tmp_var, _ret); \ } while (0) #define GET_SIZE_KEY(_this, var, _ret) \ { \ GET_QUOTA_KEY(_this, var, QUOTA_SIZE_KEY, _ret); \ } #define QUOTA_SAFE_INCREMENT(lock, var) \ do { \ LOCK(lock); \ var++; \ UNLOCK(lock); \ } while (0) struct quota_inode_ctx { int64_t size; int64_t file_count; int64_t dir_count; int8_t dirty; gf_boolean_t create_status; gf_boolean_t updation_status; gf_boolean_t dirty_status; gf_lock_t lock; struct list_head contribution_head; }; typedef struct quota_inode_ctx quota_inode_ctx_t; struct quota_synctask { xlator_t *this; loc_t loc; quota_meta_t contri; gf_boolean_t is_static; uint32_t ia_nlink; call_stub_t *stub; }; typedef struct quota_synctask quota_synctask_t; struct inode_contribution { struct list_head contri_list; int64_t contribution; int64_t file_count; int64_t dir_count; uuid_t gfid; gf_lock_t lock; GF_REF_DECL; }; typedef struct inode_contribution inode_contribution_t; int32_t mq_req_xattr(xlator_t *, loc_t *, dict_t *, char *, char *); int32_t mq_xattr_state(xlator_t *, loc_t *, dict_t *, struct iatt *); int mq_initiate_quota_txn(xlator_t *, loc_t *, struct iatt *); int mq_initiate_quota_blocking_txn(xlator_t *, loc_t *, struct iatt *); int mq_create_xattrs_txn(xlator_t *this, loc_t *loc, struct iatt *buf); int32_t mq_reduce_parent_size_txn(xlator_t *, loc_t *, quota_meta_t *, uint32_t nlink, call_stub_t *stub); int32_t mq_forget(xlator_t *, quota_inode_ctx_t *); #endif glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/marker-common.c0000644000000000000000000000013214522202451024655 xustar000000000000000030 mtime=1699284265.675027456 30 atime=1699284265.675027456 30 ctime=1699284303.727142068 glusterfs-11.1/xlators/features/marker/src/marker-common.c0000664000175100017510000000263314522202451025140 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "marker-common.h" marker_inode_ctx_t * marker_inode_ctx_new(void) { marker_inode_ctx_t *ctx = NULL; ctx = GF_CALLOC(1, sizeof(marker_inode_ctx_t), gf_marker_mt_marker_inode_ctx_t); if (ctx == NULL) goto out; ctx->quota_ctx = NULL; out: return ctx; } int32_t marker_force_inode_ctx_get(inode_t *inode, xlator_t *this, marker_inode_ctx_t **ctx) { int32_t ret = -1; uint64_t ctx_int = 0; LOCK(&inode->lock); { ret = __inode_ctx_get(inode, this, &ctx_int); if (ret == 0) *ctx = (marker_inode_ctx_t *)(unsigned long)ctx_int; else { *ctx = marker_inode_ctx_new(); if (*ctx == NULL) goto unlock; ret = __inode_ctx_put(inode, this, (uint64_t)(unsigned long)*ctx); if (ret == -1) { GF_FREE(*ctx); goto unlock; } ret = 0; } } unlock: UNLOCK(&inode->lock); return ret; } glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/marker.c0000644000000000000000000000013114522202451023366 xustar000000000000000030 mtime=1699284265.678027465 30 atime=1699284265.677027462 29 ctime=1699284303.72114205 glusterfs-11.1/xlators/features/marker/src/marker.c0000664000175100017510000026403214522202451023655 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "libxlator.h" #include "marker.h" #include "marker-mem-types.h" #include "marker-quota.h" #include "marker-quota-helper.h" #include "marker-common.h" #include #include #include #define _GF_UID_GID_CHANGED 1 static char *mq_ext_xattrs[] = { QUOTA_SIZE_KEY, QUOTA_LIMIT_KEY, QUOTA_LIMIT_OBJECTS_KEY, NULL, }; void fini(xlator_t *this); int32_t marker_start_setxattr(call_frame_t *, xlator_t *); /* When client/quotad request for quota xattrs, * replace the key-name by adding the version number * in end of the key-name. * In the cbk, result value of xattrs for original * key-name. * Below function marker_key_replace_with_ver and * marker_key_set_ver is used for setting/removing * version for the key-name */ int marker_key_replace_with_ver(xlator_t *this, dict_t *dict) { int ret = -1; int i = 0; marker_conf_t *priv = NULL; char key[QUOTA_KEY_MAX] = { 0, }; priv = this->private; if (dict == NULL || priv->version <= 0) { ret = 0; goto out; } for (i = 0; mq_ext_xattrs[i]; i++) { if (dict_get(dict, mq_ext_xattrs[i])) { GET_QUOTA_KEY(this, key, mq_ext_xattrs[i], ret); if (ret < 0) goto out; ret = dict_set(dict, key, dict_get(dict, mq_ext_xattrs[i])); if (ret < 0) goto out; dict_del(dict, mq_ext_xattrs[i]); } } ret = 0; out: return ret; } int marker_key_set_ver(xlator_t *this, dict_t *dict) { int ret = -1; int i = -1; marker_conf_t *priv = NULL; char key[QUOTA_KEY_MAX] = { 0, }; priv = this->private; if (dict == NULL || priv->version <= 0) { ret = 0; goto out; } for (i = 0; mq_ext_xattrs[i]; i++) { GET_QUOTA_KEY(this, key, mq_ext_xattrs[i], ret); if (ret < 0) goto out; if (dict_get(dict, key)) dict_set(dict, mq_ext_xattrs[i], dict_get(dict, key)); } ret = 0; out: return ret; } marker_local_t * marker_local_ref(marker_local_t *local) { GF_VALIDATE_OR_GOTO("marker", local, err); LOCK(&local->lock); { local->ref++; } UNLOCK(&local->lock); return local; err: return NULL; } int marker_loc_fill(loc_t *loc, inode_t *inode, inode_t *parent, char *path) { int ret = -1; if (!loc) return ret; if (inode) { loc->inode = inode_ref(inode); if (gf_uuid_is_null(loc->gfid)) { gf_uuid_copy(loc->gfid, loc->inode->gfid); } } if (parent) loc->parent = inode_ref(parent); if (path) { loc->path = gf_strdup(path); if (!loc->path) { gf_log("loc fill", GF_LOG_ERROR, "strdup failed"); goto loc_wipe; } loc->name = strrchr(loc->path, '/'); if (loc->name) loc->name++; } ret = 0; loc_wipe: if (ret < 0) loc_wipe(loc); return ret; } int _marker_inode_loc_fill(inode_t *inode, inode_t *parent, char *name, loc_t *loc) { char *resolvedpath = NULL; int ret = -1; gf_boolean_t free_parent = _gf_false; if ((!inode) || (!loc)) return ret; if (parent && name) ret = inode_path(parent, name, &resolvedpath); else ret = inode_path(inode, NULL, &resolvedpath); if (ret < 0) goto err; if (parent == NULL) { parent = inode_parent(inode, NULL, NULL); free_parent = _gf_true; } ret = marker_loc_fill(loc, inode, parent, resolvedpath); if (ret < 0) goto err; err: if (free_parent) inode_unref(parent); GF_FREE(resolvedpath); return ret; } int marker_inode_loc_fill(inode_t *inode, loc_t *loc) { return _marker_inode_loc_fill(inode, NULL, NULL, loc); } int32_t marker_trav_parent(marker_local_t *local) { int32_t ret = 0; loc_t loc = { 0, }; inode_t *parent = NULL; int8_t need_unref = 0; if (!local->loc.parent) { parent = inode_parent(local->loc.inode, NULL, NULL); if (parent) need_unref = 1; } else parent = local->loc.parent; ret = marker_inode_loc_fill(parent, &loc); if (ret < 0) { ret = -1; goto out; } loc_wipe(&local->loc); local->loc = loc; out: if (need_unref) inode_unref(parent); return ret; } void marker_error_handler(xlator_t *this, marker_local_t *local, int32_t op_errno) { marker_conf_t *priv = (marker_conf_t *)this->private; const char *path = local ? ((local->loc.path) ? local->loc.path : uuid_utoa(local->loc.gfid)) : ""; gf_log(this->name, GF_LOG_CRITICAL, "Indexing gone corrupt at %s (reason: %s)." " Geo-replication secondary content needs to be revalidated", path, strerror(op_errno)); sys_unlink(priv->timestamp_file); } int32_t marker_local_unref(marker_local_t *local) { int32_t var = 0; if (local == NULL) return -1; LOCK(&local->lock); { var = --local->ref; } UNLOCK(&local->lock); if (var != 0) goto out; loc_wipe(&local->loc); loc_wipe(&local->parent_loc); if (local->xdata) dict_unref(local->xdata); if (local->lk_frame) { STACK_DESTROY(local->lk_frame->root); local->lk_frame = NULL; } if (local->oplocal) { marker_local_unref(local->oplocal); local->oplocal = NULL; } mem_put(local); out: return 0; } int32_t stat_stampfile(xlator_t *this, marker_conf_t *priv, struct volume_mark **status) { struct stat buf = { 0, }; struct volume_mark *vol_mark = NULL; vol_mark = GF_CALLOC(sizeof(struct volume_mark), 1, gf_marker_mt_volume_mark); vol_mark->major = 1; vol_mark->minor = 0; GF_ASSERT(sizeof(priv->volume_uuid_bin) == 16); memcpy(vol_mark->uuid, priv->volume_uuid_bin, 16); if (sys_stat(priv->timestamp_file, &buf) != -1) { vol_mark->retval = 0; vol_mark->sec = htonl(buf.st_mtime); vol_mark->usec = htonl(ST_MTIM_NSEC(&buf) / 1000); } else vol_mark->retval = 1; *status = vol_mark; return 0; } int32_t marker_getxattr_stampfile_cbk(call_frame_t *frame, xlator_t *this, const char *name, struct volume_mark *vol_mark, dict_t *xdata) { int32_t ret = -1; dict_t *dict = NULL; if (vol_mark == NULL) { STACK_UNWIND_STRICT(getxattr, frame, -1, ENOMEM, NULL, NULL); goto out; } dict = dict_new(); ret = dict_set_bin(dict, (char *)name, vol_mark, sizeof(struct volume_mark)); if (ret) { GF_FREE(vol_mark); gf_log(this->name, GF_LOG_WARNING, "failed to set key %s", name); } STACK_UNWIND_STRICT(getxattr, frame, 0, 0, dict, xdata); if (dict) dict_unref(dict); out: return 0; } gf_boolean_t call_from_special_client(call_frame_t *frame, xlator_t *this, const char *name) { struct volume_mark *vol_mark = NULL; marker_conf_t *priv = NULL; gf_boolean_t is_true = _gf_true; priv = (marker_conf_t *)this->private; if (frame->root->pid != GF_CLIENT_PID_GSYNCD || name == NULL || strcmp(name, MARKER_XATTR_PREFIX "." VOLUME_MARK) != 0) { is_true = _gf_false; goto out; } stat_stampfile(this, priv, &vol_mark); marker_getxattr_stampfile_cbk(frame, this, name, vol_mark, NULL); out: return is_true; } static gf_boolean_t _is_quota_internal_xattr(dict_t *d, char *k, data_t *v, void *data) { int i = 0; char **external_xattrs = data; for (i = 0; external_xattrs && external_xattrs[i]; i++) { if (strcmp(k, external_xattrs[i]) == 0) return _gf_false; } if (fnmatch("trusted.glusterfs.quota*", k, 0) == 0) return _gf_true; /* It would be nice if posix filters pgfid xattrs. But since marker * also takes up responsibility to clean these up, adding the filtering * here (Check 'quota_xattr_cleaner') */ if (fnmatch(PGFID_XATTR_KEY_PREFIX "*", k, 0) == 0) return _gf_true; return _gf_false; } static void marker_filter_internal_xattrs(xlator_t *this, dict_t *xattrs) { marker_conf_t *priv = NULL; char **ext = NULL; priv = this->private; if (priv->feature_enabled & GF_QUOTA) ext = mq_ext_xattrs; dict_foreach_match(xattrs, _is_quota_internal_xattr, ext, dict_remove_foreach_fn, NULL); } static void marker_filter_gsyncd_xattrs(call_frame_t *frame, xlator_t *this, dict_t *xattrs) { marker_conf_t *priv = NULL; priv = this->private; GF_ASSERT(priv); GF_ASSERT(frame); if (xattrs && frame->root->pid != GF_CLIENT_PID_GSYNCD) { GF_REMOVE_INTERNAL_XATTR(GF_XATTR_XTIME_PATTERN, xattrs); } return; } int32_t marker_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { int32_t ret = -1; if (op_ret < 0) goto unwind; ret = marker_key_set_ver(this, dict); if (ret < 0) { op_ret = -1; op_errno = ENOMEM; goto unwind; } if (cookie) { gf_log(this->name, GF_LOG_DEBUG, "Filtering the quota extended attributes"); /* If the getxattr is from a non special client, then do not copy the quota related xattrs (except the quota limit key i.e trusted.glusterfs.quota.limit-set which has been set by glusterd on the directory on which quota limit is set.) for directories. Let the healing of xattrs happen upon lookup. NOTE: setting of trusted.glusterfs.quota.limit-set as of now happens from glusterd. It should be moved to quotad. Also trusted.glusterfs.quota.limit-set is set on directory which is permanent till quota is removed on that directory or limit is changed. So let that xattr be healed by other xlators properly whenever directory healing is done. */ /* * Except limit-set xattr, rest of the xattrs are maintained * by quota xlator. Don't expose them to other xlators. * This filter makes sure quota xattrs are not healed as part of * metadata self-heal */ marker_filter_internal_xattrs(frame->this, dict); } /* Filter gsyncd xtime xattr for non gsyncd clients */ marker_filter_gsyncd_xattrs(frame, frame->this, dict); unwind: MARKER_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } int32_t marker_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { gf_boolean_t is_true = _gf_false; marker_conf_t *priv = NULL; unsigned long cookie = 0; marker_local_t *local = NULL; char key[QUOTA_KEY_MAX] = { 0, }; int32_t ret = -1; int32_t i = 0; priv = this->private; if (name) { for (i = 0; mq_ext_xattrs[i]; i++) { if (strcmp(name, mq_ext_xattrs[i])) continue; GET_QUOTA_KEY(this, key, mq_ext_xattrs[i], ret); if (ret < 0) goto out; name = key; break; } } frame->local = mem_get0(this->local_pool); local = frame->local; if (local == NULL) goto out; MARKER_INIT_LOCAL(frame, local); if ((loc_copy(&local->loc, loc)) < 0) goto out; gf_log(this->name, GF_LOG_DEBUG, "USER:PID = %d", frame->root->pid); if (priv && priv->feature_enabled & GF_XTIME) is_true = call_from_special_client(frame, this, name); if (is_true == _gf_false) { if (name == NULL) { /* Signifies that marker translator * has to filter the quota's xattr's, * this is to prevent afr from performing * self healing on marker-quota xattrs' */ cookie = 1; } STACK_WIND_COOKIE(frame, marker_getxattr_cbk, (void *)cookie, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); } return 0; out: MARKER_STACK_UNWIND(getxattr, frame, -1, ENOMEM, NULL, NULL); return 0; } int32_t marker_setxattr_done(call_frame_t *frame) { marker_local_t *local = NULL; local = (marker_local_t *)frame->local; frame->local = NULL; STACK_DESTROY(frame->root); marker_local_unref(local); return 0; } int marker_specific_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { int32_t ret = 0; int32_t done = 1; marker_local_t *local = NULL; local = (marker_local_t *)frame->local; if (op_ret == -1 && op_errno == ENOSPC) { marker_error_handler(this, local, op_errno); goto out; } if (local) { if (local->loc.path && strcmp(local->loc.path, "/") == 0) { goto out; } if (__is_root_gfid(local->loc.gfid)) { goto out; } } ret = (local) ? marker_trav_parent(local) : -1; if (ret == -1) { gf_log(this->name, GF_LOG_DEBUG, "Error occurred " "while traversing to the parent, stopping marker"); goto out; } marker_start_setxattr(frame, this); done = 0; out: if (done) { marker_setxattr_done(frame); } return 0; } int32_t marker_start_setxattr(call_frame_t *frame, xlator_t *this) { int32_t ret = -1; dict_t *dict = NULL; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; local = (marker_local_t *)frame->local; if (!local) goto out; dict = dict_new(); if (!dict) goto out; if (local->loc.inode && gf_uuid_is_null(local->loc.gfid)) gf_uuid_copy(local->loc.gfid, local->loc.inode->gfid); GF_UUID_ASSERT(local->loc.gfid); ret = dict_set_static_bin(dict, priv->marker_xattr, (void *)local->timebuf, 8); if (ret) { gf_log(this->name, GF_LOG_WARNING, "failed to set marker xattr (%s)", local->loc.path); goto out; } STACK_WIND(frame, marker_specific_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, &local->loc, dict, 0, NULL); ret = 0; out: if (dict) dict_unref(dict); return ret; } void marker_gettimeofday(marker_local_t *local) { struct timeval tv = { 0, }; gettimeofday(&tv, NULL); local->timebuf[0] = htonl(tv.tv_sec); local->timebuf[1] = htonl(tv.tv_usec); return; } int32_t marker_create_frame(xlator_t *this, marker_local_t *local) { call_frame_t *frame = NULL; frame = create_frame(this, this->ctx->pool); if (!frame) return -1; frame->local = (void *)local; marker_start_setxattr(frame, this); return 0; } int32_t marker_xtime_update_marks(xlator_t *this, marker_local_t *local) { marker_conf_t *priv = NULL; GF_VALIDATE_OR_GOTO("marker", this, out); GF_VALIDATE_OR_GOTO(this->name, local, out); priv = this->private; if ((local->pid == GF_CLIENT_PID_GSYNCD && !(priv->feature_enabled & GF_XTIME_GSYNC_FORCE)) || (local->pid == GF_CLIENT_PID_DEFRAG)) goto out; marker_gettimeofday(local); marker_local_ref(local); marker_create_frame(this, local); out: return 0; } int32_t marker_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { marker_conf_t *priv = NULL; marker_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "error occurred " "while creating directory %s", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; priv = this->private; if (op_ret >= 0 && inode && (priv->feature_enabled & GF_QUOTA)) { ctx = mq_inode_ctx_new(inode, this); if (ctx == NULL) { gf_log(this->name, GF_LOG_WARNING, "mq_inode_ctx_new " "failed for %s", uuid_utoa(inode->gfid)); op_ret = -1; op_errno = ENOMEM; } } STACK_UNWIND_STRICT(mkdir, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); if (op_ret == -1 || local == NULL) goto out; if (gf_uuid_is_null(local->loc.gfid)) gf_uuid_copy(local->loc.gfid, buf->ia_gfid); if (priv->feature_enabled & GF_QUOTA) mq_create_xattrs_txn(this, &local->loc, NULL); if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int marker_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; err: MARKER_STACK_UNWIND(mkdir, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t marker_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "error occurred " "while creating file %s", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; priv = this->private; if (op_ret >= 0 && inode && (priv->feature_enabled & GF_QUOTA)) { ctx = mq_inode_ctx_new(inode, this); if (ctx == NULL) { gf_log(this->name, GF_LOG_WARNING, "mq_inode_ctx_new " "failed for %s", uuid_utoa(inode->gfid)); op_ret = -1; op_errno = ENOMEM; } } STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent, xdata); if (op_ret == -1 || local == NULL) goto out; if (gf_uuid_is_null(local->loc.gfid)) gf_uuid_copy(local->loc.gfid, buf->ia_gfid); if (priv->feature_enabled & GF_QUOTA) mq_create_xattrs_txn(this, &local->loc, buf); if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; err: MARKER_STACK_UNWIND(create, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t marker_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { marker_conf_t *priv = NULL; marker_local_t *local = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "error occurred " "while write, %s", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_QUOTA) mq_initiate_quota_txn(this, &local->loc, postbuf); if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = marker_inode_loc_fill(fd->inode, &local->loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; err: MARKER_STACK_UNWIND(writev, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } int32_t marker_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { marker_conf_t *priv = NULL; marker_local_t *local = NULL; call_stub_t *stub = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "error occurred " "rmdir %s", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; priv = this->private; if (op_ret == -1 || local == NULL) goto out; if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); if (priv->feature_enabled & GF_QUOTA) { /* If a 'rm -rf' is performed by a client, rmdir can be faster than marker background mq_reduce_parent_size_txn. In this case, as part of rmdir parent child association will be removed in the server protocol. This can lead to mq_reduce_parent_size_txn failures. So perform mq_reduce_parent_size_txn in foreground and unwind to server once txn is complete */ stub = fop_rmdir_cbk_stub(frame, default_rmdir_cbk, op_ret, op_errno, preparent, postparent, xdata); mq_reduce_parent_size_txn(this, &local->loc, NULL, 1, stub); if (stub) { marker_local_unref(local); return 0; } } out: STACK_UNWIND_STRICT(rmdir, frame, op_ret, op_errno, preparent, postparent, xdata); marker_local_unref(local); return 0; } int32_t marker_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); return 0; err: MARKER_STACK_UNWIND(rmdir, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } int32_t marker_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { marker_conf_t *priv = NULL; marker_local_t *local = NULL; uint32_t nlink = -1; GF_UNUSED int32_t ret = 0; call_stub_t *stub = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred in unlink", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; priv = this->private; if (op_ret == -1 || local == NULL) goto out; if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); if (priv->feature_enabled & GF_QUOTA) { if (local->skip_txn) goto out; if (xdata) { ret = dict_get_uint32(xdata, GF_RESPONSE_LINK_COUNT_XDATA, &nlink); if (ret) { gf_log(this->name, GF_LOG_TRACE, "dict get failed %s ", strerror(-ret)); } } /* If a 'rm -rf' is performed by a client, unlink can be faster than marker background mq_reduce_parent_size_txn. In this case, as part of unlink parent child association will be removed in the server protocol. This can lead to mq_reduce_parent_size_txn failures. So perform mq_reduce_parent_size_txn in foreground and unwind to server once txn is complete */ stub = fop_unlink_cbk_stub(frame, default_unlink_cbk, op_ret, op_errno, preparent, postparent, xdata); mq_reduce_parent_size_txn(this, &local->loc, NULL, nlink, stub); if (stub) { marker_local_unref(local); return 0; } } out: STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); marker_local_unref(local); return 0; } int32_t marker_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; gf_boolean_t dict_free = _gf_false; priv = this->private; if (priv->feature_enabled == 0) goto unlink_wind; local = mem_get0(this->local_pool); local->xflag = xflag; if (xdata) local->xdata = dict_ref(xdata); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; if (xdata && dict_get(xdata, GLUSTERFS_MARKER_DONT_ACCOUNT_KEY)) { local->skip_txn = 1; goto unlink_wind; } if (xdata == NULL) { xdata = dict_new(); dict_free = _gf_true; } ret = dict_set_int32(xdata, GF_REQUEST_LINK_COUNT_XDATA, 1); if (ret < 0) goto err; unlink_wind: STACK_WIND(frame, marker_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); goto out; err: MARKER_STACK_UNWIND(unlink, frame, -1, ENOMEM, NULL, NULL, NULL); out: if (dict_free) dict_unref(xdata); return 0; } int32_t marker_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred while " "linking a file ", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(link, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_QUOTA) { if (!local->skip_txn) mq_create_xattrs_txn(this, &local->loc, buf); } if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, newloc); if (ret == -1) goto err; if (xdata && dict_get(xdata, GLUSTERFS_MARKER_DONT_ACCOUNT_KEY)) local->skip_txn = 1; wind: STACK_WIND(frame, marker_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; err: MARKER_STACK_UNWIND(link, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t marker_rename_done(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { marker_local_t *local = NULL, *oplocal = NULL; loc_t newloc = { 0, }; marker_conf_t *priv = NULL; local = frame->local; oplocal = local->oplocal; priv = this->private; frame->local = NULL; if (op_ret < 0) { gf_log(this->name, GF_LOG_WARNING, "inodelk (UNLOCK) failed on path:%s (gfid:%s) (%s)", oplocal->parent_loc.path, uuid_utoa(oplocal->parent_loc.inode->gfid), strerror(op_errno)); } if (local->err != 0) goto err; mq_reduce_parent_size_txn(this, &oplocal->loc, &oplocal->contribution, -1, NULL); if (local->loc.inode != NULL) { /* If destination file exits before rename, it would have * been unlinked while renaming a file */ mq_reduce_parent_size_txn(this, &local->loc, NULL, local->ia_nlink, NULL); } newloc.inode = inode_ref(oplocal->loc.inode); newloc.path = gf_strdup(local->loc.path); newloc.name = strrchr(newloc.path, '/'); if (newloc.name) newloc.name++; newloc.parent = inode_ref(local->loc.parent); mq_create_xattrs_txn(this, &newloc, &local->buf); loc_wipe(&newloc); if (priv->feature_enabled & GF_XTIME) { if (!local->loc.inode) local->loc.inode = inode_ref(oplocal->loc.inode); // update marks on oldpath gf_uuid_copy(local->loc.gfid, oplocal->loc.inode->gfid); marker_xtime_update_marks(this, oplocal); marker_xtime_update_marks(this, local); } err: marker_local_unref(local); marker_local_unref(oplocal); return 0; } void marker_rename_release_oldp_lock(marker_local_t *local, xlator_t *this) { marker_local_t *oplocal = NULL; call_frame_t *lk_frame = NULL; struct gf_flock lock = { 0, }; oplocal = local->oplocal; lk_frame = local->lk_frame; if (lk_frame == NULL) goto err; lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; lock.l_pid = 0; STACK_WIND(lk_frame, marker_rename_done, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, this->name, &oplocal->parent_loc, F_SETLKW, &lock, NULL); return; err: marker_local_unref(local); marker_local_unref(oplocal); } int32_t marker_rename_unwind(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { marker_local_t *local = NULL; marker_local_t *oplocal = NULL; quota_inode_ctx_t *ctx = NULL; inode_contribution_t *contri = NULL; local = frame->local; oplocal = local->oplocal; frame->local = NULL; // Reset frame uid and gid if set. if (cookie == (void *)_GF_UID_GID_CHANGED) MARKER_RESET_UID_GID(frame, frame->root, local); if (op_ret < 0) local->err = op_errno ? op_errno : EINVAL; if (local->stub != NULL) { /* Remove contribution node from in-memory even if * remove-xattr has failed as the rename is already performed * if local->stub is set, which means rename was successful */ (void)mq_inode_ctx_get(oplocal->loc.inode, this, &ctx); if (ctx) { contri = mq_get_contribution_node(oplocal->loc.parent, ctx); if (contri) { QUOTA_FREE_CONTRIBUTION_NODE(ctx, contri); GF_REF_PUT(contri); } } call_resume(local->stub); local->stub = NULL; local->err = 0; } else if (local->err != 0) { STACK_UNWIND_STRICT(rename, frame, -1, local->err, NULL, NULL, NULL, NULL, NULL, NULL); } else { gf_log(this->name, GF_LOG_CRITICAL, "continuation stub to unwind the call is absent, hence " "call will be hung (call-stack id = %" PRIu64 ")", frame->root->unique); } /* If there are in-progress writes on old-path when during rename * operation, update txn will update the wrong path if lock * is released before rename unwind. * So release lock only after rename unwind */ marker_rename_release_oldp_lock(local, this); return 0; } int32_t marker_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { marker_conf_t *priv = NULL; marker_local_t *local = NULL; marker_local_t *oplocal = NULL; call_stub_t *stub = NULL; int32_t ret = 0; char contri_key[QUOTA_KEY_MAX] = { 0, }; loc_t newloc = { 0, }; local = (marker_local_t *)frame->local; if (local != NULL) { oplocal = local->oplocal; } priv = this->private; if (op_ret < 0) { if (local != NULL) { local->err = op_errno; } gf_log(this->name, GF_LOG_TRACE, "%s occurred while " "renaming a file ", strerror(op_errno)); } if (priv->feature_enabled & GF_QUOTA) { if ((op_ret < 0) || (local == NULL)) { goto quota_err; } local->ia_nlink = 0; if (xdata) ret = dict_get_uint32(xdata, GF_RESPONSE_LINK_COUNT_XDATA, &local->ia_nlink); local->buf = *buf; stub = fop_rename_cbk_stub(frame, default_rename_cbk, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); if (stub == NULL) { local->err = ENOMEM; goto quota_err; } local->stub = stub; GET_CONTRI_KEY(this, contri_key, oplocal->loc.parent->gfid, ret); if (ret < 0) { local->err = ENOMEM; goto quota_err; } /* Removexattr requires uid and gid to be 0, * reset them in the callback. */ MARKER_SET_UID_GID(frame, local, frame->root); newloc.inode = inode_ref(oplocal->loc.inode); newloc.path = gf_strdup(local->loc.path); newloc.name = strrchr(newloc.path, '/'); if (newloc.name) newloc.name++; newloc.parent = inode_ref(local->loc.parent); gf_uuid_copy(newloc.gfid, oplocal->loc.inode->gfid); STACK_WIND_COOKIE( frame, marker_rename_unwind, frame->cookie, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, &newloc, contri_key, NULL); loc_wipe(&newloc); } else { frame->local = NULL; STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); if ((op_ret < 0) || (local == NULL)) { goto out; } if (priv->feature_enabled & GF_XTIME) { // update marks on oldpath if (!local->loc.inode) local->loc.inode = inode_ref(oplocal->loc.inode); gf_uuid_copy(local->loc.gfid, oplocal->loc.inode->gfid); marker_xtime_update_marks(this, oplocal); marker_xtime_update_marks(this, local); } } out: if (!(priv->feature_enabled & GF_QUOTA)) { marker_local_unref(local); marker_local_unref(oplocal); } return 0; quota_err: marker_rename_unwind(frame, NULL, this, 0, 0, NULL); return 0; } int32_t marker_do_rename(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { marker_local_t *local = NULL; marker_local_t *oplocal = NULL; char contri_key[QUOTA_KEY_MAX] = { 0, }; int keylen = 0; quota_meta_t contribution = { 0, }; local = frame->local; oplocal = local->oplocal; // Reset frame uid and gid if set. if (cookie == (void *)_GF_UID_GID_CHANGED) MARKER_RESET_UID_GID(frame, frame->root, local); if ((op_ret < 0) && (op_errno != ENOATTR) && (op_errno != ENODATA)) { local->err = op_errno ? op_errno : EINVAL; gf_log(this->name, GF_LOG_WARNING, "fetching contribution values from %s (gfid:%s) " "failed (%s)", oplocal->loc.path, uuid_utoa(oplocal->loc.inode->gfid), strerror(op_errno)); goto err; } GET_CONTRI_KEY(this, contri_key, oplocal->loc.parent->gfid, keylen); if (keylen < 0) { local->err = errno ? errno : ENOMEM; goto err; } quota_dict_get_meta(dict, contri_key, keylen, &contribution); oplocal->contribution = contribution; STACK_WIND(frame, marker_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, &oplocal->loc, &local->loc, local->xdata); return 0; err: marker_rename_unwind(frame, NULL, this, 0, 0, NULL); return 0; } int32_t marker_get_oldpath_contribution(call_frame_t *lk_frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { call_frame_t *frame = NULL; marker_local_t *local = NULL; marker_local_t *oplocal = NULL; char contri_key[QUOTA_KEY_MAX] = { 0, }; int32_t ret = 0; local = lk_frame->local; oplocal = local->oplocal; frame = local->frame; if (op_ret < 0) { local->err = op_errno ? op_errno : EINVAL; gf_log(this->name, GF_LOG_WARNING, "cannot hold inodelk on %s (gfid:%s) (%s)", oplocal->loc.path, uuid_utoa(oplocal->loc.inode->gfid), strerror(op_errno)); if (local->lk_frame) { STACK_DESTROY(local->lk_frame->root); local->lk_frame = NULL; } goto err; } GET_CONTRI_KEY(this, contri_key, oplocal->loc.parent->gfid, ret); if (ret < 0) { local->err = errno ? errno : ENOMEM; goto err; } /* getxattr requires uid and gid to be 0, * reset them in the callback. */ MARKER_SET_UID_GID(frame, local, frame->root); if (gf_uuid_is_null(oplocal->loc.gfid)) gf_uuid_copy(oplocal->loc.gfid, oplocal->loc.inode->gfid); GF_UUID_ASSERT(oplocal->loc.gfid); STACK_WIND_COOKIE(frame, marker_do_rename, frame->cookie, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, &oplocal->loc, contri_key, NULL); return 0; err: marker_rename_unwind(frame, NULL, this, 0, 0, NULL); return 0; } /* For a marker_rename FOP, following is the algorithm used for Quota * accounting. The use-case considered is: * 1. rename (src, dst) * 2. both src and dst exist * 3. there are parallel operations on src and dst (lets say through fds * opened on them before rename was initiated). * * PS: We've not thought through whether this algo works in the presence of * hardlinks to src and/or dst. * * Algorithm: * ========== * * 1) set inodelk on src-parent * As part of rename operation, parent can change for the file. * We need to remove contribution (both on disk xattr and in-memory one) * to src-parent (and its ancestors) and add the contribution to dst-parent * (and its ancestors). While we are doing these operations, contribution of * the file/directory shouldn't be changing as we want to be sure that * a) what we subtract from src-parent is exactly what we add to dst-parent * b) we should subtract from src-parent exactly what we contributed to * src-parent * So, We hold a lock on src-parent to block any parallel transcations on * src-inode (since that's the one which survives rename). * * If there are any parallel transactions on dst-inode they keep succeeding * till the association of dst-inode with dst-parent is broken because of an * inode_rename after unwind of rename fop from marker. Only after unwind * (and hence inode_rename), we delete and subtract the contribution of * dst-inode to dst-parent. That way we are making sure we subtract exactly * what dst-inode contributed to dst-parent. * * 2) lookup contribution to src-parent on src-inode. * We need to save the contribution info for use at step-8. * * 3) wind rename * Perform rename on disk * * 4) remove xattr on src-loc * After rename, parent can change, so * need to remove xattrs storing contribution to src-parent. * * 5) remove contribution node corresponding to src-parent from the in-memory * list. * After rename, contri gfid can change and we have * also removed xattr from file. * We need to remove in-memory contribution node to prevent updations to * src-parent even after a successful rename * * 6) unwind rename * This will ensure that rename is done in the server * inode table. An inode_rename disassociates src-inode from src-parent and * associates it with dst-parent. It also disassociates dst-inode from * dst-parent. After inode_rename, inode_parent on src-inode will give * dst-parent and inode_parent on dst-inode will return NULL (assuming * dst-inode doesn't have any hardlinks). * * 7) release inodelk on src-parent * Lock on src-parent should be released only after * rename on disk, remove xattr and rename_unwind (and hence inode_rename) * operations. If lock is released before inode_rename, a parallel * transaction on src-inode can still update src-parent (as inode_parent on * src-inode can still return src-parent). This would make the * contribution from src-inode to src-parent stored in step-2 stale. * * 8) Initiate mq_reduce_parent_size_txn on src-parent to remove contribution * of src-inode to src-parent. We use the contribution stored in step-2. * Since, we had acquired the lock on src-parent all along step-2 through * inode_rename, we can be sure that a parallel transaction wouldn't have * added a delta to src-parent. * * 9) Initiate mq_reduce_parent_size_txn on dst-parent if dst-inode exists. * The size reduced from dst-parent and its ancestors is the * size stored as contribution to dst-parent in dst-inode. * If the destination file had existed, rename will unlink the * destination file as part of its operation. * We need to reduce the size on the dest parent similarly to * unlink. Since, we are initiating reduce-parent-size transaction after * inode_rename, we can be sure that a parallel transaction wouldn't add * delta to dst-parent while we are reducing the contribution of dst-inode * from its ancestors before rename. * * 10) create contribution xattr to dst-parent on src-inode. */ int32_t marker_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_local_t *oplocal = NULL; marker_conf_t *priv = NULL; struct gf_flock lock = { 0, }; priv = this->private; if (priv->feature_enabled == 0) goto rename_wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); oplocal = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, oplocal); frame->local = local; local->oplocal = marker_local_ref(oplocal); ret = loc_copy(&local->loc, newloc); if (ret < 0) goto err; ret = loc_copy(&oplocal->loc, oldloc); if (ret < 0) goto err; if (!(priv->feature_enabled & GF_QUOTA)) { goto rename_wind; } ret = mq_inode_loc_fill(NULL, newloc->parent, &local->parent_loc); if (ret < 0) goto err; ret = mq_inode_loc_fill(NULL, oldloc->parent, &oplocal->parent_loc); if (ret < 0) goto err; lock.l_len = 0; lock.l_start = 0; lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; local->xdata = xdata ? dict_ref(xdata) : dict_new(); ret = dict_set_int32(local->xdata, GF_REQUEST_LINK_COUNT_XDATA, 1); if (ret < 0) goto err; local->frame = frame; local->lk_frame = create_frame(this, this->ctx->pool); if (local->lk_frame == NULL) goto err; local->lk_frame->root->uid = 0; local->lk_frame->root->gid = 0; local->lk_frame->local = local; set_lk_owner_from_ptr(&local->lk_frame->root->lk_owner, local->lk_frame->root); STACK_WIND(local->lk_frame, marker_get_oldpath_contribution, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, this->name, &oplocal->parent_loc, F_SETLKW, &lock, NULL); return 0; rename_wind: STACK_WIND(frame, marker_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; err: MARKER_STACK_UNWIND(rename, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL, NULL); marker_local_unref(oplocal); return 0; } int32_t marker_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred while " "truncating a file ", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_QUOTA) { /* DHT Rebalance process, at the end of migration will * first make the src file as a linkto file and then * truncate the file. By doing a truncate after making the * src file as linkto file, the contri which is already * accounted is left over. * So, we need to account for the linkto file when a truncate * happens, thereby updating the contri properly. * By passing NULL for postbuf, mq_prevalidate does not check * for linkto file. * Same happens with ftruncate as well. */ if (postbuf && IS_DHT_LINKFILE_MODE(postbuf)) mq_initiate_quota_txn(this, &local->loc, NULL); else mq_initiate_quota_txn(this, &local->loc, postbuf); } if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; err: MARKER_STACK_UNWIND(truncate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } int32_t marker_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred while " "truncating a file ", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_QUOTA) { if (postbuf && IS_DHT_LINKFILE_MODE(postbuf)) mq_initiate_quota_txn(this, &local->loc, NULL); else mq_initiate_quota_txn(this, &local->loc, postbuf); } if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = marker_inode_loc_fill(fd->inode, &local->loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; err: MARKER_STACK_UNWIND(ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } int32_t marker_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { marker_conf_t *priv = NULL; marker_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred while " "creating symlinks ", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; priv = this->private; if (op_ret >= 0 && inode && (priv->feature_enabled & GF_QUOTA)) { ctx = mq_inode_ctx_new(inode, this); if (ctx == NULL) { gf_log(this->name, GF_LOG_WARNING, "mq_inode_ctx_new " "failed for %s", uuid_utoa(inode->gfid)); op_ret = -1; op_errno = ENOMEM; } } STACK_UNWIND_STRICT(symlink, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); if (op_ret == -1 || local == NULL) goto out; if (gf_uuid_is_null(local->loc.gfid)) gf_uuid_copy(local->loc.gfid, buf->ia_gfid); if (priv->feature_enabled & GF_QUOTA) { mq_create_xattrs_txn(this, &local->loc, buf); } if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int marker_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); return 0; err: MARKER_STACK_UNWIND(symlink, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t marker_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred with " "mknod ", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; priv = this->private; if (op_ret >= 0 && inode && (priv->feature_enabled & GF_QUOTA)) { ctx = mq_inode_ctx_new(inode, this); if (ctx == NULL) { gf_log(this->name, GF_LOG_WARNING, "mq_inode_ctx_new " "failed for %s", uuid_utoa(inode->gfid)); op_ret = -1; op_errno = ENOMEM; } } STACK_UNWIND_STRICT(mknod, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); if (op_ret == -1 || local == NULL) goto out; if (gf_uuid_is_null(local->loc.gfid)) gf_uuid_copy(local->loc.gfid, buf->ia_gfid); if ((priv->feature_enabled & GF_QUOTA) && (S_ISREG(local->mode))) { mq_create_xattrs_txn(this, &local->loc, buf); } if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int marker_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); local->mode = mode; if (ret == -1) goto err; wind: STACK_WIND(frame, marker_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; err: MARKER_STACK_UNWIND(mknod, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t marker_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred while " "fallocating a file ", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, prebuf, postbuf, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_QUOTA) mq_initiate_quota_txn(this, &local->loc, postbuf); if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = marker_inode_loc_fill(fd->inode, &local->loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_fallocate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, xdata); return 0; err: MARKER_STACK_UNWIND(fallocate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } int32_t marker_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred during discard", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, prebuf, postbuf, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_QUOTA) mq_initiate_quota_txn(this, &local->loc, postbuf); if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = marker_inode_loc_fill(fd->inode, &local->loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_discard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); return 0; err: MARKER_STACK_UNWIND(discard, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } int32_t marker_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred during zerofill", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, prebuf, postbuf, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_QUOTA) mq_initiate_quota_txn(this, &local->loc, postbuf); if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = marker_inode_loc_fill(fd->inode, &local->loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_zerofill_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata); return 0; err: MARKER_STACK_UNWIND(zerofill, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } /* when a call from the special client is received on * key trusted.glusterfs.volume-mark with value "RESET" * or if the value is 0length, update the change the * access time and modification time via touching the * timestamp file. */ int32_t call_from_sp_client_to_reset_tmfile(call_frame_t *frame, xlator_t *this, dict_t *dict) { int32_t fd = 0; int32_t op_ret = 0; int32_t op_errno = 0; data_t *data = NULL; marker_conf_t *priv = NULL; if (frame == NULL || this == NULL || dict == NULL) return -1; priv = this->private; data = dict_get(dict, "trusted.glusterfs.volume-mark"); if (data == NULL) return -1; if (frame->root->pid != GF_CLIENT_PID_GSYNCD) { op_ret = -1; op_errno = EPERM; goto out; } if (data->len == 0 || (data->len == 5 && memcmp(data->data, "RESET", 5) == 0)) { fd = open(priv->timestamp_file, O_WRONLY | O_TRUNC); if (fd != -1) { /* TODO check whether the O_TRUNC would update the * timestamps on a zero length file on all machies. */ sys_close(fd); } if (fd != -1 || errno == ENOENT) { op_ret = 0; op_errno = 0; } else { op_ret = -1; op_errno = errno; } } else { op_ret = -1; op_errno = EINVAL; } out: STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, NULL); return 0; } int32_t marker_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred in " "setxattr ", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int remove_quota_keys(dict_t *dict, char *k, data_t *v, void *data) { call_frame_t *frame = data; marker_local_t *local = frame->local; xlator_t *this = frame->this; marker_conf_t *priv = NULL; char ver_str[NAME_MAX] = { 0, }; char *dot = NULL; int ret = -1; priv = this->private; /* If quota is enabled immediately after disable. * quota healing starts creating new xattrs * before completing the cleanup operation. * So we should check if the xattr is the new. * Do not remove xattr if its xattr * version is same as current version */ if ((priv->feature_enabled & GF_QUOTA) && priv->version > 0) { snprintf(ver_str, sizeof(ver_str), ".%d", priv->version); dot = strrchr(k, '.'); if (dot && !strcmp(dot, ver_str)) return 0; } ret = syncop_removexattr(FIRST_CHILD(this), &local->loc, k, 0, NULL); if (ret) { gf_log(this->name, GF_LOG_ERROR, "%s: Failed to remove " "extended attribute: %s", local->loc.path, k); return -1; } return 0; } int quota_xattr_cleaner_cbk(int ret, call_frame_t *frame, void *args) { dict_t *xdata = args; int op_ret = -1; int op_errno = 0; op_ret = (ret < 0) ? -1 : 0; op_errno = -ret; MARKER_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); return ret; } int quota_xattr_cleaner(void *args) { struct synctask *task = NULL; call_frame_t *frame = NULL; xlator_t *this = NULL; marker_local_t *local = NULL; dict_t *xdata = NULL; int ret = -1; task = synctask_get(); if (!task) goto out; frame = task->frame; this = frame->this; local = frame->local; ret = syncop_listxattr(FIRST_CHILD(this), &local->loc, &xdata, NULL, NULL); if (ret == -1) { ret = -errno; goto out; } ret = dict_foreach_fnmatch(xdata, "trusted.glusterfs.quota.*", remove_quota_keys, frame); if (ret == -1) { ret = -errno; goto out; } ret = dict_foreach_fnmatch(xdata, PGFID_XATTR_KEY_PREFIX "*", remove_quota_keys, frame); if (ret == -1) { ret = -errno; goto out; } ret = 0; out: if (xdata) dict_unref(xdata); return ret; } int marker_do_xattr_cleanup(call_frame_t *frame, xlator_t *this, dict_t *xdata, loc_t *loc) { int ret = -1; marker_local_t *local = NULL; local = mem_get0(this->local_pool); if (!local) goto out; MARKER_INIT_LOCAL(frame, local); loc_copy(&local->loc, loc); ret = synctask_new(this->ctx->env, quota_xattr_cleaner, quota_xattr_cleaner_cbk, frame, xdata); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to create synctask " "for cleaning up quota extended attributes"); goto out; } ret = 0; out: if (ret) MARKER_STACK_UNWIND(setxattr, frame, -1, ENOMEM, xdata); return ret; } static gf_boolean_t marker_xattr_cleanup_cmd(dict_t *dict) { return (dict_get(dict, VIRTUAL_QUOTA_XATTR_CLEANUP_KEY) != NULL); } int32_t marker_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; int op_errno = ENOMEM; priv = this->private; if (marker_xattr_cleanup_cmd(dict)) { if (frame->root->uid != 0 || frame->root->gid != 0) { op_errno = EPERM; ret = -1; goto err; } /* The following function does the cleanup and then unwinds the * corresponding call*/ loc_path(loc, NULL); marker_do_xattr_cleanup(frame, this, xdata, loc); return 0; } ret = marker_key_replace_with_ver(this, dict); if (ret < 0) goto err; if (priv->feature_enabled == 0) goto wind; ret = call_from_sp_client_to_reset_tmfile(frame, this, dict); if (ret == 0) return 0; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; err: MARKER_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); return 0; } int32_t marker_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred in " "fsetxattr", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; ret = call_from_sp_client_to_reset_tmfile(frame, this, dict); if (ret == 0) return 0; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = marker_inode_loc_fill(fd->inode, &local->loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; err: MARKER_STACK_UNWIND(fsetxattr, frame, -1, ENOMEM, NULL); return 0; } int32_t marker_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred in " "fsetattr ", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(fsetattr, frame, op_ret, op_errno, statpre, statpost, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = marker_inode_loc_fill(fd->inode, &local->loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; err: MARKER_STACK_UNWIND(fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } int32_t marker_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; local = (marker_local_t *)frame->local; frame->local = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred during setattr of %s", strerror(op_errno), (local ? local->loc.path : "")); } STACK_UNWIND_STRICT(setattr, frame, op_ret, op_errno, statpre, statpost, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; priv = this->private; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; err: MARKER_STACK_UNWIND(setattr, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } int32_t marker_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { marker_local_t *local = NULL; marker_conf_t *priv = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "%s occurred while " "removing extended attribute", strerror(op_errno)); } local = (marker_local_t *)frame->local; frame->local = NULL; STACK_UNWIND_STRICT(removexattr, frame, op_ret, op_errno, xdata); if (op_ret == -1 || local == NULL) goto out; priv = this->private; if (priv->feature_enabled & GF_XTIME) marker_xtime_update_marks(this, local); out: marker_local_unref(local); return 0; } int32_t marker_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int32_t ret = -1; int32_t i = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; char key[QUOTA_KEY_MAX] = { 0, }; priv = this->private; if (name) { for (i = 0; mq_ext_xattrs[i]; i++) { if (strcmp(name, mq_ext_xattrs[i])) continue; GET_QUOTA_KEY(this, key, mq_ext_xattrs[i], ret); if (ret < 0) goto err; name = key; break; } } if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; wind: STACK_WIND(frame, marker_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; err: MARKER_STACK_UNWIND(removexattr, frame, -1, ENOMEM, NULL); return 0; } static gf_boolean_t __has_quota_xattrs(dict_t *xattrs) { if (dict_foreach_match(xattrs, _is_quota_internal_xattr, NULL, dict_null_foreach_fn, NULL) > 0) return _gf_true; return _gf_false; } static int32_t marker_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *dict, struct iatt *postparent) { marker_conf_t *priv = NULL; marker_local_t *local = NULL; dict_t *xattrs = NULL; quota_inode_ctx_t *ctx = NULL; int32_t ret = -1; priv = this->private; local = (marker_local_t *)frame->local; frame->local = NULL; if (op_ret == -1) { gf_log(this->name, GF_LOG_TRACE, "lookup failed with %s", strerror(op_errno)); goto unwind; } ret = marker_key_set_ver(this, dict); if (ret < 0) { op_ret = -1; op_errno = ENOMEM; goto unwind; } if (dict && __has_quota_xattrs(dict)) { xattrs = dict_copy_with_ref(dict, NULL); if (!xattrs) { op_ret = -1; op_errno = ENOMEM; } else { marker_filter_internal_xattrs(this, xattrs); } } else if (dict) { xattrs = dict_ref(dict); } if (op_ret >= 0 && inode && (priv->feature_enabled & GF_QUOTA)) { ctx = mq_inode_ctx_new(inode, this); if (ctx == NULL) { gf_log(this->name, GF_LOG_WARNING, "mq_inode_ctx_new " "failed for %s", uuid_utoa(inode->gfid)); op_ret = -1; op_errno = ENOMEM; } } unwind: STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xattrs, postparent); if (op_ret == -1 || local == NULL) goto out; /* copy the gfid from the stat structure instead of inode, * since if the lookup is fresh lookup, then the inode * would have not yet linked to the inode table which happens * in protocol/server. */ if (gf_uuid_is_null(local->loc.gfid)) gf_uuid_copy(local->loc.gfid, buf->ia_gfid); if (priv->feature_enabled & GF_QUOTA) { mq_xattr_state(this, &local->loc, dict, buf); } out: marker_local_unref(local); if (xattrs) dict_unref(xattrs); return 0; } static int32_t marker_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { int32_t ret = 0; marker_local_t *local = NULL; marker_conf_t *priv = NULL; gf_boolean_t unref = _gf_false; // do we need to unref the dict priv = this->private; if (priv->version <= 0) goto wind; xattr_req = xattr_req ? dict_ref(xattr_req) : dict_new(); if (!xattr_req) { goto err; } unref = _gf_true; ret = marker_key_replace_with_ver(this, xattr_req); if (ret < 0) goto err; if (priv->feature_enabled == 0) goto wind; local = mem_get0(this->local_pool); if (local == NULL) goto err; MARKER_INIT_LOCAL(frame, local); ret = loc_copy(&local->loc, loc); if (ret == -1) goto err; if ((priv->feature_enabled & GF_QUOTA)) mq_req_xattr(this, loc, xattr_req, NULL, NULL); wind: STACK_WIND(frame, marker_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xattr_req); if (unref) dict_unref(xattr_req); return 0; err: MARKER_STACK_UNWIND(lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL); if (xattr_req) dict_unref(xattr_req); return 0; } int marker_build_ancestry_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata) { gf_dirent_t *entry = NULL; quota_inode_ctx_t *ctx = NULL; int ret = -1; if ((op_ret <= 0) || (entries == NULL)) { goto out; } list_for_each_entry(entry, &entries->list, list) { if (entry->inode == NULL) continue; ret = marker_key_set_ver(this, entry->dict); if (ret < 0) { op_ret = -1; op_errno = ENOMEM; break; } ctx = mq_inode_ctx_new(entry->inode, this); if (ctx == NULL) gf_log(this->name, GF_LOG_WARNING, "mq_inode_ctx_new " "failed for %s", uuid_utoa(entry->inode->gfid)); } out: STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata); return 0; } int marker_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata) { gf_dirent_t *entry = NULL; marker_conf_t *priv = NULL; marker_local_t *local = NULL; loc_t loc = { 0, }; int ret = -1; char *resolvedpath = NULL; quota_inode_ctx_t *ctx = NULL; int no_found_entry = 1; if (op_ret <= 0) goto unwind; priv = this->private; local = frame->local; if (!(priv->feature_enabled & GF_QUOTA) || (local == NULL)) { goto unwind; } list_for_each_entry(entry, &entries->list, list) { /* skip . and .. */ if (entry->inode == NULL || inode_dir_or_parentdir(entry)) continue; if (no_found_entry) no_found_entry = 0; loc.parent = inode_ref(local->loc.inode); loc.inode = inode_ref(entry->inode); ret = inode_path(loc.parent, entry->d_name, &resolvedpath); if (ret < 0) { gf_log(this->name, GF_LOG_ERROR, "failed to get the " "path for the entry %s", entry->d_name); loc_wipe(&loc); continue; } loc.path = resolvedpath; resolvedpath = NULL; ctx = mq_inode_ctx_new(loc.inode, this); if (ctx == NULL) gf_log(this->name, GF_LOG_WARNING, "mq_inode_ctx_new " "failed for %s", uuid_utoa(loc.inode->gfid)); mq_xattr_state(this, &loc, entry->dict, &entry->d_stat); loc_wipe(&loc); ret = marker_key_set_ver(this, entry->dict); if (ret < 0) { op_ret = -1; op_errno = ENOMEM; goto unwind; } } if (no_found_entry && loc_is_root(&local->loc)) mq_create_xattrs_txn(this, &local->loc, NULL); unwind: MARKER_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata); return 0; } int marker_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *dict) { marker_conf_t *priv = NULL; loc_t loc = { 0, }; marker_local_t *local = NULL; int ret = -1; priv = this->private; dict = dict ? dict_ref(dict) : dict_new(); if (!dict) goto unwind; ret = marker_key_replace_with_ver(this, dict); if (ret < 0) goto unwind; if (dict_get(dict, GET_ANCESTRY_DENTRY_KEY)) { STACK_WIND(frame, marker_build_ancestry_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); } else { if (priv->feature_enabled & GF_QUOTA) { local = mem_get0(this->local_pool); MARKER_INIT_LOCAL(frame, local); loc.parent = local->loc.inode = inode_ref(fd->inode); mq_req_xattr(this, &loc, dict, NULL, NULL); } STACK_WIND(frame, marker_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); } dict_unref(dict); return 0; unwind: MARKER_STACK_UNWIND(readdirp, frame, -1, ENOMEM, NULL, NULL); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_marker_mt_end); if (ret != 0) { gf_log(this->name, GF_LOG_ERROR, "Memory accounting init" " failed"); return ret; } return ret; } int32_t init_xtime_priv(xlator_t *this, dict_t *options) { int32_t ret = -1; marker_conf_t *priv = NULL; char *tmp_opt = NULL; GF_VALIDATE_OR_GOTO("marker", this, out); GF_VALIDATE_OR_GOTO(this->name, options, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); priv = this->private; ret = dict_get_str(options, "volume-uuid", &tmp_opt); if (ret) { priv->volume_uuid = NULL; tmp_opt = ""; gf_log(this->name, GF_LOG_ERROR, "please specify the volume-uuid" "in the translator options"); return -1; } gf_asprintf(&priv->volume_uuid, "%s", tmp_opt); ret = gf_uuid_parse(priv->volume_uuid, priv->volume_uuid_bin); if (ret == -1) { gf_log(this->name, GF_LOG_ERROR, "invalid volume uuid %s", priv->volume_uuid); goto out; } ret = gf_asprintf(&(priv->marker_xattr), "%s.%s.%s", MARKER_XATTR_PREFIX, priv->volume_uuid, XTIME); if (ret == -1) { priv->marker_xattr = NULL; goto out; } gf_log(this->name, GF_LOG_DEBUG, "volume-uuid = %s", priv->volume_uuid); ret = dict_get_str(options, "timestamp-file", &tmp_opt); if (ret) { priv->timestamp_file = NULL; tmp_opt = ""; gf_log(this->name, GF_LOG_ERROR, "please specify the timestamp-file" "in the translator options"); goto out; } ret = gf_asprintf(&priv->timestamp_file, "%s", tmp_opt); if (ret == -1) { priv->timestamp_file = NULL; goto out; } gf_log(this->name, GF_LOG_DEBUG, "the timestamp-file is = %s", priv->timestamp_file); ret = 0; out: return ret; } void marker_xtime_priv_cleanup(xlator_t *this) { marker_conf_t *priv = NULL; GF_VALIDATE_OR_GOTO("marker", this, out); priv = (marker_conf_t *)this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); GF_FREE(priv->volume_uuid); GF_FREE(priv->timestamp_file); GF_FREE(priv->marker_xattr); out: return; } void marker_priv_cleanup(xlator_t *this) { marker_conf_t *priv = NULL; GF_VALIDATE_OR_GOTO("marker", this, out); priv = (marker_conf_t *)this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); marker_xtime_priv_cleanup(this); LOCK_DESTROY(&priv->lock); GF_FREE(priv); if (this->local_pool) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; } out: return; } int32_t reconfigure(xlator_t *this, dict_t *options) { int32_t ret = 0; data_t *data = NULL; gf_boolean_t flag = _gf_false; marker_conf_t *priv = NULL; int32_t version = 0; GF_ASSERT(this); GF_ASSERT(this->private); priv = this->private; priv->feature_enabled = 0; GF_VALIDATE_OR_GOTO(this->name, options, out); data = dict_get(options, "quota"); if (data) { ret = gf_string2boolean(data->data, &flag); if (ret == 0 && flag == _gf_true) priv->feature_enabled |= GF_QUOTA; } data = dict_get(options, "inode-quota"); if (data) { ret = gf_string2boolean(data->data, &flag); if (ret == 0 && flag == _gf_true) priv->feature_enabled |= GF_INODE_QUOTA; } data = dict_get(options, "quota-version"); if (data) ret = gf_string2int32(data->data, &version); if (priv->feature_enabled) { if (version >= 0) priv->version = version; else gf_log(this->name, GF_LOG_ERROR, "Invalid quota " "version %d", priv->version); } data = dict_get(options, "xtime"); if (data) { ret = gf_string2boolean(data->data, &flag); if (ret == 0 && flag == _gf_true) { marker_xtime_priv_cleanup(this); ret = init_xtime_priv(this, options); if (ret < 0) { gf_log(this->name, GF_LOG_WARNING, "failed to initialize xtime private, " "xtime updation will fail"); } else { priv->feature_enabled |= GF_XTIME; data = dict_get(options, "gsync-force-xtime"); if (!data) goto out; ret = gf_string2boolean(data->data, &flag); if (ret == 0 && flag) priv->feature_enabled |= GF_XTIME_GSYNC_FORCE; } } } out: return ret; } int32_t init(xlator_t *this) { dict_t *options = NULL; data_t *data = NULL; int32_t ret = 0; gf_boolean_t flag = _gf_false; marker_conf_t *priv = NULL; if (!this->children) { gf_log(this->name, GF_LOG_ERROR, "marker translator needs subvolume defined."); return -1; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "Volume is dangling."); return -1; } options = this->options; ALLOCATE_OR_GOTO(this->private, marker_conf_t, err); priv = this->private; priv->feature_enabled = 0; priv->version = 0; LOCK_INIT(&priv->lock); data = dict_get(options, "quota"); if (data) { ret = gf_string2boolean(data->data, &flag); if (ret == 0 && flag == _gf_true) priv->feature_enabled |= GF_QUOTA; } data = dict_get(options, "inode-quota"); if (data) { ret = gf_string2boolean(data->data, &flag); if (ret == 0 && flag == _gf_true) priv->feature_enabled |= GF_INODE_QUOTA; } data = dict_get(options, "quota-version"); if (data) ret = gf_string2int32(data->data, &priv->version); if ((ret == 0) && priv->feature_enabled && priv->version < 0) { gf_log(this->name, GF_LOG_ERROR, "Invalid quota version %d", priv->version); goto err; } data = dict_get(options, "xtime"); if (data) { ret = gf_string2boolean(data->data, &flag); if (ret == 0 && flag == _gf_true) { ret = init_xtime_priv(this, options); if (ret < 0) goto err; priv->feature_enabled |= GF_XTIME; data = dict_get(options, "gsync-force-xtime"); if (!data) goto cont; ret = gf_string2boolean(data->data, &flag); if (ret == 0 && flag) priv->feature_enabled |= GF_XTIME_GSYNC_FORCE; } } cont: this->local_pool = mem_pool_new(marker_local_t, 128); if (!this->local_pool) { gf_log(this->name, GF_LOG_ERROR, "failed to create local_t's memory pool"); goto err; } return 0; err: marker_priv_cleanup(this); return -1; } int32_t marker_forget(xlator_t *this, inode_t *inode) { marker_inode_ctx_t *ctx = NULL; uint64_t value = 0; if (inode_ctx_del(inode, this, &value) != 0) goto out; ctx = (marker_inode_ctx_t *)(unsigned long)value; if (ctx == NULL) { goto out; } mq_forget(this, ctx->quota_ctx); GF_FREE(ctx); out: return 0; } void fini(xlator_t *this) { marker_priv_cleanup(this); } struct xlator_fops fops = { .lookup = marker_lookup, .create = marker_create, .mkdir = marker_mkdir, .writev = marker_writev, .truncate = marker_truncate, .ftruncate = marker_ftruncate, .symlink = marker_symlink, .link = marker_link, .unlink = marker_unlink, .rmdir = marker_rmdir, .rename = marker_rename, .mknod = marker_mknod, .setxattr = marker_setxattr, .fsetxattr = marker_fsetxattr, .setattr = marker_setattr, .fsetattr = marker_fsetattr, .removexattr = marker_removexattr, .getxattr = marker_getxattr, .readdirp = marker_readdirp, .fallocate = marker_fallocate, .discard = marker_discard, .zerofill = marker_zerofill, }; struct xlator_cbks cbks = {.forget = marker_forget}; struct volume_options options[] = { {.key = {"volume-uuid"}, .default_value = "{{ volume.id }}"}, {.key = {"timestamp-file"}}, { .key = {"quota"}, .op_version = {1}, .flags = OPT_FLAG_NONE, .tags = {}, }, { .key = {"inode-quota"}, .op_version = {1}, .flags = OPT_FLAG_NONE, .tags = {}, }, { .key = {"xtime"}, .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_FORCE, .tags = {}, }, { .key = {"gsync-force-xtime"}, .op_version = {2}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_FORCE, .tags = {}, }, { .key = {"quota-version"}, .flags = OPT_FLAG_NONE, }, {.key = {NULL}}}; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "marker", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464024013 xustar000000000000000030 mtime=1699284276.455059926 30 atime=1699284290.390101898 30 ctime=1699284303.703141996 glusterfs-11.1/xlators/features/marker/src/Makefile.in0000664000175100017510000006036114522202464024300 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/marker/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) marker_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_marker_la_OBJECTS = marker.lo marker-quota.lo \ marker-quota-helper.lo marker-common.lo marker_la_OBJECTS = $(am_marker_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = marker_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(marker_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_marker_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(marker_la_SOURCES) DIST_SOURCES = $(marker_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = marker.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features marker_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) marker_la_SOURCES = marker.c marker-quota.c marker-quota-helper.c \ marker-common.c marker_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = marker-mem-types.h marker.h marker-quota.h \ marker-quota-helper.h marker-common.h \ $(top_builddir)/xlators/lib/src/libxlator.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/xlators/lib/src AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/marker/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/marker/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } marker.la: $(marker_la_OBJECTS) $(marker_la_DEPENDENCIES) $(EXTRA_marker_la_DEPENDENCIES) $(AM_V_CCLD)$(marker_la_LINK) $(am_marker_la_rpath) $(marker_la_OBJECTS) $(marker_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marker-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marker-quota-helper.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marker-quota.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marker.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023776 xustar000000000000000030 mtime=1699284265.675027456 30 atime=1699284276.418059814 30 ctime=1699284303.704141999 glusterfs-11.1/xlators/features/marker/src/Makefile.am0000664000175100017510000000130414522202451024253 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = marker.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features marker_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) marker_la_SOURCES = marker.c marker-quota.c marker-quota-helper.c \ marker-common.c marker_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = marker-mem-types.h marker.h marker-quota.h \ marker-quota-helper.h marker-common.h \ $(top_builddir)/xlators/lib/src/libxlator.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/xlators/lib/src AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/marker-common.h0000644000000000000000000000013214522202451024662 xustar000000000000000030 mtime=1699284265.675027456 30 atime=1699284265.675027456 30 ctime=1699284303.717142038 glusterfs-11.1/xlators/features/marker/src/marker-common.h0000664000175100017510000000102514522202451025137 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _MARKER_COMMON_H #define _MARKER_COMMON_H #include "marker.h" int32_t marker_force_inode_ctx_get(inode_t *, xlator_t *, marker_inode_ctx_t **); #endif glusterfs-11.1/xlators/features/marker/src/PaxHeaders.9031/marker-mem-types.h0000644000000000000000000000013214522202451025312 xustar000000000000000030 mtime=1699284265.675027456 30 atime=1699284265.675027456 30 ctime=1699284303.706142005 glusterfs-11.1/xlators/features/marker/src/marker-mem-types.h0000664000175100017510000000157314522202451025577 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __MARKER_MEM_TYPES_H__ #define __MARKER_MEM_TYPES_H__ #include enum gf_marker_mem_types_ { /* Those are used by ALLOCATE_OR_GOTO macro */ gf_marker_mt_marker_conf_t = gf_common_mt_end + 1, gf_marker_mt_loc_t, gf_marker_mt_volume_mark, gf_marker_mt_int64_t, gf_marker_mt_quota_inode_ctx_t, gf_marker_mt_marker_inode_ctx_t, gf_marker_mt_inode_contribution_t, gf_marker_mt_quota_meta_t, gf_marker_mt_quota_synctask_t, gf_marker_mt_end }; #endif glusterfs-11.1/xlators/features/marker/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023224 xustar000000000000000030 mtime=1699284276.407059781 30 atime=1699284290.369101835 30 ctime=1699284303.653141845 glusterfs-11.1/xlators/features/marker/Makefile.in0000664000175100017510000005272414522202464023515 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/marker DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/marker/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/marker/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/marker/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023207 xustar000000000000000030 mtime=1699284265.675027456 30 atime=1699284276.383059709 30 ctime=1699284303.655141851 glusterfs-11.1/xlators/features/marker/Makefile.am0000664000175100017510000000003414522202451023463 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/sdfs0000644000000000000000000000013214522202521020552 xustar000000000000000030 mtime=1699284305.256146673 30 atime=1699284309.686160016 30 ctime=1699284305.256146673 glusterfs-11.1/xlators/features/sdfs/0002775000175100017510000000000014522202521021110 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/sdfs/PaxHeaders.9031/src0000644000000000000000000000012614522202521021344 xustar000000000000000028 mtime=1699284305.2981468 30 atime=1699284309.686160016 28 ctime=1699284305.2981468 glusterfs-11.1/xlators/features/sdfs/src/0002775000175100017510000000000014522202521021677 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/sdfs/src/PaxHeaders.9031/sdfs.h0000644000000000000000000000013114522202451022527 xustar000000000000000030 mtime=1699284265.687027492 30 atime=1699284265.687027492 29 ctime=1699284305.29514679 glusterfs-11.1/xlators/features/sdfs/src/sdfs.h0000664000175100017510000000311514522202451023007 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "sdfs-messages.h" #include #define SDFS_LOCK_COUNT_MAX 2 typedef struct { loc_t parent_loc; char *basename; int locked[SDFS_LOCK_COUNT_MAX]; } sdfs_entry_lock_t; typedef struct { sdfs_entry_lock_t entrylk[SDFS_LOCK_COUNT_MAX]; int lock_count; } sdfs_lock_t; struct sdfs_local { call_frame_t *main_frame; loc_t loc; loc_t parent_loc; call_stub_t *stub; sdfs_lock_t *lock; int op_ret; int op_errno; gf_atomic_t call_cnt; }; typedef struct sdfs_local sdfs_local_t; #define SDFS_STACK_DESTROY(frame) \ do { \ sdfs_local_t *__local = NULL; \ __local = frame->local; \ frame->local = NULL; \ gf_client_unref(frame->root->client); \ STACK_DESTROY(frame->root); \ sdfs_local_cleanup(__local); \ } while (0) glusterfs-11.1/xlators/features/sdfs/src/PaxHeaders.9031/sdfs-messages.h0000644000000000000000000000013214522202451024335 xustar000000000000000030 mtime=1699284265.687027492 30 atime=1699284265.687027492 30 ctime=1699284305.296146794 glusterfs-11.1/xlators/features/sdfs/src/sdfs-messages.h0000664000175100017510000000447414522202451024625 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _DFS_MESSAGES_H_ #define _DFS_MESSAGES_H_ #include /* file bit-rot-bitd-messages.h * brief SDFS log-message IDs and their descriptions */ /* NOTE: Rules for message additions * 1) Each instance of a message is _better_ left with a unique message ID, even * if the message format is the same. Reasoning is that, if the message * format needs to change in one instance, the other instances are not * impacted or the new change does not change the ID of the instance being * modified. * 2) Addition of a message, * - Should increment the GLFS_NUM_MESSAGES * - Append to the list of messages defined, towards the end * - Retain macro naming as glfs_msg_X (for redability across developers) * NOTE: Rules for message format modifications * 3) Check acorss the code if the message ID macro in question is reused * anywhere. If reused then then the modifications should ensure correctness * everywhere, or needs a new message ID as (1) above was not adhered to. If * not used anywhere, proceed with the required modification. * NOTE: Rules for message deletion * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used * anywhere, then can be deleted, but will leave a hole by design, as * addition rules specify modification to the end of the list and not filling * holes. */ #define GLFS_SDFS_BASE GLFS_MSGID_COMP_SDFS #define GLFS_SDFS_NUM_MESSAGES 2 #define GLFS_MSGID_END (GLFS_SDFS_BASE + GLFS_SDFS_NUM_MESSAGES + 1) /* Messaged with message IDs */ #define glfs_msg_start_x GLFS_DFS_BASE, "Invalid: Start of messages" /*------------*/ #define SDFS_MSG_ENTRYLK_ERROR (GLFS_SDFS_BASE + 1) /*! * @messageid * @diagnosis * @recommendedaction * */ #define SDFS_MSG_MKDIR_ERROR (GLFS_SDFS_BASE + 2) /*! * @messageid * @diagnosis * @recommendedaction * */ /*------------*/ #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" #endif /* !_SDFS_MESSAGES_H_ */ glusterfs-11.1/xlators/features/sdfs/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023471 xustar000000000000000030 mtime=1699284276.962061453 30 atime=1699284290.476102157 30 ctime=1699284305.292146782 glusterfs-11.1/xlators/features/sdfs/src/Makefile.in0000664000175100017510000005750014522202464023757 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/sdfs/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) sdfs_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_sdfs_la_OBJECTS = sdfs.lo sdfs_la_OBJECTS = $(am_sdfs_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = sdfs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(sdfs_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_sdfs_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(sdfs_la_SOURCES) DIST_SOURCES = $(sdfs_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = sdfs.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features sdfs_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) sdfs_la_SOURCES = sdfs.c sdfs_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = sdfs.h sdfs-messages.h $(top_builddir)/xlators/lib/src/libxlator.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/lib/src \ -I$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/sdfs/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/sdfs/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } sdfs.la: $(sdfs_la_OBJECTS) $(sdfs_la_DEPENDENCIES) $(EXTRA_sdfs_la_DEPENDENCIES) $(AM_V_CCLD)$(sdfs_la_LINK) $(am_sdfs_la_rpath) $(sdfs_la_OBJECTS) $(sdfs_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdfs.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/sdfs/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023454 xustar000000000000000030 mtime=1699284265.687027492 30 atime=1699284276.923061336 30 ctime=1699284305.294146788 glusterfs-11.1/xlators/features/sdfs/src/Makefile.am0000664000175100017510000000115114522202451023731 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = sdfs.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features sdfs_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) sdfs_la_SOURCES = sdfs.c sdfs_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = sdfs.h sdfs-messages.h $(top_builddir)/xlators/lib/src/libxlator.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/lib/src \ -I$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/sdfs/src/PaxHeaders.9031/sdfs.c0000644000000000000000000000013014522202451022521 xustar000000000000000030 mtime=1699284265.687027492 30 atime=1699284265.687027492 28 ctime=1699284305.2981468 glusterfs-11.1/xlators/features/sdfs/src/sdfs.c0000664000175100017510000011333514522202451023010 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "sdfs.h" static int sdfs_frame_return(call_frame_t *frame) { sdfs_local_t *local = NULL; if (!frame) return -1; local = frame->local; return GF_ATOMIC_DEC(local->call_cnt); } static void sdfs_lock_free(sdfs_entry_lock_t *entrylk) { if (entrylk == NULL) goto out; loc_wipe(&entrylk->parent_loc); GF_FREE(entrylk->basename); out: return; } static void sdfs_lock_array_free(sdfs_lock_t *lock) { sdfs_entry_lock_t *entrylk = NULL; int i = 0; if (lock == NULL) goto out; for (i = 0; i < lock->lock_count; i++) { entrylk = &lock->entrylk[i]; sdfs_lock_free(entrylk); } out: return; } static void sdfs_local_cleanup(sdfs_local_t *local) { if (!local) return; loc_wipe(&local->loc); loc_wipe(&local->parent_loc); if (local->stub) { call_stub_destroy(local->stub); local->stub = NULL; } sdfs_lock_array_free(local->lock); GF_FREE(local->lock); mem_put(local); } static int sdfs_build_parent_loc(loc_t *parent, loc_t *child) { int ret = -1; char *path = NULL; if (!child->parent) { goto out; } parent->inode = inode_ref(child->parent); path = gf_strdup(child->path); if (!path) { ret = -ENOMEM; goto out; } parent->path = dirname(path); if (!parent->path) { goto out; } gf_uuid_copy(parent->gfid, child->pargfid); return 0; out: GF_FREE(path); return ret; } static sdfs_local_t * sdfs_local_init(call_frame_t *frame, xlator_t *this) { sdfs_local_t *local = NULL; local = mem_get0(this->local_pool); if (!local) goto out; frame->local = local; out: return local; } static int sdfs_get_new_frame_common(call_frame_t *frame, call_frame_t **new_frame) { int ret = -1; sdfs_local_t *local = NULL; client_t *client = NULL; *new_frame = copy_frame(frame); if (!*new_frame) { goto err; } client = frame->root->client; gf_client_ref(client); (*new_frame)->root->client = client; local = sdfs_local_init(*new_frame, THIS); if (!local) { goto err; } local->main_frame = frame; /*Set unique lk-owner for the fop*/ set_lk_owner_from_ptr(&(*new_frame)->root->lk_owner, (*new_frame)->root); ret = 0; err: if ((ret == -1) && (*new_frame)) { SDFS_STACK_DESTROY((*new_frame)); *new_frame = NULL; } return ret; } static int sdfs_get_new_frame(call_frame_t *frame, loc_t *loc, call_frame_t **new_frame) { int ret = -1; sdfs_local_t *local = NULL; ret = sdfs_get_new_frame_common(frame, new_frame); if (ret < 0) { goto err; } local = (*new_frame)->local; ret = sdfs_build_parent_loc(&local->parent_loc, loc); if (ret) { goto err; } ret = loc_copy(&local->loc, loc); if (ret == -1) { goto err; } ret = 0; err: if (ret && (*new_frame)) { SDFS_STACK_DESTROY((*new_frame)); *new_frame = NULL; ret = -1; } return ret; } static int sdfs_get_new_frame_readdirp(call_frame_t *frame, fd_t *fd, call_frame_t **new_frame) { int ret = -1; sdfs_local_t *local = NULL; ret = sdfs_get_new_frame_common(frame, new_frame); if (ret < 0) { goto err; } local = (*new_frame)->local; local->parent_loc.inode = inode_ref(fd->inode); gf_uuid_copy(local->parent_loc.gfid, fd->inode->gfid); ret = 0; err: return ret; } int sdfs_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { sdfs_local_t *local = NULL; call_stub_t *stub = NULL; local = frame->local; local->op_ret = op_ret; local->op_errno = op_errno; if (local->stub) { stub = local->stub; local->stub = NULL; call_resume(stub); } else { if (op_ret < 0) gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Unlocking entry lock failed for %s", local->loc.name); SDFS_STACK_DESTROY(frame); } return 0; } int sdfs_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { sdfs_local_t *local = NULL; local = frame->local; STACK_UNWIND_STRICT(mkdir, local->main_frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); local->main_frame = NULL; STACK_WIND(frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); return 0; } int sdfs_mkdir_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { sdfs_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; int op_errno = -1; local = frame->local; gf_uuid_unparse(loc->pargfid, gfid); if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed for directory %s " "with parent gfid %s", local->loc.name, gfid); op_errno = local->op_errno; goto err; } STACK_WIND(frame, sdfs_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; err: STACK_UNWIND_STRICT(mkdir, local->main_frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); local->main_frame = NULL; SDFS_STACK_DESTROY(frame); return 0; } int sdfs_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { sdfs_local_t *local = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; int op_errno = 0; if (-1 == sdfs_get_new_frame(frame, loc, &new_frame)) { op_errno = ENOMEM; goto err; } stub = fop_mkdir_stub(new_frame, sdfs_mkdir_helper, loc, mode, umask, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local = new_frame->local; local->stub = stub; STACK_WIND(new_frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_LOCK, ENTRYLK_WRLCK, xdata); return 0; err: STACK_UNWIND_STRICT(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int sdfs_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { sdfs_local_t *local = NULL; local = frame->local; STACK_UNWIND_STRICT(rmdir, local->main_frame, op_ret, op_errno, preparent, postparent, xdata); local->main_frame = NULL; STACK_WIND(frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); return 0; } int sdfs_rmdir_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { sdfs_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; gf_uuid_unparse(loc->pargfid, gfid); if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed for directory %s " "with parent gfid %s", local->loc.name, gfid); goto err; } STACK_WIND(frame, sdfs_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); return 0; err: STACK_UNWIND_STRICT(rmdir, local->main_frame, -1, local->op_errno, NULL, NULL, NULL); local->main_frame = NULL; SDFS_STACK_DESTROY(frame); return 0; } int sdfs_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { sdfs_local_t *local = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; int op_errno = 0; if (-1 == sdfs_get_new_frame(frame, loc, &new_frame)) { op_errno = ENOMEM; goto err; } stub = fop_rmdir_stub(new_frame, sdfs_rmdir_helper, loc, flags, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local = new_frame->local; local->stub = stub; STACK_WIND(new_frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_LOCK, ENTRYLK_WRLCK, xdata); return 0; err: STACK_UNWIND_STRICT(rmdir, frame, -1, op_errno, NULL, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int sdfs_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { sdfs_local_t *local = NULL; local = frame->local; STACK_UNWIND_STRICT(create, local->main_frame, op_ret, op_errno, fd, inode, stbuf, preparent, postparent, xdata); local->main_frame = NULL; STACK_WIND(frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); return 0; } int sdfs_create_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { sdfs_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; gf_uuid_unparse(loc->pargfid, gfid); if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed for directory %s " "with parent gfid %s", local->loc.name, gfid); goto err; } STACK_WIND(frame, sdfs_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; err: STACK_UNWIND_STRICT(create, local->main_frame, -1, local->op_errno, NULL, NULL, NULL, NULL, NULL, NULL); local->main_frame = NULL; SDFS_STACK_DESTROY(frame); return 0; } int sdfs_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { sdfs_local_t *local = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; int op_errno = 0; if (-1 == sdfs_get_new_frame(frame, loc, &new_frame)) { op_errno = ENOMEM; goto err; } stub = fop_create_stub(new_frame, sdfs_create_helper, loc, flags, mode, umask, fd, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local = new_frame->local; local->stub = stub; STACK_WIND(new_frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_LOCK, ENTRYLK_WRLCK, xdata); return 0; err: STACK_UNWIND_STRICT(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int sdfs_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { sdfs_local_t *local = NULL; local = frame->local; STACK_UNWIND_STRICT(unlink, local->main_frame, op_ret, op_errno, preparent, postparent, xdata); local->main_frame = NULL; STACK_WIND(frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); return 0; } int sdfs_unlink_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { sdfs_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; gf_uuid_unparse(loc->pargfid, gfid); if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed for directory %s " "with parent gfid %s", local->loc.name, gfid); goto err; } STACK_WIND(frame, sdfs_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, flags, xdata); return 0; err: STACK_UNWIND_STRICT(unlink, local->main_frame, -1, local->op_errno, NULL, NULL, NULL); local->main_frame = NULL; SDFS_STACK_DESTROY(frame); return 0; } int sdfs_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { sdfs_local_t *local = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; int op_errno = 0; if (-1 == sdfs_get_new_frame(frame, loc, &new_frame)) { op_errno = ENOMEM; goto err; } stub = fop_unlink_stub(new_frame, sdfs_unlink_helper, loc, flags, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local = new_frame->local; local->stub = stub; STACK_WIND(new_frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_LOCK, ENTRYLK_WRLCK, xdata); return 0; err: STACK_UNWIND_STRICT(unlink, frame, -1, op_errno, NULL, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int sdfs_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { sdfs_local_t *local = NULL; local = frame->local; STACK_UNWIND_STRICT(link, local->main_frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); local->main_frame = NULL; STACK_WIND(frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); return 0; } int sdfs_symlink_helper(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { sdfs_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; gf_uuid_unparse(loc->pargfid, gfid); if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed for directory %s " "with parent gfid %s", local->loc.name, gfid); goto err; } STACK_WIND(frame, sdfs_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkname, loc, umask, xdata); return 0; err: STACK_UNWIND_STRICT(link, local->main_frame, -1, local->op_errno, NULL, NULL, NULL, NULL, NULL); local->main_frame = NULL; SDFS_STACK_DESTROY(frame); return 0; } int sdfs_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { sdfs_local_t *local = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; int op_errno = 0; if (-1 == sdfs_get_new_frame(frame, loc, &new_frame)) { op_errno = ENOMEM; goto err; } stub = fop_symlink_stub(new_frame, sdfs_symlink_helper, linkname, loc, umask, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local = new_frame->local; local->stub = stub; STACK_WIND(new_frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_LOCK, ENTRYLK_WRLCK, xdata); return 0; err: STACK_UNWIND_STRICT(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int sdfs_common_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { sdfs_local_t *local = NULL; int this_call_cnt = 0; int lk_index = 0; sdfs_lock_t *locks = NULL; call_stub_t *stub = NULL; local = frame->local; locks = local->lock; lk_index = (long)cookie; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; } else { locks->entrylk->locked[lk_index] = _gf_true; } this_call_cnt = sdfs_frame_return(frame); if (this_call_cnt > 0) { gf_log(this->name, GF_LOG_DEBUG, "As there are more callcnt (%d) returning without WIND", this_call_cnt); return 0; } if (local->stub) { stub = local->stub; local->stub = NULL; call_resume(stub); } else { if (local->op_ret < 0) gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "unlocking entry lock failed "); SDFS_STACK_DESTROY(frame); } return 0; } int sdfs_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { sdfs_local_t *local = NULL; sdfs_lock_t *lock = NULL; int i = 0; int lock_count = 0; local = frame->local; lock = local->lock; STACK_UNWIND_STRICT(link, local->main_frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); local->main_frame = NULL; lock_count = lock->lock_count; for (i = 0; i < lock_count; i++) { STACK_WIND_COOKIE(frame, sdfs_common_entrylk_cbk, (void *)(long)i, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &lock->entrylk[i].parent_loc, lock->entrylk[i].basename, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); } return 0; } int sdfs_link_helper(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { sdfs_local_t *local = NULL; sdfs_lock_t *locks = NULL; gf_boolean_t stack_destroy = _gf_true; int lock_count = 0; int i = 0; local = frame->local; locks = local->lock; if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed"); goto err; } STACK_WIND(frame, sdfs_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; err: STACK_UNWIND_STRICT(link, local->main_frame, -1, local->op_errno, NULL, NULL, NULL, NULL, NULL); local->main_frame = NULL; for (i = 0; i < locks->lock_count && locks->entrylk->locked[i]; i++) { lock_count++; } GF_ATOMIC_INIT(local->call_cnt, lock_count); for (i = 0; i < lock_count; i++) { if (!locks->entrylk->locked[i]) { lock_count++; continue; } stack_destroy = _gf_false; STACK_WIND(frame, sdfs_common_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &locks->entrylk[i].parent_loc, locks->entrylk[i].basename, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); } if (stack_destroy) SDFS_STACK_DESTROY(frame); return 0; } static int sdfs_init_entry_lock(sdfs_entry_lock_t *lock, loc_t *loc) { int ret = 0; ret = sdfs_build_parent_loc(&lock->parent_loc, loc); if (ret) return -1; lock->basename = gf_strdup(loc->name); if (!lock->basename) return -1; return 0; } int sdfs_entry_lock_cmp(const void *l1, const void *l2) { const sdfs_entry_lock_t *r1 = l1; const sdfs_entry_lock_t *r2 = l2; int ret = 0; uuid_t gfid1 = {0}; uuid_t gfid2 = {0}; loc_gfid((loc_t *)&r1->parent_loc, gfid1); loc_gfid((loc_t *)&r2->parent_loc, gfid2); ret = gf_uuid_compare(gfid1, gfid2); /*Entrylks with NULL basename are the 'smallest'*/ if (ret == 0) { if (!r1->basename) return -1; if (!r2->basename) return 1; ret = strcmp(r1->basename, r2->basename); } if (ret <= 0) return -1; else return 1; } int sdfs_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { sdfs_local_t *local = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; sdfs_lock_t *lock = NULL; client_t *client = NULL; int ret = 0; int op_errno = ENOMEM; new_frame = copy_frame(frame); if (!new_frame) { op_errno = ENOMEM; goto err; } /*Set unique lk-owner for the fop*/ set_lk_owner_from_ptr(&new_frame->root->lk_owner, new_frame->root); gf_client_ref(client); new_frame->root->client = client; local = sdfs_local_init(new_frame, this); if (!local) { op_errno = ENOMEM; goto err; } local->main_frame = frame; lock = GF_CALLOC(1, sizeof(*lock), gf_common_mt_char); if (!lock) goto err; local->lock = lock; ret = sdfs_init_entry_lock(&lock->entrylk[0], newloc); if (ret) goto err; ++lock->lock_count; local->lock = lock; GF_ATOMIC_INIT(local->call_cnt, lock->lock_count); ret = loc_copy(&local->loc, newloc); if (ret == -1) { op_errno = ENOMEM; goto err; } stub = fop_link_stub(new_frame, sdfs_link_helper, oldloc, newloc, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local->stub = stub; STACK_WIND_COOKIE(new_frame, sdfs_common_entrylk_cbk, 0, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &lock->entrylk[0].parent_loc, lock->entrylk[0].basename, ENTRYLK_LOCK, ENTRYLK_WRLCK, xdata); return 0; err: STACK_UNWIND_STRICT(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int sdfs_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { sdfs_local_t *local = NULL; local = frame->local; STACK_UNWIND_STRICT(mknod, local->main_frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); local->main_frame = NULL; STACK_WIND(frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); return 0; } int sdfs_mknod_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { sdfs_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; gf_uuid_unparse(loc->pargfid, gfid); if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed for directory %s " "with parent gfid %s", local->loc.name, gfid); goto err; } STACK_WIND(frame, sdfs_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; err: STACK_UNWIND_STRICT(mknod, local->main_frame, -1, local->op_errno, NULL, NULL, NULL, NULL, NULL); local->main_frame = NULL; SDFS_STACK_DESTROY(frame); return 0; } int sdfs_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { sdfs_local_t *local = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; int op_errno = 0; if (-1 == sdfs_get_new_frame(frame, loc, &new_frame)) { op_errno = ENOMEM; goto err; } stub = fop_mknod_stub(new_frame, sdfs_mknod_helper, loc, mode, rdev, umask, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local = new_frame->local; local->stub = stub; STACK_WIND(new_frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_LOCK, ENTRYLK_WRLCK, xdata); return 0; err: STACK_UNWIND_STRICT(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int sdfs_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { sdfs_local_t *local = NULL; sdfs_lock_t *lock = NULL; int i = 0; int call_cnt = 0; local = frame->local; lock = local->lock; GF_ATOMIC_INIT(local->call_cnt, lock->lock_count); STACK_UNWIND_STRICT(rename, local->main_frame, op_ret, op_errno, stbuf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); local->main_frame = NULL; call_cnt = GF_ATOMIC_GET(local->call_cnt); for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(frame, sdfs_common_entrylk_cbk, (void *)(long)i, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &lock->entrylk[i].parent_loc, lock->entrylk[i].basename, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); } return 0; } int sdfs_rename_helper(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { sdfs_local_t *local = NULL; sdfs_lock_t *lock = NULL; gf_boolean_t stack_destroy = _gf_true; int lock_count = 0; int i = 0; local = frame->local; lock = local->lock; if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed "); goto err; } STACK_WIND(frame, sdfs_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; err: STACK_UNWIND_STRICT(rename, local->main_frame, -1, local->op_errno, NULL, NULL, NULL, NULL, NULL, NULL); local->main_frame = NULL; for (i = 0; i < lock->lock_count && lock->entrylk->locked[i]; i++) { lock_count++; } GF_ATOMIC_INIT(local->call_cnt, lock_count); for (i = 0; i < lock_count; i++) { if (!lock->entrylk->locked[i]) { lock_count++; continue; } stack_destroy = _gf_false; STACK_WIND(frame, sdfs_common_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &lock->entrylk[i].parent_loc, lock->entrylk[i].basename, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, xdata); } if (stack_destroy) SDFS_STACK_DESTROY(frame); return 0; } int sdfs_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { sdfs_local_t *local = NULL; sdfs_lock_t *lock = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; client_t *client = NULL; int ret = 0; int op_errno = ENOMEM; int i = 0; int call_cnt = 0; new_frame = copy_frame(frame); if (!new_frame) { op_errno = ENOMEM; goto err; } /*Set unique lk-owner for the fop*/ set_lk_owner_from_ptr(&new_frame->root->lk_owner, new_frame->root); gf_client_ref(client); new_frame->root->client = client; local = sdfs_local_init(new_frame, this); if (!local) { op_errno = ENOMEM; goto err; } local->main_frame = frame; lock = GF_CALLOC(1, sizeof(*lock), gf_common_mt_char); if (!lock) goto err; local->lock = lock; ret = sdfs_init_entry_lock(&lock->entrylk[0], oldloc); if (ret) goto err; lock->entrylk->locked[0] = _gf_false; ++lock->lock_count; ret = sdfs_init_entry_lock(&lock->entrylk[1], newloc); if (ret) goto err; lock->entrylk->locked[1] = _gf_false; ++lock->lock_count; qsort(lock->entrylk, lock->lock_count, sizeof(*lock->entrylk), sdfs_entry_lock_cmp); local->lock = lock; GF_ATOMIC_INIT(local->call_cnt, lock->lock_count); stub = fop_rename_stub(new_frame, sdfs_rename_helper, oldloc, newloc, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local->stub = stub; call_cnt = GF_ATOMIC_GET(local->call_cnt); for (i = 0; i < call_cnt; i++) { STACK_WIND_COOKIE(new_frame, sdfs_common_entrylk_cbk, (void *)(long)i, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &lock->entrylk[i].parent_loc, lock->entrylk[i].basename, ENTRYLK_LOCK, ENTRYLK_WRLCK, xdata); } return 0; err: STACK_UNWIND_STRICT(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int sdfs_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xdata, struct iatt *postparent) { sdfs_local_t *local = NULL; local = frame->local; if (!local->loc.parent) { sdfs_local_cleanup(local); frame->local = NULL; STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, stbuf, xdata, postparent); return 0; } STACK_UNWIND_STRICT(lookup, local->main_frame, op_ret, op_errno, inode, stbuf, xdata, postparent); local->main_frame = NULL; STACK_WIND(frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_UNLOCK, ENTRYLK_RDLCK, xdata); return 0; } int sdfs_lookup_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { sdfs_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; gf_uuid_unparse(loc->pargfid, gfid); if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed for directory %s " "with parent gfid %s", local->loc.name, gfid); goto err; } STACK_WIND(frame, sdfs_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); return 0; err: STACK_UNWIND_STRICT(lookup, local->main_frame, -1, local->op_errno, NULL, NULL, NULL, NULL); local->main_frame = NULL; SDFS_STACK_DESTROY(frame); return 0; } int sdfs_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { sdfs_local_t *local = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; int op_errno = 0; if (!loc->parent) { local = sdfs_local_init(frame, this); if (!local) { op_errno = ENOMEM; goto err; } STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); return 0; } if (-1 == sdfs_get_new_frame(frame, loc, &new_frame)) { op_errno = ENOMEM; goto err; } stub = fop_lookup_stub(new_frame, sdfs_lookup_helper, loc, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local = new_frame->local; local->stub = stub; STACK_WIND(new_frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, local->loc.name, ENTRYLK_LOCK, ENTRYLK_RDLCK, xdata); return 0; err: STACK_UNWIND_STRICT(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int32_t sdfs_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { sdfs_local_t *local = NULL; local = frame->local; STACK_UNWIND_STRICT(readdirp, local->main_frame, op_ret, op_errno, entries, xdata); local->main_frame = NULL; STACK_WIND(frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, NULL, ENTRYLK_UNLOCK, ENTRYLK_RDLCK, xdata); return 0; } int32_t sdfs_readdirp_helper(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { sdfs_local_t *local = NULL; char gfid[GF_UUID_BUF_SIZE] = {0}; local = frame->local; gf_uuid_unparse(fd->inode->gfid, gfid); if (local->op_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, SDFS_MSG_ENTRYLK_ERROR, "Acquiring entry lock failed for directory %s " "with parent gfid %s", local->loc.name, gfid); goto err; } STACK_WIND(frame, sdfs_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata); return 0; err: STACK_UNWIND_STRICT(readdirp, local->main_frame, -1, local->op_errno, NULL, NULL); local->main_frame = NULL; SDFS_STACK_DESTROY(frame); return 0; } int32_t sdfs_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { sdfs_local_t *local = NULL; call_frame_t *new_frame = NULL; call_stub_t *stub = NULL; int op_errno = 0; if (-1 == sdfs_get_new_frame_readdirp(frame, fd, &new_frame)) { op_errno = ENOMEM; goto err; } stub = fop_readdirp_stub(new_frame, sdfs_readdirp_helper, fd, size, off, xdata); if (!stub) { op_errno = ENOMEM; goto err; } local = new_frame->local; local->stub = stub; STACK_WIND(new_frame, sdfs_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, this->name, &local->parent_loc, NULL, ENTRYLK_LOCK, ENTRYLK_RDLCK, xdata); return 0; err: STACK_UNWIND_STRICT(readdirp, frame, -1, op_errno, NULL, NULL); if (new_frame) SDFS_STACK_DESTROY(new_frame); return 0; } int init(xlator_t *this) { int ret = -1; if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "'dentry-fop-serializer' not configured with exactly one child"); goto out; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); } this->local_pool = mem_pool_new(sdfs_local_t, 512); if (!this->local_pool) { goto out; } GF_OPTION_INIT("pass-through", this->pass_through, bool, out); ret = 0; out: return ret; } int reconfigure(xlator_t *this, dict_t *options) { int ret = -1; GF_OPTION_RECONF("pass-through", this->pass_through, options, bool, out); ret = 0; out: return ret; } void fini(xlator_t *this) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; return; } struct xlator_fops fops = { .mkdir = sdfs_mkdir, .rmdir = sdfs_rmdir, .create = sdfs_create, .unlink = sdfs_unlink, .symlink = sdfs_symlink, .link = sdfs_link, .mknod = sdfs_mknod, .rename = sdfs_rename, .lookup = sdfs_lookup, .readdirp = sdfs_readdirp, }; struct xlator_cbks cbks; struct volume_options options[] = { {.key = {"pass-through"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "true", .op_version = {GD_OP_VERSION_4_1_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_CLIENT_OPT, .tags = {"sdfs"}, .description = "Enable/Disable dentry serialize functionality"}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .op_version = {GD_OP_VERSION_4_0_0}, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "sdfs", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/features/sdfs/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464022702 xustar000000000000000030 mtime=1699284276.913061305 30 atime=1699284290.455102094 30 ctime=1699284305.251146658 glusterfs-11.1/xlators/features/sdfs/Makefile.in0000664000175100017510000005271614522202464023174 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/sdfs DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/sdfs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/sdfs/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/sdfs/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451022665 xustar000000000000000030 mtime=1699284265.687027492 30 atime=1699284276.889061233 30 ctime=1699284305.252146661 glusterfs-11.1/xlators/features/sdfs/Makefile.am0000664000175100017510000000003414522202451023141 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/quiesce0000644000000000000000000000013214522202517021256 xustar000000000000000030 mtime=1699284303.563141574 30 atime=1699284309.686160016 30 ctime=1699284303.563141574 glusterfs-11.1/xlators/features/quiesce/0002775000175100017510000000000014522202517021614 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/quiesce/PaxHeaders.9031/src0000644000000000000000000000013214522202517022045 xustar000000000000000030 mtime=1699284303.613141725 30 atime=1699284309.686160016 30 ctime=1699284303.613141725 glusterfs-11.1/xlators/features/quiesce/src/0002775000175100017510000000000014522202517022403 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/quiesce/src/PaxHeaders.9031/quiesce-mem-types.h0000644000000000000000000000013214522202451025644 xustar000000000000000030 mtime=1699284265.681027474 30 atime=1699284265.681027474 30 ctime=1699284303.609141713 glusterfs-11.1/xlators/features/quiesce/src/quiesce-mem-types.h0000664000175100017510000000114714522202451026126 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __QUIESCE_MEM_TYPES_H__ #define __QUIESCE_MEM_TYPES_H__ #include enum gf_quiesce_mem_types_ { gf_quiesce_mt_priv_t = gf_common_mt_end + 1, gf_quiesce_mt_failover_hosts, gf_quiesce_mt_end }; #endif glusterfs-11.1/xlators/features/quiesce/src/PaxHeaders.9031/quiesce.h0000644000000000000000000000013214522202451023726 xustar000000000000000030 mtime=1699284265.682027477 30 atime=1699284265.682027477 30 ctime=1699284303.607141707 glusterfs-11.1/xlators/features/quiesce/src/quiesce.h0000664000175100017510000000273214522202451024211 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __QUIESCE_H__ #define __QUIESCE_H__ #include "quiesce-mem-types.h" #include "quiesce-messages.h" #include #define GF_FOPS_EXPECTED_IN_PARALLEL 512 typedef struct { struct list_head list; char *addr; gf_boolean_t tried; /* indicates attempted connecting */ } quiesce_failover_hosts_t; typedef struct { gf_timer_t *timer; gf_boolean_t pass_through; gf_lock_t lock; struct list_head req; int queue_size; pthread_t thr; struct mem_pool *local_pool; time_t timeout; char *failover_hosts; struct list_head failover_list; } quiesce_priv_t; typedef struct { fd_t *fd; char *name; char *volname; loc_t loc; off_t size; off_t offset; mode_t mode; int32_t flag; struct iatt stbuf; struct iovec *vector; struct iobref *iobref; dict_t *dict; struct gf_flock flock; entrylk_cmd cmd; entrylk_type type; gf_xattrop_flags_t xattrop_flags; int32_t wbflags; uint32_t io_flag; /* for fallocate */ size_t len; /* for lseek */ gf_seek_what_t what; } quiesce_local_t; #endif glusterfs-11.1/xlators/features/quiesce/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202464024167 xustar000000000000000030 mtime=1699284276.708060688 29 atime=1699284290.65310269 30 ctime=1699284303.604141697 glusterfs-11.1/xlators/features/quiesce/src/Makefile.in0000664000175100017510000005731514522202464024462 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/quiesce/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) quiesce_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_quiesce_la_OBJECTS = quiesce.lo quiesce_la_OBJECTS = $(am_quiesce_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = quiesce_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(quiesce_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(quiesce_la_SOURCES) DIST_SOURCES = $(quiesce_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = quiesce.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features quiesce_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) quiesce_la_SOURCES = quiesce.c quiesce_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = quiesce.h quiesce-mem-types.h quiesce-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/quiesce/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/quiesce/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } quiesce.la: $(quiesce_la_OBJECTS) $(quiesce_la_DEPENDENCIES) $(EXTRA_quiesce_la_DEPENDENCIES) $(AM_V_CCLD)$(quiesce_la_LINK) -rpath $(xlatordir) $(quiesce_la_OBJECTS) $(quiesce_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quiesce.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/quiesce/src/PaxHeaders.9031/quiesce-messages.h0000644000000000000000000000013214522202451025533 xustar000000000000000030 mtime=1699284265.681027474 30 atime=1699284265.681027474 30 ctime=1699284303.611141719 glusterfs-11.1/xlators/features/quiesce/src/quiesce-messages.h0000664000175100017510000000221114522202451026006 0ustar00jenkinsjenkins00000000000000/* * Copyright (c) 2016 Red Hat, Inc. * This file is part of GlusterFS. * * This file is licensed to you under your choice of the GNU Lesser * General Public License, version 3 or any later version (LGPLv3 or * later), or the GNU General Public License, version 2 (GPLv2), in all * cases as published by the Free Software Foundation. */ #ifndef __QUIESCE_MESSAGES_H__ #define __QUIESCE_MESSAGES_H__ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ // clang-format off GLFS_COMPONENT(QUIESCE); GLFS_NEW(QUIESCE, QUIESCE_MSG_INVAL_HOST, "Invalid internet address", 1, GLFS_STR(address) ) GLFS_NEW(QUIESCE, QUIESCE_MSG_FAILOVER_FAILED, "Failed to initiate failover", 2, GLFS_STR(host), GLFS_ERR(error) ) // clang-format on #endif /* __NL_CACHE_MESSAGES_H__ */ glusterfs-11.1/xlators/features/quiesce/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024153 xustar000000000000000030 mtime=1699284265.681027474 30 atime=1699284276.671060576 30 ctime=1699284303.606141704 glusterfs-11.1/xlators/features/quiesce/src/Makefile.am0000664000175100017510000000076014522202451024435 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = quiesce.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features quiesce_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) quiesce_la_SOURCES = quiesce.c quiesce_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = quiesce.h quiesce-mem-types.h quiesce-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/quiesce/src/PaxHeaders.9031/quiesce.c0000644000000000000000000000013214522202451023721 xustar000000000000000030 mtime=1699284265.682027477 30 atime=1699284265.681027474 30 ctime=1699284303.613141725 glusterfs-11.1/xlators/features/quiesce/src/quiesce.c0000664000175100017510000022147714522202451024215 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "quiesce.h" #include /* TODO: */ /* Think about 'writev/_*_lk/setattr/xattrop/' fops to do re-transmittion */ void gf_quiesce_timeout(void *data); /* Quiesce Specific Functions */ void gf_quiesce_local_wipe(xlator_t *this, quiesce_local_t *local) { if (!local || !this || !this->private) return; if (local->loc.inode) loc_wipe(&local->loc); if (local->fd) fd_unref(local->fd); GF_FREE(local->name); GF_FREE(local->volname); if (local->dict) dict_unref(local->dict); if (local->iobref) iobref_unref(local->iobref); GF_FREE(local->vector); mem_put(local); } void __gf_quiesce_start_timer(xlator_t *this, quiesce_priv_t *priv) { struct timespec timeout = { 0, }; if (!priv->timer) { timeout.tv_sec = priv->timeout; timeout.tv_nsec = 0; priv->timer = gf_timer_call_after(this->ctx, timeout, gf_quiesce_timeout, (void *)this); if (priv->timer == NULL) { gf_log(this->name, GF_LOG_ERROR, "Cannot create timer"); } } } static void __gf_quiesce_cleanup_failover_hosts(xlator_t *this, quiesce_priv_t *priv) { quiesce_failover_hosts_t *tmp = NULL; quiesce_failover_hosts_t *failover_host = NULL; list_for_each_entry_safe(failover_host, tmp, &priv->failover_list, list) { GF_FREE(failover_host->addr); list_del(&failover_host->list); GF_FREE(failover_host); } return; } void gf_quiesce_populate_failover_hosts(xlator_t *this, quiesce_priv_t *priv, const char *value) { char *dup_val = NULL; char *addr_tok = NULL; char *save_ptr = NULL; quiesce_failover_hosts_t *failover_host = NULL; if (!value) goto out; dup_val = gf_strdup(value); if (!dup_val) goto out; addr_tok = strtok_r(dup_val, ",", &save_ptr); LOCK(&priv->lock); { if (!list_empty(&priv->failover_list)) __gf_quiesce_cleanup_failover_hosts(this, priv); while (addr_tok) { if (!valid_internet_address(addr_tok, _gf_true, _gf_false)) { GF_LOG_I(this->name, QUIESCE_MSG_INVAL_HOST(addr_tok)); continue; } failover_host = GF_CALLOC(1, sizeof(*failover_host), gf_quiesce_mt_failover_hosts); failover_host->addr = gf_strdup(addr_tok); INIT_LIST_HEAD(&failover_host->list); list_add(&failover_host->list, &priv->failover_list); addr_tok = strtok_r(NULL, ",", &save_ptr); } } UNLOCK(&priv->lock); GF_FREE(dup_val); out: return; } int32_t gf_quiesce_failover_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { quiesce_priv_t *priv = NULL; if (op_ret < 0) { /* Failure here doesn't mean the failover to another host didn't * succeed, we will know if failover succeeds or not by the * CHILD_UP/CHILD_DOWN event. A failure here indicates something * went wrong with the submission of failover command, hence * just abort the failover attempts without retrying with other * hosts. */ GF_LOG_I(this->name, QUIESCE_MSG_FAILOVER_FAILED(cookie, op_errno)); } GF_FREE(cookie); STACK_DESTROY(frame->root); priv = this->private; __gf_quiesce_start_timer(this, priv); return 0; } int __gf_quiesce_perform_failover(xlator_t *this) { int ret = 0; call_frame_t *frame = NULL; dict_t *dict = NULL; quiesce_priv_t *priv = NULL; quiesce_failover_hosts_t *failover_host = NULL; quiesce_failover_hosts_t *host = NULL; priv = this->private; if (priv->pass_through) { gf_msg_trace(this->name, 0, "child is up, hence not " "performing any failover"); goto out; } list_for_each_entry(failover_host, &priv->failover_list, list) { if (failover_host->tried == 0) { host = failover_host; failover_host->tried = 1; break; } } if (!host) { /*TODO: Keep trying until any of the gfproxy comes back up. Currently it tries failing over once for each host, if it doesn't succeed then returns error to mount point list_for_each_entry (failover_host, &priv->failover_list, list) { failover_host->tried = 0; }*/ GF_LOG_D(this->name, "All the failover hosts have been tried and looks like " "didn't succeed", 0); ret = -1; goto out; } frame = create_frame(this, this->ctx->pool); if (!frame) { GF_LOG_D(this->name, "Failed to create the frame", 0); ret = -1; goto out; } dict = dict_new(); ret = dict_set_dynstr(dict, CLIENT_CMD_CONNECT, gf_strdup(host->addr)); gf_msg_trace(this->name, 0, "Initiating failover to:%s", host->addr); STACK_WIND_COOKIE(frame, gf_quiesce_failover_cbk, NULL, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, NULL, dict, 0, NULL); out: if (dict) dict_unref(dict); return ret; } call_stub_t * gf_quiesce_dequeue(xlator_t *this) { call_stub_t *stub = NULL; quiesce_priv_t *priv = NULL; priv = this->private; if (!priv || list_empty(&priv->req)) return NULL; LOCK(&priv->lock); { stub = list_entry(priv->req.next, call_stub_t, list); list_del_init(&stub->list); priv->queue_size--; } UNLOCK(&priv->lock); return stub; } void * gf_quiesce_dequeue_start(void *data) { xlator_t *this = NULL; quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; this = data; priv = this->private; THIS = this; while (!list_empty(&priv->req)) { stub = gf_quiesce_dequeue(this); if (stub) { call_resume(stub); } } return 0; } void gf_quiesce_timeout(void *data) { xlator_t *this = NULL; quiesce_priv_t *priv = NULL; int ret = -1; this = data; priv = this->private; THIS = this; LOCK(&priv->lock); { priv->timer = NULL; if (priv->pass_through) { UNLOCK(&priv->lock); goto out; } ret = __gf_quiesce_perform_failover(THIS); } UNLOCK(&priv->lock); if (ret < 0) { priv->pass_through = _gf_true; gf_quiesce_dequeue_start(this); } out: return; } void gf_quiesce_enqueue(xlator_t *this, call_stub_t *stub) { quiesce_priv_t *priv = NULL; priv = this->private; if (!priv) { gf_log_callingfn(this->name, GF_LOG_ERROR, "this->private == NULL"); return; } LOCK(&priv->lock); { list_add_tail(&stub->list, &priv->req); priv->queue_size++; __gf_quiesce_start_timer(this, priv); } UNLOCK(&priv->lock); return; } /* _CBK function section */ int32_t quiesce_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *dict, struct iatt *postparent) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_lookup_stub(frame, default_lookup_resume, &local->loc, local->dict); if (!stub) { STACK_UNWIND_STRICT(lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, dict, postparent); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_stat_stub(frame, default_stat_resume, &local->loc, xdata); if (!stub) { STACK_UNWIND_STRICT(stat, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(stat, frame, op_ret, op_errno, buf, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_access_stub(frame, default_access_resume, &local->loc, local->flag, xdata); if (!stub) { STACK_UNWIND_STRICT(access, frame, -1, ENOMEM, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(access, frame, op_ret, op_errno, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, const char *path, struct iatt *buf, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_readlink_stub(frame, default_readlink_resume, &local->loc, local->size, xdata); if (!stub) { STACK_UNWIND_STRICT(readlink, frame, -1, ENOMEM, NULL, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(readlink, frame, op_ret, op_errno, path, buf, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_open_stub(frame, default_open_resume, &local->loc, local->flag, local->fd, xdata); if (!stub) { STACK_UNWIND_STRICT(open, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_readv_stub(frame, default_readv_resume, local->fd, local->size, local->offset, local->io_flag, xdata); if (!stub) { STACK_UNWIND_STRICT(readv, frame, -1, ENOMEM, NULL, 0, NULL, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, stbuf, iobref, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_flush_stub(frame, default_flush_resume, local->fd, xdata); if (!stub) { STACK_UNWIND_STRICT(flush, frame, -1, ENOMEM, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(flush, frame, op_ret, op_errno, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_fsync_stub(frame, default_fsync_resume, local->fd, local->flag, xdata); if (!stub) { STACK_UNWIND_STRICT(fsync, frame, -1, ENOMEM, NULL, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_fstat_stub(frame, default_fstat_resume, local->fd, xdata); if (!stub) { STACK_UNWIND_STRICT(fstat, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(fstat, frame, op_ret, op_errno, buf, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_opendir_stub(frame, default_opendir_resume, &local->loc, local->fd, xdata); if (!stub) { STACK_UNWIND_STRICT(opendir, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(opendir, frame, op_ret, op_errno, fd, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_fsyncdir_stub(frame, default_fsyncdir_resume, local->fd, local->flag, xdata); if (!stub) { STACK_UNWIND_STRICT(fsyncdir, frame, -1, ENOMEM, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(fsyncdir, frame, op_ret, op_errno, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_statfs_stub(frame, default_statfs_resume, &local->loc, xdata); if (!stub) { STACK_UNWIND_STRICT(statfs, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(statfs, frame, op_ret, op_errno, buf, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_fgetxattr_stub(frame, default_fgetxattr_resume, local->fd, local->name, xdata); if (!stub) { STACK_UNWIND_STRICT(fgetxattr, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_getxattr_stub(frame, default_getxattr_resume, &local->loc, local->name, xdata); if (!stub) { STACK_UNWIND_STRICT(getxattr, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_rchecksum_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, uint32_t weak_checksum, uint8_t *strong_checksum, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_rchecksum_stub(frame, default_rchecksum_resume, local->fd, local->offset, local->flag, xdata); if (!stub) { STACK_UNWIND_STRICT(rchecksum, frame, -1, ENOMEM, 0, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(rchecksum, frame, op_ret, op_errno, weak_checksum, strong_checksum, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_readdir_stub(frame, default_readdir_resume, local->fd, local->size, local->offset, xdata); if (!stub) { STACK_UNWIND_STRICT(readdir, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(readdir, frame, op_ret, op_errno, entries, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int32_t quiesce_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_readdirp_stub(frame, default_readdirp_resume, local->fd, local->size, local->offset, local->dict); if (!stub) { STACK_UNWIND_STRICT(readdirp, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } #if 0 int32_t quiesce_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_writev_stub (frame, default_writev_resume, local->fd, local->vector, local->flag, local->offset, local->io_flags, local->iobref, xdata); if (!stub) { STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, NULL, NULL, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } int32_t quiesce_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_xattrop_stub (frame, default_xattrop_resume, &local->loc, local->xattrop_flags, local->dict, xdata); if (!stub) { STACK_UNWIND_STRICT (xattrop, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } int32_t quiesce_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_fxattrop_stub (frame, default_fxattrop_resume, local->fd, local->xattrop_flags, local->dict, xdata); if (!stub) { STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } int32_t quiesce_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_lk_stub (frame, default_lk_resume, local->fd, local->flag, &local->flock, xdata); if (!stub) { STACK_UNWIND_STRICT (lk, frame, -1, ENOMEM, NULL, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } int32_t quiesce_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_inodelk_stub (frame, default_inodelk_resume, local->volname, &local->loc, local->flag, &local->flock, xdata); if (!stub) { STACK_UNWIND_STRICT (inodelk, frame, -1, ENOMEM, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } int32_t quiesce_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_finodelk_stub (frame, default_finodelk_resume, local->volname, local->fd, local->flag, &local->flock, xdata); if (!stub) { STACK_UNWIND_STRICT (finodelk, frame, -1, ENOMEM, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } int32_t quiesce_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_entrylk_stub (frame, default_entrylk_resume, local->volname, &local->loc, local->name, local->cmd, local->type, xdata); if (!stub) { STACK_UNWIND_STRICT (entrylk, frame, -1, ENOMEM, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } int32_t quiesce_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_fentrylk_stub (frame, default_fentrylk_resume, local->volname, local->fd, local->name, local->cmd, local->type, xdata); if (!stub) { STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOMEM, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } int32_t quiesce_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_setattr_stub (frame, default_setattr_resume, &local->loc, &local->stbuf, local->flag, xdata); if (!stub) { STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM, NULL, NULL, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre, statpost, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } int32_t quiesce_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_fsetattr_stub (frame, default_fsetattr_resume, local->fd, &local->stbuf, local->flag, xdata); if (!stub) { STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL); goto out; } gf_quiesce_enqueue (this, stub); goto out; } STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre, statpost, xdata); out: gf_quiesce_local_wipe (this, local); return 0; } #endif /* if 0 */ /* FOP */ /* No retransmittion */ int32_t quiesce_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; } stub = fop_removexattr_stub(frame, default_removexattr_resume, loc, name, xdata); if (!stub) { STACK_UNWIND_STRICT(removexattr, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_fremovexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; } stub = fop_fremovexattr_stub(frame, default_fremovexattr_resume, fd, name, xdata); if (!stub) { STACK_UNWIND_STRICT(fremovexattr, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } stub = fop_truncate_stub(frame, default_truncate_resume, loc, offset, xdata); if (!stub) { STACK_UNWIND_STRICT(truncate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; } stub = fop_fsetxattr_stub(frame, default_fsetxattr_resume, fd, dict, flags, xdata); if (!stub) { STACK_UNWIND_STRICT(fsetxattr, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; } stub = fop_setxattr_stub(frame, default_setxattr_resume, loc, dict, flags, xdata); if (!stub) { STACK_UNWIND_STRICT(setxattr, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { /* Don't send O_APPEND below, as write() re-transmittions can fail with O_APPEND */ STACK_WIND(frame, default_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, (flags & ~O_APPEND), mode, umask, fd, xdata); return 0; } stub = fop_create_stub(frame, default_create_resume, loc, (flags & ~O_APPEND), mode, umask, fd, xdata); if (!stub) { STACK_UNWIND_STRICT(create, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; } stub = fop_link_stub(frame, default_link_resume, oldloc, newloc, xdata); if (!stub) { STACK_UNWIND_STRICT(link, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; } stub = fop_rename_stub(frame, default_rename_resume, oldloc, newloc, xdata); if (!stub) { STACK_UNWIND_STRICT(rename, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int quiesce_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); return 0; } stub = fop_symlink_stub(frame, default_symlink_resume, linkpath, loc, umask, xdata); if (!stub) { STACK_UNWIND_STRICT(symlink, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int quiesce_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); return 0; } stub = fop_rmdir_stub(frame, default_rmdir_resume, loc, flags, xdata); if (!stub) { STACK_UNWIND_STRICT(rmdir, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; } stub = fop_unlink_stub(frame, default_unlink_resume, loc, xflag, xdata); if (!stub) { STACK_UNWIND_STRICT(unlink, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int quiesce_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; } stub = fop_mkdir_stub(frame, default_mkdir_resume, loc, mode, umask, xdata); if (!stub) { STACK_UNWIND_STRICT(mkdir, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int quiesce_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; } stub = fop_mknod_stub(frame, default_mknod_resume, loc, mode, rdev, umask, xdata); if (!stub) { STACK_UNWIND_STRICT(mknod, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv->pass_through) { STACK_WIND(frame, default_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } stub = fop_ftruncate_stub(frame, default_ftruncate_resume, fd, offset, xdata); if (!stub) { STACK_UNWIND_STRICT(ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } /* Re-transmittion */ int32_t quiesce_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); loc_dup(loc, &local->loc); local->size = size; frame->local = local; STACK_WIND(frame, quiesce_readlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink, loc, size, xdata); return 0; } stub = fop_readlink_stub(frame, default_readlink_resume, loc, size, xdata); if (!stub) { STACK_UNWIND_STRICT(readlink, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); loc_dup(loc, &local->loc); local->flag = mask; frame->local = local; STACK_WIND(frame, quiesce_access_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->access, loc, mask, xdata); return 0; } stub = fop_access_stub(frame, default_access_resume, loc, mask, xdata); if (!stub) { STACK_UNWIND_STRICT(access, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); if (name) local->name = gf_strdup(name); frame->local = local; STACK_WIND(frame, quiesce_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); return 0; } stub = fop_fgetxattr_stub(frame, default_fgetxattr_resume, fd, name, xdata); if (!stub) { STACK_UNWIND_STRICT(fgetxattr, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); loc_dup(loc, &local->loc); frame->local = local; STACK_WIND(frame, quiesce_statfs_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, loc, xdata); return 0; } stub = fop_statfs_stub(frame, default_statfs_resume, loc, xdata); if (!stub) { STACK_UNWIND_STRICT(statfs, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); local->flag = flags; frame->local = local; STACK_WIND(frame, quiesce_fsyncdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsyncdir, fd, flags, xdata); return 0; } stub = fop_fsyncdir_stub(frame, default_fsyncdir_resume, fd, flags, xdata); if (!stub) { STACK_UNWIND_STRICT(fsyncdir, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); loc_dup(loc, &local->loc); local->fd = fd_ref(fd); frame->local = local; STACK_WIND(frame, quiesce_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); return 0; } stub = fop_opendir_stub(frame, default_opendir_resume, loc, fd, xdata); if (!stub) { STACK_UNWIND_STRICT(opendir, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); frame->local = local; STACK_WIND(frame, quiesce_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; } stub = fop_fstat_stub(frame, default_fstat_resume, fd, xdata); if (!stub) { STACK_UNWIND_STRICT(fstat, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); local->flag = flags; frame->local = local; STACK_WIND(frame, quiesce_fsync_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); return 0; } stub = fop_fsync_stub(frame, default_fsync_resume, fd, flags, xdata); if (!stub) { STACK_UNWIND_STRICT(fsync, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); frame->local = local; STACK_WIND(frame, quiesce_flush_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush, fd, xdata); return 0; } stub = fop_flush_stub(frame, default_flush_resume, fd, xdata); if (!stub) { STACK_UNWIND_STRICT(flush, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, iobref, xdata); return 0; } stub = fop_writev_stub(frame, default_writev_resume, fd, vector, count, off, flags, iobref, xdata); if (!stub) { STACK_UNWIND_STRICT(writev, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); local->size = size; local->offset = offset; local->io_flag = flags; frame->local = local; STACK_WIND(frame, quiesce_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; } stub = fop_readv_stub(frame, default_readv_resume, fd, size, offset, flags, xdata); if (!stub) { STACK_UNWIND_STRICT(readv, frame, -1, ENOMEM, NULL, 0, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); loc_dup(loc, &local->loc); local->fd = fd_ref(fd); /* Don't send O_APPEND below, as write() re-transmittions can fail with O_APPEND */ local->flag = (flags & ~O_APPEND); frame->local = local; STACK_WIND(frame, quiesce_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, (flags & ~O_APPEND), fd, xdata); return 0; } stub = fop_open_stub(frame, default_open_resume, loc, (flags & ~O_APPEND), fd, xdata); if (!stub) { STACK_UNWIND_STRICT(open, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); loc_dup(loc, &local->loc); if (name) local->name = gf_strdup(name); frame->local = local; STACK_WIND(frame, quiesce_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); return 0; } stub = fop_getxattr_stub(frame, default_getxattr_resume, loc, name, xdata); if (!stub) { STACK_UNWIND_STRICT(getxattr, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata); return 0; } stub = fop_xattrop_stub(frame, default_xattrop_resume, loc, flags, dict, xdata); if (!stub) { STACK_UNWIND_STRICT(xattrop, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_fxattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata); return 0; } stub = fop_fxattrop_stub(frame, default_fxattrop_resume, fd, flags, dict, xdata); if (!stub) { STACK_UNWIND_STRICT(fxattrop, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_lk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata); return 0; } stub = fop_lk_stub(frame, default_lk_resume, fd, cmd, lock, xdata); if (!stub) { STACK_UNWIND_STRICT(lk, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_inodelk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, volume, loc, cmd, lock, xdata); return 0; } stub = fop_inodelk_stub(frame, default_inodelk_resume, volume, loc, cmd, lock, xdata); if (!stub) { STACK_UNWIND_STRICT(inodelk, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_finodelk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd, lock, xdata); return 0; } stub = fop_finodelk_stub(frame, default_finodelk_resume, volume, fd, cmd, lock, xdata); if (!stub) { STACK_UNWIND_STRICT(finodelk, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_entrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, volume, loc, basename, cmd, type, xdata); return 0; } stub = fop_entrylk_stub(frame, default_entrylk_resume, volume, loc, basename, cmd, type, xdata); if (!stub) { STACK_UNWIND_STRICT(entrylk, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_fentrylk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fentrylk, volume, fd, basename, cmd, type, xdata); return 0; } stub = fop_fentrylk_stub(frame, default_fentrylk_resume, volume, fd, basename, cmd, type, xdata); if (!stub) { STACK_UNWIND_STRICT(fentrylk, frame, -1, ENOMEM, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, int32_t len, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); local->offset = offset; local->flag = len; frame->local = local; STACK_WIND(frame, quiesce_rchecksum_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata); return 0; } stub = fop_rchecksum_stub(frame, default_rchecksum_resume, fd, offset, len, xdata); if (!stub) { STACK_UNWIND_STRICT(rchecksum, frame, -1, ENOMEM, 0, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); local->size = size; local->offset = off; frame->local = local; STACK_WIND(frame, quiesce_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, fd, size, off, xdata); return 0; } stub = fop_readdir_stub(frame, default_readdir_resume, fd, size, off, xdata); if (!stub) { STACK_UNWIND_STRICT(readdir, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *dict) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); local->size = size; local->offset = off; local->dict = dict_ref(dict); frame->local = local; STACK_WIND(frame, quiesce_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, off, dict); return 0; } stub = fop_readdirp_stub(frame, default_readdirp_resume, fd, size, off, dict); if (!stub) { STACK_UNWIND_STRICT(readdirp, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } stub = fop_setattr_stub(frame, default_setattr_resume, loc, stbuf, valid, xdata); if (!stub) { STACK_UNWIND_STRICT(setattr, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); loc_dup(loc, &local->loc); frame->local = local; STACK_WIND(frame, quiesce_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; } stub = fop_stat_stub(frame, default_stat_resume, loc, xdata); if (!stub) { STACK_UNWIND_STRICT(stat, frame, -1, ENOMEM, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); loc_dup(loc, &local->loc); local->dict = dict_ref(xattr_req); frame->local = local; STACK_WIND(frame, quiesce_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xattr_req); return 0; } stub = fop_lookup_stub(frame, default_lookup_resume, loc, xattr_req); if (!stub) { STACK_UNWIND_STRICT(lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } stub = fop_fsetattr_stub(frame, default_fsetattr_resume, fd, stbuf, valid, xdata); if (!stub) { STACK_UNWIND_STRICT(fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t quiesce_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; priv = this->private; if (priv && priv->pass_through) { STACK_WIND(frame, default_fallocate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, xdata); return 0; } stub = fop_fallocate_stub(frame, default_fallocate_resume, fd, mode, offset, len, xdata); if (!stub) { STACK_UNWIND_STRICT(fallocate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int quiesce_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata) { call_stub_t *stub = NULL; quiesce_local_t *local = NULL; local = frame->local; frame->local = NULL; if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_seek_stub(frame, default_seek_resume, local->fd, local->offset, local->what, xdata); if (!stub) { STACK_UNWIND_STRICT(seek, frame, -1, ENOMEM, 0, NULL); goto out; } gf_quiesce_enqueue(this, stub); goto out; } STACK_UNWIND_STRICT(seek, frame, op_ret, op_errno, offset, xdata); out: gf_quiesce_local_wipe(this, local); return 0; } int quiesce_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; quiesce_local_t *local = NULL; priv = this->private; if (priv && priv->pass_through) { local = mem_get0(priv->local_pool); local->fd = fd_ref(fd); local->offset = offset; local->what = what; frame->local = local; STACK_WIND(frame, quiesce_seek_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->seek, fd, offset, what, xdata); return 0; } stub = fop_seek_stub(frame, default_seek_resume, fd, offset, what, xdata); if (!stub) { STACK_UNWIND_STRICT(seek, frame, -1, ENOMEM, 0, NULL); return 0; } gf_quiesce_enqueue(this, stub); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; ret = xlator_mem_acct_init(this, gf_quiesce_mt_end); return ret; } int reconfigure(xlator_t *this, dict_t *options) { int32_t ret = -1; quiesce_priv_t *priv = NULL; priv = this->private; GF_OPTION_RECONF("timeout", priv->timeout, options, time, out); GF_OPTION_RECONF("failover-hosts", priv->failover_hosts, options, str, out); gf_quiesce_populate_failover_hosts(this, priv, priv->failover_hosts); ret = 0; out: return ret; } int init(xlator_t *this) { int ret = -1; quiesce_priv_t *priv = NULL; if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "'quiesce' not configured with exactly one child"); goto out; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); } priv = GF_CALLOC(1, sizeof(*priv), gf_quiesce_mt_priv_t); if (!priv) goto out; INIT_LIST_HEAD(&priv->failover_list); GF_OPTION_INIT("timeout", priv->timeout, time, out); GF_OPTION_INIT("failover-hosts", priv->failover_hosts, str, out); LOCK_INIT(&priv->lock); gf_quiesce_populate_failover_hosts(this, priv, priv->failover_hosts); priv->local_pool = mem_pool_new(quiesce_local_t, GF_FOPS_EXPECTED_IN_PARALLEL); priv->pass_through = _gf_false; INIT_LIST_HEAD(&priv->req); this->private = priv; ret = 0; out: if (ret) { GF_FREE(priv); } return ret; } void fini(xlator_t *this) { quiesce_priv_t *priv = NULL; priv = this->private; if (!priv) goto out; this->private = NULL; mem_pool_destroy(priv->local_pool); priv->local_pool = NULL; LOCK_DESTROY(&priv->lock); GF_FREE(priv); out: return; } int notify(xlator_t *this, int event, void *data, ...) { int ret = 0; quiesce_priv_t *priv = NULL; priv = this->private; if (!priv) goto out; switch (event) { case GF_EVENT_CHILD_UP: { ret = gf_thread_create(&priv->thr, NULL, gf_quiesce_dequeue_start, this, "quiesce"); if (ret) { gf_log(this->name, GF_LOG_ERROR, "failed to create the quiesce-dequeue thread"); } LOCK(&priv->lock); { priv->pass_through = _gf_true; } UNLOCK(&priv->lock); break; } case GF_EVENT_CHILD_DOWN: LOCK(&priv->lock); { priv->pass_through = _gf_false; __gf_quiesce_start_timer(this, priv); } UNLOCK(&priv->lock); break; default: break; } ret = default_notify(this, event, data); out: return ret; } struct xlator_fops fops = { /* write/modifying fops */ .mknod = quiesce_mknod, .create = quiesce_create, .truncate = quiesce_truncate, .ftruncate = quiesce_ftruncate, .setxattr = quiesce_setxattr, .fsetxattr = quiesce_fsetxattr, .removexattr = quiesce_removexattr, .fremovexattr = quiesce_fremovexattr, .symlink = quiesce_symlink, .unlink = quiesce_unlink, .link = quiesce_link, .mkdir = quiesce_mkdir, .rmdir = quiesce_rmdir, .rename = quiesce_rename, .fallocate = quiesce_fallocate, /* The below calls are known to change state, hence re-transmittion is not advised */ .lk = quiesce_lk, .inodelk = quiesce_inodelk, .finodelk = quiesce_finodelk, .entrylk = quiesce_entrylk, .fentrylk = quiesce_fentrylk, .xattrop = quiesce_xattrop, .fxattrop = quiesce_fxattrop, .setattr = quiesce_setattr, .fsetattr = quiesce_fsetattr, /* Special case, re-transmittion is not harmful * * as offset is properly sent from above layers */ /* TODO: not re-transmitted as of now */ .writev = quiesce_writev, /* re-transmittable fops */ .lookup = quiesce_lookup, .stat = quiesce_stat, .fstat = quiesce_fstat, .access = quiesce_access, .readlink = quiesce_readlink, .getxattr = quiesce_getxattr, .fgetxattr = quiesce_fgetxattr, .open = quiesce_open, .readv = quiesce_readv, .flush = quiesce_flush, .fsync = quiesce_fsync, .statfs = quiesce_statfs, .opendir = quiesce_opendir, .readdir = quiesce_readdir, .readdirp = quiesce_readdirp, .fsyncdir = quiesce_fsyncdir, .seek = quiesce_seek, }; struct xlator_dumpops dumpops; struct xlator_cbks cbks; struct volume_options options[] = { { .key = {"timeout"}, .type = GF_OPTION_TYPE_TIME, .default_value = "45", .description = "After 'timeout' seconds since the time 'quiesce' " "option was set to \"!pass-through\", acknowledgements to file " "operations are no longer quiesced and previously " "quiesced acknowledgements are sent to the application", .op_version = {GD_OP_VERSION_4_0_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, }, {.key = {"failover-hosts"}, .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .op_version = {GD_OP_VERSION_4_0_0}, .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .description = "It is a comma separated list of hostname/IP " "addresses. It Specifies the list of hosts where " "the gfproxy daemons are running, to which the " "the thin clients can failover to."}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {GD_OP_VERSION_3_12_0}, .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "quiesce", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/features/quiesce/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202464023400 xustar000000000000000030 mtime=1699284276.661060546 29 atime=1699284290.63310263 30 ctime=1699284303.556141553 glusterfs-11.1/xlators/features/quiesce/Makefile.in0000664000175100017510000005272714522202464023675 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/quiesce DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/quiesce/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/quiesce/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/quiesce/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023364 xustar000000000000000030 mtime=1699284265.681027474 30 atime=1699284276.637060474 30 ctime=1699284303.558141559 glusterfs-11.1/xlators/features/quiesce/Makefile.am0000664000175100017510000000003414522202451023640 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/bit-rot0000644000000000000000000000013214522202520021172 xustar000000000000000030 mtime=1699284304.914145643 30 atime=1699284309.687160019 30 ctime=1699284304.914145643 glusterfs-11.1/xlators/features/bit-rot/0002775000175100017510000000000014522202520021530 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/bit-rot/PaxHeaders.9031/src0000644000000000000000000000013214522202520021761 xustar000000000000000030 mtime=1699284304.991145875 30 atime=1699284309.687160019 30 ctime=1699284304.991145875 glusterfs-11.1/xlators/features/bit-rot/src/0002775000175100017510000000000014522202520022317 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/bit-rot/src/PaxHeaders.9031/bitd0000644000000000000000000000013214522202521022704 xustar000000000000000030 mtime=1699284305.038146017 30 atime=1699284309.687160019 30 ctime=1699284305.038146017 glusterfs-11.1/xlators/features/bit-rot/src/bitd/0002775000175100017510000000000014522202521023242 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/bit-rot-scrub.c0000644000000000000000000000013214522202451025623 xustar000000000000000030 mtime=1699284265.652027387 30 atime=1699284265.652027387 30 ctime=1699284305.035146007 glusterfs-11.1/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c0000664000175100017510000015607214522202451026115 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include "bit-rot-scrub.h" #include #include "bit-rot-bitd-messages.h" #include "bit-rot-scrub-status.h" #include struct br_scrubbers { pthread_t scrubthread; struct list_head list; }; struct br_fsscan_entry { void *data; loc_t parent; gf_dirent_t *entry; struct br_scanfs *fsscan; /* backpointer to subvolume scanner */ struct list_head list; }; /** * fetch signature extended attribute from an object's fd. * NOTE: On success @xattr is not unref'd as @sign points * to the dictionary value. */ static int32_t bitd_fetch_signature(xlator_t *this, br_child_t *child, fd_t *fd, dict_t **xattr, br_isignature_out_t **sign) { int32_t ret = -1; ret = syncop_fgetxattr(child->xl, fd, xattr, GLUSTERFS_GET_OBJECT_SIGNATURE, NULL, NULL); if (ret < 0) { br_log_object(this, "fgetxattr", fd->inode->gfid, -ret); goto out; } ret = dict_get_ptr(*xattr, GLUSTERFS_GET_OBJECT_SIGNATURE, (void **)sign); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_GET_SIGN_FAILED, "failed to extract signature info [GFID: %s]", uuid_utoa(fd->inode->gfid)); goto unref_dict; } return 0; unref_dict: dict_unref(*xattr); out: return -1; } /** * POST COMPUTE CHECK * * Checks to be performed before verifying calculated signature * Object is skipped if: * - has stale signature * - mismatches versions caches in pre-compute check */ static int32_t bitd_scrub_post_compute_check(xlator_t *this, br_child_t *child, fd_t *fd, unsigned long version, br_isignature_out_t **signature, br_scrub_stats_t *scrub_stat, gf_boolean_t skip_stat) { int32_t ret = 0; size_t signlen = 0; dict_t *xattr = NULL; br_isignature_out_t *signptr = NULL; ret = bitd_fetch_signature(this, child, fd, &xattr, &signptr); if (ret < 0) { if (!skip_stat) br_inc_unsigned_file_count(scrub_stat); goto out; } /** * Either the object got dirtied during the time the signature was * calculated OR the version we saved during pre-compute check does * not match now, implying that the object got dirtied and signed in * between scrubs pre & post compute checks (checksum window). * * The log entry looks pretty ugly, but helps in debugging.. */ if (signptr->stale || (signptr->version != version)) { if (!skip_stat) br_inc_unsigned_file_count(scrub_stat); gf_msg_debug(this->name, 0, " Object [GFID: %s] " "either has a stale signature OR underwent " "signing during checksumming {Stale: %d | " "Version: %lu,%lu}", uuid_utoa(fd->inode->gfid), (signptr->stale) ? 1 : 0, version, signptr->version); ret = -1; goto unref_dict; } signlen = signptr->signaturelen; *signature = GF_MALLOC(sizeof(br_isignature_out_t) + signlen, gf_common_mt_char); (void)memcpy(*signature, signptr, sizeof(br_isignature_out_t) + signlen); (*signature)->signaturelen = signlen; unref_dict: dict_unref(xattr); out: return ret; } static int32_t bitd_signature_staleness(xlator_t *this, br_child_t *child, fd_t *fd, int *stale, unsigned long *version, br_scrub_stats_t *scrub_stat, gf_boolean_t skip_stat) { int32_t ret = -1; dict_t *xattr = NULL; br_isignature_out_t *signptr = NULL; ret = bitd_fetch_signature(this, child, fd, &xattr, &signptr); if (ret < 0) { if (!skip_stat) br_inc_unsigned_file_count(scrub_stat); goto out; } /** * save version for validation in post compute stage * c.f. bitd_scrub_post_compute_check() */ *stale = signptr->stale ? 1 : 0; *version = signptr->version; dict_unref(xattr); out: return ret; } /** * PRE COMPUTE CHECK * * Checks to be performed before initiating object signature calculation. * An object is skipped if: * - it's already marked corrupted * - has stale signature */ static int32_t bitd_scrub_pre_compute_check(xlator_t *this, br_child_t *child, fd_t *fd, unsigned long *version, br_scrub_stats_t *scrub_stat, gf_boolean_t skip_stat) { int stale = 0; int32_t ret = -1; if (bitd_is_bad_file(this, child, NULL, fd)) { gf_msg(this->name, GF_LOG_WARNING, 0, BRB_MSG_SKIP_OBJECT, "Object [GFID: %s] is marked corrupted, skipping..", uuid_utoa(fd->inode->gfid)); goto out; } ret = bitd_signature_staleness(this, child, fd, &stale, version, scrub_stat, skip_stat); if (!ret && stale) { if (!skip_stat) br_inc_unsigned_file_count(scrub_stat); gf_msg_debug(this->name, 0, " Object [GFID: %s] " "has stale signature", uuid_utoa(fd->inode->gfid)); ret = -1; } out: return ret; } /* static int */ static int bitd_compare_ckum(xlator_t *this, br_isignature_out_t *sign, unsigned char *md, inode_t *linked_inode, gf_dirent_t *entry, fd_t *fd, br_child_t *child, loc_t *loc) { int ret = -1; dict_t *xattr = NULL; GF_VALIDATE_OR_GOTO("bit-rot", this, out); GF_VALIDATE_OR_GOTO(this->name, sign, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, child, out); GF_VALIDATE_OR_GOTO(this->name, linked_inode, out); GF_VALIDATE_OR_GOTO(this->name, md, out); GF_VALIDATE_OR_GOTO(this->name, entry, out); if (strncmp(sign->signature, (char *)md, sign->signaturelen) == 0) { gf_msg_debug(this->name, 0, "%s [GFID: %s | Brick: %s] " "matches calculated checksum", loc->path, uuid_utoa(linked_inode->gfid), child->brick_path); return 0; } gf_msg(this->name, GF_LOG_DEBUG, 0, BRB_MSG_CHECKSUM_MISMATCH, "Object checksum mismatch: %s [GFID: %s | Brick: %s]", loc->path, uuid_utoa(linked_inode->gfid), child->brick_path); gf_msg(this->name, GF_LOG_ALERT, 0, BRB_MSG_CHECKSUM_MISMATCH, "CORRUPTION DETECTED: Object %s {Brick: %s | GFID: %s}", loc->path, child->brick_path, uuid_utoa(linked_inode->gfid)); /* Perform bad-file marking */ xattr = dict_new(); if (!xattr) { ret = -1; goto out; } ret = dict_set_int32(xattr, BITROT_OBJECT_BAD_KEY, _gf_true); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_MARK_BAD_FILE, "Error setting bad-file marker for %s [GFID: %s | " "Brick: %s]", loc->path, uuid_utoa(linked_inode->gfid), child->brick_path); goto dictfree; } gf_msg(this->name, GF_LOG_ALERT, 0, BRB_MSG_MARK_CORRUPTED, "Marking" " %s [GFID: %s | Brick: %s] as corrupted..", loc->path, uuid_utoa(linked_inode->gfid), child->brick_path); gf_event(EVENT_BITROT_BAD_FILE, "gfid=%s;path=%s;brick=%s", uuid_utoa(linked_inode->gfid), loc->path, child->brick_path); ret = syncop_fsetxattr(child->xl, fd, xattr, 0, NULL, NULL); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_MARK_BAD_FILE, "Error marking object %s [GFID: %s] as corrupted", loc->path, uuid_utoa(linked_inode->gfid)); dictfree: dict_unref(xattr); out: return ret; } /** * "The Scrubber" * * Perform signature validation for a given object with the assumption * that the signature is SHA256 (because signer as of now _always_ * signs with SHA256). */ static int br_scrubber_scrub_begin(xlator_t *this, struct br_fsscan_entry *fsentry) { int32_t ret = -1; fd_t *fd = NULL; loc_t loc = { 0, }; struct iatt iatt = { 0, }; pid_t pid = 0; br_child_t *child = NULL; unsigned char *md = NULL; inode_t *linked_inode = NULL; br_isignature_out_t *sign = NULL; unsigned long signedversion = 0; gf_dirent_t *entry = NULL; br_private_t *priv = NULL; loc_t *parent = NULL; gf_boolean_t skip_stat = _gf_false; uuid_t shard_root_gfid = { 0, }; GF_VALIDATE_OR_GOTO("bit-rot", fsentry, out); entry = fsentry->entry; parent = &fsentry->parent; child = fsentry->data; priv = this->private; GF_VALIDATE_OR_GOTO("bit-rot", entry, out); GF_VALIDATE_OR_GOTO("bit-rot", parent, out); GF_VALIDATE_OR_GOTO("bit-rot", child, out); GF_VALIDATE_OR_GOTO("bit-rot", priv, out); pid = GF_CLIENT_PID_SCRUB; ret = br_prepare_loc(this, child, parent, entry, &loc); if (!ret) goto out; syncopctx_setfspid(&pid); ret = syncop_lookup(child->xl, &loc, &iatt, NULL, NULL, NULL); if (ret) { br_log_object_path(this, "lookup", loc.path, -ret); goto out; } linked_inode = inode_link(loc.inode, parent->inode, loc.name, &iatt); if (linked_inode) inode_lookup(linked_inode); gf_msg_debug(this->name, 0, "Scrubbing object %s [GFID: %s]", entry->d_name, uuid_utoa(linked_inode->gfid)); if (iatt.ia_type != IA_IFREG) { gf_msg_debug(this->name, 0, "%s is not a regular file", entry->d_name); ret = 0; goto unref_inode; } if (IS_DHT_LINKFILE_MODE((&iatt))) { gf_msg_debug(this->name, 0, "%s is a dht sticky bit file", entry->d_name); ret = 0; goto unref_inode; } /* skip updating scrub statistics for shard entries */ gf_uuid_parse(SHARD_ROOT_GFID, shard_root_gfid); if (gf_uuid_compare(loc.pargfid, shard_root_gfid) == 0) skip_stat = _gf_true; /** * open() an fd for subsequent operations */ fd = fd_create(linked_inode, 0); if (!fd) { gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_FD_CREATE_FAILED, "failed to create fd for inode %s", uuid_utoa(linked_inode->gfid)); goto unref_inode; } ret = syncop_open(child->xl, &loc, O_RDWR, fd, NULL, NULL); if (ret) { br_log_object(this, "open", linked_inode->gfid, -ret); ret = -1; goto unrefd; } fd_bind(fd); /** * perform pre compute checks before initiating checksum * computation * - presence of bad object * - signature staleness */ ret = bitd_scrub_pre_compute_check(this, child, fd, &signedversion, &priv->scrub_stat, skip_stat); if (ret) goto unrefd; /* skip this object */ /* if all's good, proceed to calculate the hash */ md = GF_MALLOC(SHA256_DIGEST_LENGTH, gf_common_mt_char); if (!md) goto unrefd; ret = br_calculate_obj_checksum(md, child, fd); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_CALC_ERROR, "error calculating hash for object [GFID: %s]", uuid_utoa(fd->inode->gfid)); ret = -1; goto free_md; } /** * perform post compute checks as an object's signature may have * become stale while scrubber calculated checksum. */ ret = bitd_scrub_post_compute_check(this, child, fd, signedversion, &sign, &priv->scrub_stat, skip_stat); if (ret) goto free_md; ret = bitd_compare_ckum(this, sign, md, linked_inode, entry, fd, child, &loc); if (!skip_stat) br_inc_scrubbed_file(&priv->scrub_stat); GF_FREE(sign); /* allocated on post-compute */ /** fd_unref() takes care of closing fd.. like syncop_close() */ free_md: GF_FREE(md); unrefd: fd_unref(fd); unref_inode: inode_unref(linked_inode); out: loc_wipe(&loc); return ret; } static void _br_lock_cleaner(void *arg) { pthread_mutex_t *mutex = arg; pthread_mutex_unlock(mutex); } static void wait_for_scrubbing(xlator_t *this, struct br_scanfs *fsscan) { br_private_t *priv = NULL; struct br_scrubber *fsscrub = NULL; priv = this->private; fsscrub = &priv->fsscrub; pthread_cleanup_push(_br_lock_cleaner, &fsscan->waitlock); pthread_mutex_lock(&fsscan->waitlock); { pthread_cleanup_push(_br_lock_cleaner, &fsscrub->mutex); pthread_mutex_lock(&fsscrub->mutex); { list_replace_init(&fsscan->queued, &fsscan->ready); /* wake up scrubbers */ pthread_cond_broadcast(&fsscrub->cond); } pthread_mutex_unlock(&fsscrub->mutex); pthread_cleanup_pop(0); while (fsscan->entries != 0) pthread_cond_wait(&fsscan->waitcond, &fsscan->waitlock); } pthread_mutex_unlock(&fsscan->waitlock); pthread_cleanup_pop(0); } static void _br_fsscan_inc_entry_count(struct br_scanfs *fsscan) { fsscan->entries++; } static void _br_fsscan_dec_entry_count(struct br_scanfs *fsscan) { if (--fsscan->entries == 0) { pthread_mutex_lock(&fsscan->waitlock); { pthread_cond_signal(&fsscan->waitcond); } pthread_mutex_unlock(&fsscan->waitlock); } } static void _br_fsscan_collect_entry(struct br_scanfs *fsscan, struct br_fsscan_entry *fsentry) { list_add_tail(&fsentry->list, &fsscan->queued); _br_fsscan_inc_entry_count(fsscan); } #define NR_ENTRIES (1 << 7) /* ..bulk scrubbing */ static int br_fsscanner_handle_entry(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { int32_t ret = -1; int scrub = 0; br_child_t *child = NULL; xlator_t *this = NULL; struct br_scanfs *fsscan = NULL; struct br_fsscan_entry *fsentry = NULL; GF_VALIDATE_OR_GOTO("bit-rot", subvol, error_return); GF_VALIDATE_OR_GOTO("bit-rot", data, error_return); child = data; this = child->this; fsscan = &child->fsscan; _mask_cancellation(); fsentry = GF_CALLOC(1, sizeof(*fsentry), gf_br_mt_br_fsscan_entry_t); if (!fsentry) goto error_return; { fsentry->data = data; fsentry->fsscan = &child->fsscan; /* copy parent loc */ ret = loc_copy(&fsentry->parent, parent); if (ret) goto dealloc; /* copy child entry */ fsentry->entry = entry_copy(entry); if (!fsentry->entry) goto locwipe; INIT_LIST_HEAD(&fsentry->list); } LOCK(&fsscan->entrylock); { _br_fsscan_collect_entry(fsscan, fsentry); /** * need not be a equality check as entries may be pushed * back onto the scanned queue when thread(s) are cleaned. */ if (fsscan->entries >= NR_ENTRIES) scrub = 1; } UNLOCK(&fsscan->entrylock); _unmask_cancellation(); if (scrub) wait_for_scrubbing(this, fsscan); return 0; locwipe: loc_wipe(&fsentry->parent); dealloc: GF_FREE(fsentry); error_return: return -1; } int32_t br_fsscan_deactivate(xlator_t *this) { int ret = 0; br_private_t *priv = NULL; br_scrub_state_t nstate = 0; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; ret = gf_tw_del_timer(priv->timer_wheel, scrub_monitor->timer); if (ret == 0) { nstate = BR_SCRUB_STATE_STALLED; gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Volume is under active scrubbing. Pausing scrub.."); } else { nstate = BR_SCRUB_STATE_PAUSED; gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Scrubber paused"); } _br_monitor_set_scrub_state(scrub_monitor, nstate); return 0; } static void br_scrubber_log_time(xlator_t *this, const char *sfx) { char timestr[GF_TIMESTR_SIZE] = { 0, }; br_private_t *priv = NULL; time_t now = 0; now = gf_time(); priv = this->private; gf_time_fmt_FT(timestr, sizeof(timestr), now); if (strcasecmp(sfx, "started") == 0) { br_update_scrub_start_time(&priv->scrub_stat, now); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_START, "Scrubbing %s at %s", sfx, timestr); } else { br_update_scrub_finish_time(&priv->scrub_stat, timestr, now); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_FINISH, "Scrubbing %s at %s", sfx, timestr); } } static void br_fsscanner_log_time(xlator_t *this, br_child_t *child, const char *sfx) { char timestr[GF_TIMESTR_SIZE] = { 0, }; time_t now = 0; now = gf_time(); gf_time_fmt_FT(timestr, sizeof(timestr), now); if (strcasecmp(sfx, "started") == 0) { gf_msg_debug(this->name, 0, "Scrubbing \"%s\" %s at %s", child->brick_path, sfx, timestr); } else { gf_msg_debug(this->name, 0, "Scrubbing \"%s\" %s at %s", child->brick_path, sfx, timestr); } } void br_child_set_scrub_state(br_child_t *child, gf_boolean_t state) { child->active_scrubbing = state; } static void br_fsscanner_wait_until_kicked(xlator_t *this, br_child_t *child) { br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; pthread_cleanup_push(_br_lock_cleaner, &scrub_monitor->wakelock); pthread_mutex_lock(&scrub_monitor->wakelock); { while (!scrub_monitor->kick) pthread_cond_wait(&scrub_monitor->wakecond, &scrub_monitor->wakelock); /* Child lock is to synchronize with disconnect events */ pthread_cleanup_push(_br_lock_cleaner, &child->lock); pthread_mutex_lock(&child->lock); { scrub_monitor->active_child_count++; br_child_set_scrub_state(child, _gf_true); } pthread_mutex_unlock(&child->lock); pthread_cleanup_pop(0); } pthread_mutex_unlock(&scrub_monitor->wakelock); pthread_cleanup_pop(0); } static void br_scrubber_entry_control(xlator_t *this) { br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; LOCK(&scrub_monitor->lock); { /* Move the state to BR_SCRUB_STATE_ACTIVE */ if (scrub_monitor->state == BR_SCRUB_STATE_PENDING) scrub_monitor->state = BR_SCRUB_STATE_ACTIVE; br_scrubber_log_time(this, "started"); priv->scrub_stat.scrub_running = 1; } UNLOCK(&scrub_monitor->lock); } static void br_scrubber_exit_control(xlator_t *this) { br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; LOCK(&scrub_monitor->lock); { br_scrubber_log_time(this, "finished"); priv->scrub_stat.scrub_running = 0; if (scrub_monitor->state == BR_SCRUB_STATE_ACTIVE) { (void)br_fsscan_activate(this); } else { UNLOCK(&scrub_monitor->lock); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Volume waiting to get rescheduled.."); return; } } UNLOCK(&scrub_monitor->lock); } static void br_fsscanner_entry_control(xlator_t *this, br_child_t *child) { br_fsscanner_log_time(this, child, "started"); } static void br_fsscanner_exit_control(xlator_t *this, br_child_t *child) { br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; if (!_br_is_child_connected(child)) { gf_msg(this->name, GF_LOG_WARNING, 0, BRB_MSG_SCRUB_INFO, "Brick [%s] disconnected while scrubbing. Scrubbing " "might be incomplete", child->brick_path); } br_fsscanner_log_time(this, child, "finished"); pthread_cleanup_push(_br_lock_cleaner, &scrub_monitor->wakelock); pthread_mutex_lock(&scrub_monitor->wakelock); { scrub_monitor->active_child_count--; pthread_cleanup_push(_br_lock_cleaner, &child->lock); pthread_mutex_lock(&child->lock); { br_child_set_scrub_state(child, _gf_false); } pthread_mutex_unlock(&child->lock); pthread_cleanup_pop(0); if (scrub_monitor->active_child_count == 0) { /* The last child has finished scrubbing. * Set the kick to false and wake up other * children who are waiting for the last * child to complete scrubbing. */ scrub_monitor->kick = _gf_false; pthread_cond_broadcast(&scrub_monitor->wakecond); /* Signal monitor thread waiting for the all * the children to finish scrubbing. */ pthread_cleanup_push(_br_lock_cleaner, &scrub_monitor->donelock); pthread_mutex_lock(&scrub_monitor->donelock); { scrub_monitor->done = _gf_true; pthread_cond_signal(&scrub_monitor->donecond); } pthread_mutex_unlock(&scrub_monitor->donelock); pthread_cleanup_pop(0); } else { while (scrub_monitor->active_child_count) pthread_cond_wait(&scrub_monitor->wakecond, &scrub_monitor->wakelock); } } pthread_mutex_unlock(&scrub_monitor->wakelock); pthread_cleanup_pop(0); } void * br_fsscanner(void *arg) { loc_t loc = { 0, }; br_child_t *child = NULL; xlator_t *this = NULL; struct br_scanfs *fsscan = NULL; child = arg; this = child->this; fsscan = &child->fsscan; THIS = this; loc.inode = child->table->root; while (1) { br_fsscanner_wait_until_kicked(this, child); { /* precursor for scrub */ br_fsscanner_entry_control(this, child); /* scrub */ (void)syncop_ftw(child->xl, &loc, GF_CLIENT_PID_SCRUB, child, br_fsscanner_handle_entry); if (!list_empty(&fsscan->queued)) wait_for_scrubbing(this, fsscan); /* scrub exit criteria */ br_fsscanner_exit_control(this, child); } } return NULL; } /** * Keep this routine extremely simple and do not ever try to acquire * child->lock here: it may lead to deadlock. Scrubber state is * modified in br_fsscanner(). An intermediate state change to pause * changes the scrub state to the _correct_ state by identifying a * non-pending timer. */ static void br_kickstart_scanner(struct gf_tw_timer_list *timer, void *data, unsigned long calltime) { xlator_t *this = NULL; struct br_monitor *scrub_monitor = data; br_private_t *priv = NULL; THIS = this = scrub_monitor->this; priv = this->private; /* Reset scrub statistics */ priv->scrub_stat.scrubbed_files = 0; priv->scrub_stat.unsigned_files = 0; /* Moves state from PENDING to ACTIVE */ (void)br_scrubber_entry_control(this); /* kickstart scanning.. */ pthread_mutex_lock(&scrub_monitor->wakelock); { scrub_monitor->kick = _gf_true; GF_ASSERT(scrub_monitor->active_child_count == 0); pthread_cond_broadcast(&scrub_monitor->wakecond); } pthread_mutex_unlock(&scrub_monitor->wakelock); return; } #define BR_SCRUB_ONDEMAND (1) #define BR_SCRUB_MINUTE (60) #define BR_SCRUB_HOURLY (60 * 60) #define BR_SCRUB_DAILY (1 * 24 * 60 * 60) #define BR_SCRUB_WEEKLY (7 * 24 * 60 * 60) #define BR_SCRUB_BIWEEKLY (14 * 24 * 60 * 60) #define BR_SCRUB_MONTHLY (30 * 24 * 60 * 60) static time_t br_fsscan_calculate_timeout(scrub_freq_t freq) { time_t timo = 0; switch (freq) { case BR_FSSCRUB_FREQ_MINUTE: timo = BR_SCRUB_MINUTE; break; case BR_FSSCRUB_FREQ_HOURLY: timo = BR_SCRUB_HOURLY; break; case BR_FSSCRUB_FREQ_DAILY: timo = BR_SCRUB_DAILY; break; case BR_FSSCRUB_FREQ_WEEKLY: timo = BR_SCRUB_WEEKLY; break; case BR_FSSCRUB_FREQ_BIWEEKLY: timo = BR_SCRUB_BIWEEKLY; break; case BR_FSSCRUB_FREQ_MONTHLY: timo = BR_SCRUB_MONTHLY; break; default: timo = 0; } return timo; } int32_t br_fsscan_schedule(xlator_t *this) { time_t timo = 0; br_private_t *priv = NULL; char timestr[GF_TIMESTR_SIZE] = { 0, }; struct br_scrubber *fsscrub = NULL; struct gf_tw_timer_list *timer = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; fsscrub = &priv->fsscrub; scrub_monitor = &priv->scrub_monitor; scrub_monitor->boot = gf_time(); timo = br_fsscan_calculate_timeout(fsscrub->frequency); if (timo == 0) { gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_ZERO_TIMEOUT_BUG, "BUG: Zero schedule timeout"); goto error_return; } scrub_monitor->timer = GF_CALLOC(1, sizeof(*scrub_monitor->timer), gf_br_stub_mt_br_scanner_freq_t); if (!scrub_monitor->timer) goto error_return; timer = scrub_monitor->timer; INIT_LIST_HEAD(&timer->entry); timer->data = scrub_monitor; timer->expires = timo; timer->function = br_kickstart_scanner; gf_tw_add_timer(priv->timer_wheel, timer); _br_monitor_set_scrub_state(scrub_monitor, BR_SCRUB_STATE_PENDING); gf_time_fmt_FT(timestr, sizeof(timestr), (scrub_monitor->boot + timo)); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Scrubbing is " "scheduled to run at %s", timestr); return 0; error_return: return -1; } int32_t br_fsscan_activate(xlator_t *this) { time_t timo = 0; char timestr[GF_TIMESTR_SIZE] = { 0, }; time_t now = 0; br_private_t *priv = NULL; struct br_scrubber *fsscrub = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; fsscrub = &priv->fsscrub; scrub_monitor = &priv->scrub_monitor; now = gf_time(); timo = br_fsscan_calculate_timeout(fsscrub->frequency); if (timo == 0) { gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_ZERO_TIMEOUT_BUG, "BUG: Zero schedule timeout"); return -1; } pthread_mutex_lock(&scrub_monitor->donelock); { scrub_monitor->done = _gf_false; } pthread_mutex_unlock(&scrub_monitor->donelock); gf_time_fmt_FT(timestr, sizeof(timestr), now + timo); (void)gf_tw_mod_timer(priv->timer_wheel, scrub_monitor->timer, timo); _br_monitor_set_scrub_state(scrub_monitor, BR_SCRUB_STATE_PENDING); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Scrubbing is " "rescheduled to run at %s", timestr); return 0; } int32_t br_fsscan_reschedule(xlator_t *this) { int32_t ret = 0; time_t timo = 0; char timestr[GF_TIMESTR_SIZE] = { 0, }; time_t now = 0; br_private_t *priv = NULL; struct br_scrubber *fsscrub = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; fsscrub = &priv->fsscrub; scrub_monitor = &priv->scrub_monitor; if (!fsscrub->frequency_reconf) return 0; now = gf_time(); timo = br_fsscan_calculate_timeout(fsscrub->frequency); if (timo == 0) { gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_ZERO_TIMEOUT_BUG, "BUG: Zero schedule timeout"); return -1; } gf_time_fmt_FT(timestr, sizeof(timestr), now + timo); pthread_mutex_lock(&scrub_monitor->donelock); { scrub_monitor->done = _gf_false; } pthread_mutex_unlock(&scrub_monitor->donelock); ret = gf_tw_mod_timer_pending(priv->timer_wheel, scrub_monitor->timer, timo); if (ret == 0) gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Scrubber is currently running and would be " "rescheduled after completion"); else { _br_monitor_set_scrub_state(scrub_monitor, BR_SCRUB_STATE_PENDING); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Scrubbing rescheduled to run at %s", timestr); } return 0; } int32_t br_fsscan_ondemand(xlator_t *this) { int32_t ret = 0; time_t timo = 0; char timestr[GF_TIMESTR_SIZE] = { 0, }; time_t now = 0; br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; now = gf_time(); timo = BR_SCRUB_ONDEMAND; gf_time_fmt_FT(timestr, sizeof(timestr), now + timo); pthread_mutex_lock(&scrub_monitor->donelock); { scrub_monitor->done = _gf_false; } pthread_mutex_unlock(&scrub_monitor->donelock); ret = gf_tw_mod_timer_pending(priv->timer_wheel, scrub_monitor->timer, timo); if (ret == 0) gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Scrubber is currently running and would be " "rescheduled after completion"); else { _br_monitor_set_scrub_state(scrub_monitor, BR_SCRUB_STATE_PENDING); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Ondemand Scrubbing scheduled to run at %s", timestr); } return 0; } #define BR_SCRUB_THREAD_SCALE_LAZY 0 #define BR_SCRUB_THREAD_SCALE_NORMAL 0.4 #define BR_SCRUB_THREAD_SCALE_AGGRESSIVE 1.0 #ifndef M_E #define M_E 2.718 #endif /** * This is just a simple exponential scale to a fixed value selected * per throttle config. We probably need to be more smart and select * the scale based on the number of processor cores too. */ static unsigned int br_scrubber_calc_scale(xlator_t *this, unsigned int child_count, scrub_throttle_t throttle) { unsigned int scale = 0; switch (throttle) { case BR_SCRUB_THROTTLE_VOID: case BR_SCRUB_THROTTLE_STALLED: scale = 0; break; case BR_SCRUB_THROTTLE_LAZY: scale = child_count * pow(M_E, BR_SCRUB_THREAD_SCALE_LAZY); break; case BR_SCRUB_THROTTLE_NORMAL: scale = child_count * pow(M_E, BR_SCRUB_THREAD_SCALE_NORMAL); break; case BR_SCRUB_THROTTLE_AGGRESSIVE: scale = child_count * pow(M_E, BR_SCRUB_THREAD_SCALE_AGGRESSIVE); break; default: gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_UNKNOWN_THROTTLE, "Unknown throttle %d", throttle); } return scale; } static br_child_t * _br_scrubber_get_next_child(struct br_scrubber *fsscrub) { br_child_t *child = NULL; child = list_first_entry(&fsscrub->scrublist, br_child_t, list); list_rotate_left(&fsscrub->scrublist); return child; } static void _br_scrubber_get_entry(br_child_t *child, struct br_fsscan_entry **fsentry) { struct br_scanfs *fsscan = &child->fsscan; if (list_empty(&fsscan->ready)) return; *fsentry = list_first_entry(&fsscan->ready, struct br_fsscan_entry, list); list_del_init(&(*fsentry)->list); } static void _br_scrubber_find_scrubbable_entry(struct br_scrubber *fsscrub, struct br_fsscan_entry **fsentry) { br_child_t *child = NULL; br_child_t *firstchild = NULL; while (1) { while (list_empty(&fsscrub->scrublist)) pthread_cond_wait(&fsscrub->cond, &fsscrub->mutex); firstchild = NULL; for (child = _br_scrubber_get_next_child(fsscrub); child != firstchild; child = _br_scrubber_get_next_child(fsscrub)) { if (!firstchild) firstchild = child; _br_scrubber_get_entry(child, fsentry); if (*fsentry) break; } if (*fsentry) break; /* nothing to work on.. wait till available */ pthread_cond_wait(&fsscrub->cond, &fsscrub->mutex); } } static void br_scrubber_pick_entry(struct br_scrubber *fsscrub, struct br_fsscan_entry **fsentry) { pthread_cleanup_push(_br_lock_cleaner, &fsscrub->mutex); pthread_mutex_lock(&fsscrub->mutex); { *fsentry = NULL; _br_scrubber_find_scrubbable_entry(fsscrub, fsentry); } pthread_mutex_unlock(&fsscrub->mutex); pthread_cleanup_pop(0); } struct br_scrub_entry { gf_boolean_t scrubbed; struct br_fsscan_entry *fsentry; }; /** * We need to be a bit careful here. These thread(s) are prone to cancellations * when threads are scaled down (depending on the thottling value configured) * and pausing scrub. A thread can get cancelled while it's waiting for entries * in the ->pending queue or when an object is undergoing scrubbing. */ static void br_scrubber_entry_handle(void *arg) { struct br_scanfs *fsscan = NULL; struct br_scrub_entry *sentry = NULL; struct br_fsscan_entry *fsentry = NULL; sentry = arg; fsentry = sentry->fsentry; fsscan = fsentry->fsscan; LOCK(&fsscan->entrylock); { if (sentry->scrubbed) { _br_fsscan_dec_entry_count(fsscan); /* cleanup ->entry */ fsentry->data = NULL; fsentry->fsscan = NULL; loc_wipe(&fsentry->parent); gf_dirent_entry_free(fsentry->entry); GF_FREE(sentry->fsentry); } else { /* (re)queue the entry again for scrub */ _br_fsscan_collect_entry(fsscan, sentry->fsentry); } } UNLOCK(&fsscan->entrylock); } static void br_scrubber_scrub_entry(xlator_t *this, struct br_fsscan_entry *fsentry) { struct br_scrub_entry sentry = { 0, }; sentry.scrubbed = 0; sentry.fsentry = fsentry; pthread_cleanup_push(br_scrubber_entry_handle, &sentry); { (void)br_scrubber_scrub_begin(this, fsentry); sentry.scrubbed = 1; } pthread_cleanup_pop(1); } void * br_scrubber_proc(void *arg) { xlator_t *this = NULL; struct br_scrubber *fsscrub = NULL; struct br_fsscan_entry *fsentry = NULL; fsscrub = arg; THIS = this = fsscrub->this; while (1) { br_scrubber_pick_entry(fsscrub, &fsentry); br_scrubber_scrub_entry(this, fsentry); sleep(1); } return NULL; } static int32_t br_scrubber_scale_up(xlator_t *this, struct br_scrubber *fsscrub, unsigned int v1, unsigned int v2) { int i = 0; int32_t ret = -1; int diff = 0; struct br_scrubbers *scrub = NULL; diff = (int)(v2 - v1); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCALING_UP_SCRUBBER, "Scaling up scrubbers [%d => %d]", v1, v2); for (i = 0; i < diff; i++) { scrub = GF_CALLOC(1, sizeof(*scrub), gf_br_mt_br_scrubber_t); if (!scrub) break; INIT_LIST_HEAD(&scrub->list); ret = gf_thread_create(&scrub->scrubthread, NULL, br_scrubber_proc, fsscrub, "brsproc"); if (ret) { GF_FREE(scrub); break; } fsscrub->nr_scrubbers++; list_add_tail(&scrub->list, &fsscrub->scrubbers); } if (ret && i == 0) goto error_return; if (i != diff) /* degraded scaling.. */ gf_msg(this->name, GF_LOG_WARNING, 0, BRB_MSG_SCALE_UP_FAILED, "Could not fully scale up to %d scrubber(s). Spawned " "%d/%d [total scrubber(s): %d]", v2, i, diff, (v1 + i)); return 0; error_return: return -1; } static int32_t br_scrubber_scale_down(xlator_t *this, struct br_scrubber *fsscrub, unsigned int v1, unsigned int v2) { int i = 0; int diff = 0; int32_t ret = -1; struct br_scrubbers *scrub = NULL; diff = (int)(v1 - v2); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCALE_DOWN_SCRUBBER, "Scaling down scrubbers [%d => %d]", v1, v2); for (i = 0; i < diff; i++) { scrub = list_first_entry(&fsscrub->scrubbers, struct br_scrubbers, list); list_del_init(&scrub->list); ret = gf_thread_cleanup_xint(scrub->scrubthread); if (ret) break; GF_FREE(scrub); fsscrub->nr_scrubbers--; } if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, BRB_MSG_SCALE_DOWN_FAILED, "Could not fully scale down " "to %d scrubber(s). Terminated %d/%d [total " "scrubber(s): %d]", v1, i, diff, (v2 - i)); ret = 0; } return ret; } static int32_t br_scrubber_configure(xlator_t *this, unsigned int child_count, struct br_scrubber *fsscrub, scrub_throttle_t nthrottle) { int32_t ret = 0; unsigned int v1 = 0; unsigned int v2 = 0; v1 = fsscrub->nr_scrubbers; v2 = br_scrubber_calc_scale(this, child_count, nthrottle); if (v1 == v2) return 0; if (v1 > v2) ret = br_scrubber_scale_down(this, fsscrub, v1, v2); else ret = br_scrubber_scale_up(this, fsscrub, v1, v2); return ret; } static int32_t br_scrubber_fetch_option(xlator_t *this, char *opt, dict_t *options, char **value) { if (options) GF_OPTION_RECONF(opt, *value, options, str, error_return); else GF_OPTION_INIT(opt, *value, str, error_return); return 0; error_return: return -1; } /* internal "throttle" override */ #define BR_SCRUB_STALLED "STALLED" /* TODO: token buket spec */ static int32_t br_scrubber_handle_throttle(xlator_t *this, br_private_t *priv, dict_t *options, gf_boolean_t scrubstall) { int32_t ret = 0; char *tmp = NULL; struct br_scrubber *fsscrub = NULL; scrub_throttle_t nthrottle = BR_SCRUB_THROTTLE_VOID; fsscrub = &priv->fsscrub; fsscrub->throttle_reconf = _gf_false; ret = br_scrubber_fetch_option(this, "scrub-throttle", options, &tmp); if (ret) goto error_return; if (scrubstall) tmp = BR_SCRUB_STALLED; if (strcasecmp(tmp, "lazy") == 0) nthrottle = BR_SCRUB_THROTTLE_LAZY; else if (strcasecmp(tmp, "normal") == 0) nthrottle = BR_SCRUB_THROTTLE_NORMAL; else if (strcasecmp(tmp, "aggressive") == 0) nthrottle = BR_SCRUB_THROTTLE_AGGRESSIVE; else if (strcasecmp(tmp, BR_SCRUB_STALLED) == 0) nthrottle = BR_SCRUB_THROTTLE_STALLED; else goto error_return; /* on failure old throttling value is preserved */ ret = br_scrubber_configure(this, priv->child_count, fsscrub, nthrottle); if (ret) goto error_return; if (fsscrub->throttle != nthrottle) fsscrub->throttle_reconf = _gf_true; fsscrub->throttle = nthrottle; return 0; error_return: return -1; } static int32_t br_scrubber_handle_stall(xlator_t *this, br_private_t *priv, dict_t *options, gf_boolean_t *scrubstall) { int32_t ret = 0; char *tmp = NULL; ret = br_scrubber_fetch_option(this, "scrub-state", options, &tmp); if (ret) goto error_return; if (strcasecmp(tmp, "pause") == 0) /* anything else is active */ *scrubstall = _gf_true; return 0; error_return: return -1; } static int32_t br_scrubber_handle_freq(xlator_t *this, br_private_t *priv, dict_t *options, gf_boolean_t scrubstall) { int32_t ret = -1; char *tmp = NULL; scrub_freq_t frequency = BR_FSSCRUB_FREQ_HOURLY; struct br_scrubber *fsscrub = NULL; fsscrub = &priv->fsscrub; fsscrub->frequency_reconf = _gf_true; ret = br_scrubber_fetch_option(this, "scrub-freq", options, &tmp); if (ret) goto error_return; if (scrubstall) tmp = BR_SCRUB_STALLED; if (strcasecmp(tmp, "hourly") == 0) { frequency = BR_FSSCRUB_FREQ_HOURLY; } else if (strcasecmp(tmp, "daily") == 0) { frequency = BR_FSSCRUB_FREQ_DAILY; } else if (strcasecmp(tmp, "weekly") == 0) { frequency = BR_FSSCRUB_FREQ_WEEKLY; } else if (strcasecmp(tmp, "biweekly") == 0) { frequency = BR_FSSCRUB_FREQ_BIWEEKLY; } else if (strcasecmp(tmp, "monthly") == 0) { frequency = BR_FSSCRUB_FREQ_MONTHLY; } else if (strcasecmp(tmp, "minute") == 0) { frequency = BR_FSSCRUB_FREQ_MINUTE; } else if (strcasecmp(tmp, BR_SCRUB_STALLED) == 0) { frequency = BR_FSSCRUB_FREQ_STALLED; } else goto error_return; if (fsscrub->frequency == frequency) fsscrub->frequency_reconf = _gf_false; else fsscrub->frequency = frequency; return 0; error_return: return -1; } static void br_scrubber_log_option(xlator_t *this, br_private_t *priv, gf_boolean_t scrubstall) { struct br_scrubber *fsscrub = &priv->fsscrub; char *scrub_throttle_str[] = { [BR_SCRUB_THROTTLE_LAZY] = "lazy", [BR_SCRUB_THROTTLE_NORMAL] = "normal", [BR_SCRUB_THROTTLE_AGGRESSIVE] = "aggressive", [BR_SCRUB_THROTTLE_STALLED] = "stalled", }; char *scrub_freq_str[] = { [0] = "", [BR_FSSCRUB_FREQ_HOURLY] = "hourly", [BR_FSSCRUB_FREQ_DAILY] = "daily", [BR_FSSCRUB_FREQ_WEEKLY] = "weekly", [BR_FSSCRUB_FREQ_BIWEEKLY] = "biweekly", [BR_FSSCRUB_FREQ_MONTHLY] = "monthly (30 days)", [BR_FSSCRUB_FREQ_MINUTE] = "every minute", }; if (scrubstall) return; /* logged as pause */ if (fsscrub->frequency_reconf || fsscrub->throttle_reconf) { if (fsscrub->throttle == BR_SCRUB_THROTTLE_VOID) return; gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_TUNABLE, "SCRUB TUNABLES:: [Frequency: %s, Throttle: %s]", scrub_freq_str[fsscrub->frequency], scrub_throttle_str[fsscrub->throttle]); } } int32_t br_scrubber_handle_options(xlator_t *this, br_private_t *priv, dict_t *options) { int32_t ret = 0; gf_boolean_t scrubstall = _gf_false; /* not as dangerous as it sounds */ ret = br_scrubber_handle_stall(this, priv, options, &scrubstall); if (ret) goto error_return; ret = br_scrubber_handle_throttle(this, priv, options, scrubstall); if (ret) goto error_return; ret = br_scrubber_handle_freq(this, priv, options, scrubstall); if (ret) goto error_return; br_scrubber_log_option(this, priv, scrubstall); return 0; error_return: return -1; } static inode_t * br_lookup_bad_obj_dir(xlator_t *this, br_child_t *child, uuid_t gfid) { struct iatt statbuf = { 0, }; inode_table_t *table = NULL; int32_t ret = -1; loc_t loc = { 0, }; inode_t *linked_inode = NULL; int32_t op_errno = 0; GF_VALIDATE_OR_GOTO("bit-rot-scrubber", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, child, out); table = child->table; loc.inode = inode_new(table); if (!loc.inode) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_NO_MEMORY, "failed to allocate a new inode for" "bad object directory"); goto out; } gf_uuid_copy(loc.gfid, gfid); ret = syncop_lookup(child->xl, &loc, &statbuf, NULL, NULL, NULL); if (ret < 0) { op_errno = -ret; gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_LOOKUP_FAILED, "failed to lookup the bad " "objects directory (gfid: %s (%s))", uuid_utoa(gfid), strerror(op_errno)); goto out; } linked_inode = inode_link(loc.inode, NULL, NULL, &statbuf); if (linked_inode) inode_lookup(linked_inode); out: loc_wipe(&loc); return linked_inode; } static int32_t br_read_bad_object_dir(xlator_t *this, br_child_t *child, fd_t *fd, dict_t *dict) { gf_dirent_t entries; gf_dirent_t *entry = NULL; int32_t ret = -1; off_t offset = 0; int32_t count = 0; char key[32] = { 0, }; dict_t *out_dict = NULL; INIT_LIST_HEAD(&entries.list); while ((ret = syncop_readdir(child->xl, fd, 131072, offset, &entries, NULL, &out_dict))) { if (ret < 0) goto out; list_for_each_entry(entry, &entries.list, list) { offset = entry->d_off; snprintf(key, sizeof(key), "quarantine-%d", count); /* * ignore the dict_set errors for now. The intention is * to get as many bad objects as possible instead of * erroring out at the first failure. */ ret = dict_set_dynstr_with_alloc(dict, key, entry->d_name); if (!ret) count++; if (out_dict) { dict_copy(out_dict, dict); dict_unref(out_dict); out_dict = NULL; } } gf_dirent_free(&entries); } ret = count; ret = dict_set_int32_sizen(dict, "count", count); out: return ret; } static int32_t br_get_bad_objects_from_child(xlator_t *this, dict_t *dict, br_child_t *child) { inode_t *inode = NULL; inode_table_t *table = NULL; fd_t *fd = NULL; int32_t ret = -1; loc_t loc = { 0, }; int32_t op_errno = 0; GF_VALIDATE_OR_GOTO("bit-rot-scrubber", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, child, out); GF_VALIDATE_OR_GOTO(this->name, dict, out); table = child->table; inode = inode_find(table, BR_BAD_OBJ_CONTAINER); if (!inode) { inode = br_lookup_bad_obj_dir(this, child, BR_BAD_OBJ_CONTAINER); if (!inode) goto out; } fd = fd_create(inode, 0); if (!fd) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_FD_CREATE_FAILED, "fd creation for the bad " "objects directory failed (gfid: %s)", uuid_utoa(BR_BAD_OBJ_CONTAINER)); goto out; } loc.inode = inode; gf_uuid_copy(loc.gfid, inode->gfid); ret = syncop_opendir(child->xl, &loc, fd, NULL, NULL); if (ret < 0) { op_errno = -ret; fd_unref(fd); fd = NULL; gf_msg(this->name, GF_LOG_ERROR, op_errno, BRB_MSG_FD_CREATE_FAILED, "failed to open the bad " "objects directory %s", uuid_utoa(BR_BAD_OBJ_CONTAINER)); goto out; } fd_bind(fd); ret = br_read_bad_object_dir(this, child, fd, dict); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, BRB_MSG_BAD_OBJ_READDIR_FAIL, "readdir of the bad " "objects directory (%s) failed ", uuid_utoa(BR_BAD_OBJ_CONTAINER)); goto out; } ret = 0; out: loc_wipe(&loc); if (fd) fd_unref(fd); return ret; } static int32_t br_collect_bad_objects_of_child(xlator_t *this, br_child_t *child, dict_t *dict, dict_t *child_dict, int32_t total_count) { int32_t ret = -1; int32_t count = 0; char key[32] = { 0, }; char main_key[32] = { 0, }; int32_t j = 0; int32_t tmp_count = 0; char *entry = NULL; char tmp[PATH_MAX] = { 0, }; char *path = NULL; int32_t len = 0; ret = dict_get_int32_sizen(child_dict, "count", &count); if (ret) goto out; tmp_count = total_count; for (j = 0; j < count; j++) { len = snprintf(key, sizeof(key), "quarantine-%d", j); ret = dict_get_strn(child_dict, key, len, &entry); if (ret) continue; ret = dict_get_str(child_dict, entry, &path); len = snprintf(tmp, PATH_MAX, "%s ==> BRICK: %s\n path: %s", entry, child->brick_path, path); if ((len < 0) || (len >= PATH_MAX)) { continue; } snprintf(main_key, sizeof(main_key), "quarantine-%d", tmp_count); ret = dict_set_dynstr_with_alloc(dict, main_key, tmp); if (!ret) tmp_count++; path = NULL; } ret = tmp_count; out: return ret; } int32_t br_collect_bad_objects_from_children(xlator_t *this, dict_t *dict) { int32_t ret = -1; dict_t *child_dict = NULL; int32_t i = 0; int32_t total_count = 0; br_child_t *child = NULL; br_private_t *priv = NULL; dict_t *tmp_dict = NULL; priv = this->private; tmp_dict = dict; for (i = 0; i < priv->child_count; i++) { child = &priv->children[i]; GF_ASSERT(child); if (!_br_is_child_connected(child)) continue; child_dict = dict_new(); if (!child_dict) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_NO_MEMORY, "failed to allocate dict"); continue; } ret = br_get_bad_objects_from_child(this, child_dict, child); /* * Continue asking the remaining children for the list of * bad objects even though getting the list from one of them * fails. */ if (ret) { dict_unref(child_dict); continue; } ret = br_collect_bad_objects_of_child(this, child, tmp_dict, child_dict, total_count); if (ret < 0) { dict_unref(child_dict); continue; } total_count = ret; dict_unref(child_dict); child_dict = NULL; } ret = dict_set_int32(tmp_dict, "total-count", total_count); return ret; } int32_t br_get_bad_objects_list(xlator_t *this, dict_t **dict) { int32_t ret = -1; dict_t *tmp_dict = NULL; GF_VALIDATE_OR_GOTO("bir-rot-scrubber", this, out); GF_VALIDATE_OR_GOTO(this->name, dict, out); tmp_dict = *dict; if (!tmp_dict) { tmp_dict = dict_new(); if (!tmp_dict) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_NO_MEMORY, "failed to allocate dict"); goto out; } *dict = tmp_dict; } ret = br_collect_bad_objects_from_children(this, tmp_dict); out: return ret; } static int wait_for_scrub_to_finish(xlator_t *this) { int ret = -1; br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; GF_VALIDATE_OR_GOTO("bit-rot", scrub_monitor, out); GF_VALIDATE_OR_GOTO("bit-rot", this, out); gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, "Waiting for all children to start and finish scrub"); pthread_mutex_lock(&scrub_monitor->donelock); { while (!scrub_monitor->done) pthread_cond_wait(&scrub_monitor->donecond, &scrub_monitor->donelock); } pthread_mutex_unlock(&scrub_monitor->donelock); ret = 0; out: return ret; } /** * This function is executed in a separate thread. This is scrubber monitor * thread that takes care of state machine. */ void * br_monitor_thread(void *arg) { int32_t ret = 0; xlator_t *this = NULL; br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; this = arg; priv = this->private; /* * Since, this is the topmost xlator, THIS has to be set by bit-rot * xlator itself (STACK_WIND won't help in this case). Also it has * to be done for each thread that gets spawned. Otherwise, a new * thread will get global_xlator's pointer when it does "THIS". */ THIS = this; scrub_monitor = &priv->scrub_monitor; pthread_mutex_lock(&scrub_monitor->mutex); { while (!scrub_monitor->inited) pthread_cond_wait(&scrub_monitor->cond, &scrub_monitor->mutex); } pthread_mutex_unlock(&scrub_monitor->mutex); /* this needs to be serialized with reconfigure() */ pthread_mutex_lock(&priv->lock); { ret = br_scrub_state_machine(this, _gf_false); } pthread_mutex_unlock(&priv->lock); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, BRB_MSG_SSM_FAILED, "Scrub state machine failed"); goto out; } while (1) { /* Wait for all children to finish scrubbing */ ret = wait_for_scrub_to_finish(this); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, BRB_MSG_SCRUB_WAIT_FAILED, "Scrub wait failed"); goto out; } /* scrub exit criteria: Move the state to PENDING */ br_scrubber_exit_control(this); } out: return NULL; } static void br_set_scrub_state(struct br_monitor *scrub_monitor, br_scrub_state_t state) { LOCK(&scrub_monitor->lock); { _br_monitor_set_scrub_state(scrub_monitor, state); } UNLOCK(&scrub_monitor->lock); } int32_t br_scrubber_monitor_init(xlator_t *this, br_private_t *priv) { struct br_monitor *scrub_monitor = NULL; int ret = 0; scrub_monitor = &priv->scrub_monitor; LOCK_INIT(&scrub_monitor->lock); scrub_monitor->this = this; scrub_monitor->inited = _gf_false; pthread_mutex_init(&scrub_monitor->mutex, NULL); pthread_cond_init(&scrub_monitor->cond, NULL); scrub_monitor->kick = _gf_false; scrub_monitor->active_child_count = 0; pthread_mutex_init(&scrub_monitor->wakelock, NULL); pthread_cond_init(&scrub_monitor->wakecond, NULL); scrub_monitor->done = _gf_false; pthread_mutex_init(&scrub_monitor->donelock, NULL); pthread_cond_init(&scrub_monitor->donecond, NULL); /* Set the state to INACTIVE */ br_set_scrub_state(&priv->scrub_monitor, BR_SCRUB_STATE_INACTIVE); /* Start the monitor thread */ ret = gf_thread_create(&scrub_monitor->thread, NULL, br_monitor_thread, this, "brmon"); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, -ret, BRB_MSG_SPAWN_FAILED, "monitor thread creation failed"); ret = -1; goto err; } return 0; err: pthread_mutex_destroy(&scrub_monitor->mutex); pthread_cond_destroy(&scrub_monitor->cond); pthread_mutex_destroy(&scrub_monitor->wakelock); pthread_cond_destroy(&scrub_monitor->wakecond); pthread_mutex_destroy(&scrub_monitor->donelock); pthread_cond_destroy(&scrub_monitor->donecond); LOCK_DESTROY(&scrub_monitor->lock); return ret; } int32_t br_scrubber_init(xlator_t *this, br_private_t *priv) { struct br_scrubber *fsscrub = NULL; int ret = 0; priv->tbf = tbf_init(NULL, 0); if (!priv->tbf) return -1; ret = br_scrubber_monitor_init(this, priv); if (ret) return -1; fsscrub = &priv->fsscrub; fsscrub->this = this; fsscrub->throttle = BR_SCRUB_THROTTLE_VOID; pthread_mutex_init(&fsscrub->mutex, NULL); pthread_cond_init(&fsscrub->cond, NULL); fsscrub->nr_scrubbers = 0; INIT_LIST_HEAD(&fsscrub->scrubbers); INIT_LIST_HEAD(&fsscrub->scrublist); return 0; } glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/bit-rot.c0000644000000000000000000000013114522202451024506 xustar000000000000000029 mtime=1699284265.65302739 30 atime=1699284265.652027387 30 ctime=1699284305.034146004 glusterfs-11.1/xlators/features/bit-rot/src/bitd/bit-rot.c0000664000175100017510000016467014522202451025004 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "bit-rot.h" #include "bit-rot-scrub.h" #include #include "bit-rot-bitd-messages.h" #define BR_HASH_CALC_READ_SIZE (128 * 1024) typedef int32_t(br_child_handler)(xlator_t *, br_child_t *); struct br_child_event { xlator_t *this; br_child_t *child; br_child_handler *call; struct list_head list; }; static int br_find_child_index(xlator_t *this, xlator_t *child) { br_private_t *priv = NULL; int i = -1; int index = -1; GF_VALIDATE_OR_GOTO("bit-rot", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, child, out); priv = this->private; for (i = 0; i < priv->child_count; i++) { if (child == priv->children[i].xl) { index = i; break; } } out: return index; } static br_child_t * br_get_child_from_brick_path(xlator_t *this, char *brick_path) { br_private_t *priv = NULL; br_child_t *child = NULL; br_child_t *tmp = NULL; int i = 0; GF_VALIDATE_OR_GOTO("bit-rot", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_VALIDATE_OR_GOTO(this->name, brick_path, out); priv = this->private; pthread_mutex_lock(&priv->lock); { for (i = 0; i < priv->child_count; i++) { tmp = &priv->children[i]; if (!strcmp(tmp->brick_path, brick_path)) { child = tmp; break; } } } pthread_mutex_unlock(&priv->lock); out: return child; } /** * probably we'll encapsulate brick inside our own structure when * needed -- later. */ static void * br_brick_init(void *xl, struct gf_brick_spec *brick) { return brick; } /** * and cleanup things here when allocated br_brick_init(). */ static void br_brick_fini(void *xl, char *brick, void *data) { return; } /** * TODO: Signature can contain null terminators which causes bitrot * stub to store truncated hash as it depends on string length of * the hash. * * FIX: Send the string length as part of the signature struct and * change stub to handle this change. */ static br_isignature_t * br_prepare_signature(const unsigned char *sign, unsigned long hashlen, int8_t hashtype, br_object_t *object) { br_isignature_t *signature = NULL; /* TODO: use mem-pool */ signature = GF_CALLOC(1, signature_size(hashlen + 1), gf_br_stub_mt_signature_t); if (!signature) return NULL; /* object version */ signature->signedversion = object->signedversion; /* signature length & type */ signature->signaturelen = hashlen; signature->signaturetype = hashtype; /* signature itself */ memcpy(signature->signature, (char *)sign, hashlen); signature->signature[hashlen + 1] = '\0'; return signature; } gf_boolean_t bitd_is_bad_file(xlator_t *this, br_child_t *child, loc_t *loc, fd_t *fd) { int32_t ret = -1; dict_t *xattr = NULL; inode_t *inode = NULL; gf_boolean_t bad_file = _gf_false; GF_VALIDATE_OR_GOTO("bit-rot", this, out); inode = (loc) ? loc->inode : fd->inode; if (fd) ret = syncop_fgetxattr(child->xl, fd, &xattr, BITROT_OBJECT_BAD_KEY, NULL, NULL); else if (loc) ret = syncop_getxattr(child->xl, loc, &xattr, BITROT_OBJECT_BAD_KEY, NULL, NULL); if (!ret) { gf_msg_debug(this->name, 0, "[GFID: %s] is marked corrupted", uuid_utoa(inode->gfid)); bad_file = _gf_true; } if (xattr) dict_unref(xattr); out: return bad_file; } /** * Do a lookup on the gfid present within the object. */ static int32_t br_object_lookup(xlator_t *this, br_object_t *object, struct iatt *iatt, inode_t **linked_inode) { int ret = -EINVAL; loc_t loc = { 0, }; inode_t *inode = NULL; GF_VALIDATE_OR_GOTO("bit-rot", this, out); GF_VALIDATE_OR_GOTO(this->name, object, out); inode = inode_find(object->child->table, object->gfid); if (inode) loc.inode = inode; else loc.inode = inode_new(object->child->table); if (!loc.inode) { ret = -ENOMEM; goto out; } gf_uuid_copy(loc.gfid, object->gfid); ret = syncop_lookup(object->child->xl, &loc, iatt, NULL, NULL, NULL); if (ret < 0) goto out; /* * The file might have been deleted by the application * after getting the event, but before doing a lookup. * So use linked_inode after inode_link is done. */ *linked_inode = inode_link(loc.inode, NULL, NULL, iatt); if (*linked_inode) inode_lookup(*linked_inode); out: loc_wipe(&loc); return ret; } /** * open the object with O_RDONLY flags and return the fd. How to let brick * know that open is being done by bitd because syncop framework does not allow * passing xdata -- may be use frame->root->pid itself. */ static int32_t br_object_open(xlator_t *this, br_object_t *object, inode_t *inode, fd_t **openfd) { int32_t ret = -1; fd_t *fd = NULL; loc_t loc = { 0, }; GF_VALIDATE_OR_GOTO("bit-rot", this, out); GF_VALIDATE_OR_GOTO(this->name, object, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); ret = -EINVAL; fd = fd_create(inode, 0); if (!fd) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_FD_CREATE_FAILED, "gfid=%s", uuid_utoa(inode->gfid), NULL); goto out; } loc.inode = inode_ref(inode); gf_uuid_copy(loc.gfid, inode->gfid); ret = syncop_open(object->child->xl, &loc, O_RDONLY, fd, NULL, NULL); if (ret) { br_log_object(this, "open", inode->gfid, -ret); fd_unref(fd); fd = NULL; } else { fd_bind(fd); *openfd = fd; } loc_wipe(&loc); out: return ret; } /** * read 128k block from the object @object from the offset @offset * and return the buffer. */ static int32_t br_object_read_block_and_sign(xlator_t *this, fd_t *fd, br_child_t *child, off_t offset, size_t size, SHA256_CTX *sha256) { int32_t ret = -1; tbf_t *tbf = NULL; struct iovec *iovec = NULL; struct iobref *iobref = NULL; br_private_t *priv = NULL; int count = 0; int i = 0; GF_VALIDATE_OR_GOTO("bit-rot", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); GF_VALIDATE_OR_GOTO(this->name, child, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv->tbf, out); tbf = priv->tbf; ret = syncop_readv(child->xl, fd, size, offset, 0, &iovec, &count, &iobref, NULL, NULL, NULL); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, BRB_MSG_READV_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); ret = -1; goto out; } if (ret == 0) goto out; for (i = 0; i < count; i++) { TBF_THROTTLE_BEGIN(tbf, TBF_OP_HASH, iovec[i].iov_len); { SHA256_Update(sha256, (const unsigned char *)(iovec[i].iov_base), iovec[i].iov_len); } TBF_THROTTLE_BEGIN(tbf, TBF_OP_HASH, iovec[i].iov_len); } out: if (iovec) GF_FREE(iovec); if (iobref) iobref_unref(iobref); return ret; } int32_t br_calculate_obj_checksum(unsigned char *md, br_child_t *child, fd_t *fd) { int32_t ret = -1; off_t offset = 0; size_t block = BR_HASH_CALC_READ_SIZE; xlator_t *this = NULL; SHA256_CTX sha256; GF_VALIDATE_OR_GOTO("bit-rot", child, out); GF_VALIDATE_OR_GOTO("bit-rot", fd, out); this = child->this; SHA256_Init(&sha256); while (1) { ret = br_object_read_block_and_sign(this, fd, child, offset, block, &sha256); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_BLOCK_READ_FAILED, "offset=%" PRIu64, offset, "object-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); break; } if (ret == 0) break; offset += ret; } if (ret == 0) SHA256_Final(md, &sha256); out: return ret; } static int32_t br_object_read_sign(inode_t *linked_inode, fd_t *fd, br_object_t *object) { int32_t ret = -1; xlator_t *this = NULL; dict_t *xattr = NULL; unsigned char *md = NULL; br_isignature_t *sign = NULL; GF_VALIDATE_OR_GOTO("bit-rot", object, out); GF_VALIDATE_OR_GOTO("bit-rot", linked_inode, out); GF_VALIDATE_OR_GOTO("bit-rot", fd, out); this = object->this; md = GF_MALLOC(SHA256_DIGEST_LENGTH, gf_common_mt_char); if (!md) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_SAVING_HASH_FAILED, "object-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } ret = br_calculate_obj_checksum(md, object->child, fd); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_CALC_CHECKSUM_FAILED, "object-gfid=%s", uuid_utoa(linked_inode->gfid), NULL); goto free_signature; } sign = br_prepare_signature(md, SHA256_DIGEST_LENGTH, BR_SIGNATURE_TYPE_SHA256, object); if (!sign) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_GET_SIGN_FAILED, "object-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto free_signature; } xattr = dict_for_key_value(GLUSTERFS_SET_OBJECT_SIGNATURE, (void *)sign, signature_size(SHA256_DIGEST_LENGTH), _gf_true); if (!xattr) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_SET_SIGN_FAILED, "dict-allocation object-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto free_isign; } ret = syncop_fsetxattr(object->child->xl, fd, xattr, 0, NULL, NULL); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_SET_SIGN_FAILED, "fsetxattr object-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto unref_dict; } ret = 0; unref_dict: dict_unref(xattr); free_isign: GF_FREE(sign); free_signature: GF_FREE(md); out: return ret; } static int br_object_sign_softerror(int32_t op_errno) { return ((op_errno == ENOENT) || (op_errno == ESTALE) || (op_errno == ENODATA)); } void br_log_object(xlator_t *this, char *op, uuid_t gfid, int32_t op_errno) { int softerror = br_object_sign_softerror(op_errno); if (softerror) { gf_msg_debug(this->name, op_errno, "%s() failed on object %s", op, uuid_utoa(gfid)); } else { gf_smsg(this->name, GF_LOG_ERROR, op_errno, BRB_MSG_OP_FAILED, "op=%s", op, "gfid=%s", uuid_utoa(gfid), NULL); } } void br_log_object_path(xlator_t *this, char *op, const char *path, int32_t op_errno) { int softerror = br_object_sign_softerror(op_errno); if (softerror) { gf_msg_debug(this->name, op_errno, "%s() failed on object %s", op, path); } else { gf_smsg(this->name, GF_LOG_ERROR, op_errno, BRB_MSG_OP_FAILED, "op=%s", op, "path=%s", path, NULL); } } static void br_trigger_sign(xlator_t *this, br_child_t *child, inode_t *linked_inode, loc_t *loc, gf_boolean_t need_reopen) { fd_t *fd = NULL; int32_t ret = -1; uint32_t val = 0; dict_t *dict = NULL; pid_t pid = GF_CLIENT_PID_BITD; syncopctx_setfspid(&pid); val = (need_reopen == _gf_true) ? BR_OBJECT_REOPEN : BR_OBJECT_RESIGN; dict = dict_new(); if (!dict) goto out; ret = dict_set_uint32(dict, BR_REOPEN_SIGN_HINT_KEY, val); if (ret) goto cleanup_dict; ret = -1; fd = fd_create(linked_inode, 0); if (!fd) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_FD_CREATE_FAILED, "gfid=%s", uuid_utoa(linked_inode->gfid), NULL); goto cleanup_dict; } ret = syncop_open(child->xl, loc, O_RDWR, fd, NULL, NULL); if (ret) { br_log_object(this, "open", linked_inode->gfid, -ret); goto unref_fd; } fd_bind(fd); ret = syncop_fsetxattr(child->xl, fd, dict, 0, NULL, NULL); if (ret) br_log_object(this, "fsetxattr", linked_inode->gfid, -ret); /* passthough: fd_unref() */ unref_fd: fd_unref(fd); cleanup_dict: dict_unref(dict); out: if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRB_MSG_TRIGGER_SIGN_FAILED, "gfid=%s", uuid_utoa(linked_inode->gfid), "reopen-hint-val=%d", val, NULL); } } static void br_object_resign(xlator_t *this, br_object_t *object, inode_t *linked_inode) { loc_t loc = { 0, }; loc.inode = inode_ref(linked_inode); gf_uuid_copy(loc.gfid, linked_inode->gfid); br_trigger_sign(this, object->child, linked_inode, &loc, _gf_false); loc_wipe(&loc); } /** * Sign a given object. This routine runs full throttle. There needs to be * some form of priority scheduling and/or read burstness to avoid starving * (or kicking) client I/O's. */ static int32_t br_sign_object(br_object_t *object) { int32_t ret = -1; inode_t *linked_inode = NULL; xlator_t *this = NULL; fd_t *fd = NULL; struct iatt iatt = { 0, }; pid_t pid = GF_CLIENT_PID_BITD; br_sign_state_t sign_info = BR_SIGN_NORMAL; GF_VALIDATE_OR_GOTO("bit-rot", object, out); this = object->this; /** * FIXME: This is required as signing an object is restricted to * clients with special frame->root->pid. Change the way client * pid is set. */ syncopctx_setfspid(&pid); ret = br_object_lookup(this, object, &iatt, &linked_inode); if (ret) { br_log_object(this, "lookup", object->gfid, -ret); goto out; } /** * For fd's that have notified for reopening, we send an explicit * open() followed by a dummy write() call. This triggers the * actual signing of the object. */ sign_info = ntohl(object->sign_info); if (sign_info == BR_SIGN_REOPEN_WAIT) { br_object_resign(this, object, linked_inode); goto unref_inode; } ret = br_object_open(this, object, linked_inode, &fd); if (!fd) { br_log_object(this, "open", object->gfid, -ret); goto unref_inode; } /** * we have an open file descriptor on the object. from here on, * do not be generous to file operation errors. */ gf_msg_debug(this->name, 0, "Signing object [%s]", uuid_utoa(linked_inode->gfid)); ret = br_object_read_sign(linked_inode, fd, object); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_READ_AND_SIGN_FAILED, "gfid=%s", uuid_utoa(linked_inode->gfid), NULL); goto unref_fd; } ret = 0; unref_fd: fd_unref(fd); unref_inode: inode_unref(linked_inode); out: return ret; } static br_object_t * __br_pick_object(br_private_t *priv) { br_object_t *object = NULL; while (list_empty(&priv->obj_queue->objects)) { pthread_cond_wait(&priv->object_cond, &priv->lock); } object = list_first_entry(&priv->obj_queue->objects, br_object_t, list); list_del_init(&object->list); return object; } /** * This is the place where the signing of the objects is triggered. */ void * br_process_object(void *arg) { xlator_t *this = NULL; br_object_t *object = NULL; br_private_t *priv = NULL; int32_t ret = -1; this = arg; priv = this->private; THIS = this; for (;;) { pthread_mutex_lock(&priv->lock); { object = __br_pick_object(priv); } pthread_mutex_unlock(&priv->lock); ret = br_sign_object(object); if (ret && !br_object_sign_softerror(-ret)) gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_SET_SIGN_FAILED, "gfid=%s", uuid_utoa(object->gfid), NULL); GF_FREE(object); } return NULL; } /** * This function gets kicked in once the object is expired from the * timer wheel. This actually adds the object received via notification * from the changelog to the queue from where the objects gets picked * up for signing. * * This routine can be made lightweight by introducing an alternate * timer-wheel API that dispatches _all_ expired objects in one-shot * rather than an object at-a-time. This routine can then just simply * be a call to list_splice_tail(). * * NOTE: use call_time to instrument signing time in br_sign_object(). */ static void br_add_object_to_queue(struct gf_tw_timer_list *timer, void *data, unsigned long call_time) { br_object_t *object = NULL; xlator_t *this = NULL; br_private_t *priv = NULL; object = data; this = object->this; priv = this->private; THIS = this; pthread_mutex_lock(&priv->lock); { list_add_tail(&object->list, &priv->obj_queue->objects); pthread_cond_broadcast(&priv->object_cond); } pthread_mutex_unlock(&priv->lock); if (timer) mem_put(timer); return; } static br_object_t * br_initialize_object(xlator_t *this, br_child_t *child, changelog_event_t *ev) { br_object_t *object = NULL; object = GF_CALLOC(1, sizeof(*object), gf_br_mt_br_object_t); if (!object) goto out; INIT_LIST_HEAD(&object->list); object->this = this; object->child = child; gf_uuid_copy(object->gfid, ev->u.releasebr.gfid); /* NOTE: it's BE, but no worry */ object->signedversion = ev->u.releasebr.version; object->sign_info = ev->u.releasebr.sign_info; out: return object; } static struct gf_tw_timer_list * br_initialize_timer(xlator_t *this, br_object_t *object, br_child_t *child, changelog_event_t *ev) { br_private_t *priv = NULL; struct gf_tw_timer_list *timer = NULL; priv = this->private; timer = mem_get0(child->timer_pool); if (!timer) goto out; INIT_LIST_HEAD(&timer->entry); timer->expires = priv->expiry_time; if (!timer->expires) timer->expires = 1; timer->data = object; timer->function = br_add_object_to_queue; gf_tw_add_timer(priv->timer_wheel, timer); out: return timer; } static int32_t br_schedule_object_reopen(xlator_t *this, br_object_t *object, br_child_t *child, changelog_event_t *ev) { struct gf_tw_timer_list *timer = NULL; timer = br_initialize_timer(this, object, child, ev); if (!timer) gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_SET_TIMER_FAILED, "gfid=%s", uuid_utoa(object->gfid), NULL); return timer ? 0 : -1; } static int32_t br_object_quicksign(xlator_t *this, br_object_t *object) { br_add_object_to_queue(NULL, object, 0ULL); return 0; } /** * This callback function registered with the changelog is executed * whenever a notification from the changelog is received. This should * add the object (or the gfid) on which the notification has come to * the timer-wheel with some expiry time. * * TODO: use mem-pool for allocations and maybe allocate timer and * object as a single alloc and bifurcate their respective pointers. */ static void br_brick_callback(void *xl, char *brick, void *data, changelog_event_t *ev) { int32_t ret = 0; uuid_t gfid = { 0, }; xlator_t *this = NULL; br_object_t *object = NULL; br_child_t *child = NULL; br_sign_state_t sign_info = BR_SIGN_INVALID; this = xl; GF_VALIDATE_OR_GOTO(this->name, ev, out); GF_VALIDATE_OR_GOTO("bit-rot", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); GF_ASSERT(ev->ev_type == CHANGELOG_OP_TYPE_BR_RELEASE); GF_ASSERT(!gf_uuid_is_null(ev->u.releasebr.gfid)); gf_uuid_copy(gfid, ev->u.releasebr.gfid); gf_msg_debug(this->name, 0, "RELEASE EVENT [GFID %s]", uuid_utoa(gfid)); child = br_get_child_from_brick_path(this, brick); if (!child) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_GET_SUBVOL_FAILED, "brick=%s", brick, NULL); goto out; } object = br_initialize_object(this, child, ev); if (!object) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_NO_MEMORY, "object-gfid=%s", uuid_utoa(gfid), NULL); goto out; } /* sanity check */ sign_info = ntohl(object->sign_info); GF_ASSERT(sign_info != BR_SIGN_NORMAL); if (sign_info == BR_SIGN_REOPEN_WAIT) ret = br_schedule_object_reopen(this, object, child, ev); else ret = br_object_quicksign(this, object); if (ret) goto free_object; gf_msg_debug(this->name, 0, "->callback: brick [%s], type [%d]\n", brick, ev->ev_type); return; free_object: GF_FREE(object); out: return; } static void br_fill_brick_spec(struct gf_brick_spec *brick, char *path) { brick->brick_path = gf_strdup(path); brick->filter = CHANGELOG_OP_TYPE_BR_RELEASE; brick->init = br_brick_init; brick->fini = br_brick_fini; brick->callback = br_brick_callback; brick->connected = NULL; brick->disconnected = NULL; } static gf_boolean_t br_check_object_need_sign(xlator_t *this, dict_t *xattr, br_child_t *child) { int32_t ret = -1; gf_boolean_t need_sign = _gf_false; br_isignature_out_t *sign = NULL; GF_VALIDATE_OR_GOTO("bit-rot", this, out); GF_VALIDATE_OR_GOTO(this->name, xattr, out); GF_VALIDATE_OR_GOTO(this->name, child, out); ret = dict_get_ptr(xattr, GLUSTERFS_GET_OBJECT_SIGNATURE, (void **)&sign); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_GET_SIGN_FAILED, "object-info", NULL); goto out; } /* Object has been opened and hence dirty. Do not sign it */ if (sign->stale) need_sign = _gf_true; out: return need_sign; } int32_t br_prepare_loc(xlator_t *this, br_child_t *child, loc_t *parent, gf_dirent_t *entry, loc_t *loc) { int32_t ret = -1; inode_t *inode = NULL; inode = inode_grep(child->table, parent->inode, entry->d_name); if (!inode) loc->inode = inode_new(child->table); else { loc->inode = inode; if (loc->inode->ia_type != IA_IFREG) { gf_msg_debug(this->name, 0, "%s is not a regular " "file", entry->d_name); ret = 0; goto out; } } loc->parent = inode_ref(parent->inode); gf_uuid_copy(loc->pargfid, parent->inode->gfid); ret = inode_path(parent->inode, entry->d_name, (char **)&loc->path); if (ret < 0 || !loc->path) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_PATH_FAILED, "inode_path=%s", entry->d_name, "parent-gfid=%s", uuid_utoa(parent->inode->gfid), NULL); goto out; } loc->name = strrchr(loc->path, '/'); if (loc->name) loc->name++; ret = 1; out: return ret; } /** * Oneshot crawler * --------------- * This is a catchup mechanism. Objects that remained unsigned from the * last run for whatever reason (node crashes, reboots, etc..) become * candidates for signing. This allows the signature to "catch up" with * the current state of the object. Triggering signing is easy: perform * an open() followed by a close() thereby resulting in call boomerang. * (though not back to itself :)) */ static int bitd_oneshot_crawl(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { int op_errno = 0; br_child_t *child = NULL; xlator_t *this = NULL; loc_t loc = { 0, }; struct iatt iatt = { 0, }; dict_t *xattr = NULL; int32_t ret = -1; inode_t *linked_inode = NULL; gf_boolean_t need_signing = _gf_false; gf_boolean_t need_reopen = _gf_true; GF_VALIDATE_OR_GOTO("bit-rot", subvol, out); GF_VALIDATE_OR_GOTO("bit-rot", data, out); child = data; this = child->this; ret = br_prepare_loc(this, child, parent, entry, &loc); if (!ret) goto out; ret = syncop_lookup(child->xl, &loc, &iatt, NULL, NULL, NULL); if (ret) { br_log_object_path(this, "lookup", loc.path, -ret); goto out; } linked_inode = inode_link(loc.inode, parent->inode, loc.name, &iatt); if (linked_inode) inode_lookup(linked_inode); if (iatt.ia_type != IA_IFREG) { gf_msg_debug(this->name, 0, "%s is not a regular file, " "skipping..", entry->d_name); ret = 0; goto unref_inode; } /** * As of now, 2 cases are possible and handled. * 1) GlusterFS is upgraded from a previous version which does not * have any idea about bit-rot and have data in the filesystem. * In this case syncop_getxattr fails with ENODATA and the object * is signed. (In real, when crawler sends lookup, bit-rot-stub * creates the xattrs before returning lookup reply) * 2) Bit-rot was not enabled or BitD was does for some reasons, during * which some files were created, but since BitD was down, were not * signed. * If the file was just created and was being written some data when * the down BitD came up, then bit-rot stub should be intelligent to * identify this case (by comparing the ongoing version or by checking * if there are any fds present for that inode) and handle properly. */ if (bitd_is_bad_file(this, child, &loc, NULL)) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRB_MSG_SKIP_OBJECT, "path=%s", loc.path, NULL); goto unref_inode; } ret = syncop_getxattr(child->xl, &loc, &xattr, GLUSTERFS_GET_OBJECT_SIGNATURE, NULL, NULL); if (ret < 0) { op_errno = -ret; br_log_object(this, "getxattr", linked_inode->gfid, op_errno); /** * No need to sign the zero byte objects as the signing * happens upon first modification of the object. */ if (op_errno == ENODATA && (iatt.ia_size != 0)) need_signing = _gf_true; if (op_errno == EINVAL) gf_smsg(this->name, GF_LOG_WARNING, 0, BRB_MSG_PARTIAL_VERSION_PRESENCE, "gfid=%s", uuid_utoa(linked_inode->gfid), NULL); } else { need_signing = br_check_object_need_sign(this, xattr, child); /* * If we are here means, bitrot daemon has started. Is it just * a simple restart of the daemon or is it started because the * feature is enabled is something hard to determine. Hence, * if need_signing is false (because bit-rot version and signature * are present), then still go ahead and sign it. */ if (!need_signing) { need_signing = _gf_true; need_reopen = _gf_true; } } if (!need_signing) goto unref_dict; gf_smsg(this->name, GF_LOG_INFO, 0, BRB_MSG_TRIGGER_SIGN, "path=%s", loc.path, "gfid=%s", uuid_utoa(linked_inode->gfid), "Brick-path=%s", child->brick_path, NULL); br_trigger_sign(this, child, linked_inode, &loc, need_reopen); ret = 0; unref_dict: if (xattr) dict_unref(xattr); unref_inode: inode_unref(linked_inode); out: loc_wipe(&loc); return ret; } #define BR_CRAWL_THROTTLE_COUNT 50 #define BR_CRAWL_THROTTLE_ZZZ 5 void * br_oneshot_signer(void *arg) { loc_t loc = { 0, }; xlator_t *this = NULL; br_child_t *child = NULL; child = arg; this = child->this; THIS = this; gf_smsg(this->name, GF_LOG_INFO, 0, BRB_MSG_CRAWLING_START, "brick-path=%s", child->brick_path, NULL); loc.inode = child->table->root; (void)syncop_ftw_throttle(child->xl, &loc, GF_CLIENT_PID_BITD, child, bitd_oneshot_crawl, BR_CRAWL_THROTTLE_COUNT, BR_CRAWL_THROTTLE_ZZZ); gf_smsg(this->name, GF_LOG_INFO, 0, BRB_MSG_CRAWLING_FINISH, "brick-path=%s", child->brick_path, NULL); return NULL; } static void br_set_child_state(br_child_t *child, br_child_state_t state) { pthread_mutex_lock(&child->lock); { _br_set_child_state(child, state); } pthread_mutex_unlock(&child->lock); } /** * At this point a thread is spawned to crawl the filesystem (in * tortoise pace) to sign objects that were not signed in previous run(s). * Such objects are identified by examining it's dirtyness and timestamp. * * pick object: * signature_is_stale() && (object_timestamp() <= stub_init_time()) * * Also, we register to the changelog library to subscribe for event * notifications. */ static int32_t br_enact_signer(xlator_t *this, br_child_t *child, br_stub_init_t *stub) { int32_t ret = 0; br_private_t *priv = NULL; struct gf_brick_spec *brick = NULL; priv = this->private; brick = GF_CALLOC(1, sizeof(struct gf_brick_spec), gf_common_mt_gf_brick_spec_t); if (!brick) goto error_return; br_fill_brick_spec(brick, stub->export); ret = gf_changelog_register_generic(brick, 1, 1, this->ctx->cmd_args.log_file, -1, this); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, BRB_MSG_REGISTER_FAILED, NULL); goto dealloc; } child->threadrunning = 0; ret = gf_thread_create(&child->thread, NULL, br_oneshot_signer, child, "brosign"); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, BRB_MSG_SPAWN_FAILED, "FS-crawler-thread", NULL); else child->threadrunning = 1; /* it's OK to continue, "old" objects would be signed when modified */ list_add_tail(&child->list, &priv->signing); return 0; dealloc: GF_FREE(brick); error_return: return -1; } static int32_t br_launch_scrubber(xlator_t *this, br_child_t *child, struct br_scanfs *fsscan, struct br_scrubber *fsscrub) { int32_t ret = -1; br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; ret = gf_thread_create(&child->thread, NULL, br_fsscanner, child, "brfsscan"); if (ret != 0) { gf_smsg(this->name, GF_LOG_ALERT, 0, BRB_MSG_SPAWN_FAILED, "bitrot-scrubber-daemon Brick-path=%s", child->brick_path, NULL); goto error_return; } /* Signal monitor to kick off state machine*/ pthread_mutex_lock(&scrub_monitor->mutex); { if (!scrub_monitor->inited) pthread_cond_signal(&scrub_monitor->cond); scrub_monitor->inited = _gf_true; } pthread_mutex_unlock(&scrub_monitor->mutex); /** * Everything has been setup.. add this subvolume to scrubbers * list. */ pthread_mutex_lock(&fsscrub->mutex); { list_add_tail(&child->list, &fsscrub->scrublist); pthread_cond_broadcast(&fsscrub->cond); } pthread_mutex_unlock(&fsscrub->mutex); return 0; error_return: return -1; } static int32_t br_enact_scrubber(xlator_t *this, br_child_t *child) { int32_t ret = 0; br_private_t *priv = NULL; struct br_scanfs *fsscan = NULL; struct br_scrubber *fsscrub = NULL; priv = this->private; fsscan = &child->fsscan; fsscrub = &priv->fsscrub; /** * if this child already witnesses a successful connection earlier * there's no need to initialize mutexes, condvars, etc.. */ if (_br_child_witnessed_connection(child)) return br_launch_scrubber(this, child, fsscan, fsscrub); LOCK_INIT(&fsscan->entrylock); pthread_mutex_init(&fsscan->waitlock, NULL); pthread_cond_init(&fsscan->waitcond, NULL); fsscan->entries = 0; INIT_LIST_HEAD(&fsscan->queued); INIT_LIST_HEAD(&fsscan->ready); ret = br_launch_scrubber(this, child, fsscan, fsscrub); if (ret) goto error_return; return 0; error_return: LOCK_DESTROY(&fsscan->entrylock); pthread_mutex_destroy(&fsscan->waitlock); pthread_cond_destroy(&fsscan->waitcond); return -1; } static int32_t br_child_enaction(xlator_t *this, br_child_t *child, br_stub_init_t *stub) { int32_t ret = -1; br_private_t *priv = this->private; pthread_mutex_lock(&child->lock); { if (priv->iamscrubber) ret = br_enact_scrubber(this, child); else ret = br_enact_signer(this, child, stub); if (!ret) { child->witnessed = 1; _br_set_child_state(child, BR_CHILD_STATE_CONNECTED); gf_smsg(this->name, GF_LOG_INFO, 0, BRB_MSG_CONNECTED_TO_BRICK, "brick-path=%s", child->brick_path, NULL); } } pthread_mutex_unlock(&child->lock); return ret; } /** * This routine fetches various attributes associated with a child which * is basically a subvolume. Attributes include brick path and the stub * birth time. This is done by performing a lookup on the root followed * by getxattr() on a virtual key. Depending on the configuration, the * process either acts as a signer or a scrubber. */ static int32_t br_brick_connect(xlator_t *this, br_child_t *child) { int32_t ret = -1; loc_t loc = { 0, }; br_stub_init_t *stub = NULL; dict_t *xattr = NULL; int op_errno = 0; GF_VALIDATE_OR_GOTO("bit-rot", this, out); GF_VALIDATE_OR_GOTO(this->name, child, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); br_child_set_scrub_state(child, _gf_false); br_set_child_state(child, BR_CHILD_STATE_INITIALIZING); loc.inode = inode_ref(child->table->root); gf_uuid_copy(loc.gfid, loc.inode->gfid); loc.path = gf_strdup("/"); ret = syncop_lookup(child->xl, &loc, NULL, NULL, NULL, NULL); if (ret) { op_errno = -ret; ret = -1; gf_smsg(this->name, GF_LOG_ERROR, op_errno, BRB_MSG_LOOKUP_FAILED, NULL); goto wipeloc; } ret = syncop_getxattr(child->xl, &loc, &xattr, GLUSTERFS_GET_BR_STUB_INIT_TIME, NULL, NULL); if (ret) { op_errno = -ret; ret = -1; gf_smsg(this->name, GF_LOG_ERROR, op_errno, BRB_MSG_GET_INFO_FAILED, NULL); goto wipeloc; } ret = dict_get_ptr(xattr, GLUSTERFS_GET_BR_STUB_INIT_TIME, (void **)&stub); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_GET_INFO_FAILED, NULL); goto free_dict; } memcpy(child->brick_path, stub->export, strlen(stub->export) + 1); ret = br_child_enaction(this, child, stub); free_dict: dict_unref(xattr); wipeloc: loc_wipe(&loc); out: if (ret) br_set_child_state(child, BR_CHILD_STATE_CONNFAILED); return ret; } /* TODO: cleanup signer */ static int32_t br_cleanup_signer(xlator_t *this, br_child_t *child) { return 0; } static int32_t br_cleanup_scrubber(xlator_t *this, br_child_t *child) { int32_t ret = 0; br_private_t *priv = NULL; struct br_scrubber *fsscrub = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; fsscrub = &priv->fsscrub; scrub_monitor = &priv->scrub_monitor; if (_br_is_child_scrub_active(child)) { scrub_monitor->active_child_count--; br_child_set_scrub_state(child, _gf_false); } /** * 0x0: child (brick) goes out of rotation * * This is fully safe w.r.t. entries for this child being actively * scrubbed. Each of the scrubber thread(s) would finish scrubbing * the entry (probably failing due to disconnection) and either * putting the entry back into the queue or continuing further. * Either way, pending entries for this child's queue need not be * drained; entries just sit there in the queued/ready list to be * consumed later upon re-connection. */ pthread_mutex_lock(&fsscrub->mutex); { list_del_init(&child->list); } pthread_mutex_unlock(&fsscrub->mutex); /** * 0x1: cleanup scanner thread * * The pending timer needs to be removed _after_ cleaning up the * filesystem scanner (scheduling the next scrub time is not a * cancellation point). */ ret = gf_thread_cleanup_xint(child->thread); if (ret) gf_smsg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_THREAD_CLEANUP, NULL); gf_smsg(this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUBBER_CLEANED, "brick-path=%s", child->brick_path, NULL); return 0; } /** * OK.. this child has made it's mind to go down the drain. So, * let's clean up what it touched. (NOTE: there's no need to clean * the inode table, it's just reused taking care of stale inodes) */ static int32_t br_brick_disconnect(xlator_t *this, br_child_t *child) { int32_t ret = 0; struct br_monitor *scrub_monitor = NULL; br_private_t *priv = this->private; scrub_monitor = &priv->scrub_monitor; /* Lock order should be wakelock and then child lock to * dead locks. */ pthread_mutex_lock(&scrub_monitor->wakelock); { pthread_mutex_lock(&child->lock); { if (!_br_is_child_connected(child)) goto unblock; /* child is on death row.. */ _br_set_child_state(child, BR_CHILD_STATE_DISCONNECTED); if (priv->iamscrubber) ret = br_cleanup_scrubber(this, child); else ret = br_cleanup_signer(this, child); } unblock: pthread_mutex_unlock(&child->lock); } pthread_mutex_unlock(&scrub_monitor->wakelock); return ret; } /** * This function is executed in a separate thread. The thread gets the * brick from where CHILD_UP has received from the queue and gets the * information regarding that brick (such as brick path). */ void * br_handle_events(void *arg) { int32_t ret = 0; xlator_t *this = NULL; br_private_t *priv = NULL; br_child_t *child = NULL; struct br_child_event *childev = NULL; this = arg; priv = this->private; /* * Since, this is the topmost xlator, THIS has to be set by bit-rot * xlator itself (STACK_WIND won't help in this case). Also it has * to be done for each thread that gets spawned. Otherwise, a new * thread will get global_xlator's pointer when it does "THIS". */ THIS = this; while (1) { pthread_mutex_lock(&priv->lock); { while (list_empty(&priv->bricks)) pthread_cond_wait(&priv->cond, &priv->lock); childev = list_first_entry(&priv->bricks, struct br_child_event, list); list_del_init(&childev->list); } pthread_mutex_unlock(&priv->lock); child = childev->child; ret = childev->call(this, child); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_SUBVOL_CONNECT_FAILED, "name=%s", child->xl->name, NULL); GF_FREE(childev); } return NULL; } int32_t mem_acct_init(xlator_t *this) { int32_t ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_br_stub_mt_end); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRB_MSG_MEM_ACNT_FAILED, NULL); return ret; } return ret; } static void _br_qchild_event(xlator_t *this, br_child_t *child, br_child_handler *call) { br_private_t *priv = NULL; struct br_child_event *childev = NULL; priv = this->private; childev = GF_CALLOC(1, sizeof(*childev), gf_br_mt_br_child_event_t); if (!childev) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_EVENT_UNHANDLED, "Brick-name=%s", child->xl->name, NULL); return; } INIT_LIST_HEAD(&childev->list); childev->this = this; childev->child = child; childev->call = call; list_add_tail(&childev->list, &priv->bricks); } static int br_scrubber_status_get(xlator_t *this, dict_t **dict) { int ret = -1; br_private_t *priv = NULL; struct br_scrub_stats *scrub_stats = NULL; priv = this->private; GF_VALIDATE_OR_GOTO("bit-rot", priv, out); scrub_stats = &priv->scrub_stat; ret = br_get_bad_objects_list(this, dict); if (ret) { gf_msg_debug(this->name, 0, "Failed to collect corrupt " "files"); } ret = dict_set_int8(*dict, "scrub-running", scrub_stats->scrub_running); if (ret) { gf_msg_debug(this->name, 0, "Failed setting scrub_running " "entry to the dictionary"); } ret = dict_set_uint64(*dict, "scrubbed-files", scrub_stats->scrubbed_files); if (ret) { gf_msg_debug(this->name, 0, "Failed to setting scrubbed file " "entry to the dictionary"); } ret = dict_set_uint64(*dict, "unsigned-files", scrub_stats->unsigned_files); if (ret) { gf_msg_debug(this->name, 0, "Failed to set unsigned file count" " entry to the dictionary"); } ret = dict_set_uint64(*dict, "scrub-duration", scrub_stats->scrub_duration); if (ret) { gf_msg_debug(this->name, 0, "Failed to set scrub duration" " entry to the dictionary"); } ret = dict_set_dynstr_with_alloc(*dict, "last-scrub-time", scrub_stats->last_scrub_time); if (ret) { gf_msg_debug(this->name, 0, "Failed to set " "last scrub time value"); } out: return ret; } int notify(xlator_t *this, int32_t event, void *data, ...) { int idx = -1; int ret = -1; xlator_t *subvol = NULL; br_child_t *child = NULL; br_private_t *priv = NULL; dict_t *output = NULL; va_list ap; struct br_monitor *scrub_monitor = NULL; subvol = (xlator_t *)data; priv = this->private; scrub_monitor = &priv->scrub_monitor; gf_msg_trace(this->name, 0, "Notification received: %d", event); idx = br_find_child_index(this, subvol); switch (event) { case GF_EVENT_CHILD_UP: if (idx < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_INVALID_SUBVOL, "event=%d", event, NULL); goto out; } pthread_mutex_lock(&priv->lock); { child = &priv->children[idx]; if (child->child_up == 1) goto unblock_0; priv->up_children++; child->child_up = 1; child->xl = subvol; if (!child->table) child->table = inode_table_new(4096, subvol, 0, 0); _br_qchild_event(this, child, br_brick_connect); pthread_cond_signal(&priv->cond); } unblock_0: pthread_mutex_unlock(&priv->lock); if (priv->up_children == priv->child_count) default_notify(this, event, data); break; case GF_EVENT_CHILD_DOWN: if (idx < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_INVALID_SUBVOL, "event=%d", event, NULL); goto out; } pthread_mutex_lock(&priv->lock); { child = &priv->children[idx]; if (child->child_up == 0) goto unblock_1; child->child_up = 0; priv->up_children--; _br_qchild_event(this, child, br_brick_disconnect); pthread_cond_signal(&priv->cond); } unblock_1: pthread_mutex_unlock(&priv->lock); if (priv->up_children == 0) default_notify(this, event, data); break; case GF_EVENT_SCRUB_STATUS: gf_msg_debug(this->name, GF_LOG_INFO, "BitRot scrub status " "called"); va_start(ap, data); output = va_arg(ap, dict_t *); va_end(ap); ret = br_scrubber_status_get(this, &output); gf_msg_debug(this->name, 0, "returning %d", ret); break; case GF_EVENT_SCRUB_ONDEMAND: gf_log(this->name, GF_LOG_INFO, "BitRot scrub ondemand " "called"); if (scrub_monitor->state != BR_SCRUB_STATE_PENDING) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_RESCHEDULE_SCRUBBER_FAILED, "Current-state=%d", scrub_monitor->state, NULL); return -2; } /* Needs synchronization with reconfigure thread */ pthread_mutex_lock(&priv->lock); { ret = br_scrub_state_machine(this, _gf_true); } pthread_mutex_unlock(&priv->lock); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_COULD_NOT_SCHEDULE_SCRUB, NULL); } gf_msg_debug(this->name, 0, "returning %d", ret); break; default: default_notify(this, event, data); } out: return 0; } static void br_fini_signer(br_private_t *priv) { int i = 0; for (; i < priv->signer_th_count; i++) { (void)gf_thread_cleanup_xint(priv->obj_queue->workers[i]); } GF_FREE(priv->obj_queue->workers); pthread_cond_destroy(&priv->object_cond); } /** * Initialize signer specific structures, spawn worker threads. */ static int32_t br_init_signer(xlator_t *this, br_private_t *priv) { int i = 0; int32_t ret = -1; /* initialize gfchangelog xlator context */ ret = gf_changelog_init(this); if (ret) goto out; pthread_cond_init(&priv->object_cond, NULL); priv->obj_queue = GF_CALLOC(1, sizeof(*priv->obj_queue), gf_br_mt_br_ob_n_wk_t); if (!priv->obj_queue) goto cleanup_cond; INIT_LIST_HEAD(&priv->obj_queue->objects); priv->obj_queue->workers = GF_CALLOC( priv->signer_th_count, sizeof(pthread_t), gf_br_mt_br_worker_t); if (!priv->obj_queue->workers) goto cleanup_obj_queue; for (i = 0; i < priv->signer_th_count; i++) { ret = gf_thread_create(&priv->obj_queue->workers[i], NULL, br_process_object, this, "brpobj"); if (ret != 0) { gf_smsg(this->name, GF_LOG_ERROR, -ret, BRB_MSG_THREAD_CREATION_FAILED, NULL); ret = -1; goto cleanup_threads; } } return 0; cleanup_threads: for (i--; i >= 0; i--) { (void)gf_thread_cleanup_xint(priv->obj_queue->workers[i]); } GF_FREE(priv->obj_queue->workers); cleanup_obj_queue: GF_FREE(priv->obj_queue); cleanup_cond: /* that's explicit */ pthread_cond_destroy(&priv->object_cond); out: return -1; } /** * For signer, only rate limit CPU usage (during hash calculation) when * compiled with -DBR_RATE_LIMIT_SIGNER cflags, else let it run full * throttle. */ static int32_t br_rate_limit_signer(xlator_t *this, int child_count, int numbricks) { br_private_t *priv = NULL; tbf_opspec_t spec = { 0, }; priv = this->private; spec.op = TBF_OP_HASH; spec.rate = 0; spec.maxlimit = 0; /** * OK. Most implementations of TBF I've come across generate tokens * every second (UML, etc..) and some chose sub-second granularity * (blk-iothrottle cgroups). TBF algorithm itself does not enforce * any logic for choosing generation interval and it seems pretty * logical as one could jack up token count per interval w.r.t. * generation rate. * * Value used here is chosen based on a series of test(s) performed * to balance object signing time and not maxing out on all available * CPU cores. It's obvious to have seconds granularity and jack up * token count per interval, thereby achieving close to similar * results. Let's stick to this as it seems to be working fine for * the set of ops that are throttled. **/ spec.token_gen_interval = 600000; /* In usec */ #ifdef BR_RATE_LIMIT_SIGNER double contribution = 0; contribution = ((double)1 - ((double)child_count / (double)numbricks)); if (contribution == 0) contribution = 1; spec.rate = BR_HASH_CALC_READ_SIZE * contribution; spec.maxlimit = priv->signer_th_count * BR_HASH_CALC_READ_SIZE; #endif if (!spec.rate) gf_smsg(this->name, GF_LOG_INFO, 0, BRB_MSG_RATE_LIMIT_INFO, "FULL THROTTLE", NULL); else gf_smsg(this->name, GF_LOG_INFO, 0, BRB_MSG_RATE_LIMIT_INFO, "tokens/sec-rate=%lu", spec.rate, "maxlimit=%lu", spec.maxlimit, NULL); priv->tbf = tbf_init(&spec, 1); return priv->tbf ? 0 : -1; } static int32_t br_signer_handle_options(xlator_t *this, br_private_t *priv, dict_t *options) { if (options) { GF_OPTION_RECONF("expiry-time", priv->expiry_time, options, time, error_return); GF_OPTION_RECONF("signer-threads", priv->signer_th_count, options, uint32, error_return); } else { GF_OPTION_INIT("expiry-time", priv->expiry_time, time, error_return); GF_OPTION_INIT("signer-threads", priv->signer_th_count, uint32, error_return); } return 0; error_return: return -1; } static int32_t br_signer_init(xlator_t *this, br_private_t *priv) { int32_t ret = 0; int numbricks = 0; GF_OPTION_INIT("expiry-time", priv->expiry_time, time, error_return); GF_OPTION_INIT("brick-count", numbricks, int32, error_return); GF_OPTION_INIT("signer-threads", priv->signer_th_count, uint32, error_return); ret = br_rate_limit_signer(this, priv->child_count, numbricks); if (ret) goto error_return; ret = br_init_signer(this, priv); if (ret) goto cleanup_tbf; return 0; cleanup_tbf: /* cleanup TBF */ error_return: return -1; } static void br_free_scrubber_monitor(br_private_t *priv) { struct br_monitor *scrub_monitor = &priv->scrub_monitor; if (scrub_monitor->timer) { (void)gf_tw_del_timer(priv->timer_wheel, scrub_monitor->timer); GF_FREE(scrub_monitor->timer); scrub_monitor->timer = NULL; } (void)gf_thread_cleanup_xint(scrub_monitor->thread); /* Clean up cond and mutex variables */ pthread_mutex_destroy(&scrub_monitor->mutex); pthread_cond_destroy(&scrub_monitor->cond); pthread_mutex_destroy(&scrub_monitor->wakelock); pthread_cond_destroy(&scrub_monitor->wakecond); pthread_mutex_destroy(&scrub_monitor->donelock); pthread_cond_destroy(&scrub_monitor->donecond); LOCK_DESTROY(&scrub_monitor->lock); } static void br_free_children(xlator_t *this, br_private_t *priv, int count) { br_child_t *child = NULL; for (--count; count >= 0; count--) { child = &priv->children[count]; mem_pool_destroy(child->timer_pool); pthread_mutex_destroy(&child->lock); } GF_FREE(priv->children); priv->children = NULL; } static int br_init_children(xlator_t *this, br_private_t *priv) { int i = 0; br_child_t *child = NULL; xlator_list_t *trav = NULL; priv->child_count = xlator_subvolume_count(this); priv->children = GF_CALLOC(priv->child_count, sizeof(*priv->children), gf_br_mt_br_child_t); if (!priv->children) goto err; trav = this->children; while (trav) { child = &priv->children[i]; pthread_mutex_init(&child->lock, NULL); child->witnessed = 0; br_set_child_state(child, BR_CHILD_STATE_DISCONNECTED); child->this = this; child->xl = trav->xlator; child->timer_pool = mem_pool_new(struct gf_tw_timer_list, 4096); if (!child->timer_pool) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_MEM_POOL_ALLOC, NULL); errno = ENOMEM; goto freechild; } INIT_LIST_HEAD(&child->list); i++; trav = trav->next; } return 0; freechild: br_free_children(this, priv, i); err: return -1; } int32_t init(xlator_t *this) { int32_t ret = -1; br_private_t *priv = NULL; if (!this->children) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_NO_CHILD, NULL); goto out; } priv = GF_CALLOC(1, sizeof(*priv), gf_br_mt_br_private_t); if (!priv) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_NO_MEMORY, NULL); goto out; } GF_OPTION_INIT("scrubber", priv->iamscrubber, bool, free_priv); ret = br_init_children(this, priv); if (ret) goto free_priv; pthread_mutex_init(&priv->lock, NULL); pthread_cond_init(&priv->cond, NULL); INIT_LIST_HEAD(&priv->bricks); INIT_LIST_HEAD(&priv->signing); priv->timer_wheel = glusterfs_ctx_tw_get(this->ctx); if (!priv->timer_wheel) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_TIMER_WHEEL_UNAVAILABLE, NULL); goto cleanup; } this->private = priv; if (!priv->iamscrubber) { ret = br_signer_init(this, priv); if (!ret) ret = br_signer_handle_options(this, priv, NULL); } else { ret = br_scrubber_init(this, priv); if (!ret) ret = br_scrubber_handle_options(this, priv, NULL); } if (ret) goto cleanup; ret = gf_thread_create(&priv->thread, NULL, br_handle_events, this, "brhevent"); if (ret != 0) { gf_smsg(this->name, GF_LOG_ERROR, -ret, BRB_MSG_THREAD_CREATION_FAILED, NULL); ret = -1; } if (!ret) { gf_smsg(this->name, GF_LOG_INFO, 0, BRB_MSG_BITROT_LOADED, "mode=%s", (priv->iamscrubber) ? "SCRUBBER" : "SIGNER", NULL); return 0; } cleanup: (void)pthread_cond_destroy(&priv->cond); (void)pthread_mutex_destroy(&priv->lock); br_free_children(this, priv, priv->child_count); free_priv: GF_FREE(priv); out: this->private = NULL; return -1; } void fini(xlator_t *this) { br_private_t *priv = this->private; if (!priv) return; if (!priv->iamscrubber) br_fini_signer(priv); else (void)br_free_scrubber_monitor(priv); br_free_children(this, priv, priv->child_count); this->private = NULL; GF_FREE(priv); glusterfs_ctx_tw_put(this->ctx); return; } static void br_reconfigure_monitor(xlator_t *this) { int32_t ret = 0; ret = br_scrub_state_machine(this, _gf_false); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRB_MSG_COULD_NOT_SCHEDULE_SCRUB, NULL); } } static int br_reconfigure_scrubber(xlator_t *this, dict_t *options) { int32_t ret = -1; br_private_t *priv = NULL; priv = this->private; pthread_mutex_lock(&priv->lock); { ret = br_scrubber_handle_options(this, priv, options); } pthread_mutex_unlock(&priv->lock); if (ret) goto err; /* change state for all _up_ subvolume(s) */ pthread_mutex_lock(&priv->lock); { br_reconfigure_monitor(this); } pthread_mutex_unlock(&priv->lock); err: return ret; } static int br_reconfigure_signer(xlator_t *this, dict_t *options) { br_private_t *priv = this->private; return br_signer_handle_options(this, priv, options); } int reconfigure(xlator_t *this, dict_t *options) { int ret = 0; br_private_t *priv = NULL; priv = this->private; if (priv->iamscrubber) ret = br_reconfigure_scrubber(this, options); else ret = br_reconfigure_signer(this, options); return ret; } struct xlator_fops fops; struct xlator_cbks cbks; struct volume_options options[] = { { .key = {"expiry-time"}, .type = GF_OPTION_TYPE_INT, .default_value = TOSTRING(SIGNING_TIMEOUT), .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE, .description = "Waiting time for an object on which it waits " "before it is signed", }, { .key = {"brick-count"}, .type = GF_OPTION_TYPE_STR, .description = "Total number of bricks for the current node for " "all volumes in the trusted storage pool.", }, { .key = {"scrubber", "scrub"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "false", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_FORCE, .description = "option to run as a scrubber", }, { .key = {"scrub-throttle"}, .type = GF_OPTION_TYPE_STR, .default_value = "lazy", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE, .description = "Scrub-throttle value is a measure of how fast " "or slow the scrubber scrubs the filesystem for " "volume ", }, { .key = {"scrub-freq"}, .type = GF_OPTION_TYPE_STR, .default_value = "biweekly", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE, .description = "Scrub frequency for volume ", }, { .key = {"scrub-state"}, .type = GF_OPTION_TYPE_STR, .default_value = "active", .op_version = {GD_OP_VERSION_4_0_0}, .flags = OPT_FLAG_SETTABLE, .description = "Pause/Resume scrub. Upon resume, scrubber " "continues from where it left off.", }, { .key = {"signer-threads"}, .type = GF_OPTION_TYPE_INT, .default_value = TOSTRING(BR_DEFAULT_THREADS), .op_version = {GD_OP_VERSION_8_0}, .flags = OPT_FLAG_SETTABLE, .description = "Number of signing process threads. As a best " "practice, set this to the number of processor cores", }, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "bit-rot", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/bit-rot-ssm.h0000644000000000000000000000013214522202451025314 xustar000000000000000030 mtime=1699284265.652027387 30 atime=1699284265.652027387 30 ctime=1699284305.031145995 glusterfs-11.1/xlators/features/bit-rot/src/bitd/bit-rot-ssm.h0000664000175100017510000000171414522202451025576 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __BIT_ROT_SSM_H__ #define __BIT_ROT_SSM_H__ #include typedef enum br_scrub_state { BR_SCRUB_STATE_INACTIVE = 0, BR_SCRUB_STATE_PENDING, BR_SCRUB_STATE_ACTIVE, BR_SCRUB_STATE_PAUSED, BR_SCRUB_STATE_IPAUSED, BR_SCRUB_STATE_STALLED, BR_SCRUB_MAXSTATES, } br_scrub_state_t; typedef enum br_scrub_event { BR_SCRUB_EVENT_SCHEDULE = 0, BR_SCRUB_EVENT_PAUSE, BR_SCRUB_EVENT_ONDEMAND, BR_SCRUB_MAXEVENTS, } br_scrub_event_t; struct br_monitor; int32_t br_scrub_state_machine(xlator_t *, gf_boolean_t); #endif /* __BIT_ROT_SSM_H__ */ glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/bit-rot-bitd-messages.h0000644000000000000000000000013214522202451027241 xustar000000000000000030 mtime=1699284265.651027384 30 atime=1699284265.651027384 30 ctime=1699284305.029145989 glusterfs-11.1/xlators/features/bit-rot/src/bitd/bit-rot-bitd-messages.h0000664000175100017510000001311714522202451027523 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _BITROT_BITD_MESSAGES_H_ #define _BITROT_BITD_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(BITROT_BITD, BRB_MSG_FD_CREATE_FAILED, BRB_MSG_READV_FAILED, BRB_MSG_BLOCK_READ_FAILED, BRB_MSG_CALC_CHECKSUM_FAILED, BRB_MSG_NO_MEMORY, BRB_MSG_GET_SIGN_FAILED, BRB_MSG_SET_SIGN_FAILED, BRB_MSG_OP_FAILED, BRB_MSG_READ_AND_SIGN_FAILED, BRB_MSG_SIGN_FAILED, BRB_MSG_GET_SUBVOL_FAILED, BRB_MSG_SET_TIMER_FAILED, BRB_MSG_GET_INFO_FAILED, BRB_MSG_PATH_FAILED, BRB_MSG_MARK_BAD_FILE, BRB_MSG_TRIGGER_SIGN, BRB_MSG_REGISTER_FAILED, BRB_MSG_CRAWLING_START, BRB_MSG_SPAWN_FAILED, BRB_MSG_INVALID_SUBVOL_CHILD, BRB_MSG_SKIP_OBJECT, BRB_MSG_NO_CHILD, BRB_MSG_CHECKSUM_MISMATCH, BRB_MSG_MARK_CORRUPTED, BRB_MSG_CRAWLING_FINISH, BRB_MSG_CALC_ERROR, BRB_MSG_LOOKUP_FAILED, BRB_MSG_PARTIAL_VERSION_PRESENCE, BRB_MSG_MEM_ACNT_FAILED, BRB_MSG_TIMER_WHEEL_UNAVAILABLE, BRB_MSG_BITROT_LOADED, BRB_MSG_SCALE_DOWN_FAILED, BRB_MSG_SCALE_UP_FAILED, BRB_MSG_SCALE_DOWN_SCRUBBER, BRB_MSG_SCALING_UP_SCRUBBER, BRB_MSG_UNKNOWN_THROTTLE, BRB_MSG_RATE_LIMIT_INFO, BRB_MSG_SCRUB_INFO, BRB_MSG_CONNECTED_TO_BRICK, BRB_MSG_BRICK_INFO, BRB_MSG_SUBVOL_CONNECT_FAILED, BRB_MSG_INVALID_SUBVOL, BRB_MSG_RESCHEDULE_SCRUBBER_FAILED, BRB_MSG_SCRUB_START, BRB_MSG_SCRUB_FINISH, BRB_MSG_SCRUB_RUNNING, BRB_MSG_SCRUB_RESCHEDULED, BRB_MSG_SCRUB_TUNABLE, BRB_MSG_SCRUB_THREAD_CLEANUP, BRB_MSG_SCRUBBER_CLEANED, BRB_MSG_GENERIC_SSM_INFO, BRB_MSG_ZERO_TIMEOUT_BUG, BRB_MSG_BAD_OBJ_READDIR_FAIL, BRB_MSG_SSM_FAILED, BRB_MSG_SCRUB_WAIT_FAILED, BRB_MSG_TRIGGER_SIGN_FAILED, BRB_MSG_EVENT_UNHANDLED, BRB_MSG_COULD_NOT_SCHEDULE_SCRUB, BRB_MSG_THREAD_CREATION_FAILED, BRB_MSG_MEM_POOL_ALLOC, BRB_MSG_SAVING_HASH_FAILED); #define BRB_MSG_FD_CREATE_FAILED_STR "failed to create fd for the inode" #define BRB_MSG_READV_FAILED_STR "readv failed" #define BRB_MSG_BLOCK_READ_FAILED_STR "reading block failed" #define BRB_MSG_NO_MEMORY_STR "failed to allocate memory" #define BRB_MSG_CALC_CHECKSUM_FAILED_STR "calculating checksum failed" #define BRB_MSG_GET_SIGN_FAILED_STR "failed to get the signature" #define BRB_MSG_SET_SIGN_FAILED_STR "signing failed" #define BRB_MSG_OP_FAILED_STR "failed on object" #define BRB_MSG_TRIGGER_SIGN_FAILED_STR "Could not trigger signing" #define BRB_MSG_READ_AND_SIGN_FAILED_STR "reading and signing of object failed" #define BRB_MSG_SET_TIMER_FAILED_STR "Failed to allocate object expiry timer" #define BRB_MSG_GET_SUBVOL_FAILED_STR \ "failed to get the subvolume for the brick" #define BRB_MSG_PATH_FAILED_STR "path failed" #define BRB_MSG_SKIP_OBJECT_STR "Entry is marked corrupted. skipping" #define BRB_MSG_PARTIAL_VERSION_PRESENCE_STR \ "PArtial version xattr presence detected, ignoring" #define BRB_MSG_TRIGGER_SIGN_STR "Triggering signing" #define BRB_MSG_CRAWLING_START_STR \ "Crawling brick, scanning for unsigned objects" #define BRB_MSG_CRAWLING_FINISH_STR "Completed crawling brick" #define BRB_MSG_REGISTER_FAILED_STR "Register to changelog failed" #define BRB_MSG_SPAWN_FAILED_STR "failed to spawn" #define BRB_MSG_CONNECTED_TO_BRICK_STR "Connected to brick" #define BRB_MSG_LOOKUP_FAILED_STR "lookup on root failed" #define BRB_MSG_GET_INFO_FAILED_STR "failed to get stub info" #define BRB_MSG_SCRUB_THREAD_CLEANUP_STR "Error cleaning up scanner thread" #define BRB_MSG_SCRUBBER_CLEANED_STR "clened up scrubber for brick" #define BRB_MSG_SUBVOL_CONNECT_FAILED_STR \ "callback handler for subvolume failed" #define BRB_MSG_MEM_ACNT_FAILED_STR "Memory accounting init failed" #define BRB_MSG_EVENT_UNHANDLED_STR "Event unhandled for child" #define BRB_MSG_INVALID_SUBVOL_STR "Got event from invalid subvolume" #define BRB_MSG_RESCHEDULE_SCRUBBER_FAILED_STR \ "on demand scrub schedule failed. Scrubber is not in pending state." #define BRB_MSG_COULD_NOT_SCHEDULE_SCRUB_STR \ "Could not schedule ondemand scrubbing. Scrubbing will continue " \ "according to old frequency." #define BRB_MSG_THREAD_CREATION_FAILED_STR "thread creation failed" #define BRB_MSG_RATE_LIMIT_INFO_STR "Rate Limit Info" #define BRB_MSG_MEM_POOL_ALLOC_STR "failed to allocate mem-pool for timer" #define BRB_MSG_NO_CHILD_STR "FATAL: no children" #define BRB_MSG_TIMER_WHEEL_UNAVAILABLE_STR "global timer wheel unavailable" #define BRB_MSG_BITROT_LOADED_STR "bit-rot xlator loaded" #define BRB_MSG_SAVING_HASH_FAILED_STR \ "failed to allocate memory for saving hash of the object" #endif /* !_BITROT_BITD_MESSAGES_H_ */ glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/bit-rot-scrub-status.h0000644000000000000000000000013214522202451027151 xustar000000000000000030 mtime=1699284265.651027384 30 atime=1699284265.651027384 30 ctime=1699284305.032145998 glusterfs-11.1/xlators/features/bit-rot/src/bitd/bit-rot-scrub-status.h0000664000175100017510000000261414522202451027433 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __BIT_ROT_SCRUB_STATUS_H__ #define __BIT_ROT_SCRUB_STATUS_H__ #include #include #include struct br_scrub_stats { uint64_t scrubbed_files; /* Total number of scrubbed files. */ uint64_t unsigned_files; /* Total number of unsigned files. */ uint64_t scrub_duration; /* Duration of last scrub. */ char last_scrub_time[GF_TIMESTR_SIZE]; /* Last scrub completion time. */ time_t scrub_start_time; /* Scrubbing starting time. */ time_t scrub_end_time; /* Scrubbing finishing time. */ int8_t scrub_running; /* Whether scrub running or not. */ pthread_mutex_t lock; }; typedef struct br_scrub_stats br_scrub_stats_t; void br_inc_unsigned_file_count(br_scrub_stats_t *scrub_stat); void br_inc_scrubbed_file(br_scrub_stats_t *scrub_stat); void br_update_scrub_start_time(br_scrub_stats_t *scrub_stat, time_t time); void br_update_scrub_finish_time(br_scrub_stats_t *scrub_stat, char *timestr, time_t time); #endif /* __BIT_ROT_SCRUB_STATUS_H__ */ glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/bit-rot-ssm.c0000644000000000000000000000013214522202451025307 xustar000000000000000030 mtime=1699284265.652027387 30 atime=1699284265.652027387 30 ctime=1699284305.037146014 glusterfs-11.1/xlators/features/bit-rot/src/bitd/bit-rot-ssm.c0000664000175100017510000000660214522202451025572 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "bit-rot-ssm.h" #include "bit-rot-scrub.h" #include "bit-rot-bitd-messages.h" int br_scrub_ssm_noop(xlator_t *this) { return 0; } int br_scrub_ssm_state_pause(xlator_t *this) { br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_GENERIC_SSM_INFO, "Scrubber paused"); _br_monitor_set_scrub_state(scrub_monitor, BR_SCRUB_STATE_PAUSED); return 0; } int br_scrub_ssm_state_ipause(xlator_t *this) { br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_GENERIC_SSM_INFO, "Scrubber paused"); _br_monitor_set_scrub_state(scrub_monitor, BR_SCRUB_STATE_IPAUSED); return 0; } int br_scrub_ssm_state_active(xlator_t *this) { br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; if (scrub_monitor->done) { (void)br_fsscan_activate(this); } else { gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_GENERIC_SSM_INFO, "Scrubbing resumed"); _br_monitor_set_scrub_state(scrub_monitor, BR_SCRUB_STATE_ACTIVE); } return 0; } int br_scrub_ssm_state_stall(xlator_t *this) { br_private_t *priv = NULL; struct br_monitor *scrub_monitor = NULL; priv = this->private; scrub_monitor = &priv->scrub_monitor; gf_msg(this->name, GF_LOG_INFO, 0, BRB_MSG_GENERIC_SSM_INFO, "Volume is under active scrubbing. Pausing scrub.."); _br_monitor_set_scrub_state(scrub_monitor, BR_SCRUB_STATE_STALLED); return 0; } static br_scrub_ssm_call *br_scrub_ssm[BR_SCRUB_MAXSTATES][BR_SCRUB_MAXEVENTS] = { /* INACTIVE */ {br_fsscan_schedule, br_scrub_ssm_state_ipause, br_scrub_ssm_noop}, /* PENDING */ {br_fsscan_reschedule, br_fsscan_deactivate, br_fsscan_ondemand}, /* ACTIVE */ {br_scrub_ssm_noop, br_scrub_ssm_state_stall, br_scrub_ssm_noop}, /* PAUSED */ {br_fsscan_activate, br_scrub_ssm_noop, br_scrub_ssm_noop}, /* IPAUSED */ {br_fsscan_schedule, br_scrub_ssm_noop, br_scrub_ssm_noop}, /* STALLED */ {br_scrub_ssm_state_active, br_scrub_ssm_noop, br_scrub_ssm_noop}, }; int32_t br_scrub_state_machine(xlator_t *this, gf_boolean_t scrub_ondemand) { br_private_t *priv = NULL; br_scrub_ssm_call *call = NULL; struct br_scrubber *fsscrub = NULL; br_scrub_state_t currstate = 0; br_scrub_event_t event = 0; struct br_monitor *scrub_monitor = NULL; priv = this->private; fsscrub = &priv->fsscrub; scrub_monitor = &priv->scrub_monitor; currstate = scrub_monitor->state; if (scrub_ondemand) event = BR_SCRUB_EVENT_ONDEMAND; else event = _br_child_get_scrub_event(fsscrub); call = br_scrub_ssm[currstate][event]; return call(this); } glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/Makefile.in0000644000000000000000000000012714522202463025037 xustar000000000000000030 mtime=1699284275.400056748 27 atime=1699284291.088104 30 ctime=1699284305.024145974 glusterfs-11.1/xlators/features/bit-rot/src/bitd/Makefile.in0000664000175100017510000006074014522202463025321 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/bit-rot/src/bitd DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) bit_rot_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/xlators/features/changelog/lib/src/libgfchangelog.la am_bit_rot_la_OBJECTS = bit-rot.lo bit-rot-scrub.lo bit-rot-ssm.lo \ bit-rot-scrub-status.lo bit_rot_la_OBJECTS = $(am_bit_rot_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = bit_rot_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(bit_rot_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_bit_rot_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(bit_rot_la_SOURCES) DIST_SOURCES = $(bit_rot_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = bit-rot.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features bit_rot_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ \ -I$(top_srcdir)/rpc/rpc-lib/src -I$(CONTRIBDIR)/timer-wheel \ -I$(top_srcdir)/xlators/features/bit-rot/src/stub bit_rot_la_SOURCES = bit-rot.c bit-rot-scrub.c bit-rot-ssm.c \ bit-rot-scrub-status.c bit_rot_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/xlators/features/changelog/lib/src/libgfchangelog.la noinst_HEADERS = bit-rot.h bit-rot-scrub.h bit-rot-bitd-messages.h bit-rot-ssm.h \ bit-rot-scrub-status.h AM_CFLAGS = -Wall -DBR_RATE_LIMIT_SIGNER $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/bit-rot/src/bitd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/bit-rot/src/bitd/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } bit-rot.la: $(bit_rot_la_OBJECTS) $(bit_rot_la_DEPENDENCIES) $(EXTRA_bit_rot_la_DEPENDENCIES) $(AM_V_CCLD)$(bit_rot_la_LINK) $(am_bit_rot_la_rpath) $(bit_rot_la_OBJECTS) $(bit_rot_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit-rot-scrub-status.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit-rot-scrub.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit-rot-ssm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit-rot.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451025017 xustar000000000000000030 mtime=1699284265.651027384 30 atime=1699284275.363056637 30 ctime=1699284305.025145977 glusterfs-11.1/xlators/features/bit-rot/src/bitd/Makefile.am0000664000175100017510000000150314522202451025275 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = bit-rot.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features bit_rot_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ \ -I$(top_srcdir)/rpc/rpc-lib/src -I$(CONTRIBDIR)/timer-wheel \ -I$(top_srcdir)/xlators/features/bit-rot/src/stub bit_rot_la_SOURCES = bit-rot.c bit-rot-scrub.c bit-rot-ssm.c \ bit-rot-scrub-status.c bit_rot_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/xlators/features/changelog/lib/src/libgfchangelog.la noinst_HEADERS = bit-rot.h bit-rot-scrub.h bit-rot-bitd-messages.h bit-rot-ssm.h \ bit-rot-scrub-status.h AM_CFLAGS = -Wall -DBR_RATE_LIMIT_SIGNER $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/bit-rot.h0000644000000000000000000000012714522202451024520 xustar000000000000000029 mtime=1699284265.65302739 29 atime=1699284265.65302739 29 ctime=1699284305.02614598 glusterfs-11.1/xlators/features/bit-rot/src/bitd/bit-rot.h0000664000175100017510000002052614522202451025000 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __BIT_ROT_H__ #define __BIT_ROT_H__ #include #include #include #include #include "changelog.h" #include "timer-wheel.h" #include #include "bit-rot-ssm.h" #include "bit-rot-common.h" #include "bit-rot-stub-mem-types.h" #include "bit-rot-scrub-status.h" typedef enum scrub_throttle { BR_SCRUB_THROTTLE_VOID = -1, BR_SCRUB_THROTTLE_LAZY = 0, BR_SCRUB_THROTTLE_NORMAL = 1, BR_SCRUB_THROTTLE_AGGRESSIVE = 2, BR_SCRUB_THROTTLE_STALLED = 3, } scrub_throttle_t; typedef enum scrub_freq { BR_FSSCRUB_FREQ_HOURLY = 1, BR_FSSCRUB_FREQ_DAILY, BR_FSSCRUB_FREQ_WEEKLY, BR_FSSCRUB_FREQ_BIWEEKLY, BR_FSSCRUB_FREQ_MONTHLY, BR_FSSCRUB_FREQ_MINUTE, BR_FSSCRUB_FREQ_STALLED, } scrub_freq_t; #define signature_size(hl) (sizeof(br_isignature_t) + hl + 1) struct br_scanfs { gf_lock_t entrylock; pthread_mutex_t waitlock; pthread_cond_t waitcond; unsigned int entries; struct list_head queued; struct list_head ready; }; /* just need three states to track child status */ typedef enum br_child_state { BR_CHILD_STATE_CONNECTED = 1, BR_CHILD_STATE_INITIALIZING, BR_CHILD_STATE_CONNFAILED, BR_CHILD_STATE_DISCONNECTED, } br_child_state_t; struct br_child { pthread_mutex_t lock; /* protects child state */ char witnessed; /* witnessed at least one successful connection */ br_child_state_t c_state; /* current state of this child */ char child_up; /* Indicates whether this child is up or not */ xlator_t *xl; /* client xlator corresponding to this child */ inode_table_t *table; /* inode table for this child */ char brick_path[PATH_MAX]; /* brick export directory of this child */ struct list_head list; /* hook to attach to the list of UP children */ xlator_t *this; /* Bit rot xlator */ pthread_t thread; /* initial crawler for unsigned object(s) or scrub crawler */ int threadrunning; /* active thread */ struct mem_pool *timer_pool; /* timer-wheel's timer mem-pool */ struct br_scanfs fsscan; /* per subvolume FS scanner */ gf_boolean_t active_scrubbing; /* Actively scrubbing or not */ }; typedef struct br_child br_child_t; struct br_obj_n_workers { struct list_head objects; /* queue of objects expired from the timer wheel and ready to be picked up for signing */ pthread_t *workers; /* Threads which pick up the objects from the above queue and start signing each object */ }; struct br_scrubber { xlator_t *this; scrub_throttle_t throttle; /** * frequency of scanning for this subvolume. this should * normally be per-child, but since all children follow the * same frequency for a volume, this option ends up here * instead of br_child_t. */ scrub_freq_t frequency; gf_boolean_t frequency_reconf; gf_boolean_t throttle_reconf; pthread_mutex_t mutex; pthread_cond_t cond; unsigned int nr_scrubbers; struct list_head scrubbers; /** * list of "rotatable" subvolume(s) undergoing scrubbing */ struct list_head scrublist; }; struct br_monitor { gf_lock_t lock; pthread_t thread; /* Monitor thread */ gf_boolean_t inited; pthread_mutex_t mutex; pthread_cond_t cond; /* Thread starts and will be waiting on cond. First child which is up wakes this up */ xlator_t *this; /* scheduler */ time_t boot; int32_t active_child_count; /* Number of children currently scrubbing */ gf_boolean_t kick; /* This variable tracks the scrubber is * kicked or not. Both 'kick' and * 'active_child_count' uses the same pair * of mutex-cond variable, i.e, wakelock and * wakecond. */ pthread_mutex_t wakelock; pthread_cond_t wakecond; gf_boolean_t done; pthread_mutex_t donelock; pthread_cond_t donecond; struct gf_tw_timer_list *timer; br_scrub_state_t state; /* current scrub state */ }; typedef struct br_obj_n_workers br_obj_n_workers_t; typedef struct br_private br_private_t; typedef void (*br_scrubbed_file_update)(br_private_t *priv); struct br_private { pthread_mutex_t lock; struct list_head bricks; /* list of bricks from which enents have been received */ struct list_head signing; pthread_cond_t object_cond; /* handling signing of objects */ int child_count; br_child_t *children; /* list of subvolumes */ int up_children; pthread_cond_t cond; /* handling CHILD_UP notifications */ pthread_t thread; /* thread for connecting each UP child with changelog */ struct tvec_base *timer_wheel; /* timer wheel where the objects which changelog has sent sits and waits for expiry */ br_obj_n_workers_t *obj_queue; /* place holder for all the objects that are expired from timer wheel and ready to be picked up for signing and the workers which sign the objects */ time_t expiry_time; /* objects "wait" time */ uint32_t signer_th_count; /* Number of signing process threads */ tbf_t *tbf; /* token bucket filter */ gf_boolean_t iamscrubber; /* function as a fs scrubber */ struct br_scrub_stats scrub_stat; /* statistics of scrub*/ struct br_scrubber fsscrub; /* scrubbers for this subvolume */ struct br_monitor scrub_monitor; /* scrubber monitor */ }; struct br_object { xlator_t *this; uuid_t gfid; unsigned long signedversion; /* version against which this object will be signed */ br_child_t *child; /* object's subvolume */ int sign_info; struct list_head list; /* hook to add to the queue once the object is expired from timer wheel */ void *data; }; typedef struct br_object br_object_t; typedef int32_t(br_scrub_ssm_call)(xlator_t *); void br_log_object(xlator_t *, char *, uuid_t, int32_t); void br_log_object_path(xlator_t *, char *, const char *, int32_t); int32_t br_calculate_obj_checksum(unsigned char *, br_child_t *, fd_t *); int32_t br_prepare_loc(xlator_t *, br_child_t *, loc_t *, gf_dirent_t *, loc_t *); gf_boolean_t bitd_is_bad_file(xlator_t *, br_child_t *, loc_t *, fd_t *); static inline void _br_set_child_state(br_child_t *child, br_child_state_t state) { child->c_state = state; } static inline int _br_is_child_connected(br_child_t *child) { return (child->c_state == BR_CHILD_STATE_CONNECTED); } static inline int _br_is_child_scrub_active(br_child_t *child) { return child->active_scrubbing; } static inline int _br_child_failed_conn(br_child_t *child) { return (child->c_state == BR_CHILD_STATE_CONNFAILED); } static inline int _br_child_witnessed_connection(br_child_t *child) { return (child->witnessed == 1); } /* scrub state */ static inline void _br_monitor_set_scrub_state(struct br_monitor *scrub_monitor, br_scrub_state_t state) { scrub_monitor->state = state; } static inline br_scrub_event_t _br_child_get_scrub_event(struct br_scrubber *fsscrub) { return (fsscrub->frequency == BR_FSSCRUB_FREQ_STALLED) ? BR_SCRUB_EVENT_PAUSE : BR_SCRUB_EVENT_SCHEDULE; } int32_t br_get_bad_objects_list(xlator_t *this, dict_t **dict); #endif /* __BIT_ROT_H__ */ glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/bit-rot-scrub.h0000644000000000000000000000013214522202451025630 xustar000000000000000030 mtime=1699284265.652027387 30 atime=1699284265.652027387 30 ctime=1699284305.028145986 glusterfs-11.1/xlators/features/bit-rot/src/bitd/bit-rot-scrub.h0000664000175100017510000000202414522202451026105 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __BIT_ROT_SCRUB_H__ #define __BIT_ROT_SCRUB_H__ #include "bit-rot.h" void * br_fsscanner(void *); int32_t br_fsscan_schedule(xlator_t *); int32_t br_fsscan_reschedule(xlator_t *); int32_t br_fsscan_activate(xlator_t *); int32_t br_fsscan_deactivate(xlator_t *); int32_t br_fsscan_ondemand(xlator_t *); int32_t br_scrubber_handle_options(xlator_t *, br_private_t *, dict_t *); int32_t br_scrubber_monitor_init(xlator_t *, br_private_t *); int32_t br_scrubber_init(xlator_t *, br_private_t *); int32_t br_collect_bad_objects_from_children(xlator_t *this, dict_t *dict); void br_child_set_scrub_state(br_child_t *, gf_boolean_t); #endif /* __BIT_ROT_SCRUB_H__ */ glusterfs-11.1/xlators/features/bit-rot/src/bitd/PaxHeaders.9031/bit-rot-scrub-status.c0000644000000000000000000000013214522202451027144 xustar000000000000000030 mtime=1699284265.651027384 30 atime=1699284265.651027384 30 ctime=1699284305.038146017 glusterfs-11.1/xlators/features/bit-rot/src/bitd/bit-rot-scrub-status.c0000664000175100017510000000347714522202451027436 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "bit-rot-scrub-status.h" void br_inc_unsigned_file_count(br_scrub_stats_t *scrub_stat) { if (!scrub_stat) return; pthread_mutex_lock(&scrub_stat->lock); { scrub_stat->unsigned_files++; } pthread_mutex_unlock(&scrub_stat->lock); } void br_inc_scrubbed_file(br_scrub_stats_t *scrub_stat) { if (!scrub_stat) return; pthread_mutex_lock(&scrub_stat->lock); { scrub_stat->scrubbed_files++; } pthread_mutex_unlock(&scrub_stat->lock); } void br_update_scrub_start_time(br_scrub_stats_t *scrub_stat, time_t time) { if (!scrub_stat) return; pthread_mutex_lock(&scrub_stat->lock); { scrub_stat->scrub_start_time = time; } pthread_mutex_unlock(&scrub_stat->lock); } void br_update_scrub_finish_time(br_scrub_stats_t *scrub_stat, char *timestr, time_t time) { int lst_size = 0; if (!scrub_stat) return; lst_size = sizeof(scrub_stat->last_scrub_time); if (strlen(timestr) >= lst_size) return; pthread_mutex_lock(&scrub_stat->lock); { scrub_stat->scrub_end_time = time; scrub_stat->scrub_duration = scrub_stat->scrub_end_time - scrub_stat->scrub_start_time; snprintf(scrub_stat->last_scrub_time, lst_size, "%s", timestr); } pthread_mutex_unlock(&scrub_stat->lock); } glusterfs-11.1/xlators/features/bit-rot/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463024111 xustar000000000000000030 mtime=1699284275.353056607 30 atime=1699284291.049103883 30 ctime=1699284304.941145724 glusterfs-11.1/xlators/features/bit-rot/src/Makefile.in0000664000175100017510000005265214522202463024402 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/bit-rot/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = stub bitd all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/bit-rot/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/bit-rot/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/bit-rot/src/PaxHeaders.9031/stub0000644000000000000000000000013214522202520022736 xustar000000000000000030 mtime=1699284304.989145869 30 atime=1699284309.687160019 30 ctime=1699284304.989145869 glusterfs-11.1/xlators/features/bit-rot/src/stub/0002775000175100017510000000000014522202520023274 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/bit-rot/src/stub/PaxHeaders.9031/bit-rot-stub-helpers.c0000644000000000000000000000013114522202451027154 xustar000000000000000030 mtime=1699284265.654027393 29 atime=1699284265.65302739 30 ctime=1699284304.987145863 glusterfs-11.1/xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c0000664000175100017510000005510014522202451027435 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "bit-rot-stub.h" br_stub_fd_t * br_stub_fd_new(void) { br_stub_fd_t *br_stub_fd = NULL; br_stub_fd = GF_CALLOC(1, sizeof(*br_stub_fd), gf_br_stub_mt_br_stub_fd_t); return br_stub_fd; } int __br_stub_fd_ctx_set(xlator_t *this, fd_t *fd, br_stub_fd_t *br_stub_fd) { uint64_t value = 0; int ret = -1; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, br_stub_fd, out); value = (uint64_t)(long)br_stub_fd; ret = __fd_ctx_set(fd, this, value); out: return ret; } br_stub_fd_t * __br_stub_fd_ctx_get(xlator_t *this, fd_t *fd) { br_stub_fd_t *br_stub_fd = NULL; br_stub_fd = __fd_ctx_get_ptr(fd, this); if (!br_stub_fd) { /* check if one of the parameters was null and provide meaningful error */ GF_VALIDATE_OR_GOTO("bit-rot-stub", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); } out: return br_stub_fd; } br_stub_fd_t * br_stub_fd_ctx_get(xlator_t *this, fd_t *fd) { br_stub_fd_t *br_stub_fd = NULL; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); LOCK(&fd->lock); { br_stub_fd = __br_stub_fd_ctx_get(this, fd); } UNLOCK(&fd->lock); out: return br_stub_fd; } int32_t br_stub_fd_ctx_set(xlator_t *this, fd_t *fd, br_stub_fd_t *br_stub_fd) { int32_t ret = -1; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, br_stub_fd, out); LOCK(&fd->lock); { ret = __br_stub_fd_ctx_set(this, fd, br_stub_fd); } UNLOCK(&fd->lock); out: return ret; } /** * Adds an entry to the bad objects directory. * @gfid: gfid of the bad object being added to the bad objects directory */ int br_stub_add(xlator_t *this, uuid_t gfid) { char gfid_path[BR_PATH_MAX_PLUS] = {0}; char bad_gfid_path[BR_PATH_MAX_PLUS] = {0}; int ret = 0; br_stub_private_t *priv = NULL; struct stat st = {0}; priv = this->private; GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(gfid), out, errno, EINVAL); snprintf(gfid_path, sizeof(gfid_path), "%s/%s", priv->stub_basepath, uuid_utoa(gfid)); ret = sys_stat(gfid_path, &st); if (!ret) goto out; snprintf(bad_gfid_path, sizeof(bad_gfid_path), "%s/stub-%s", priv->stub_basepath, uuid_utoa(priv->bad_object_dir_gfid)); ret = sys_link(bad_gfid_path, gfid_path); if (ret) { if ((errno != ENOENT) && (errno != EMLINK) && (errno != EEXIST)) goto out; /* * Continue with success. At least we'll have half of the * functionality, in the sense, object is marked bad and * would be inaccessible. It's only scrub status that would * show up less number of objects. That's fine as we'll have * the log files that will have the missing information. */ gf_smsg(this->name, GF_LOG_WARNING, errno, BRS_MSG_LINK_FAIL, "gfid=%s", uuid_utoa(gfid), NULL); } return 0; out: return -1; } int br_stub_del(xlator_t *this, uuid_t gfid) { int32_t op_errno __attribute__((unused)) = 0; br_stub_private_t *priv = NULL; int ret = 0; char gfid_path[BR_PATH_MAX_PLUS] = {0}; priv = this->private; GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(gfid), out, op_errno, EINVAL); snprintf(gfid_path, sizeof(gfid_path), "%s/%s", priv->stub_basepath, uuid_utoa(gfid)); if (!gf_unlink(gfid_path)) { ret = -errno; goto out; } ret = 0; out: return ret; } static int br_stub_check_stub_directory(xlator_t *this, char *fullpath) { int ret = 0; struct stat st = { 0, }; char oldpath[BR_PATH_MAX_PLUS] = {0}; br_stub_private_t *priv = NULL; priv = this->private; snprintf(oldpath, sizeof(oldpath), "%s/%s", priv->export, OLD_BR_STUB_QUARANTINE_DIR); ret = sys_stat(fullpath, &st); if (!ret && !S_ISDIR(st.st_mode)) goto error_return; if (ret) { if (errno != ENOENT) goto error_return; ret = sys_stat(oldpath, &st); if (ret) ret = mkdir_p(fullpath, 0600, _gf_true); else ret = sys_rename(oldpath, fullpath); } if (ret) gf_smsg(this->name, GF_LOG_ERROR, errno, BRS_MSG_BAD_OBJECT_DIR_FAIL, "create-path=%s", fullpath, NULL); return ret; error_return: gf_smsg(this->name, GF_LOG_ERROR, errno, BRS_MSG_BAD_OBJECT_DIR_FAIL, "verify-path=%s", fullpath, NULL); return -1; } /** * Function to create the container for the bad objects within the bad objects * directory. */ static int br_stub_check_stub_file(xlator_t *this, char *path) { int ret = 0; int fd = -1; struct stat st = { 0, }; ret = sys_stat(path, &st); if (!ret && !S_ISREG(st.st_mode)) goto error_return; if (ret) { if (errno != ENOENT) goto error_return; fd = sys_creat(path, 0); if (fd < 0) gf_smsg(this->name, GF_LOG_ERROR, errno, BRS_MSG_BAD_OBJECT_DIR_FAIL, "create-path=%s", path, NULL); } if (fd >= 0) { sys_close(fd); ret = 0; } return ret; error_return: gf_smsg(this->name, GF_LOG_ERROR, errno, BRS_MSG_BAD_OBJECT_DIR_FAIL, "verify-path=%s", path, NULL); return -1; } int br_stub_dir_create(xlator_t *this, br_stub_private_t *priv) { int ret = -1; char fullpath[BR_PATH_MAX_PLUS] = { 0, }; char stub_gfid_path[BR_PATH_MAX_PLUS] = { 0, }; gf_uuid_copy(priv->bad_object_dir_gfid, BR_BAD_OBJ_CONTAINER); if (snprintf(fullpath, sizeof(fullpath), "%s", priv->stub_basepath) >= sizeof(fullpath)) goto out; if (snprintf(stub_gfid_path, sizeof(stub_gfid_path), "%s/stub-%s", priv->stub_basepath, uuid_utoa(priv->bad_object_dir_gfid)) >= sizeof(stub_gfid_path)) goto out; ret = br_stub_check_stub_directory(this, fullpath); if (ret) goto out; ret = br_stub_check_stub_file(this, stub_gfid_path); if (ret) goto out; return 0; out: return -1; } call_stub_t * __br_stub_dequeue(struct list_head *callstubs) { call_stub_t *stub = NULL; if (!list_empty(callstubs)) { stub = list_entry(callstubs->next, call_stub_t, list); list_del_init(&stub->list); } return stub; } void __br_stub_enqueue(struct list_head *callstubs, call_stub_t *stub) { list_add_tail(&stub->list, callstubs); } void br_stub_worker_enqueue(xlator_t *this, call_stub_t *stub) { br_stub_private_t *priv = NULL; priv = this->private; pthread_mutex_lock(&priv->container.bad_lock); { __br_stub_enqueue(&priv->container.bad_queue, stub); pthread_cond_signal(&priv->container.bad_cond); } pthread_mutex_unlock(&priv->container.bad_lock); } void * br_stub_worker(void *data) { br_stub_private_t *priv = NULL; xlator_t *this = NULL; call_stub_t *stub = NULL; THIS = data; this = data; priv = this->private; for (;;) { pthread_mutex_lock(&priv->container.bad_lock); { while (list_empty(&priv->container.bad_queue)) { (void)pthread_cond_wait(&priv->container.bad_cond, &priv->container.bad_lock); } stub = __br_stub_dequeue(&priv->container.bad_queue); } pthread_mutex_unlock(&priv->container.bad_lock); if (stub) /* guard against spurious wakeups */ call_resume(stub); } return NULL; } int32_t br_stub_lookup_wrapper(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { br_stub_private_t *priv = NULL; struct stat lstatbuf = {0}; int ret = 0; int32_t op_errno = EINVAL; int32_t op_ret = -1; struct iatt stbuf = { 0, }; struct iatt postparent = { 0, }; dict_t *xattr = NULL; gf_boolean_t ver_enabled = _gf_false; BR_STUB_VER_ENABLED_IN_CALLPATH(frame, ver_enabled); priv = this->private; BR_STUB_VER_COND_GOTO(priv, (!ver_enabled), done); VALIDATE_OR_GOTO(loc, done); if (gf_uuid_compare(loc->gfid, priv->bad_object_dir_gfid)) goto done; ret = sys_lstat(priv->stub_basepath, &lstatbuf); if (ret) { gf_msg_debug(this->name, errno, "Stat failed on stub bad " "object dir"); op_errno = errno; goto done; } else if (!S_ISDIR(lstatbuf.st_mode)) { gf_msg_debug(this->name, errno, "bad object container is not " "a directory"); op_errno = ENOTDIR; goto done; } iatt_from_stat(&stbuf, &lstatbuf); gf_uuid_copy(stbuf.ia_gfid, priv->bad_object_dir_gfid); op_ret = op_errno = 0; xattr = dict_new(); if (!xattr) { op_ret = -1; op_errno = ENOMEM; } done: STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, loc->inode, &stbuf, xattr, &postparent); if (xattr) dict_unref(xattr); return 0; } static int is_bad_gfid_file_current(char *filename, uuid_t gfid) { char current_stub_gfid[GF_UUID_BUF_SIZE + 16] = { 0, }; snprintf(current_stub_gfid, sizeof current_stub_gfid, "stub-%s", uuid_utoa(gfid)); return (!strcmp(filename, current_stub_gfid)); } static void check_delete_stale_bad_file(xlator_t *this, char *filename) { int ret = 0; struct stat st = {0}; char filepath[BR_PATH_MAX_PLUS] = {0}; br_stub_private_t *priv = NULL; priv = this->private; if (is_bad_gfid_file_current(filename, priv->bad_object_dir_gfid)) return; snprintf(filepath, sizeof(filepath), "%s/%s", priv->stub_basepath, filename); ret = sys_stat(filepath, &st); if (!ret && st.st_nlink == 1) sys_unlink(filepath); } static int br_stub_fill_readdir(fd_t *fd, br_stub_fd_t *fctx, DIR *dir, off_t off, size_t size, gf_dirent_t *entries) { off_t in_case = -1; off_t last_off = 0; size_t filled = 0; int count = 0; int32_t this_size = -1; gf_dirent_t *this_entry = NULL; xlator_t *this = NULL; struct dirent *entry = NULL; struct dirent scratch[2] = { { 0, }, }; size_t entry_dname_len; this = THIS; if (!off) { rewinddir(dir); } else { seekdir(dir, off); #ifndef GF_LINUX_HOST_OS if ((u_long)telldir(dir) != off && off != fctx->bad_object.dir_eof) { gf_smsg(THIS->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJECT_DIR_SEEK_FAIL, "off=(0x%llx)", off, "dir=%p", dir, NULL); errno = EINVAL; count = -1; goto out; } #endif /* GF_LINUX_HOST_OS */ } while (filled <= size) { in_case = (u_long)telldir(dir); if (in_case == -1) { gf_smsg(THIS->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJECT_DIR_TELL_FAIL, "dir=%p", dir, "err=%s", strerror(errno), NULL); goto out; } errno = 0; entry = sys_readdir(dir, scratch); if (!entry || errno != 0) { if (errno == EBADF) { gf_smsg(THIS->name, GF_LOG_WARNING, 0, BRS_MSG_BAD_OBJECT_DIR_READ_FAIL, "dir=%p", dir, "err=%s", strerror(errno), NULL); goto out; } break; } if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) continue; entry_dname_len = strlen(entry->d_name); /* skip checking for stable bad file if the file name is not * exactly the length of 'stub-'. Most file name lenghts aren't. */ if (entry_dname_len == SLEN("stub-") + UUID_CANONICAL_FORM_LEN) { if (!strncmp(entry->d_name, "stub-", SLEN("stub-"))) { check_delete_stale_bad_file(this, entry->d_name); continue; } } this_size = max(sizeof(gf_dirent_t), sizeof(gfx_dirplist)) + entry_dname_len + 1; if (this_size + filled > size) { seekdir(dir, in_case); #ifndef GF_LINUX_HOST_OS if ((u_long)telldir(dir) != in_case && in_case != fctx->bad_object.dir_eof) { gf_smsg(THIS->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJECT_DIR_SEEK_FAIL, "in_case=(0x%llx)", in_case, "dir=%p", dir, NULL); errno = EINVAL; count = -1; goto out; } #endif /* GF_LINUX_HOST_OS */ break; } this_entry = gf_dirent_for_name(entry->d_name); if (!this_entry) { gf_smsg(THIS->name, GF_LOG_ERROR, 0, BRS_MSG_CREATE_GF_DIRENT_FAILED, "entry-name=%s", entry->d_name, "err=%s", strerror(errno), NULL); goto out; } /* * we store the offset of next entry here, which is * probably not intended, but code using syncop_readdir() * (glfs-heal.c, afr-self-heald.c) rely on it * for directory read resumption. */ last_off = (u_long)telldir(dir); this_entry->d_off = last_off; this_entry->d_ino = entry->d_ino; list_add_tail(&this_entry->list, &entries->list); filled += this_size; count++; } if ((!sys_readdir(dir, scratch) && (errno == 0))) { /* Indicate EOF */ errno = ENOENT; /* Remember EOF offset for later detection */ fctx->bad_object.dir_eof = last_off; } out: return count; } int32_t br_stub_readdir_wrapper(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { br_stub_fd_t *fctx = NULL; DIR *dir = NULL; int ret = -1; int32_t op_ret = -1; int32_t op_errno = 0; int count = 0; gf_dirent_t entries; gf_boolean_t xdata_unref = _gf_false; dict_t *dict = NULL; INIT_LIST_HEAD(&entries.list); fctx = br_stub_fd_ctx_get(this, fd); if (!fctx) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_GET_FD_CONTEXT_FAILED, "fd=%p", fd, NULL); op_errno = -ret; goto done; } dir = fctx->bad_object.dir; if (!dir) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_BAD_HANDLE_DIR_NULL, "fd=%p", fd, NULL); op_errno = EINVAL; goto done; } count = br_stub_fill_readdir(fd, fctx, dir, off, size, &entries); /* pick ENOENT to indicate EOF */ op_errno = errno; op_ret = count; dict = xdata; (void)br_stub_bad_objects_path(this, fd, &entries, &dict); if (!xdata && dict) { xdata = dict; xdata_unref = _gf_true; } done: STACK_UNWIND_STRICT(readdir, frame, op_ret, op_errno, &entries, xdata); gf_dirent_free(&entries); if (xdata_unref) dict_unref(xdata); return 0; } /** * This function is called to mainly obtain the paths of the corrupt * objects (files as of now). Currently scrub status prints only the * gfid of the corrupted files. Reason is, bitrot-stub maintains the * list of the corrupted objects as entries inside the quarantine * directory (/.glusterfs/quarantine) * * And the name of each entry in the qurantine directory is the gfid * of the corrupted object. So scrub status will just show that info. * But it helps the users a lot if the actual path to the object is * also reported. Hence the below function to get that information. * The function allocates a new dict to be returned (if it does not * get one from the caller of readdir i.e. scrubber as of now), and * stores the paths of each corrupted gfid there. The gfid is used as * the key and path is used as the value. * * NOTE: The path will be there in following situations * 1) gfid2path option has been enabled (posix xlator option) * and the corrupted file contains the path as an extended * attribute. * 2) If the gfid2path option is not enabled, OR if the xattr * is absent, then the inode table should have it. * The path will be there if a name based lookup has happened * on the file which has been corrupted. With lookup a inode and * dentry would be created in the inode table. And the path is * constructed using the in memory inode and dentry. If a lookup * has not happened OR the inode corresponding to the corrupted * file does not exist in the inode table (because it got purged * as lru limit of the inodes exceeded) OR a nameless lookup had * happened to populate the inode in the inode table, then the * path will not be printed in scrub and only the gfid will be there. **/ int br_stub_bad_objects_path(xlator_t *this, fd_t *fd, gf_dirent_t *entries, dict_t **dict) { gf_dirent_t *entry = NULL; inode_t *inode = NULL; char *hpath = NULL; uuid_t gfid = {0}; int ret = -1; dict_t *tmp_dict = NULL; char str_gfid[64] = {0}; if (list_empty(&entries->list)) return 0; tmp_dict = *dict; if (!tmp_dict) { tmp_dict = dict_new(); /* * If the allocation of dict fails then no need treat it * it as a error. This path (or function) is executed when * "gluster volume bitrot scrub status" is * executed, to get the list of the corrupted objects. * And the motive of this function is to get the paths of * the corrupted objects. If the dict allocation fails, then * the scrub status will only show the gfids of those corrupted * objects (which is the behavior as of the time of this patch * being worked upon). So just return and only the gfids will * be shown. */ if (!tmp_dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_ALLOC_FAILED, NULL); goto out; } } list_for_each_entry(entry, &entries->list, list) { gf_uuid_clear(gfid); gf_uuid_parse(entry->d_name, gfid); inode = inode_find(fd->inode->table, gfid); /* No need to check the return value here. * Because @hpath is examined. */ (void)br_stub_get_path_of_gfid(this, fd->inode, inode, gfid, &hpath); if (hpath) { gf_msg_debug(this->name, 0, "path of the corrupted " "object (gfid: %s) is %s", uuid_utoa(gfid), hpath); br_stub_entry_xattr_fill(this, hpath, entry, tmp_dict); } else gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_PATH_GET_FAILED, "gfid=%s", uuid_utoa_r(gfid, str_gfid), NULL); inode = NULL; hpath = NULL; } ret = 0; *dict = tmp_dict; out: return ret; } int br_stub_get_path_of_gfid(xlator_t *this, inode_t *parent, inode_t *inode, uuid_t gfid, char **path) { int32_t ret = -1; char gfid_str[64] = {0}; GF_VALIDATE_OR_GOTO("bitrot-stub", this, out); GF_VALIDATE_OR_GOTO(this->name, parent, out); GF_VALIDATE_OR_GOTO(this->name, path, out); /* Above, No need to validate the @inode for hard resolution. Because * inode can be NULL and if it is NULL, then syncop_gfid_to_path_hard * will allocate a new inode and proceed. So no need to bother about * @inode. Because we need it only to send a syncop_getxattr call * from inside syncop_gfid_to_path_hard. And getxattr fetches the * path from the backend. */ ret = syncop_gfid_to_path_hard(parent->table, FIRST_CHILD(this), gfid, inode, path, _gf_true); if (ret < 0) gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_PATH_GET_FAILED, "gfid=%s", uuid_utoa_r(gfid, gfid_str), NULL); /* * Try with soft resolution of path if hard resolve fails. Because * checking the xattr on disk to get the path of a inode (or gfid) * is dependent on whether that option is enabled in the posix * xlator or not. If it is not enabled, then hard resolution by * checking the on disk xattr fails. * * Thus in such situations fall back to the soft resolution which * mainly depends on the inode_path() function. And for using * inode_path, @inode has to be linked i.e. a successful lookup should * have happened on the gfid (or the path) to link the inode to the * inode table. And if @inode is NULL, means, the inode has not been * found in the inode table and better not to do inode_path() on the * inode which has not been linked. */ if (ret < 0 && inode) { ret = syncop_gfid_to_path_hard(parent->table, FIRST_CHILD(this), gfid, inode, path, _gf_false); if (ret < 0) gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_PATH_GET_FAILED, "from-memory gfid=%s", uuid_utoa_r(gfid, gfid_str), NULL); } out: return ret; } /** * NOTE: If the file has multiple hardlinks (in gluster volume * namespace), the path would be one of the hardlinks. Its up to * the user to find the remaining hardlinks (using find -samefile) * and remove them. **/ void br_stub_entry_xattr_fill(xlator_t *this, char *hpath, gf_dirent_t *entry, dict_t *dict) { int32_t ret = -1; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, out); GF_VALIDATE_OR_GOTO(this->name, hpath, out); /* * Use the entry->d_name (which is nothing but the gfid of the * corrupted object) as the key. And the value will be the actual * path of that object (or file). * * ALso ignore the dict_set errors. scrubber will get the gfid of * the corrupted object for sure. So, for now lets just log the * dict_set_dynstr failure and move on. */ ret = dict_set_dynstr(dict, entry->d_name, hpath); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_DICT_SET_FAILED, "path=%s", hpath, "object-name=%s", entry->d_name, NULL); out: return; } glusterfs-11.1/xlators/features/bit-rot/src/stub/PaxHeaders.9031/bit-rot-common.h0000644000000000000000000000013014522202451026033 xustar000000000000000029 mtime=1699284265.65302739 29 atime=1699284265.65302739 30 ctime=1699284304.982145848 glusterfs-11.1/xlators/features/bit-rot/src/stub/bit-rot-common.h0000664000175100017510000001230214522202451026312 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __BIT_ROT_COMMON_H__ #define __BIT_ROT_COMMON_H__ #include "bit-rot-object-version.h" #define BR_VXATTR_VERSION (1 << 0) #define BR_VXATTR_SIGNATURE (1 << 1) #define BR_VXATTR_SIGN_MISSING (BR_VXATTR_SIGNATURE) #define BR_VXATTR_ALL_MISSING (BR_VXATTR_VERSION | BR_VXATTR_SIGNATURE) #define BR_BAD_OBJ_CONTAINER \ (uuid_t) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 } typedef enum br_vxattr_state { BR_VXATTR_STATUS_FULL = 0, BR_VXATTR_STATUS_MISSING = 1, BR_VXATTR_STATUS_UNSIGNED = 2, BR_VXATTR_STATUS_INVALID = 3, } br_vxattr_status_t; typedef enum br_sign_state { BR_SIGN_INVALID = -1, BR_SIGN_NORMAL = 0, BR_SIGN_REOPEN_WAIT = 1, BR_SIGN_QUICK = 2, } br_sign_state_t; static inline br_vxattr_status_t br_version_xattr_state(dict_t *xattr, br_version_t **obuf, br_signature_t **sbuf, gf_boolean_t *objbad) { int32_t ret = 0; int32_t vxattr = 0; br_vxattr_status_t status; void *data = NULL; /** * The key being present in the dict indicates the xattr was set on * disk. The presence of xattr itself as of now is suffecient to say * the the object is bad. */ *objbad = _gf_false; ret = dict_get_bin(xattr, BITROT_OBJECT_BAD_KEY, (void **)&data); if (!ret) *objbad = _gf_true; ret = dict_get_bin(xattr, BITROT_CURRENT_VERSION_KEY, (void **)obuf); if (ret) vxattr |= BR_VXATTR_VERSION; ret = dict_get_bin(xattr, BITROT_SIGNING_VERSION_KEY, (void **)sbuf); if (ret) vxattr |= BR_VXATTR_SIGNATURE; switch (vxattr) { case 0: status = BR_VXATTR_STATUS_FULL; break; case BR_VXATTR_SIGN_MISSING: status = BR_VXATTR_STATUS_UNSIGNED; break; case BR_VXATTR_ALL_MISSING: status = BR_VXATTR_STATUS_MISSING; break; default: status = BR_VXATTR_STATUS_INVALID; } return status; } /** * in-memory representation of signature used by signer for object * signing. */ typedef struct br_isignature_in { int8_t signaturetype; /* signature type */ unsigned long signedversion; /* version against which the object was signed */ size_t signaturelen; /* signature length */ char signature[0]; /* object signature */ } br_isignature_t; /** * in-memory representation of signature used by scrubber for object * verification. */ typedef struct br_isignature_out { char stale; /* stale signature? */ unsigned long version; /* current signed version */ unsigned long time[2]; /* time when the object got dirtied */ int8_t signaturetype; /* hash type */ size_t signaturelen; /* signature length */ char signature[0]; /* signature (hash) */ } br_isignature_out_t; typedef struct br_stub_init { unsigned long timebuf[2]; char export[PATH_MAX]; } br_stub_init_t; typedef enum { BR_SIGNATURE_TYPE_VOID = -1, /* object is not signed */ BR_SIGNATURE_TYPE_ZERO = 0, /* min boundary */ BR_SIGNATURE_TYPE_SHA256 = 1, /* signed with SHA256 */ BR_SIGNATURE_TYPE_MAX = 2, /* max boundary */ } br_signature_type; /* BitRot stub start time (virtual xattr) */ #define GLUSTERFS_GET_BR_STUB_INIT_TIME "trusted.glusterfs.bit-rot.stub-init" /* signing/reopen hint */ #define BR_OBJECT_RESIGN 0 #define BR_OBJECT_REOPEN 1 #define BR_REOPEN_SIGN_HINT_KEY "trusted.glusterfs.bit-rot.reopen-hint" static inline int br_is_signature_type_valid(int8_t signaturetype) { return ((signaturetype > BR_SIGNATURE_TYPE_ZERO) && (signaturetype < BR_SIGNATURE_TYPE_MAX)); } static inline void br_set_default_ongoingversion(br_version_t *buf, unsigned long *tv) { buf->ongoingversion = BITROT_DEFAULT_CURRENT_VERSION; buf->timebuf[0] = tv[0]; buf->timebuf[1] = tv[1]; } static inline void br_set_default_signature(br_signature_t *buf, size_t *size) { buf->signaturetype = (int8_t)BR_SIGNATURE_TYPE_VOID; buf->signedversion = BITROT_DEFAULT_SIGNING_VERSION; *size = sizeof(br_signature_t); /* no signature */ } static inline void br_set_ongoingversion(br_version_t *buf, unsigned long version, unsigned long *tv) { buf->ongoingversion = version; buf->timebuf[0] = tv[0]; buf->timebuf[1] = tv[1]; } static inline void br_set_signature(br_signature_t *buf, br_isignature_t *sign, size_t signaturelen, size_t *size) { buf->signaturetype = sign->signaturetype; buf->signedversion = ntohl(sign->signedversion); memcpy(buf->signature, sign->signature, signaturelen); *size = sizeof(br_signature_t) + signaturelen; } #endif /* __BIT_ROT_COMMON_H__ */ glusterfs-11.1/xlators/features/bit-rot/src/stub/PaxHeaders.9031/bit-rot-object-version.h0000644000000000000000000000013014522202451027474 xustar000000000000000029 mtime=1699284265.65302739 29 atime=1699284265.65302739 30 ctime=1699284304.985145857 glusterfs-11.1/xlators/features/bit-rot/src/stub/bit-rot-object-version.h0000664000175100017510000000142014522202451027752 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __BIT_ROT_OBJECT_VERSION_H #define __BIT_ROT_OBJECT_VERSION_H /** * on-disk formats for ongoing version and object signature. */ typedef struct br_version { unsigned long ongoingversion; unsigned long timebuf[2]; } br_version_t; typedef struct __attribute__((__packed__)) br_signature { int8_t signaturetype; unsigned long signedversion; char signature[0]; } br_signature_t; #endif glusterfs-11.1/xlators/features/bit-rot/src/stub/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463025066 xustar000000000000000030 mtime=1699284275.449056896 30 atime=1699284291.069103943 30 ctime=1699284304.978145836 glusterfs-11.1/xlators/features/bit-rot/src/stub/Makefile.in0000664000175100017510000006016714522202463025357 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/bit-rot/src/stub DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) bitrot_stub_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_bitrot_stub_la_OBJECTS = bit-rot-stub-helpers.lo bit-rot-stub.lo bitrot_stub_la_OBJECTS = $(am_bitrot_stub_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = bitrot_stub_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(bitrot_stub_la_LDFLAGS) $(LDFLAGS) -o \ $@ @WITH_SERVER_TRUE@am_bitrot_stub_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(bitrot_stub_la_SOURCES) DIST_SOURCES = $(bitrot_stub_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = bitrot-stub.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features bitrot_stub_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) bitrot_stub_la_SOURCES = bit-rot-stub-helpers.c bit-rot-stub.c bitrot_stub_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = bit-rot-stub.h bit-rot-common.h bit-rot-stub-mem-types.h \ bit-rot-object-version.h bit-rot-stub-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/bit-rot/src/stub/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/bit-rot/src/stub/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } bitrot-stub.la: $(bitrot_stub_la_OBJECTS) $(bitrot_stub_la_DEPENDENCIES) $(EXTRA_bitrot_stub_la_DEPENDENCIES) $(AM_V_CCLD)$(bitrot_stub_la_LINK) $(am_bitrot_stub_la_rpath) $(bitrot_stub_la_OBJECTS) $(bitrot_stub_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit-rot-stub-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit-rot-stub.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/bit-rot/src/stub/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451025051 xustar000000000000000029 mtime=1699284265.65302739 30 atime=1699284275.411056781 30 ctime=1699284304.979145839 glusterfs-11.1/xlators/features/bit-rot/src/stub/Makefile.am0000664000175100017510000000122014522202451025324 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = bitrot-stub.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features bitrot_stub_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) bitrot_stub_la_SOURCES = bit-rot-stub-helpers.c bit-rot-stub.c bitrot_stub_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = bit-rot-stub.h bit-rot-common.h bit-rot-stub-mem-types.h \ bit-rot-object-version.h bit-rot-stub-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/bit-rot/src/stub/PaxHeaders.9031/bit-rot-stub-messages.h0000644000000000000000000000013114522202451027326 xustar000000000000000030 mtime=1699284265.654027393 30 atime=1699284265.654027393 29 ctime=1699284304.98614586 glusterfs-11.1/xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h0000664000175100017510000001501514522202451027610 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _BITROT_STUB_MESSAGES_H_ #define _BITROT_STUB_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(BITROT_STUB, BRS_MSG_NO_MEMORY, BRS_MSG_SET_EVENT_FAILED, BRS_MSG_MEM_ACNT_FAILED, BRS_MSG_CREATE_FRAME_FAILED, BRS_MSG_SET_CONTEXT_FAILED, BRS_MSG_CHANGE_VERSION_FAILED, BRS_MSG_ADD_FD_TO_LIST_FAILED, BRS_MSG_SET_FD_CONTEXT_FAILED, BRS_MSG_CREATE_ANONYMOUS_FD_FAILED, BRS_MSG_NO_CHILD, BRS_MSG_STUB_ALLOC_FAILED, BRS_MSG_GET_INODE_CONTEXT_FAILED, BRS_MSG_CANCEL_SIGN_THREAD_FAILED, BRS_MSG_ADD_FD_TO_INODE, BRS_MSG_SIGN_VERSION_ERROR, BRS_MSG_BAD_OBJ_MARK_FAIL, BRS_MSG_NON_SCRUB_BAD_OBJ_MARK, BRS_MSG_REMOVE_INTERNAL_XATTR, BRS_MSG_SET_INTERNAL_XATTR, BRS_MSG_BAD_OBJECT_ACCESS, BRS_MSG_BAD_CONTAINER_FAIL, BRS_MSG_BAD_OBJECT_DIR_FAIL, BRS_MSG_BAD_OBJECT_DIR_SEEK_FAIL, BRS_MSG_BAD_OBJECT_DIR_TELL_FAIL, BRS_MSG_BAD_OBJECT_DIR_READ_FAIL, BRS_MSG_GET_FD_CONTEXT_FAILED, BRS_MSG_BAD_HANDLE_DIR_NULL, BRS_MSG_BAD_OBJ_THREAD_FAIL, BRS_MSG_BAD_OBJ_DIR_CLOSE_FAIL, BRS_MSG_LINK_FAIL, BRS_MSG_UNUSED_PLACEHOLDER, BRS_MSG_DICT_SET_FAILED, BRS_MSG_PATH_GET_FAILED, BRS_MSG_NULL_LOCAL, BRS_MSG_SPAWN_SIGN_THRD_FAILED, BRS_MSG_KILL_SIGN_THREAD, BRS_MSG_NON_BITD_PID, BRS_MSG_SIGN_PREPARE_FAIL, BRS_MSG_USING_DEFAULT_THREAD_SIZE, BRS_MSG_ALLOC_MEM_FAILED, BRS_MSG_DICT_ALLOC_FAILED, BRS_MSG_CREATE_GF_DIRENT_FAILED, BRS_MSG_ALLOC_FAILED, BRS_MSG_PATH_XATTR_GET_FAILED, BRS_MSG_VERSION_PREPARE_FAIL); #define BRS_MSG_MEM_ACNT_FAILED_STR "Memory accounting init failed" #define BRS_MSG_BAD_OBJ_THREAD_FAIL_STR "pthread_init failed" #define BRS_MSG_USING_DEFAULT_THREAD_SIZE_STR "Using default thread stack size" #define BRS_MSG_NO_CHILD_STR "FATAL: no children" #define BRS_MSG_SPAWN_SIGN_THRD_FAILED_STR \ "failed to create the new thread for signer" #define BRS_MSG_BAD_CONTAINER_FAIL_STR \ "failed to launch the thread for storing bad gfids" #define BRS_MSG_CANCEL_SIGN_THREAD_FAILED_STR \ "Could not cancel sign serializer thread" #define BRS_MSG_KILL_SIGN_THREAD_STR "killed the signer thread" #define BRS_MSG_GET_INODE_CONTEXT_FAILED_STR \ "failed to init the inode context for the inode" #define BRS_MSG_ADD_FD_TO_INODE_STR "failed to add fd to the inode" #define BRS_MSG_NO_MEMORY_STR "local allocation failed" #define BRS_MSG_BAD_OBJECT_ACCESS_STR "bad object accessed. Returning" #define BRS_MSG_SIGN_VERSION_ERROR_STR "Signing version exceeds current version" #define BRS_MSG_NON_BITD_PID_STR \ "PID from where signature request came, does not belong to bit-rot " \ "daemon. Unwinding the fop" #define BRS_MSG_SIGN_PREPARE_FAIL_STR \ "failed to prepare the signature. Unwinding the fop" #define BRS_MSG_VERSION_PREPARE_FAIL_STR \ "failed to prepare the version. Unwinding the fop" #define BRS_MSG_STUB_ALLOC_FAILED_STR "failed to allocate stub fop, Unwinding" #define BRS_MSG_BAD_OBJ_MARK_FAIL_STR "failed to mark object as bad" #define BRS_MSG_NON_SCRUB_BAD_OBJ_MARK_STR \ "bad object marking is not from the scrubber" #define BRS_MSG_ALLOC_MEM_FAILED_STR "failed to allocate memory" #define BRS_MSG_SET_INTERNAL_XATTR_STR "called on the internal xattr" #define BRS_MSG_REMOVE_INTERNAL_XATTR_STR "removexattr called on internal xattr" #define BRS_MSG_CREATE_ANONYMOUS_FD_FAILED_STR \ "failed to create anonymous fd for the inode" #define BRS_MSG_ADD_FD_TO_LIST_FAILED_STR "failed add fd to the list" #define BRS_MSG_SET_FD_CONTEXT_FAILED_STR \ "failed to set the fd context for the file" #define BRS_MSG_NULL_LOCAL_STR "local is NULL" #define BRS_MSG_DICT_ALLOC_FAILED_STR \ "dict allocation failed: cannot send IPC FOP to changelog" #define BRS_MSG_SET_EVENT_FAILED_STR "cannot set release event in dict" #define BRS_MSG_CREATE_FRAME_FAILED_STR "create_frame() failure" #define BRS_MSG_BAD_OBJ_DIR_CLOSE_FAIL_STR "closedir error" #define BRS_MSG_LINK_FAIL_STR "failed to record gfid" #define BRS_MSG_BAD_OBJECT_DIR_FAIL_STR "failed stub directory" #define BRS_MSG_BAD_OBJECT_DIR_SEEK_FAIL_STR \ "seekdir failed. Invalid argument (offset reused from another DIR * " \ "structure)" #define BRS_MSG_BAD_OBJECT_DIR_TELL_FAIL_STR "telldir failed on dir" #define BRS_MSG_BAD_OBJECT_DIR_READ_FAIL_STR "readdir failed on dir" #define BRS_MSG_CREATE_GF_DIRENT_FAILED_STR "could not create gf_dirent" #define BRS_MSG_GET_FD_CONTEXT_FAILED_STR "pfd is NULL" #define BRS_MSG_BAD_HANDLE_DIR_NULL_STR "dir if NULL" #define BRS_MSG_ALLOC_FAILED_STR \ "failed to allocate new dict for saving the paths of the corrupted " \ "objects. Scrub status will only display the gfid" #define BRS_MSG_PATH_GET_FAILED_STR "failed to get the path" #define BRS_MSG_PATH_XATTR_GET_FAILED_STR \ "failed to get the path xattr from disk for the gfid. Trying to get path " \ "from the memory" #define BRS_MSG_DICT_SET_FAILED_STR \ "failed to set the actual path as the value in the dict for the " \ "corrupted object" #define BRS_MSG_SET_CONTEXT_FAILED_STR \ "could not set fd context for release callback" #define BRS_MSG_CHANGE_VERSION_FAILED_STR "change version failed" #endif /* !_BITROT_STUB_MESSAGES_H_ */ glusterfs-11.1/xlators/features/bit-rot/src/stub/PaxHeaders.9031/bit-rot-stub-mem-types.h0000644000000000000000000000013214522202451027440 xustar000000000000000030 mtime=1699284265.654027393 30 atime=1699284265.654027393 30 ctime=1699284304.983145851 glusterfs-11.1/xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h0000664000175100017510000000173714522202451027727 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _BR_MEM_TYPES_H #define _BR_MEM_TYPES_H #include enum br_mem_types { gf_br_stub_mt_private_t = gf_common_mt_end + 1, gf_br_stub_mt_version_t, gf_br_stub_mt_inode_ctx_t, gf_br_stub_mt_signature_t, gf_br_mt_br_private_t, gf_br_mt_br_child_t, gf_br_mt_br_object_t, gf_br_mt_br_ob_n_wk_t, gf_br_mt_br_scrubber_t, gf_br_mt_br_fsscan_entry_t, gf_br_stub_mt_br_stub_fd_t, gf_br_stub_mt_br_scanner_freq_t, gf_br_stub_mt_sigstub_t, gf_br_mt_br_child_event_t, gf_br_stub_mt_misc, gf_br_mt_br_worker_t, gf_br_stub_mt_end, }; #endif glusterfs-11.1/xlators/features/bit-rot/src/stub/PaxHeaders.9031/bit-rot-stub.c0000644000000000000000000000013214522202451025515 xustar000000000000000030 mtime=1699284265.655027396 30 atime=1699284265.654027393 30 ctime=1699284304.989145869 glusterfs-11.1/xlators/features/bit-rot/src/stub/bit-rot-stub.c0000664000175100017510000031406214522202451026002 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include "changelog.h" #include #include #include "bit-rot-stub.h" #include "bit-rot-stub-mem-types.h" #include "bit-rot-stub-messages.h" #include "bit-rot-common.h" #define BR_STUB_REQUEST_COOKIE 0x1 void br_stub_lock_cleaner(void *arg) { pthread_mutex_t *clean_mutex = arg; pthread_mutex_unlock(clean_mutex); return; } void * br_stub_signth(void *); struct br_stub_signentry { unsigned long v; call_stub_t *stub; struct list_head list; }; int32_t mem_acct_init(xlator_t *this) { int32_t ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_br_stub_mt_end); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_MEM_ACNT_FAILED, NULL); return ret; } return ret; } int br_stub_bad_object_container_init(xlator_t *this, br_stub_private_t *priv) { pthread_attr_t w_attr; int ret = -1; ret = pthread_cond_init(&priv->container.bad_cond, NULL); if (ret != 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJ_THREAD_FAIL, "cond_init ret=%d", ret, NULL); goto out; } ret = pthread_mutex_init(&priv->container.bad_lock, NULL); if (ret != 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJ_THREAD_FAIL, "mutex_init ret=%d", ret, NULL); goto cleanup_cond; } ret = pthread_attr_init(&w_attr); if (ret != 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJ_THREAD_FAIL, "attr_init ret=%d", ret, NULL); goto cleanup_lock; } ret = pthread_attr_setstacksize(&w_attr, BAD_OBJECT_THREAD_STACK_SIZE); if (ret == EINVAL) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_USING_DEFAULT_THREAD_SIZE, NULL); } INIT_LIST_HEAD(&priv->container.bad_queue); ret = br_stub_dir_create(this, priv); if (ret < 0) goto cleanup_lock; ret = gf_thread_create(&priv->container.thread, &w_attr, br_stub_worker, this, "brswrker"); if (ret) goto cleanup_attr; return 0; cleanup_attr: pthread_attr_destroy(&w_attr); cleanup_lock: pthread_mutex_destroy(&priv->container.bad_lock); cleanup_cond: pthread_cond_destroy(&priv->container.bad_cond); out: return -1; } int32_t init(xlator_t *this) { int ret = 0; char *tmp = NULL; struct timeval tv = { 0, }; br_stub_private_t *priv = NULL; if (!this->children) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_NO_CHILD, NULL); goto error_return; } priv = GF_CALLOC(1, sizeof(*priv), gf_br_stub_mt_private_t); if (!priv) goto error_return; priv->local_pool = mem_pool_new(br_stub_local_t, 512); if (!priv->local_pool) goto free_priv; GF_OPTION_INIT("bitrot", priv->do_versioning, bool, free_mempool); GF_OPTION_INIT("export", tmp, str, free_mempool); if (snprintf(priv->export, PATH_MAX, "%s", tmp) >= PATH_MAX) goto free_mempool; if (snprintf(priv->stub_basepath, sizeof(priv->stub_basepath), "%s/%s", priv->export, BR_STUB_QUARANTINE_DIR) >= sizeof(priv->stub_basepath)) goto free_mempool; (void)gettimeofday(&tv, NULL); /* boot time is in network endian format */ priv->boot[0] = htonl(tv.tv_sec); priv->boot[1] = htonl(tv.tv_usec); pthread_mutex_init(&priv->lock, NULL); pthread_cond_init(&priv->cond, NULL); INIT_LIST_HEAD(&priv->squeue); /* Thread creations need 'this' to be passed so that THIS can be * assigned inside the thread. So setting this->private here. */ this->private = priv; if (!priv->do_versioning) return 0; ret = gf_thread_create(&priv->signth, NULL, br_stub_signth, this, "brssign"); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_SPAWN_SIGN_THRD_FAILED, NULL); goto cleanup_lock; } ret = br_stub_bad_object_container_init(this, priv); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_CONTAINER_FAIL, NULL); goto cleanup_lock; } gf_msg_debug(this->name, 0, "bit-rot stub loaded"); return 0; cleanup_lock: pthread_cond_destroy(&priv->cond); pthread_mutex_destroy(&priv->lock); free_mempool: mem_pool_destroy(priv->local_pool); priv->local_pool = NULL; free_priv: GF_FREE(priv); this->private = NULL; error_return: return -1; } /* TODO: * As of now enabling bitrot option does 2 things. * 1) Start the Bitrot Daemon which signs the objects (currently files only) * upon getting notified by the stub. * 2) Enable versioning of the objects. Object versions (again files only) are * incremented upon modification. * So object versioning is tied to bitrot daemon's signing. In future, object * versioning might be necessary for other things as well apart from bit-rot * detection (well that's the objective of bringing in object-versioning :)). * In that case, better to make versioning a new option and letting it to be * enabled despite bit-rot detection is not needed. * Ex: ICAP. */ int32_t reconfigure(xlator_t *this, dict_t *options) { int32_t ret = -1; br_stub_private_t *priv = NULL; priv = this->private; GF_OPTION_RECONF("bitrot", priv->do_versioning, options, bool, err); if (priv->do_versioning && !priv->signth) { ret = gf_thread_create(&priv->signth, NULL, br_stub_signth, this, "brssign"); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_SPAWN_SIGN_THRD_FAILED, NULL); goto err; } ret = br_stub_bad_object_container_init(this, priv); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_CONTAINER_FAIL, NULL); goto err; } } else { if (priv->signth) { if (gf_thread_cleanup_xint(priv->signth)) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_CANCEL_SIGN_THREAD_FAILED, NULL); } else { gf_smsg(this->name, GF_LOG_INFO, 0, BRS_MSG_KILL_SIGN_THREAD, NULL); priv->signth = 0; } } if (priv->container.thread) { if (gf_thread_cleanup_xint(priv->container.thread)) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_CANCEL_SIGN_THREAD_FAILED, NULL); } priv->container.thread = 0; } } ret = 0; return ret; err: if (priv->signth) { if (gf_thread_cleanup_xint(priv->signth)) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_CANCEL_SIGN_THREAD_FAILED, NULL); } priv->signth = 0; } if (priv->container.thread) { if (gf_thread_cleanup_xint(priv->container.thread)) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_CANCEL_SIGN_THREAD_FAILED, NULL); } priv->container.thread = 0; } ret = -1; return ret; } int notify(xlator_t *this, int event, void *data, ...) { br_stub_private_t *priv = NULL; if (!this) return 0; priv = this->private; if (!priv) return 0; default_notify(this, event, data); return 0; } void fini(xlator_t *this) { int32_t ret = 0; br_stub_private_t *priv = this->private; struct br_stub_signentry *sigstub = NULL; call_stub_t *stub = NULL; if (!priv) return; if (!priv->do_versioning) goto cleanup; ret = gf_thread_cleanup_xint(priv->signth); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_CANCEL_SIGN_THREAD_FAILED, NULL); goto out; } priv->signth = 0; while (!list_empty(&priv->squeue)) { sigstub = list_first_entry(&priv->squeue, struct br_stub_signentry, list); list_del_init(&sigstub->list); call_stub_destroy(sigstub->stub); GF_FREE(sigstub); } ret = gf_thread_cleanup_xint(priv->container.thread); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_CANCEL_SIGN_THREAD_FAILED, NULL); goto out; } priv->container.thread = 0; while (!list_empty(&priv->container.bad_queue)) { stub = list_first_entry(&priv->container.bad_queue, call_stub_t, list); list_del_init(&stub->list); call_stub_destroy(stub); } pthread_mutex_destroy(&priv->container.bad_lock); pthread_cond_destroy(&priv->container.bad_cond); cleanup: pthread_mutex_destroy(&priv->lock); pthread_cond_destroy(&priv->cond); if (priv->local_pool) { mem_pool_destroy(priv->local_pool); priv->local_pool = NULL; } this->private = NULL; GF_FREE(priv); out: return; } static int br_stub_alloc_versions(br_version_t **obuf, br_signature_t **sbuf, size_t signaturelen) { void *mem = NULL; size_t size = 0; if (obuf) size += sizeof(br_version_t); if (sbuf) size += sizeof(br_signature_t) + signaturelen; mem = GF_CALLOC(1, size, gf_br_stub_mt_version_t); if (!mem) goto error_return; if (obuf) { *obuf = (br_version_t *)mem; mem = ((char *)mem + sizeof(br_version_t)); } if (sbuf) { *sbuf = (br_signature_t *)mem; } return 0; error_return: return -1; } static void br_stub_dealloc_versions(void *mem) { GF_FREE(mem); } static br_stub_local_t * br_stub_alloc_local(xlator_t *this) { br_stub_private_t *priv = this->private; return mem_get0(priv->local_pool); } static void br_stub_dealloc_local(br_stub_local_t *ptr) { if (!ptr) return; mem_put(ptr); } static int br_stub_prepare_version_request(xlator_t *this, dict_t *dict, br_version_t *obuf, unsigned long oversion) { br_stub_private_t *priv = NULL; priv = this->private; br_set_ongoingversion(obuf, oversion, priv->boot); return dict_set_bin(dict, BITROT_CURRENT_VERSION_KEY, (void *)obuf, sizeof(br_version_t)); } static int br_stub_prepare_signing_request(dict_t *dict, br_signature_t *sbuf, br_isignature_t *sign, size_t signaturelen) { size_t size = 0; br_set_signature(sbuf, sign, signaturelen, &size); return dict_set_bin(dict, BITROT_SIGNING_VERSION_KEY, (void *)sbuf, size); } /** * initialize an inode context starting with a given ongoing version. * a fresh lookup() or a first creat() call initializes the inode * context, hence the inode is marked dirty. this routine also * initializes the transient inode version. */ static int br_stub_init_inode_versions(xlator_t *this, fd_t *fd, inode_t *inode, unsigned long version, gf_boolean_t markdirty, gf_boolean_t bad_object, uint64_t *ctx_addr) { int32_t ret = 0; br_stub_inode_ctx_t *ctx = NULL; ctx = GF_CALLOC(1, sizeof(br_stub_inode_ctx_t), gf_br_stub_mt_inode_ctx_t); if (!ctx) goto error_return; INIT_LIST_HEAD(&ctx->fd_list); (markdirty) ? __br_stub_mark_inode_dirty(ctx) : __br_stub_mark_inode_synced(ctx); __br_stub_set_ongoing_version(ctx, version); if (bad_object) __br_stub_mark_object_bad(ctx); if (fd) { ret = br_stub_add_fd_to_inode(this, fd, ctx); if (ret) goto free_ctx; } ret = br_stub_set_inode_ctx(this, inode, ctx); if (ret) goto free_ctx; if (ctx_addr) *ctx_addr = (uint64_t)(uintptr_t)ctx; return 0; free_ctx: GF_FREE(ctx); error_return: return -1; } /** * modify the ongoing version of an inode. */ static int br_stub_mod_inode_versions(xlator_t *this, fd_t *fd, inode_t *inode, unsigned long version) { int32_t ret = -1; br_stub_inode_ctx_t *ctx = 0; LOCK(&inode->lock); { ctx = __br_stub_get_ongoing_version_ctx(this, inode, NULL); if (ctx == NULL) goto unblock; if (__br_stub_is_inode_dirty(ctx)) { __br_stub_set_ongoing_version(ctx, version); __br_stub_mark_inode_synced(ctx); } ret = 0; } unblock: UNLOCK(&inode->lock); return ret; } static void br_stub_fill_local(br_stub_local_t *local, call_stub_t *stub, fd_t *fd, inode_t *inode, uuid_t gfid, int versioningtype, unsigned long memversion) { local->fopstub = stub; local->versioningtype = versioningtype; local->u.context.version = memversion; if (fd) local->u.context.fd = fd_ref(fd); if (inode) local->u.context.inode = inode_ref(inode); gf_uuid_copy(local->u.context.gfid, gfid); } static void br_stub_cleanup_local(br_stub_local_t *local) { if (!local) return; local->fopstub = NULL; local->versioningtype = 0; local->u.context.version = 0; if (local->u.context.fd) { fd_unref(local->u.context.fd); local->u.context.fd = NULL; } if (local->u.context.inode) { inode_unref(local->u.context.inode); local->u.context.inode = NULL; } memset(local->u.context.gfid, '\0', sizeof(uuid_t)); } static int br_stub_need_versioning(xlator_t *this, fd_t *fd, gf_boolean_t *versioning, gf_boolean_t *modified, br_stub_inode_ctx_t **ctx) { int32_t ret = -1; uint64_t ctx_addr = 0; br_stub_inode_ctx_t *c = NULL; unsigned long version = BITROT_DEFAULT_CURRENT_VERSION; *versioning = _gf_false; *modified = _gf_false; /* Bitrot stub inode context was initialized only in lookup, create * and mknod cbk path. Object versioning was enabled by default * irrespective of bitrot enabled or not. But it's made optional now. * As a consequence there could be cases where getting inode ctx would * fail because it's not set yet. * e.g., If versioning (with bitrot enable) is enabled while I/O is * happening, it could directly get other fops like writev without * lookup, where getting inode ctx would fail. Hence initialize the * inode ctx on failure to get ctx. This is done in all places where * applicable. */ ret = br_stub_get_inode_ctx(this, fd->inode, &ctx_addr); if (ret < 0) { ret = br_stub_init_inode_versions(this, fd, fd->inode, version, _gf_true, _gf_false, &ctx_addr); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto error_return; } } c = (br_stub_inode_ctx_t *)(long)ctx_addr; LOCK(&fd->inode->lock); { if (__br_stub_is_inode_dirty(c)) *versioning = _gf_true; if (__br_stub_is_inode_modified(c)) *modified = _gf_true; } UNLOCK(&fd->inode->lock); if (ctx) *ctx = c; return 0; error_return: return -1; } static int32_t br_stub_anon_fd_ctx(xlator_t *this, fd_t *fd, br_stub_inode_ctx_t *ctx) { int32_t ret = -1; br_stub_fd_t *br_stub_fd = NULL; br_stub_fd = br_stub_fd_ctx_get(this, fd); if (!br_stub_fd) { ret = br_stub_add_fd_to_inode(this, fd, ctx); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_ADD_FD_TO_INODE, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } } ret = 0; out: return ret; } static int br_stub_versioning_prep(call_frame_t *frame, xlator_t *this, fd_t *fd, br_stub_inode_ctx_t *ctx) { int32_t ret = -1; br_stub_local_t *local = NULL; local = br_stub_alloc_local(this); if (!local) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, BRS_MSG_NO_MEMORY, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto error_return; } if (fd_is_anonymous(fd)) { ret = br_stub_anon_fd_ctx(this, fd, ctx); if (ret) goto free_local; } frame->local = local; return 0; free_local: br_stub_dealloc_local(local); error_return: return -1; } static int br_stub_mark_inode_modified(xlator_t *this, br_stub_local_t *local) { fd_t *fd = NULL; int32_t ret = 0; uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; unsigned long version = BITROT_DEFAULT_CURRENT_VERSION; fd = local->u.context.fd; ret = br_stub_get_inode_ctx(this, fd->inode, &ctx_addr); if (ret < 0) { ret = br_stub_init_inode_versions(this, fd, fd->inode, version, _gf_true, _gf_false, &ctx_addr); if (ret) goto error_return; } ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; LOCK(&fd->inode->lock); { __br_stub_set_inode_modified(ctx); } UNLOCK(&fd->inode->lock); return 0; error_return: return -1; } /** * The possible return values from br_stub_is_bad_object () are: * 1) 0 => as per the inode context object is not bad * 2) -1 => Failed to get the inode context itself * 3) -2 => As per the inode context object is bad * Both -ve values means the fop which called this function is failed * and error is returned upwards. */ static int br_stub_check_bad_object(xlator_t *this, inode_t *inode, int32_t *op_ret, int32_t *op_errno) { int ret = -1; unsigned long version = BITROT_DEFAULT_CURRENT_VERSION; ret = br_stub_is_bad_object(this, inode); if (ret == -2) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJECT_ACCESS, "gfid=%s", uuid_utoa(inode->gfid), NULL); *op_ret = -1; *op_errno = EIO; } if (ret == -1) { ret = br_stub_init_inode_versions(this, NULL, inode, version, _gf_true, _gf_false, NULL); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(inode->gfid), NULL); *op_ret = -1; *op_errno = EINVAL; } } return ret; } /** * callback for inode/fd versioning */ int br_stub_fd_incversioning_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { fd_t *fd = NULL; inode_t *inode = NULL; unsigned long version = 0; br_stub_local_t *local = NULL; local = (br_stub_local_t *)frame->local; if (op_ret < 0) goto done; fd = local->u.context.fd; inode = local->u.context.inode; version = local->u.context.version; op_ret = br_stub_mod_inode_versions(this, fd, inode, version); if (op_ret < 0) op_errno = EINVAL; done: if (op_ret < 0) { frame->local = NULL; call_unwind_error(local->fopstub, -1, op_errno); br_stub_cleanup_local(local); br_stub_dealloc_local(local); } else { call_resume(local->fopstub); } return 0; } /** * Initial object versioning * * Version persists two (2) extended attributes as explained below: * 1. Current (ongoing) version: This is incremented on an writev () * or truncate () and is the running version for an object. * 2. Signing version: This is the version against which an object * was signed (checksummed). * * During initial versioning, both ongoing and signing versions are * set of one and zero respectively. A write() call increments the * ongoing version as an indication of modification to the object. * Additionally this needs to be persisted on disk and needs to be * durable: fsync().. :-/ * As an optimization only the first write() synchronizes the ongoing * version to disk, subsequent write()s before the *last* release() * are no-op's. * * create(), just like lookup() initializes the object versions to * the default. As an optimization this is not a durable operation: * in case of a crash, hard reboot etc.. absence of versioning xattrs * is ignored in scrubber along with the one time crawler explicitly * triggering signing for such objects. * * c.f. br_stub_writev() / br_stub_truncate() */ /** * perform full or incremental versioning on an inode pointd by an * fd. incremental versioning is done when an inode is dirty and a * writeback is triggered. */ int br_stub_fd_versioning(xlator_t *this, call_frame_t *frame, call_stub_t *stub, dict_t *dict, fd_t *fd, br_stub_version_cbk *callback, unsigned long memversion, int versioningtype, int durable) { int32_t ret = -1; int flags = 0; dict_t *xdata = NULL; br_stub_local_t *local = NULL; xdata = dict_new(); if (!xdata) goto done; ret = dict_set_int32(xdata, GLUSTERFS_INTERNAL_FOP_KEY, 1); if (ret) goto dealloc_xdata; if (durable) { ret = dict_set_int32(xdata, GLUSTERFS_DURABLE_OP, 0); if (ret) goto dealloc_xdata; } local = frame->local; br_stub_fill_local(local, stub, fd, fd->inode, fd->inode->gfid, versioningtype, memversion); STACK_WIND(frame, callback, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); ret = 0; dealloc_xdata: dict_unref(xdata); done: return ret; } static int br_stub_perform_incversioning(xlator_t *this, call_frame_t *frame, call_stub_t *stub, fd_t *fd, br_stub_inode_ctx_t *ctx) { int32_t ret = -1; dict_t *dict = NULL; br_version_t *obuf = NULL; unsigned long writeback_version = 0; int op_errno = 0; br_stub_local_t *local = NULL; op_errno = EINVAL; local = frame->local; writeback_version = __br_stub_writeback_version(ctx); op_errno = ENOMEM; dict = dict_new(); if (!dict) goto out; ret = br_stub_alloc_versions(&obuf, NULL, 0); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_ALLOC_MEM_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } ret = br_stub_prepare_version_request(this, dict, obuf, writeback_version); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_VERSION_PREPARE_FAIL, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); br_stub_dealloc_versions(obuf); goto out; } ret = br_stub_fd_versioning( this, frame, stub, dict, fd, br_stub_fd_incversioning_cbk, writeback_version, BR_STUB_INCREMENTAL_VERSIONING, !WRITEBACK_DURABLE); out: if (dict) dict_unref(dict); if (ret) { if (local) frame->local = NULL; call_unwind_error(stub, -1, op_errno); if (local) { br_stub_cleanup_local(local); br_stub_dealloc_local(local); } } return ret; } /** {{{ */ /* fsetxattr() */ int32_t br_stub_perform_objsign(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int flags, dict_t *xdata) { STACK_WIND(frame, default_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); dict_unref(xdata); return 0; } void * br_stub_signth(void *arg) { xlator_t *this = arg; br_stub_private_t *priv = this->private; struct br_stub_signentry *sigstub = NULL; THIS = this; while (1) { /* * Disabling bit-rot feature leads to this particular thread * getting cleaned up by reconfigure via a call to the function * gf_thread_cleanup_xint (which in turn calls pthread_cancel * and pthread_join). But, if this thread had held the mutex * &priv->lock at the time of cancellation, then it leads to * deadlock in future when bit-rot feature is enabled (which * again spawns this thread which cant hold the lock as the * mutex is still held by the previous instance of the thread * which got killed). Also, the br_stub_handle_object_signature * function which is called whenever file has to be signed * also gets blocked as it too attempts to acquire &priv->lock. * * So, arrange for the lock to be unlocked as part of the * cleanup of this thread using pthread_cleanup_push and * pthread_cleanup_pop. */ pthread_cleanup_push(br_stub_lock_cleaner, &priv->lock); pthread_mutex_lock(&priv->lock); { while (list_empty(&priv->squeue)) pthread_cond_wait(&priv->cond, &priv->lock); sigstub = list_first_entry(&priv->squeue, struct br_stub_signentry, list); list_del_init(&sigstub->list); } pthread_mutex_unlock(&priv->lock); pthread_cleanup_pop(0); call_resume(sigstub->stub); GF_FREE(sigstub); } return NULL; } static gf_boolean_t br_stub_internal_xattr(dict_t *dict) { if (dict_get(dict, GLUSTERFS_SET_OBJECT_SIGNATURE) || dict_get(dict, GLUSTERFS_GET_OBJECT_SIGNATURE) || dict_get(dict, BR_REOPEN_SIGN_HINT_KEY) || dict_get(dict, BITROT_OBJECT_BAD_KEY) || dict_get(dict, BITROT_SIGNING_VERSION_KEY) || dict_get(dict, BITROT_CURRENT_VERSION_KEY)) return _gf_true; return _gf_false; } int orderq(struct list_head *elem1, struct list_head *elem2) { struct br_stub_signentry *s1 = NULL; struct br_stub_signentry *s2 = NULL; s1 = list_entry(elem1, struct br_stub_signentry, list); s2 = list_entry(elem2, struct br_stub_signentry, list); return (s1->v > s2->v); } static int br_stub_compare_sign_version(xlator_t *this, inode_t *inode, br_signature_t *sbuf, dict_t *dict, int *fakesuccess) { int32_t ret = -1; uint64_t tmp_ctx = 0; gf_boolean_t invalid = _gf_false; br_stub_inode_ctx_t *ctx = NULL; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); GF_VALIDATE_OR_GOTO(this->name, sbuf, out); GF_VALIDATE_OR_GOTO(this->name, dict, out); ret = br_stub_get_inode_ctx(this, inode, &tmp_ctx); if (ret) { dict_del(dict, BITROT_SIGNING_VERSION_KEY); goto out; } ctx = (br_stub_inode_ctx_t *)(long)tmp_ctx; LOCK(&inode->lock); { if (ctx->currentversion < sbuf->signedversion) { invalid = _gf_true; } else if (ctx->currentversion > sbuf->signedversion) { gf_msg_debug(this->name, 0, "\"Signing version\" " "(%lu) lower than \"Current version \" " "(%lu)", ctx->currentversion, sbuf->signedversion); *fakesuccess = 1; } } UNLOCK(&inode->lock); if (invalid) { ret = -1; gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_SIGN_VERSION_ERROR, "Signing-ver=%lu", sbuf->signedversion, "current-ver=%lu", ctx->currentversion, NULL); } out: return ret; } static int br_stub_prepare_signature(xlator_t *this, dict_t *dict, inode_t *inode, br_isignature_t *sign, int *fakesuccess) { int32_t ret = -1; size_t signaturelen = 0; br_signature_t *sbuf = NULL; if (!br_is_signature_type_valid(sign->signaturetype)) goto out; signaturelen = sign->signaturelen; ret = br_stub_alloc_versions(NULL, &sbuf, signaturelen); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_ALLOC_MEM_FAILED, "gfid=%s", uuid_utoa(inode->gfid), NULL); ret = -1; goto out; } ret = br_stub_prepare_signing_request(dict, sbuf, sign, signaturelen); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_SIGN_PREPARE_FAIL, "gfid=%s", uuid_utoa(inode->gfid), NULL); ret = -1; br_stub_dealloc_versions(sbuf); goto out; } /* At this point sbuf has been added to dict, so the memory will be freed * when the data from the dict is destroyed */ ret = br_stub_compare_sign_version(this, inode, sbuf, dict, fakesuccess); out: return ret; } static void br_stub_handle_object_signature(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, br_isignature_t *sign, dict_t *xdata) { int32_t ret = -1; int32_t op_ret = -1; int32_t op_errno = EINVAL; int fakesuccess = 0; br_stub_private_t *priv = NULL; struct br_stub_signentry *sigstub = NULL; priv = this->private; if (frame->root->pid != GF_CLIENT_PID_BITD) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, BRS_MSG_NON_BITD_PID, "PID=%d", frame->root->pid, NULL); goto dofop; } ret = br_stub_prepare_signature(this, dict, fd->inode, sign, &fakesuccess); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_SIGN_PREPARE_FAIL, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto dofop; } if (fakesuccess) { op_ret = op_errno = 0; goto dofop; } dict_del(dict, GLUSTERFS_SET_OBJECT_SIGNATURE); ret = -1; if (!xdata) { xdata = dict_new(); if (!xdata) goto dofop; } else { dict_ref(xdata); } ret = dict_set_int32(xdata, GLUSTERFS_DURABLE_OP, 0); if (ret) goto unref_dict; /* prepare dispatch stub to order object signing */ sigstub = GF_CALLOC(1, sizeof(*sigstub), gf_br_stub_mt_sigstub_t); if (!sigstub) goto unref_dict; INIT_LIST_HEAD(&sigstub->list); sigstub->v = ntohl(sign->signedversion); sigstub->stub = fop_fsetxattr_stub(frame, br_stub_perform_objsign, fd, dict, 0, xdata); if (!sigstub->stub) goto cleanup_stub; pthread_mutex_lock(&priv->lock); { list_add_order(&sigstub->list, &priv->squeue, orderq); pthread_cond_signal(&priv->cond); } pthread_mutex_unlock(&priv->lock); return; cleanup_stub: GF_FREE(sigstub); unref_dict: dict_unref(xdata); dofop: STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, NULL); } int32_t br_stub_fsetxattr_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { int32_t ret = -1; br_stub_local_t *local = NULL; local = frame->local; frame->local = NULL; ret = br_stub_mark_inode_modified(this, local); if (ret) { op_ret = -1; op_errno = EINVAL; } STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); br_stub_cleanup_local(local); br_stub_dealloc_local(local); return 0; } /** * Handles object reopens. Object reopens can be of 3 types. 2 are from * oneshot crawler and 1 from the regular signer. * ONESHOT CRAWLER: * For those objects which were created before bitrot was enabled. oneshow * crawler crawls the namespace and signs all the objects. It has to do * the versioning before making bit-rot-stub send a sign notification. * So it sends fsetxattr with BR_OBJECT_REOPEN as the value. And bit-rot-stub * upon getting BR_OBJECT_REOPEN value checks if the version has to be * increased or not. By default the version will be increased. But if the * object is modified before BR_OBJECT_REOPEN from oneshot crawler, then * versioning need not be done. In that case simply a success is returned. * SIGNER: * Signer wait for 2 minutes upon getting the notification from bit-rot-stub * and then it sends a dummy write (in reality a fsetxattr) call, to change * the state of the inode from REOPEN_WAIT to SIGN_QUICK. The funny part here * is though the inode's state is REOPEN_WAIT, the call sent by signer is * BR_OBJECT_RESIGN. Once the state is changed to SIGN_QUICK, then yet another * notification is sent upon release (RESIGN would have happened via fsetxattr, * so a fd is needed) and the object is signed truly this time. * There is a challenge in the above RESIGN method by signer. After sending * the 1st notification, the inode could be forgotten before RESIGN request * is received. In that case, the inode's context (the newly looked up inode) * would not indicate the inode as being modified (it would be in the default * state) and because of this, a SIGN_QUICK notification to truly sign the * object would not be sent. So, this is how its handled. * if (request == RESIGN) { * if (inode->sign_info == NORMAL) { * mark_inode_non_dirty; * mark_inode_modified; * } * GOBACK (means unwind without doing versioning) * } */ static void br_stub_handle_object_reopen(call_frame_t *frame, xlator_t *this, fd_t *fd, uint32_t val) { int32_t ret = -1; int32_t op_ret = -1; int32_t op_errno = EINVAL; call_stub_t *stub = NULL; gf_boolean_t inc_version = _gf_false; gf_boolean_t modified = _gf_false; br_stub_inode_ctx_t *ctx = NULL; br_stub_local_t *local = NULL; gf_boolean_t goback = _gf_true; ret = br_stub_need_versioning(this, fd, &inc_version, &modified, &ctx); if (ret) goto unwind; LOCK(&fd->inode->lock); { if ((val == BR_OBJECT_REOPEN) && inc_version) goback = _gf_false; if (val == BR_OBJECT_RESIGN && ctx->info_sign == BR_SIGN_NORMAL) { __br_stub_mark_inode_synced(ctx); __br_stub_set_inode_modified(ctx); } (void)__br_stub_inode_sign_state(ctx, GF_FOP_FSETXATTR, fd); } UNLOCK(&fd->inode->lock); if (goback) { op_ret = op_errno = 0; goto unwind; } ret = br_stub_versioning_prep(frame, this, fd, ctx); if (ret) goto unwind; local = frame->local; stub = fop_fsetxattr_cbk_stub(frame, br_stub_fsetxattr_resume, 0, 0, NULL); if (!stub) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_STUB_ALLOC_FAILED, "fsetxattr gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto cleanup_local; } (void)br_stub_perform_incversioning(this, frame, stub, fd, ctx); return; cleanup_local: br_stub_cleanup_local(local); br_stub_dealloc_local(local); unwind: frame->local = NULL; STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, NULL); } /** * This function only handles bad file identification. Instead of checking in * fops like open, readv, writev whether the object is bad or not by doing * getxattr calls, better to catch them when scrubber marks it as bad. * So this callback is called only when the fsetxattr is sent by the scrubber * to mark the object as bad. */ int br_stub_fsetxattr_bad_object_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { br_stub_local_t *local = NULL; int32_t ret = -1; local = frame->local; frame->local = NULL; if (op_ret < 0) goto unwind; /* * What to do if marking the object as bad fails? (i.e. in memory * marking within the inode context. If we are here means fsetxattr * fop has succeeded on disk and the bad object xattr has been set). * We can return failure to scruber, but there is nothing the scrubber * can do with it (it might assume that the on disk setxattr itself has * failed). The main purpose of this operation is to help identify the * bad object by checking the inode context itself (thus avoiding the * necessity of doing a getxattr fop on the disk). * * So as of now, success itself is being returned even though inode * context set operation fails. * In future if there is any change in the policy which can handle this, * then appropriate response should be sent (i.e. success or error). */ ret = br_stub_mark_object_bad(this, local->u.context.inode); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJ_MARK_FAIL, "gfid=%s", uuid_utoa(local->u.context.inode->gfid), NULL); ret = br_stub_add(this, local->u.context.inode->gfid); unwind: STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); br_stub_cleanup_local(local); br_stub_dealloc_local(local); return 0; } static int32_t br_stub_handle_bad_object_key(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int flags, dict_t *xdata) { br_stub_local_t *local = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; if (frame->root->pid != GF_CLIENT_PID_SCRUB) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_NON_SCRUB_BAD_OBJ_MARK, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto unwind; } local = br_stub_alloc_local(this); if (!local) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_ALLOC_MEM_FAILED, "fsetxattr gfid=%s", uuid_utoa(fd->inode->gfid), NULL); op_ret = -1; op_errno = ENOMEM; goto unwind; } br_stub_fill_local(local, NULL, fd, fd->inode, fd->inode->gfid, BR_STUB_NO_VERSIONING, 0); frame->local = local; STACK_WIND(frame, br_stub_fsetxattr_bad_object_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; unwind: STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, NULL); return 0; } /** * As of now, versioning is done by the stub (though as a setxattr * operation) as part of inode modification operations such as writev, * truncate, ftruncate. And signing is done by BitD by a fsetxattr call. * So any kind of setxattr coming on the versioning and the signing xattr is * not allowed (i.e. BITROT_CURRENT_VERSION_KEY and BITROT_SIGNING_VERSION_KEY). * In future if BitD/scrubber are allowed to change the versioning * xattrs (though I cannot see a reason for it as of now), then the below * function can be modified to block setxattr on version for only applications. * * NOTE: BitD sends sign request on GLUSTERFS_SET_OBJECT_SIGNATURE key. * BITROT_SIGNING_VERSION_KEY is the xattr used to save the signature. * */ static int32_t br_stub_handle_internal_xattr(call_frame_t *frame, xlator_t *this, fd_t *fd, char *key) { int32_t op_ret = -1; int32_t op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_SET_INTERNAL_XATTR, "setxattr key=%s", key, "inode-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, NULL); return 0; } static void br_stub_dump_xattr(xlator_t *this, dict_t *dict, int *op_errno) { char *format = "(%s:%s)"; char *dump = NULL; dump = GF_CALLOC(1, BR_STUB_DUMP_STR_SIZE, gf_br_stub_mt_misc); if (!dump) { *op_errno = ENOMEM; goto out; } dict_dump_to_str(dict, dump, BR_STUB_DUMP_STR_SIZE, format); gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_SET_INTERNAL_XATTR, "fsetxattr dump=%s", dump, NULL); out: if (dump) { GF_FREE(dump); } return; } int br_stub_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int flags, dict_t *xdata) { int32_t ret = 0; uint32_t val = 0; br_isignature_t *sign = NULL; br_stub_private_t *priv = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; priv = this->private; if ((frame->root->pid != GF_CLIENT_PID_BITD && frame->root->pid != GF_CLIENT_PID_SCRUB) && br_stub_internal_xattr(dict)) { br_stub_dump_xattr(this, dict, &op_errno); goto unwind; } if (!priv->do_versioning) goto wind; if (!IA_ISREG(fd->inode->ia_type)) goto wind; /* object signature request */ ret = dict_get_bin(dict, GLUSTERFS_SET_OBJECT_SIGNATURE, (void **)&sign); if (!ret) { gf_msg_debug(this->name, 0, "got SIGNATURE request on %s", uuid_utoa(fd->inode->gfid)); br_stub_handle_object_signature(frame, this, fd, dict, sign, xdata); goto done; } /* signing xattr */ if (dict_get(dict, BITROT_SIGNING_VERSION_KEY)) { br_stub_handle_internal_xattr(frame, this, fd, BITROT_SIGNING_VERSION_KEY); goto done; } /* version xattr */ if (dict_get(dict, BITROT_CURRENT_VERSION_KEY)) { br_stub_handle_internal_xattr(frame, this, fd, BITROT_CURRENT_VERSION_KEY); goto done; } if (dict_get(dict, GLUSTERFS_GET_OBJECT_SIGNATURE)) { br_stub_handle_internal_xattr(frame, this, fd, GLUSTERFS_GET_OBJECT_SIGNATURE); goto done; } /* object reopen request */ ret = dict_get_uint32(dict, BR_REOPEN_SIGN_HINT_KEY, &val); if (!ret) { br_stub_handle_object_reopen(frame, this, fd, val); goto done; } /* handle bad object */ if (dict_get(dict, BITROT_OBJECT_BAD_KEY)) { br_stub_handle_bad_object_key(frame, this, fd, dict, flags, xdata); goto done; } wind: STACK_WIND(frame, default_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; unwind: STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, NULL); done: return 0; } /** * Currently BitD and scrubber are doing fsetxattr to either sign the object * or to mark it as bad. Hence setxattr on any of those keys is denied directly * without checking from where the fop is coming. * Later, if BitD or Scrubber does setxattr of those keys, then appropriate * check has to be added below. */ int br_stub_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int flags, dict_t *xdata) { int32_t op_ret = -1; int32_t op_errno = EINVAL; if (br_stub_internal_xattr(dict)) { br_stub_dump_xattr(this, dict, &op_errno); goto unwind; } STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; unwind: STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, NULL); return 0; } /** }}} */ /** {{{ */ /* {f}removexattr() */ int32_t br_stub_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int32_t op_ret = -1; int32_t op_errno = EINVAL; if (!strcmp(BITROT_OBJECT_BAD_KEY, name) || !strcmp(BITROT_SIGNING_VERSION_KEY, name) || !strcmp(BITROT_CURRENT_VERSION_KEY, name)) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_REMOVE_INTERNAL_XATTR, "name=%s", name, "file-path=%s", loc->path, NULL); goto unwind; } STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; unwind: STACK_UNWIND_STRICT(removexattr, frame, op_ret, op_errno, NULL); return 0; } int32_t br_stub_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int32_t op_ret = -1; int32_t op_errno = EINVAL; if (!strcmp(BITROT_OBJECT_BAD_KEY, name) || !strcmp(BITROT_SIGNING_VERSION_KEY, name) || !strcmp(BITROT_CURRENT_VERSION_KEY, name)) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_REMOVE_INTERNAL_XATTR, "name=%s", name, "inode-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto unwind; } STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; unwind: STACK_UNWIND_STRICT(fremovexattr, frame, op_ret, op_errno, NULL); return 0; } /** }}} */ /** {{{ */ /* {f}getxattr() */ int br_stub_listxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { if (op_ret < 0) goto unwind; br_stub_remove_vxattrs(xattr, _gf_true); unwind: STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, xattr, xdata); return 0; } /** * ONE SHOT CRAWLER from BitD signs the objects that it encounters while * crawling, if the object is identified as stale by the stub. Stub follows * the below logic to mark an object as stale or not. * If the ongoing version and the signed_version match, then the object is not * stale. Just return. Otherwise if they does not match, then it means one * of the below things. * 1) If the inode does not need write back of the version and the sign state is * is NORMAL, then some active i/o is going on the object. So skip it. * A notification will be sent to trigger the sign once the release is * received on the object. * 2) If inode does not need writeback of the version and the sign state is * either reopen wait or quick sign, then it means: * A) BitD restarted and it is not sure whether the object it encountered * while crawling is in its timer wheel or not. Since there is no way to * scan the timer wheel as of now, ONE SHOT CRAWLER just goes ahead and * signs the object. Since the inode does not need writeback, version will * not be incremented and directly the object will be signed. * 3) If the inode needs writeback, then it means the inode was forgotten after * the versioning and it has to be signed now. * * This is the algorithm followed: * if (ongoing_version == signed_version); then * object_is_not_stale; * return; * else; then * if (!inode_needs_writeback && inode_sign_state != NORMAL); then * object_is_stale; * if (inode_needs_writeback); then * object_is_stale; * * For SCRUBBER, no need to check for the sign state and inode writeback. * If the ondisk ongoingversion and the ondisk signed version does not match, * then treat the object as stale. */ char br_stub_is_object_stale(xlator_t *this, call_frame_t *frame, inode_t *inode, br_version_t *obuf, br_signature_t *sbuf) { uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; int32_t ret = -1; char stale = 0; if (obuf->ongoingversion == sbuf->signedversion) goto out; if (frame->root->pid == GF_CLIENT_PID_SCRUB) { stale = 1; goto out; } ret = br_stub_get_inode_ctx(this, inode, &ctx_addr); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(inode->gfid), NULL); goto out; } ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; LOCK(&inode->lock); { if ((!__br_stub_is_inode_dirty(ctx) && ctx->info_sign != BR_SIGN_NORMAL) || __br_stub_is_inode_dirty(ctx)) stale = 1; } UNLOCK(&inode->lock); out: return stale; } int br_stub_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { int32_t ret = 0; size_t totallen = 0; uint32_t signaturelen = 0; br_stub_private_t *priv = NULL; br_version_t *obuf = NULL; br_signature_t *sbuf = NULL; br_isignature_out_t *sign = NULL; br_vxattr_status_t status; br_stub_local_t *local = NULL; inode_t *inode = NULL; gf_boolean_t bad_object = _gf_false; gf_boolean_t ver_enabled = _gf_false; BR_STUB_VER_ENABLED_IN_CALLPATH(frame, ver_enabled); priv = this->private; if (op_ret < 0) goto unwind; BR_STUB_VER_COND_GOTO(priv, (!ver_enabled), delkeys); if (cookie != (void *)BR_STUB_REQUEST_COOKIE) goto unwind; local = frame->local; frame->local = NULL; if (!local) { op_ret = -1; op_errno = EINVAL; goto unwind; } inode = local->u.context.inode; op_ret = -1; status = br_version_xattr_state(xattr, &obuf, &sbuf, &bad_object); op_errno = EIO; if (bad_object) goto delkeys; op_errno = EINVAL; if (status == BR_VXATTR_STATUS_INVALID) goto delkeys; op_errno = ENODATA; if ((status == BR_VXATTR_STATUS_MISSING) || (status == BR_VXATTR_STATUS_UNSIGNED)) goto delkeys; /** * okay.. we have enough information to satisfy the request, * namely: version and signing extended attribute. what's * pending is the signature length -- that's figured out * indirectly via the size of the _whole_ xattr and the * on-disk signing xattr header size. */ op_errno = EINVAL; ret = dict_get_uint32(xattr, BITROT_SIGNING_XATTR_SIZE_KEY, (uint32_t *)&signaturelen); if (ret) goto delkeys; signaturelen -= sizeof(br_signature_t); totallen = sizeof(br_isignature_out_t) + signaturelen; op_errno = ENOMEM; sign = GF_CALLOC(1, totallen, gf_br_stub_mt_signature_t); if (!sign) goto delkeys; sign->time[0] = obuf->timebuf[0]; sign->time[1] = obuf->timebuf[1]; /* Object's dirty state & current signed version */ sign->version = sbuf->signedversion; sign->stale = br_stub_is_object_stale(this, frame, inode, obuf, sbuf); /* Object's signature */ sign->signaturelen = signaturelen; sign->signaturetype = sbuf->signaturetype; (void)memcpy(sign->signature, sbuf->signature, signaturelen); op_errno = EINVAL; ret = dict_set_bin(xattr, GLUSTERFS_GET_OBJECT_SIGNATURE, (void *)sign, totallen); if (ret < 0) { GF_FREE(sign); goto delkeys; } op_errno = 0; op_ret = totallen; delkeys: br_stub_remove_vxattrs(xattr, _gf_true); unwind: STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, xattr, xdata); br_stub_cleanup_local(local); br_stub_dealloc_local(local); return 0; } static void br_stub_send_stub_init_time(call_frame_t *frame, xlator_t *this) { int op_ret = 0; int op_errno = 0; dict_t *xattr = NULL; br_stub_init_t stub = { { 0, }, }; br_stub_private_t *priv = NULL; priv = this->private; xattr = dict_new(); if (!xattr) { op_ret = -1; op_errno = ENOMEM; goto unwind; } stub.timebuf[0] = priv->boot[0]; stub.timebuf[1] = priv->boot[1]; memcpy(stub.export, priv->export, strlen(priv->export) + 1); op_ret = dict_set_static_bin(xattr, GLUSTERFS_GET_BR_STUB_INIT_TIME, (void *)&stub, sizeof(br_stub_init_t)); if (op_ret < 0) { op_errno = EINVAL; goto unwind; } op_ret = sizeof(br_stub_init_t); unwind: STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, xattr, NULL); if (xattr) dict_unref(xattr); } int br_stub_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { void *cookie = NULL; static uuid_t rootgfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; fop_getxattr_cbk_t cbk = br_stub_getxattr_cbk; int32_t op_ret = -1; int32_t op_errno = EINVAL; br_stub_local_t *local = NULL; br_stub_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, unwind); GF_VALIDATE_OR_GOTO(this->name, loc, unwind); GF_VALIDATE_OR_GOTO(this->name, this->private, unwind); GF_VALIDATE_OR_GOTO(this->name, loc->inode, unwind); if (!name) { cbk = br_stub_listxattr_cbk; goto wind; } if (br_stub_is_internal_xattr(name)) goto unwind; priv = this->private; BR_STUB_VER_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); /** * If xattr is node-uuid and the inode is marked bad, return EIO. * Returning EIO would result in AFR to choose correct node-uuid * corresponding to the subvolume * where the good copy of the * file resides. */ if (IA_ISREG(loc->inode->ia_type) && XATTR_IS_NODE_UUID(name) && br_stub_check_bad_object(this, loc->inode, &op_ret, &op_errno)) { goto unwind; } /** * this special extended attribute is allowed only on root */ if (name && (strncmp(name, GLUSTERFS_GET_BR_STUB_INIT_TIME, sizeof(GLUSTERFS_GET_BR_STUB_INIT_TIME) - 1) == 0) && ((gf_uuid_compare(loc->gfid, rootgfid) == 0) || (gf_uuid_compare(loc->inode->gfid, rootgfid) == 0))) { BR_STUB_RESET_LOCAL_NULL(frame); br_stub_send_stub_init_time(frame, this); return 0; } if (!IA_ISREG(loc->inode->ia_type)) goto wind; if (name && (strncmp(name, GLUSTERFS_GET_OBJECT_SIGNATURE, sizeof(GLUSTERFS_GET_OBJECT_SIGNATURE) - 1) == 0)) { cookie = (void *)BR_STUB_REQUEST_COOKIE; local = br_stub_alloc_local(this); if (!local) { op_ret = -1; op_errno = ENOMEM; goto unwind; } br_stub_fill_local(local, NULL, NULL, loc->inode, loc->inode->gfid, BR_STUB_NO_VERSIONING, 0); frame->local = local; } wind: STACK_WIND_COOKIE(frame, cbk, cookie, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); return 0; unwind: BR_STUB_RESET_LOCAL_NULL(frame); STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, NULL, NULL); return 0; } int br_stub_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { void *cookie = NULL; static uuid_t rootgfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; fop_fgetxattr_cbk_t cbk = br_stub_getxattr_cbk; int32_t op_ret = -1; int32_t op_errno = EINVAL; br_stub_local_t *local = NULL; br_stub_private_t *priv = NULL; priv = this->private; if (!name) { cbk = br_stub_listxattr_cbk; goto wind; } if (br_stub_is_internal_xattr(name)) goto unwind; BR_STUB_VER_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); /** * If xattr is node-uuid and the inode is marked bad, return EIO. * Returning EIO would result in AFR to choose correct node-uuid * corresponding to the subvolume * where the good copy of the * file resides. */ if (IA_ISREG(fd->inode->ia_type) && XATTR_IS_NODE_UUID(name) && br_stub_check_bad_object(this, fd->inode, &op_ret, &op_errno)) { goto unwind; } /** * this special extended attribute is allowed only on root */ if (name && (strncmp(name, GLUSTERFS_GET_BR_STUB_INIT_TIME, sizeof(GLUSTERFS_GET_BR_STUB_INIT_TIME) - 1) == 0) && (gf_uuid_compare(fd->inode->gfid, rootgfid) == 0)) { BR_STUB_RESET_LOCAL_NULL(frame); br_stub_send_stub_init_time(frame, this); return 0; } if (!IA_ISREG(fd->inode->ia_type)) goto wind; if (name && (strncmp(name, GLUSTERFS_GET_OBJECT_SIGNATURE, sizeof(GLUSTERFS_GET_OBJECT_SIGNATURE) - 1) == 0)) { cookie = (void *)BR_STUB_REQUEST_COOKIE; local = br_stub_alloc_local(this); if (!local) { op_ret = -1; op_errno = ENOMEM; goto unwind; } br_stub_fill_local(local, NULL, fd, fd->inode, fd->inode->gfid, BR_STUB_NO_VERSIONING, 0); frame->local = local; } wind: STACK_WIND_COOKIE(frame, cbk, cookie, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); return 0; unwind: BR_STUB_RESET_LOCAL_NULL(frame); STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, NULL, NULL); return 0; } int32_t br_stub_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { int32_t op_ret = -1; int32_t op_errno = EINVAL; int32_t ret = -1; br_stub_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, unwind); GF_VALIDATE_OR_GOTO(this->name, frame, unwind); GF_VALIDATE_OR_GOTO(this->name, this->private, unwind); GF_VALIDATE_OR_GOTO(this->name, fd, unwind); GF_VALIDATE_OR_GOTO(this->name, fd->inode, unwind); priv = this->private; if (!priv->do_versioning) goto wind; ret = br_stub_check_bad_object(this, fd->inode, &op_ret, &op_errno); if (ret) goto unwind; wind: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; unwind: STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, NULL, 0, NULL, NULL, NULL); return 0; } /** * The first write response on the first fd in the list of fds will set * the flag to indicate that the inode is modified. The subsequent write * respnses coming on either the first fd or some other fd will not change * the fd. The inode-modified flag is unset only upon release of all the * fds. */ int32_t br_stub_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { int32_t ret = 0; br_stub_local_t *local = NULL; local = frame->local; frame->local = NULL; if (op_ret < 0) goto unwind; ret = br_stub_mark_inode_modified(this, local); if (ret) { op_ret = -1; op_errno = EINVAL; } unwind: STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); br_stub_cleanup_local(local); br_stub_dealloc_local(local); return 0; } int32_t br_stub_writev_resume(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { STACK_WIND(frame, br_stub_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; } /** * This is probably the most crucial part about the whole versioning thing. * There's absolutely no differentiation as such between an anonymous fd * and a regular fd except the fd context initialization. Object versioning * is performed when the inode is dirty. Parallel write operations are no * special with each write performing object versioning followed by marking * the inode as non-dirty (synced). This is followed by the actual operation * (writev() in this case) which on a success marks the inode as modified. * This prevents signing of objects that have not been modified. */ int32_t br_stub_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { call_stub_t *stub = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; gf_boolean_t inc_version = _gf_false; gf_boolean_t modified = _gf_false; br_stub_inode_ctx_t *ctx = NULL; int32_t ret = -1; fop_writev_cbk_t cbk = default_writev_cbk; br_stub_local_t *local = NULL; br_stub_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, unwind); GF_VALIDATE_OR_GOTO(this->name, this->private, unwind); GF_VALIDATE_OR_GOTO(this->name, frame, unwind); GF_VALIDATE_OR_GOTO(this->name, fd, unwind); priv = this->private; if (!priv->do_versioning) goto wind; ret = br_stub_need_versioning(this, fd, &inc_version, &modified, &ctx); if (ret) goto unwind; ret = br_stub_check_bad_object(this, fd->inode, &op_ret, &op_errno); if (ret) goto unwind; /** * The inode is not dirty and also witnessed at least one successful * modification operation. Therefore, subsequent operations need not * perform any special tracking. */ if (!inc_version && modified) goto wind; /** * okay.. so, either the inode needs versioning or the modification * needs to be tracked. ->cbk is set to the appropriate callback * routine for this. * NOTE: ->local needs to be deallocated on failures from here on. */ ret = br_stub_versioning_prep(frame, this, fd, ctx); if (ret) goto unwind; local = frame->local; if (!inc_version) { br_stub_fill_local(local, NULL, fd, fd->inode, fd->inode->gfid, BR_STUB_NO_VERSIONING, 0); cbk = br_stub_writev_cbk; goto wind; } stub = fop_writev_stub(frame, br_stub_writev_resume, fd, vector, count, offset, flags, iobref, xdata); if (!stub) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_STUB_ALLOC_FAILED, "write gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto cleanup_local; } /* Perform Versioning */ return br_stub_perform_incversioning(this, frame, stub, fd, ctx); wind: STACK_WIND(frame, cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; cleanup_local: br_stub_cleanup_local(local); br_stub_dealloc_local(local); unwind: frame->local = NULL; STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } int32_t br_stub_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { int32_t ret = -1; br_stub_local_t *local = NULL; local = frame->local; frame->local = NULL; if (op_ret < 0) goto unwind; ret = br_stub_mark_inode_modified(this, local); if (ret) { op_ret = -1; op_errno = EINVAL; } unwind: STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); br_stub_cleanup_local(local); br_stub_dealloc_local(local); return 0; } int32_t br_stub_ftruncate_resume(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { STACK_WIND(frame, br_stub_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } /* c.f. br_stub_writev() for explanation */ int32_t br_stub_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { br_stub_local_t *local = NULL; call_stub_t *stub = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; gf_boolean_t inc_version = _gf_false; gf_boolean_t modified = _gf_false; br_stub_inode_ctx_t *ctx = NULL; int32_t ret = -1; fop_ftruncate_cbk_t cbk = default_ftruncate_cbk; br_stub_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, unwind); GF_VALIDATE_OR_GOTO(this->name, this->private, unwind); GF_VALIDATE_OR_GOTO(this->name, frame, unwind); GF_VALIDATE_OR_GOTO(this->name, fd, unwind); priv = this->private; if (!priv->do_versioning) goto wind; ret = br_stub_need_versioning(this, fd, &inc_version, &modified, &ctx); if (ret) goto unwind; ret = br_stub_check_bad_object(this, fd->inode, &op_ret, &op_errno); if (ret) goto unwind; if (!inc_version && modified) goto wind; ret = br_stub_versioning_prep(frame, this, fd, ctx); if (ret) goto unwind; local = frame->local; if (!inc_version) { br_stub_fill_local(local, NULL, fd, fd->inode, fd->inode->gfid, BR_STUB_NO_VERSIONING, 0); cbk = br_stub_ftruncate_cbk; goto wind; } stub = fop_ftruncate_stub(frame, br_stub_ftruncate_resume, fd, offset, xdata); if (!stub) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_STUB_ALLOC_FAILED, "ftruncate gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto cleanup_local; } return br_stub_perform_incversioning(this, frame, stub, fd, ctx); wind: STACK_WIND(frame, cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; cleanup_local: br_stub_cleanup_local(local); br_stub_dealloc_local(local); unwind: frame->local = NULL; STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } int32_t br_stub_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { int32_t ret = 0; br_stub_local_t *local = NULL; local = frame->local; frame->local = NULL; if (op_ret < 0) goto unwind; ret = br_stub_mark_inode_modified(this, local); if (ret) { op_ret = -1; op_errno = EINVAL; } unwind: STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); br_stub_cleanup_local(local); br_stub_dealloc_local(local); return 0; } int32_t br_stub_truncate_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { br_stub_local_t *local = frame->local; fd_unref(local->u.context.fd); STACK_WIND(frame, br_stub_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } /** * Bit-rot-stub depends heavily on the fd based operations to for doing * versioning and sending notification. It starts tracking the operation * upon getting first fd based modify operation by doing versioning and * sends notification when last fd using which the inode was modified is * released. * But for truncate there is no fd and hence it becomes difficult to do * the versioning and send notification. It is handled by doing versioning * on an anonymous fd. The fd will be valid till the completion of the * truncate call. It guarantees that release on this anonymous fd will happen * after the truncate call and notification is sent after the truncate call. * * c.f. br_writev_cbk() for explanation */ int32_t br_stub_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { br_stub_local_t *local = NULL; call_stub_t *stub = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; gf_boolean_t inc_version = _gf_false; gf_boolean_t modified = _gf_false; br_stub_inode_ctx_t *ctx = NULL; int32_t ret = -1; fd_t *fd = NULL; fop_truncate_cbk_t cbk = default_truncate_cbk; br_stub_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, unwind); GF_VALIDATE_OR_GOTO(this->name, this->private, unwind); GF_VALIDATE_OR_GOTO(this->name, frame, unwind); GF_VALIDATE_OR_GOTO(this->name, loc, unwind); GF_VALIDATE_OR_GOTO(this->name, loc->inode, unwind); priv = this->private; if (!priv->do_versioning) goto wind; fd = fd_anonymous(loc->inode); if (!fd) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_CREATE_ANONYMOUS_FD_FAILED, "inode-gfid=%s", uuid_utoa(loc->inode->gfid), NULL); goto unwind; } ret = br_stub_need_versioning(this, fd, &inc_version, &modified, &ctx); if (ret) goto cleanup_fd; ret = br_stub_check_bad_object(this, fd->inode, &op_ret, &op_errno); if (ret) goto unwind; if (!inc_version && modified) goto wind; ret = br_stub_versioning_prep(frame, this, fd, ctx); if (ret) goto cleanup_fd; local = frame->local; if (!inc_version) { br_stub_fill_local(local, NULL, fd, fd->inode, fd->inode->gfid, BR_STUB_NO_VERSIONING, 0); cbk = br_stub_truncate_cbk; goto wind; } stub = fop_truncate_stub(frame, br_stub_truncate_resume, loc, offset, xdata); if (!stub) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_STUB_ALLOC_FAILED, "truncate gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto cleanup_local; } return br_stub_perform_incversioning(this, frame, stub, fd, ctx); wind: STACK_WIND(frame, cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); if (fd) fd_unref(fd); return 0; cleanup_local: br_stub_cleanup_local(local); br_stub_dealloc_local(local); cleanup_fd: fd_unref(fd); unwind: frame->local = NULL; STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } /** }}} */ /** {{{ */ /* open() */ /** * It's probably worth mentioning a bit about why some of the housekeeping * work is done in open() call path, rather than the callback path. * Two (or more) open()'s in parallel can race and lead to a situation * where a release() gets triggered (possibly after a series of write() * calls) when *other* open()'s have still not reached callback path * thereby having an active fd on an inode that is in process of getting * signed with the current version. * * Maintaining fd list in the call path ensures that a release() would * not be triggered if an open() call races ahead (followed by a close()) * threby finding non-empty fd list. */ int br_stub_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { int32_t ret = -1; br_stub_inode_ctx_t *ctx = NULL; uint64_t ctx_addr = 0; int32_t op_ret = -1; int32_t op_errno = EINVAL; br_stub_private_t *priv = NULL; unsigned long version = BITROT_DEFAULT_CURRENT_VERSION; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, unwind); GF_VALIDATE_OR_GOTO(this->name, this->private, unwind); GF_VALIDATE_OR_GOTO(this->name, loc, unwind); GF_VALIDATE_OR_GOTO(this->name, fd, unwind); GF_VALIDATE_OR_GOTO(this->name, fd->inode, unwind); priv = this->private; if (!priv->do_versioning) goto wind; ret = br_stub_get_inode_ctx(this, fd->inode, &ctx_addr); if (ret) { ret = br_stub_init_inode_versions(this, fd, fd->inode, version, _gf_true, _gf_false, &ctx_addr); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_GET_INODE_CONTEXT_FAILED, "path=%s", loc->path, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto unwind; } } ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; ret = br_stub_check_bad_object(this, fd->inode, &op_ret, &op_errno); if (ret) goto unwind; if (frame->root->pid == GF_CLIENT_PID_SCRUB) goto wind; if (flags == O_RDONLY) goto wind; ret = br_stub_add_fd_to_inode(this, fd, ctx); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_ADD_FD_TO_LIST_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto unwind; } wind: STACK_WIND(frame, default_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; unwind: STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, NULL, NULL); return 0; } /** }}} */ /** {{{ */ /* creat() */ /** * This routine registers a release callback for the given fd and adds the * fd to the inode context fd tracking list. */ int32_t br_stub_add_fd_to_inode(xlator_t *this, fd_t *fd, br_stub_inode_ctx_t *ctx) { int32_t ret = -1; br_stub_fd_t *br_stub_fd = NULL; ret = br_stub_require_release_call(this, fd, &br_stub_fd); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_SET_FD_CONTEXT_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } LOCK(&fd->inode->lock); { list_add_tail(&ctx->fd_list, &br_stub_fd->list); } UNLOCK(&fd->inode->lock); ret = 0; out: return ret; } int br_stub_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int32_t ret = 0; uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; unsigned long version = BITROT_DEFAULT_CURRENT_VERSION; br_stub_private_t *priv = NULL; priv = this->private; if (op_ret < 0) goto unwind; if (!priv->do_versioning) goto unwind; ret = br_stub_get_inode_ctx(this, fd->inode, &ctx_addr); if (ret < 0) { ret = br_stub_init_inode_versions(this, fd, inode, version, _gf_true, _gf_false, &ctx_addr); if (ret) { op_ret = -1; op_errno = EINVAL; } } else { ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; ret = br_stub_add_fd_to_inode(this, fd, ctx); } unwind: STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, stbuf, preparent, postparent, xdata); return 0; } int br_stub_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { GF_VALIDATE_OR_GOTO("bit-rot-stub", this, unwind); GF_VALIDATE_OR_GOTO(this->name, loc, unwind); GF_VALIDATE_OR_GOTO(this->name, loc->inode, unwind); GF_VALIDATE_OR_GOTO(this->name, fd, unwind); GF_VALIDATE_OR_GOTO(this->name, fd->inode, unwind); STACK_WIND(frame, br_stub_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; unwind: STACK_UNWIND_STRICT(create, frame, -1, EINVAL, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int br_stub_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int32_t ret = -1; unsigned long version = BITROT_DEFAULT_CURRENT_VERSION; br_stub_private_t *priv = NULL; priv = this->private; if (op_ret < 0) goto unwind; if (!priv->do_versioning) goto unwind; ret = br_stub_init_inode_versions(this, NULL, inode, version, _gf_true, _gf_false, NULL); /** * Like lookup, if init_inode_versions fail, return EINVAL */ if (ret) { op_ret = -1; op_errno = EINVAL; } unwind: STACK_UNWIND_STRICT(mknod, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); return 0; } int br_stub_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata) { GF_VALIDATE_OR_GOTO("bit-rot-stub", this, unwind); GF_VALIDATE_OR_GOTO(this->name, loc, unwind); GF_VALIDATE_OR_GOTO(this->name, loc->inode, unwind); STACK_WIND(frame, br_stub_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, dev, umask, xdata); return 0; unwind: STACK_UNWIND_STRICT(mknod, frame, -1, EINVAL, NULL, NULL, NULL, NULL, NULL); return 0; } /** }}} */ /** * As of now, only lookup searches for bad object xattr and marks the * object as bad in its inode context if the xattr is present. But there * is a possibility that, at the time of the lookup the object was not * marked bad (i.e. bad object xattr was not set), and later its marked * as bad. In this case, object is not bad, so when a fop such as open or * readv or writev comes on the object, the fop will be sent downward instead * of sending as error upwards. * The solution for this is to do a getxattr for the below list of fops. * lookup, readdirp, open, readv, writev. * But doing getxattr for each of the above fops might be costly. * So another method followed is to catch the bad file marking by the scrubber * and set that info within the object's inode context. In this way getxattr * calls can be avoided and bad objects can be caught instantly. Fetching the * xattr is needed only in lookups when there is a brick restart or inode * forget. * * If the dict (@xattr) is NULL, then how should that be handled? Fail the * lookup operation? Or let it continue with version being initialized to * BITROT_DEFAULT_CURRENT_VERSION. But what if the version was different * on disk (and also a right signature was there), but posix failed to * successfully allocate the dict? Posix does not treat call back xdata * creattion failure as the lookup failure. */ static int32_t br_stub_lookup_version(xlator_t *this, uuid_t gfid, inode_t *inode, dict_t *xattr) { unsigned long version = 0; br_version_t *obuf = NULL; br_signature_t *sbuf = NULL; br_vxattr_status_t status; gf_boolean_t bad_object = _gf_false; /** * versioning xattrs were requested from POSIX. if available, figure * out the correct version to use in the inode context (start with * the default version if unavailable). As of now versions are not * persisted on-disk. The inode is marked dirty, so that the first * operation (such as write(), etc..) triggers synchronization to * disk. */ status = br_version_xattr_state(xattr, &obuf, &sbuf, &bad_object); version = ((status == BR_VXATTR_STATUS_FULL) || (status == BR_VXATTR_STATUS_UNSIGNED)) ? obuf->ongoingversion : BITROT_DEFAULT_CURRENT_VERSION; /** * If signature is there, but version is not there then that status is * is treated as INVALID. So in that case, we should not initialize the * inode context with wrong version names etc. */ if (status == BR_VXATTR_STATUS_INVALID) return -1; return br_stub_init_inode_versions(this, NULL, inode, version, _gf_true, bad_object, NULL); } /** {{{ */ int32_t br_stub_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { br_stub_private_t *priv = NULL; br_stub_fd_t *fd_ctx = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; priv = this->private; if (gf_uuid_compare(fd->inode->gfid, priv->bad_object_dir_gfid)) goto normal; fd_ctx = br_stub_fd_new(); if (!fd_ctx) { op_errno = ENOMEM; goto unwind; } fd_ctx->bad_object.dir_eof = -1; fd_ctx->bad_object.dir = sys_opendir(priv->stub_basepath); if (!fd_ctx->bad_object.dir) { op_errno = errno; goto err_freectx; } op_ret = br_stub_fd_ctx_set(this, fd, fd_ctx); if (!op_ret) goto unwind; sys_closedir(fd_ctx->bad_object.dir); err_freectx: GF_FREE(fd_ctx); unwind: STACK_UNWIND_STRICT(opendir, frame, op_ret, op_errno, fd, NULL); return 0; normal: STACK_WIND(frame, default_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); return 0; } int32_t br_stub_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { call_stub_t *stub = NULL; br_stub_private_t *priv = NULL; priv = this->private; if (!priv->do_versioning) goto out; if (gf_uuid_compare(fd->inode->gfid, priv->bad_object_dir_gfid)) goto out; stub = fop_readdir_stub(frame, br_stub_readdir_wrapper, fd, size, off, xdata); if (!stub) { STACK_UNWIND_STRICT(readdir, frame, -1, ENOMEM, NULL, NULL); return 0; } br_stub_worker_enqueue(this, stub); return 0; out: STACK_WIND(frame, default_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, fd, size, off, xdata); return 0; } int br_stub_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *dict) { int32_t ret = 0; uint64_t ctxaddr = 0; gf_dirent_t *entry = NULL; br_stub_private_t *priv = NULL; gf_boolean_t ver_enabled = _gf_false; BR_STUB_VER_ENABLED_IN_CALLPATH(frame, ver_enabled); priv = this->private; BR_STUB_VER_COND_GOTO(priv, (!ver_enabled), unwind); if (op_ret < 0) goto unwind; list_for_each_entry(entry, &entries->list, list) { /* skip . and .. */ if (inode_dir_or_parentdir(entry)) continue; if (!IA_ISREG(entry->d_stat.ia_type)) continue; /* * Readdirp for most part is a bulk lookup for all the entries * present in the directory being read. Ideally, for each * entry, the handling should be similar to that of a lookup * callback. But for now, just keeping this as it has been * until now (which means, this comment has been added much * later as part of a change that wanted to send the flag * of true/false to br_stub_remove_vxattrs to indicate whether * the bad-object xattr should be removed from the entry->dict * or not). Until this change, the function br_stub_remove_vxattrs * was just removing all the xattrs associated with bit-rot-stub * (like version, bad-object, signature etc). But, there are * scenarios where we only want to send bad-object xattr and not * others. So this comment is part of that change which also * mentions about another possible change that might be needed * in future. * But for now, adding _gf_true means functionally its same as * what this function was doing before. Just remove all the stub * related xattrs. */ ret = br_stub_get_inode_ctx(this, entry->inode, &ctxaddr); if (ret < 0) ctxaddr = 0; if (ctxaddr) { /* already has the context */ br_stub_remove_vxattrs(entry->dict, _gf_true); continue; } ret = br_stub_lookup_version(this, entry->inode->gfid, entry->inode, entry->dict); br_stub_remove_vxattrs(entry->dict, _gf_true); if (ret) { /** * there's no per-file granularity support in case of * failure. let's fail the entire request for now.. */ break; } } if (ret) { op_ret = -1; op_errno = EINVAL; } unwind: STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, dict); return 0; } int br_stub_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *dict) { int32_t ret = -1; int op_errno = 0; gf_boolean_t xref = _gf_false; br_stub_private_t *priv = NULL; priv = this->private; BR_STUB_VER_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); op_errno = ENOMEM; if (!dict) { dict = dict_new(); if (!dict) goto unwind; } else { dict = dict_ref(dict); } xref = _gf_true; op_errno = EINVAL; ret = dict_set_uint32(dict, BITROT_CURRENT_VERSION_KEY, 0); if (ret) goto unwind; ret = dict_set_uint32(dict, BITROT_SIGNING_VERSION_KEY, 0); if (ret) goto unwind; ret = dict_set_uint32(dict, BITROT_OBJECT_BAD_KEY, 0); if (ret) goto unwind; wind: STACK_WIND(frame, br_stub_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); goto unref_dict; unwind: if (frame->local == (void *)0x1) frame->local = NULL; STACK_UNWIND_STRICT(readdirp, frame, -1, op_errno, NULL, NULL); return 0; unref_dict: if (xref) dict_unref(dict); return 0; } /** }}} */ /** {{{ */ /* lookup() */ /** * This function mainly handles the ENOENT error for the bad objects. Though * br_stub_forget () handles removal of the link for the bad object from the * quarantine directory, its better to handle it in lookup as well, where * a failed lookup on a bad object with ENOENT, will trigger deletion of the * link for the bad object from quarantine directory. So whoever comes first * either forget () or lookup () will take care of removing the link. */ void br_stub_handle_lookup_error(xlator_t *this, inode_t *inode, int32_t op_errno) { int32_t ret = -1; uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; if (op_errno != ENOENT) goto out; if (!inode_is_linked(inode)) goto out; ret = br_stub_get_inode_ctx(this, inode, &ctx_addr); if (ret) goto out; ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; LOCK(&inode->lock); { if (__br_stub_is_bad_object(ctx)) (void)br_stub_del(this, inode->gfid); } UNLOCK(&inode->lock); if (__br_stub_is_bad_object(ctx)) { /* File is not present, might be deleted for recovery, * del the bitrot inode context */ ctx_addr = 0; inode_ctx_del(inode, this, &ctx_addr); if (ctx_addr) { ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; GF_FREE(ctx); } } out: return; } int br_stub_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, struct iatt *postparent) { int32_t ret = 0; br_stub_private_t *priv = NULL; gf_boolean_t ver_enabled = _gf_false; gf_boolean_t remove_bad_file_marker = _gf_true; BR_STUB_VER_ENABLED_IN_CALLPATH(frame, ver_enabled); priv = this->private; if (op_ret < 0) { (void)br_stub_handle_lookup_error(this, inode, op_errno); /* * If the lookup error is not ENOENT, then it is better * to send the bad file marker to the higher layer (if * it has been set) */ if (op_errno != ENOENT) remove_bad_file_marker = _gf_false; goto delkey; } BR_STUB_VER_COND_GOTO(priv, (!ver_enabled), delkey); if (!IA_ISREG(stbuf->ia_type)) goto unwind; /** * If the object is bad, then "bad inode" marker has to be sent back * in resoinse, for revalidated lookups as well. Some xlators such as * quick-read might cache the data in revalidated lookup as fresh * lookup would anyway have sent "bad inode" marker. * In general send bad inode marker for every lookup operation on the * bad object. */ if (cookie != (void *)BR_STUB_REQUEST_COOKIE) { ret = br_stub_mark_xdata_bad_object(this, inode, xattr); if (ret) { op_ret = -1; op_errno = EIO; /* * This flag ensures that in the label @delkey below, * bad file marker is not removed from the dictinary, * but other virtual xattrs (such as version, signature) * are removed. */ remove_bad_file_marker = _gf_false; } goto delkey; } ret = br_stub_lookup_version(this, stbuf->ia_gfid, inode, xattr); if (ret < 0) { op_ret = -1; op_errno = EINVAL; goto delkey; } /** * If the object is bad, send "bad inode" marker back in response * for xlator(s) to act accordingly (such as quick-read, etc..) */ ret = br_stub_mark_xdata_bad_object(this, inode, xattr); if (ret) { /** * aaha! bad object, but sorry we would not * satisfy the request on allocation failures. */ op_ret = -1; op_errno = EIO; goto delkey; } delkey: br_stub_remove_vxattrs(xattr, remove_bad_file_marker); unwind: STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, stbuf, xattr, postparent); return 0; } int br_stub_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int32_t ret = 0; int op_errno = 0; void *cookie = NULL; uint64_t ctx_addr = 0; gf_boolean_t xref = _gf_false; br_stub_private_t *priv = NULL; call_stub_t *stub = NULL; GF_VALIDATE_OR_GOTO("bit-rot-stub", this, unwind); GF_VALIDATE_OR_GOTO(this->name, loc, unwind); GF_VALIDATE_OR_GOTO(this->name, loc->inode, unwind); priv = this->private; BR_STUB_VER_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); if (!gf_uuid_compare(loc->gfid, priv->bad_object_dir_gfid) || !gf_uuid_compare(loc->pargfid, priv->bad_object_dir_gfid)) { stub = fop_lookup_stub(frame, br_stub_lookup_wrapper, loc, xdata); if (!stub) { op_errno = ENOMEM; goto unwind; } br_stub_worker_enqueue(this, stub); return 0; } ret = br_stub_get_inode_ctx(this, loc->inode, &ctx_addr); if (ret < 0) ctx_addr = 0; if (ctx_addr != 0) goto wind; /** * fresh lookup: request version keys from POSIX */ op_errno = ENOMEM; if (!xdata) { xdata = dict_new(); if (!xdata) goto unwind; } else { xdata = dict_ref(xdata); } xref = _gf_true; /** * Requesting both xattrs provides a way of sanity checking the * object. Anomaly checking is done in cbk by examining absence * of either or both xattrs. */ op_errno = EINVAL; ret = dict_set_uint32(xdata, BITROT_CURRENT_VERSION_KEY, 0); if (ret) goto unwind; ret = dict_set_uint32(xdata, BITROT_SIGNING_VERSION_KEY, 0); if (ret) goto unwind; ret = dict_set_uint32(xdata, BITROT_OBJECT_BAD_KEY, 0); if (ret) goto unwind; cookie = (void *)BR_STUB_REQUEST_COOKIE; wind: STACK_WIND_COOKIE(frame, br_stub_lookup_cbk, cookie, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); goto dealloc_dict; unwind: if (frame->local == (void *)0x1) frame->local = NULL; STACK_UNWIND_STRICT(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); dealloc_dict: if (xref) dict_unref(xdata); return 0; } /** }}} */ /** {{{ */ /* stat */ int br_stub_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int32_t ret = 0; int32_t op_ret = -1; int32_t op_errno = EINVAL; br_stub_private_t *priv = NULL; priv = this->private; if (!priv->do_versioning) goto wind; if (!IA_ISREG(loc->inode->ia_type)) goto wind; ret = br_stub_check_bad_object(this, loc->inode, &op_ret, &op_errno); if (ret) goto unwind; wind: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; unwind: STACK_UNWIND_STRICT(stat, frame, op_ret, op_errno, NULL, NULL); return 0; } /* fstat */ int br_stub_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int32_t ret = 0; int32_t op_ret = -1; int32_t op_errno = EINVAL; br_stub_private_t *priv = NULL; priv = this->private; if (!priv->do_versioning) goto wind; if (!IA_ISREG(fd->inode->ia_type)) goto wind; ret = br_stub_check_bad_object(this, fd->inode, &op_ret, &op_errno); if (ret) goto unwind; wind: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; unwind: STACK_UNWIND_STRICT(fstat, frame, op_ret, op_errno, NULL, NULL); return 0; } /** }}} */ /** {{{ */ /* unlink() */ int br_stub_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { br_stub_local_t *local = NULL; inode_t *inode = NULL; uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; int32_t ret = -1; br_stub_private_t *priv = NULL; gf_boolean_t ver_enabled = _gf_false; BR_STUB_VER_ENABLED_IN_CALLPATH(frame, ver_enabled); priv = this->private; BR_STUB_VER_COND_GOTO(priv, (!ver_enabled), unwind); local = frame->local; frame->local = NULL; if (op_ret < 0) goto unwind; if (!local) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_NULL_LOCAL, NULL); goto unwind; } inode = local->u.context.inode; if (!IA_ISREG(inode->ia_type)) goto unwind; ret = br_stub_get_inode_ctx(this, inode, &ctx_addr); if (ret) { /** * If the inode is bad AND context is not there, then there * is a possibility of the gfid of the object being listed * in the quarantine directory and will be shown in the * bad objects list. So continuing with the fop with a * warning log. The entry from the quarantine directory * has to be removed manually. Its not a good idea to fail * the fop, as the object has already been deleted. */ gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_GET_INODE_CONTEXT_FAILED, "inode-gfid=%s", uuid_utoa(inode->gfid), NULL); goto unwind; } ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; LOCK(&inode->lock); { /** * Ignoring the return value of br_stub_del (). * There is not much that can be done if unlinking * of the entry in the quarantine directory fails. * The failure is logged. */ if (__br_stub_is_bad_object(ctx)) (void)br_stub_del(this, inode->gfid); } UNLOCK(&inode->lock); unwind: STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); br_stub_cleanup_local(local); br_stub_dealloc_local(local); return 0; } int br_stub_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int flag, dict_t *xdata) { br_stub_local_t *local = NULL; int32_t op_ret = -1; int32_t op_errno = 0; br_stub_private_t *priv = NULL; priv = this->private; BR_STUB_VER_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); local = br_stub_alloc_local(this); if (!local) { op_ret = -1; op_errno = ENOMEM; gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, BRS_MSG_ALLOC_MEM_FAILED, "local path=%s", loc->path, "gfid=%s", uuid_utoa(loc->inode->gfid), NULL); goto unwind; } br_stub_fill_local(local, NULL, NULL, loc->inode, loc->inode->gfid, BR_STUB_NO_VERSIONING, 0); frame->local = local; wind: STACK_WIND(frame, br_stub_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, flag, xdata); return 0; unwind: if (frame->local == (void *)0x1) frame->local = NULL; STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } /** }}} */ /** {{{ */ /* forget() */ int br_stub_forget(xlator_t *this, inode_t *inode) { uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; inode_ctx_del(inode, this, &ctx_addr); if (!ctx_addr) return 0; ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; GF_FREE(ctx); return 0; } /** }}} */ /** {{{ */ int32_t br_stub_noop(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { STACK_DESTROY(frame->root); return 0; } static void br_stub_send_ipc_fop(xlator_t *this, fd_t *fd, unsigned long releaseversion, int sign_info) { int32_t op = 0; int32_t ret = 0; dict_t *xdata = NULL; call_frame_t *frame = NULL; changelog_event_t ev = { 0, }; ev.ev_type = CHANGELOG_OP_TYPE_BR_RELEASE; ev.u.releasebr.version = releaseversion; ev.u.releasebr.sign_info = sign_info; gf_uuid_copy(ev.u.releasebr.gfid, fd->inode->gfid); xdata = dict_new(); if (!xdata) { gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, BRS_MSG_DICT_ALLOC_FAILED, NULL); goto out; } ret = dict_set_static_bin(xdata, "RELEASE-EVENT", &ev, CHANGELOG_EV_SIZE); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_SET_EVENT_FAILED, NULL); goto dealloc_dict; } frame = create_frame(this, this->ctx->pool); if (!frame) { gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_CREATE_FRAME_FAILED, NULL); goto dealloc_dict; } op = GF_IPC_TARGET_CHANGELOG; STACK_WIND(frame, br_stub_noop, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc, op, xdata); dealloc_dict: dict_unref(xdata); out: return; } /** * This is how the state machine of sign info works: * 3 states: * 1) BR_SIGN_NORMAL => The default State of the inode * 2) BR_SIGN_REOPEN_WAIT => A release has been sent and is waiting for reopen * 3) BR_SIGN_QUICK => reopen has happened and this release should trigger sign * 2 events: * 1) GF_FOP_RELEASE * 2) GF_FOP_WRITE (actually a dummy write for BitD) * * This is how states are changed based on events: * EVENT: GF_FOP_RELEASE: * if (state == BR_SIGN_NORMAL) ; then * set state = BR_SIGN_REOPEN_WAIT; * if (state == BR_SIGN_QUICK); then * set state = BR_SIGN_NORMAL; * EVENT: GF_FOP_WRITE: * if (state == BR_SIGN_REOPEN_WAIT); then * set state = BR_SIGN_QUICK; */ br_sign_state_t __br_stub_inode_sign_state(br_stub_inode_ctx_t *ctx, glusterfs_fop_t fop, fd_t *fd) { br_sign_state_t sign_info = BR_SIGN_INVALID; switch (fop) { case GF_FOP_FSETXATTR: sign_info = ctx->info_sign = BR_SIGN_QUICK; break; case GF_FOP_RELEASE: GF_ASSERT(ctx->info_sign != BR_SIGN_REOPEN_WAIT); if (ctx->info_sign == BR_SIGN_NORMAL) { sign_info = ctx->info_sign = BR_SIGN_REOPEN_WAIT; } else { sign_info = ctx->info_sign; ctx->info_sign = BR_SIGN_NORMAL; } break; default: break; } return sign_info; } int32_t br_stub_release(xlator_t *this, fd_t *fd) { int32_t ret = 0; int32_t flags = 0; inode_t *inode = NULL; unsigned long releaseversion = 0; br_stub_inode_ctx_t *ctx = NULL; br_stub_fd_t *br_stub_fd = NULL; int32_t signinfo = 0; inode = fd->inode; LOCK(&inode->lock); { ctx = __br_stub_get_ongoing_version_ctx(this, inode, NULL); if (ctx == NULL) goto unblock; br_stub_fd = br_stub_fd_ctx_get(this, fd); if (br_stub_fd) { list_del_init(&br_stub_fd->list); } ret = __br_stub_can_trigger_release(inode, ctx, &releaseversion); if (!ret) goto unblock; signinfo = __br_stub_inode_sign_state(ctx, GF_FOP_RELEASE, fd); signinfo = htonl(signinfo); /* inode back to initital state: mark dirty */ if (ctx->info_sign == BR_SIGN_NORMAL) { __br_stub_mark_inode_dirty(ctx); __br_stub_unset_inode_modified(ctx); } } unblock: UNLOCK(&inode->lock); if (ret) { gf_msg_debug(this->name, 0, "releaseversion: %lu | flags: %d " "| signinfo: %d", (unsigned long)ntohl(releaseversion), flags, ntohl(signinfo)); br_stub_send_ipc_fop(this, fd, releaseversion, signinfo); } br_stub_fd = fd_ctx_del_ptr(fd, this); if (br_stub_fd) { GF_FREE(br_stub_fd); } return 0; } int32_t br_stub_releasedir(xlator_t *this, fd_t *fd) { br_stub_fd_t *fctx = NULL; int ret = 0; fctx = fd_ctx_del_ptr(fd, this); if (!fctx) goto out; if (fctx->bad_object.dir) { ret = sys_closedir(fctx->bad_object.dir); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJ_DIR_CLOSE_FAIL, "error=%s", strerror(errno), NULL); } GF_FREE(fctx); out: return 0; } /** }}} */ /** {{{ */ /* ictxmerge */ void br_stub_ictxmerge(xlator_t *this, fd_t *fd, inode_t *inode, inode_t *linked_inode) { int32_t ret = 0; uint64_t ctxaddr = 0; uint64_t lctxaddr = 0; br_stub_inode_ctx_t *ctx = NULL; br_stub_inode_ctx_t *lctx = NULL; br_stub_fd_t *br_stub_fd = NULL; ret = br_stub_get_inode_ctx(this, inode, &ctxaddr); if (ret < 0) goto done; ctx = (br_stub_inode_ctx_t *)(uintptr_t)ctxaddr; LOCK(&linked_inode->lock); { ret = __br_stub_get_inode_ctx(this, linked_inode, &lctxaddr); if (ret < 0) goto unblock; lctx = (br_stub_inode_ctx_t *)(uintptr_t)lctxaddr; GF_ASSERT(list_is_singular(&ctx->fd_list)); br_stub_fd = list_first_entry(&ctx->fd_list, br_stub_fd_t, list); if (br_stub_fd) { GF_ASSERT(br_stub_fd->fd == fd); list_move_tail(&br_stub_fd->list, &lctx->fd_list); } } unblock: UNLOCK(&linked_inode->lock); done: return; } /** }}} */ struct xlator_fops fops = { .lookup = br_stub_lookup, .stat = br_stub_stat, .fstat = br_stub_fstat, .open = br_stub_open, .create = br_stub_create, .readdirp = br_stub_readdirp, .getxattr = br_stub_getxattr, .fgetxattr = br_stub_fgetxattr, .fsetxattr = br_stub_fsetxattr, .writev = br_stub_writev, .truncate = br_stub_truncate, .ftruncate = br_stub_ftruncate, .mknod = br_stub_mknod, .readv = br_stub_readv, .removexattr = br_stub_removexattr, .fremovexattr = br_stub_fremovexattr, .setxattr = br_stub_setxattr, .opendir = br_stub_opendir, .readdir = br_stub_readdir, .unlink = br_stub_unlink, }; struct xlator_cbks cbks = { .forget = br_stub_forget, .release = br_stub_release, .ictxmerge = br_stub_ictxmerge, }; struct volume_options options[] = { {.key = {"bitrot"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_FORCE, .tags = {"bitrot"}, .description = "enable/disable bitrot stub"}, {.key = {"export"}, .type = GF_OPTION_TYPE_PATH, .op_version = {GD_OP_VERSION_3_7_0}, .tags = {"bitrot"}, .description = "brick path for versioning", .default_value = "{{ brick.path }}"}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "bitrot-stub", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/bit-rot/src/stub/PaxHeaders.9031/bit-rot-stub.h0000644000000000000000000000013214522202451025522 xustar000000000000000030 mtime=1699284265.655027396 30 atime=1699284265.655027396 30 ctime=1699284304.980145842 glusterfs-11.1/xlators/features/bit-rot/src/stub/bit-rot-stub.h0000664000175100017510000003373414522202451026013 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __BIT_ROT_STUB_H__ #define __BIT_ROT_STUB_H__ #include #include #include #include "bit-rot-stub-mem-types.h" #include #include "bit-rot-common.h" #include "bit-rot-stub-messages.h" #include "glusterfs4-xdr.h" #define BAD_OBJECT_THREAD_STACK_SIZE ((size_t)(1024 * 1024)) #define BR_STUB_DUMP_STR_SIZE 65536 #define BR_PATH_MAX_EXTRA (PATH_MAX + 1024) #define BR_PATH_MAX_PLUS (PATH_MAX + 2048) /* * Oops. Spelling mistake. Correcting it */ #define OLD_BR_STUB_QUARANTINE_DIR GF_HIDDEN_PATH "/quanrantine" #define BR_STUB_QUARANTINE_DIR GF_HIDDEN_PATH "/quarantine" /* do not reference frame->local in cbk unless initialized. * Assigned 0x1 marks verisoning flag between call path and * cbk path. */ #define BR_STUB_VER_NOT_ACTIVE_THEN_GOTO(frame, priv, label) \ do { \ if (priv->do_versioning) \ frame->local = (void *)0x1; \ else \ goto label; \ } while (0) #define BR_STUB_VER_COND_GOTO(priv, cond, label) \ do { \ if (!priv->do_versioning || cond) \ goto label; \ } while (0) #define BR_STUB_VER_ENABLED_IN_CALLPATH(frame, flag) \ do { \ if (frame->local) \ flag = _gf_true; \ if (frame->local == (void *)0x1) \ frame->local = NULL; \ } while (0) #define BR_STUB_RESET_LOCAL_NULL(frame) \ do { \ if (frame->local == (void *)0x1) \ frame->local = NULL; \ } while (0) typedef int(br_stub_version_cbk)(call_frame_t *, void *, xlator_t *, int32_t, int32_t, dict_t *); typedef struct br_stub_inode_ctx { int need_writeback; /* does the inode need a writeback to disk? */ unsigned long currentversion; /* ongoing version */ int info_sign; struct list_head fd_list; /* list of open fds or fds participating in write operations */ gf_boolean_t bad_object; } br_stub_inode_ctx_t; typedef struct br_stub_fd { fd_t *fd; struct list_head list; struct bad_object_dir { DIR *dir; off_t dir_eof; } bad_object; } br_stub_fd_t; #define I_DIRTY (1 << 0) /* inode needs writeback */ #define I_MODIFIED (1 << 1) #define WRITEBACK_DURABLE 1 /* writeback is durable */ /** * This could just have been a plain struct without unions and all, * but we may need additional things in the future. */ typedef struct br_stub_local { call_stub_t *fopstub; /* stub for original fop */ int versioningtype; /* not much used atm */ union { struct br_stub_ctx { fd_t *fd; uuid_t gfid; inode_t *inode; unsigned long version; } context; } u; } br_stub_local_t; #define BR_STUB_NO_VERSIONING (1 << 0) #define BR_STUB_INCREMENTAL_VERSIONING (1 << 1) typedef struct br_stub_private { gf_boolean_t do_versioning; unsigned long boot[2]; char export[PATH_MAX]; pthread_mutex_t lock; pthread_cond_t cond; struct list_head squeue; /* ordered signing queue */ pthread_t signth; struct bad_objects_container { pthread_t thread; pthread_mutex_t bad_lock; pthread_cond_t bad_cond; struct list_head bad_queue; } container; struct mem_pool *local_pool; char stub_basepath[BR_PATH_MAX_EXTRA]; uuid_t bad_object_dir_gfid; } br_stub_private_t; br_stub_fd_t * br_stub_fd_new(void); int __br_stub_fd_ctx_set(xlator_t *this, fd_t *fd, br_stub_fd_t *br_stub_fd); br_stub_fd_t * __br_stub_fd_ctx_get(xlator_t *this, fd_t *fd); br_stub_fd_t * br_stub_fd_ctx_get(xlator_t *this, fd_t *fd); int32_t br_stub_fd_ctx_set(xlator_t *this, fd_t *fd, br_stub_fd_t *br_stub_fd); static inline gf_boolean_t __br_stub_is_bad_object(br_stub_inode_ctx_t *ctx) { return ctx->bad_object; } static inline void __br_stub_mark_object_bad(br_stub_inode_ctx_t *ctx) { ctx->bad_object = _gf_true; } /* inode writeback helpers */ static inline void __br_stub_mark_inode_dirty(br_stub_inode_ctx_t *ctx) { ctx->need_writeback |= I_DIRTY; } static inline void __br_stub_mark_inode_synced(br_stub_inode_ctx_t *ctx) { ctx->need_writeback &= ~I_DIRTY; } static inline int __br_stub_is_inode_dirty(br_stub_inode_ctx_t *ctx) { return (ctx->need_writeback & I_DIRTY); } /* inode mofification markers */ static inline void __br_stub_set_inode_modified(br_stub_inode_ctx_t *ctx) { ctx->need_writeback |= I_MODIFIED; } static inline void __br_stub_unset_inode_modified(br_stub_inode_ctx_t *ctx) { ctx->need_writeback &= ~I_MODIFIED; } static inline int __br_stub_is_inode_modified(br_stub_inode_ctx_t *ctx) { return (ctx->need_writeback & I_MODIFIED); } static inline int br_stub_require_release_call(xlator_t *this, fd_t *fd, br_stub_fd_t **fd_ctx) { int32_t ret = 0; br_stub_fd_t *br_stub_fd = NULL; br_stub_fd = br_stub_fd_new(); if (!br_stub_fd) return -1; br_stub_fd->fd = fd; INIT_LIST_HEAD(&br_stub_fd->list); ret = br_stub_fd_ctx_set(this, fd, br_stub_fd); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, BRS_MSG_SET_CONTEXT_FAILED, NULL); else *fd_ctx = br_stub_fd; return ret; } /* get/set inode context helpers */ static inline int __br_stub_get_inode_ctx(xlator_t *this, inode_t *inode, uint64_t *ctx) { return __inode_ctx_get(inode, this, ctx); } static inline int br_stub_get_inode_ctx(xlator_t *this, inode_t *inode, uint64_t *ctx) { int ret = -1; LOCK(&inode->lock); { ret = __br_stub_get_inode_ctx(this, inode, ctx); } UNLOCK(&inode->lock); return ret; } static inline int br_stub_set_inode_ctx(xlator_t *this, inode_t *inode, br_stub_inode_ctx_t *ctx) { uint64_t ctx_addr = (uint64_t)(uintptr_t)ctx; return inode_ctx_set(inode, this, &ctx_addr); } /* version get/set helpers */ static inline unsigned long __br_stub_writeback_version(br_stub_inode_ctx_t *ctx) { return (ctx->currentversion + 1); } static inline void __br_stub_set_ongoing_version(br_stub_inode_ctx_t *ctx, unsigned long version) { if (ctx->currentversion < version) ctx->currentversion = version; else gf_smsg("bit-rot-stub", GF_LOG_WARNING, 0, BRS_MSG_CHANGE_VERSION_FAILED, "current version=%lu", ctx->currentversion, "new version=%lu", version, NULL); } static inline int __br_stub_can_trigger_release(inode_t *inode, br_stub_inode_ctx_t *ctx, unsigned long *version) { /** * If the inode is modified, then it has to be dirty. An inode is * marked dirty once version is increased. Its marked as modified * when the modification call (write/truncate) which triggered * the versioning is successful. */ if (__br_stub_is_inode_modified(ctx) && list_empty(&ctx->fd_list) && (ctx->info_sign != BR_SIGN_REOPEN_WAIT)) { GF_ASSERT(__br_stub_is_inode_dirty(ctx) == 0); if (version) *version = htonl(ctx->currentversion); return 1; } return 0; } static inline int32_t br_stub_get_ongoing_version(xlator_t *this, inode_t *inode, unsigned long *version) { int32_t ret = 0; uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; LOCK(&inode->lock); { ret = __inode_ctx_get(inode, this, &ctx_addr); if (ret < 0) goto unblock; ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; *version = ctx->currentversion; } unblock: UNLOCK(&inode->lock); return ret; } /** * fetch the current version from inode and return the context. * inode->lock should be held before invoking this as context * *needs* to be valid in the caller. */ static inline br_stub_inode_ctx_t * __br_stub_get_ongoing_version_ctx(xlator_t *this, inode_t *inode, unsigned long *version) { int32_t ret = 0; uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; ret = __inode_ctx_get(inode, this, &ctx_addr); if (ret < 0) return NULL; ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; if (version) *version = ctx->currentversion; return ctx; } /* filter for xattr fetch */ static inline int br_stub_is_internal_xattr(const char *name) { if (name && ((strncmp(name, BITROT_CURRENT_VERSION_KEY, SLEN(BITROT_CURRENT_VERSION_KEY)) == 0) || (strncmp(name, BITROT_SIGNING_VERSION_KEY, SLEN(BITROT_SIGNING_VERSION_KEY)) == 0))) return 1; return 0; } static inline void br_stub_remove_vxattrs(dict_t *xattr, gf_boolean_t remove_bad_marker) { if (xattr) { /* * When a file is corrupted, bad-object should be * set in the dict. But, other info such as version, * signature etc should not be set. Hence the flag * remove_bad_marker. The consumer should know whether * to send the bad-object info in the dict or not. */ if (remove_bad_marker) dict_del(xattr, BITROT_OBJECT_BAD_KEY); dict_del(xattr, BITROT_CURRENT_VERSION_KEY); dict_del(xattr, BITROT_SIGNING_VERSION_KEY); dict_del(xattr, BITROT_SIGNING_XATTR_SIZE_KEY); } } /** * This function returns the below values for different situations * 0 => as per the inode context object is not bad * -1 => Failed to get the inode context itself * -2 => As per the inode context object is bad * Both -ve values means the fop which called this function is failed * and error is returned upwards. * In future if needed or more errors have to be handled, then those * errors can be made into enums. */ static inline int br_stub_is_bad_object(xlator_t *this, inode_t *inode) { int bad_object = 0; gf_boolean_t tmp = _gf_false; uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; int32_t ret = -1; ret = br_stub_get_inode_ctx(this, inode, &ctx_addr); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_GET_INODE_CONTEXT_FAILED, "inode-gfid=%s", uuid_utoa(inode->gfid), NULL); bad_object = -1; goto out; } ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; LOCK(&inode->lock); { tmp = __br_stub_is_bad_object(ctx); if (tmp) bad_object = -2; } UNLOCK(&inode->lock); out: return bad_object; } static inline int32_t br_stub_mark_object_bad(xlator_t *this, inode_t *inode) { int32_t ret = -1; uint64_t ctx_addr = 0; br_stub_inode_ctx_t *ctx = NULL; ret = br_stub_get_inode_ctx(this, inode, &ctx_addr); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, BRS_MSG_GET_INODE_CONTEXT_FAILED, "inode-gfid=%s", uuid_utoa(inode->gfid), NULL); goto out; } ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; LOCK(&inode->lock); { __br_stub_mark_object_bad(ctx); } UNLOCK(&inode->lock); out: return ret; } /** * There is a possibility that dict_set might fail. The o/p of dict_set is * given to the caller and the caller has to decide what to do. */ static inline int32_t br_stub_mark_xdata_bad_object(xlator_t *this, inode_t *inode, dict_t *xdata) { int32_t ret = 0; if (br_stub_is_bad_object(this, inode) == -2) ret = dict_set_int32(xdata, GLUSTERFS_BAD_INODE, 1); return ret; } int32_t br_stub_add_fd_to_inode(xlator_t *this, fd_t *fd, br_stub_inode_ctx_t *ctx); br_sign_state_t __br_stub_inode_sign_state(br_stub_inode_ctx_t *ctx, glusterfs_fop_t fop, fd_t *fd); int br_stub_dir_create(xlator_t *this, br_stub_private_t *priv); int br_stub_add(xlator_t *this, uuid_t gfid); int32_t br_stub_create_stub_gfid(xlator_t *this, char *stub_gfid_path, uuid_t gfid); int br_stub_dir_create(xlator_t *this, br_stub_private_t *priv); call_stub_t * __br_stub_dequeue(struct list_head *callstubs); void __br_stub_enqueue(struct list_head *callstubs, call_stub_t *stub); void br_stub_worker_enqueue(xlator_t *this, call_stub_t *stub); void * br_stub_worker(void *data); int32_t br_stub_lookup_wrapper(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req); int32_t br_stub_readdir_wrapper(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata); int br_stub_del(xlator_t *this, uuid_t gfid); int br_stub_bad_objects_path(xlator_t *this, fd_t *fd, gf_dirent_t *entries, dict_t **dict); void br_stub_entry_xattr_fill(xlator_t *this, char *hpath, gf_dirent_t *entry, dict_t *dict); int br_stub_get_path_of_gfid(xlator_t *this, inode_t *parent, inode_t *inode, uuid_t gfid, char **path); #endif /* __BIT_ROT_STUB_H__ */ glusterfs-11.1/xlators/features/bit-rot/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451024074 xustar000000000000000030 mtime=1699284265.651027384 30 atime=1699284275.329056534 29 ctime=1699284304.94314573 glusterfs-11.1/xlators/features/bit-rot/src/Makefile.am0000664000175100017510000000002414522202451024350 0ustar00jenkinsjenkins00000000000000SUBDIRS = stub bitd glusterfs-11.1/xlators/features/bit-rot/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463023322 xustar000000000000000030 mtime=1699284275.318056501 30 atime=1699284291.029103823 30 ctime=1699284304.909145628 glusterfs-11.1/xlators/features/bit-rot/Makefile.in0000664000175100017510000005263014522202463023607 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/bit-rot DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/bit-rot/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/bit-rot/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/bit-rot/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023306 xustar000000000000000030 mtime=1699284265.651027384 30 atime=1699284275.294056429 30 ctime=1699284304.910145631 glusterfs-11.1/xlators/features/bit-rot/Makefile.am0000664000175100017510000000001514522202451023561 0ustar00jenkinsjenkins00000000000000SUBDIRS = srcglusterfs-11.1/xlators/features/PaxHeaders.9031/gfid-access0000644000000000000000000000013214522202520021762 xustar000000000000000030 mtime=1699284304.499144393 30 atime=1699284309.687160019 30 ctime=1699284304.499144393 glusterfs-11.1/xlators/features/gfid-access/0002775000175100017510000000000014522202520022320 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/gfid-access/PaxHeaders.9031/src0000644000000000000000000000013214522202520022551 xustar000000000000000030 mtime=1699284304.549144544 30 atime=1699284309.687160019 30 ctime=1699284304.549144544 glusterfs-11.1/xlators/features/gfid-access/src/0002775000175100017510000000000014522202520023107 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/gfid-access/src/PaxHeaders.9031/gfid-access.h0000644000000000000000000000013214522202451025152 xustar000000000000000030 mtime=1699284265.668027435 30 atime=1699284265.668027435 30 ctime=1699284304.545144532 glusterfs-11.1/xlators/features/gfid-access/src/gfid-access.h0000664000175100017510000000773114522202451025441 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __GFID_ACCESS_H__ #define __GFID_ACCESS_H__ #include #include #include #include "gfid-access-mem-types.h" #define UUID_CANONICAL_FORM_LEN 36 #define GF_FUSE_AUX_GFID_NEWFILE "glusterfs.gfid.newfile" #define GF_FUSE_AUX_GFID_HEAL "glusterfs.gfid.heal" #define GF_GFID_KEY "GLUSTERFS_GFID" #define GF_GFID_DIR ".gfid" #define GF_AUX_GFID 0xd #define GFID_ACCESS_ENTRY_OP_CHECK(loc, err, lbl) \ do { \ /* need to check if the lookup is on virtual dir */ \ if ((loc->name && !strcmp(GF_GFID_DIR, loc->name)) && \ ((loc->parent && __is_root_gfid(loc->parent->gfid)) || \ __is_root_gfid(loc->pargfid))) { \ err = ENOTSUP; \ goto lbl; \ } \ \ /* now, check if the lookup() is on an existing */ \ /* entry, but on gfid-path */ \ if ((loc->parent && __is_gfid_access_dir(loc->parent->gfid)) || \ __is_gfid_access_dir(loc->pargfid)) { \ err = EPERM; \ goto lbl; \ } \ } while (0) #define GFID_ACCESS_INODE_OP_CHECK(loc, err, lbl) \ do { \ /*Check if it is on .gfid*/ \ if (__is_gfid_access_dir(loc->gfid)) { \ err = ENOTSUP; \ goto lbl; \ } \ } while (0) typedef struct { unsigned int uid; unsigned int gid; char gfid[UUID_CANONICAL_FORM_LEN + 1]; unsigned int st_mode; char *bname; union { struct _symlink_in { char *linkpath; } __attribute__((__packed__)) symlink; struct _mknod_in { unsigned int mode; unsigned int rdev; unsigned int umask; } __attribute__((__packed__)) mknod; struct _mkdir_in { unsigned int mode; unsigned int umask; } __attribute__((__packed__)) mkdir; } __attribute__((__packed__)) args; } __attribute__((__packed__)) ga_newfile_args_t; typedef struct { char gfid[UUID_CANONICAL_FORM_LEN + 1]; char *bname; /* a null terminated basename */ } __attribute__((__packed__)) ga_heal_args_t; struct ga_private { /* root inode's stbuf */ struct iatt root_stbuf; struct iatt gfiddir_stbuf; struct mem_pool *newfile_args_pool; struct mem_pool *heal_args_pool; }; typedef struct ga_private ga_private_t; struct __ga_local { call_frame_t *orig_frame; unsigned int uid; unsigned int gid; loc_t loc; mode_t mode; dev_t rdev; mode_t umask; dict_t *xdata; }; typedef struct __ga_local ga_local_t; #endif /* __GFID_ACCESS_H__ */ glusterfs-11.1/xlators/features/gfid-access/src/PaxHeaders.9031/gfid-access.c0000644000000000000000000000013214522202451025145 xustar000000000000000030 mtime=1699284265.668027435 30 atime=1699284265.668027435 30 ctime=1699284304.549144544 glusterfs-11.1/xlators/features/gfid-access/src/gfid-access.c0000664000175100017510000010675214522202451025437 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "gfid-access.h" #include #include int ga_valid_inode_loc_copy(loc_t *dst, loc_t *src, xlator_t *this) { int ret = 0; uint64_t value = 0; /* if its an entry operation, on the virtual */ /* directory inode as parent, we need to handle */ /* it properly */ ret = loc_copy(dst, src); if (ret < 0) goto out; /* * Change ALL virtual inodes with real-inodes in loc */ if (dst->parent) { ret = inode_ctx_get(dst->parent, this, &value); if (ret < 0) { ret = 0; // real-inode goto out; } inode_unref(dst->parent); dst->parent = inode_ref((inode_t *)(uintptr_t)value); gf_uuid_copy(dst->pargfid, dst->parent->gfid); } if (dst->inode) { ret = inode_ctx_get(dst->inode, this, &value); if (ret < 0) { ret = 0; // real-inode goto out; } inode_unref(dst->inode); dst->inode = inode_ref((inode_t *)(uintptr_t)value); gf_uuid_copy(dst->gfid, dst->inode->gfid); } out: return ret; } void ga_newfile_args_free(ga_newfile_args_t *args) { if (!args) goto out; GF_FREE(args->bname); if (S_ISLNK(args->st_mode) && args->args.symlink.linkpath) { GF_FREE(args->args.symlink.linkpath); args->args.symlink.linkpath = NULL; } mem_put(args); out: return; } void ga_heal_args_free(ga_heal_args_t *args) { if (!args) goto out; GF_FREE(args->bname); mem_put(args); out: return; } ga_newfile_args_t * ga_newfile_parse_args(xlator_t *this, data_t *data) { ga_newfile_args_t *args = NULL; ga_private_t *priv = NULL; int len = 0; int blob_len = 0; int min_len = 0; void *blob = NULL; priv = this->private; blob = data->data; blob_len = data->len; min_len = sizeof(args->uid) + sizeof(args->gid) + sizeof(args->gfid) + sizeof(args->st_mode) + 2 + 2; if (blob_len < min_len) { gf_log(this->name, GF_LOG_ERROR, "Invalid length: Total length is less " "than minimum length."); goto err; } args = mem_get0(priv->newfile_args_pool); if (args == NULL) goto err; args->uid = be32toh(*(uint32_t *)blob); blob += sizeof(uint32_t); blob_len -= sizeof(uint32_t); args->gid = be32toh(*(uint32_t *)blob); blob += sizeof(uint32_t); blob_len -= sizeof(uint32_t); memcpy(args->gfid, blob, sizeof(args->gfid)); blob += sizeof(args->gfid); blob_len -= sizeof(args->gfid); args->st_mode = be32toh(*(uint32_t *)blob); blob += sizeof(uint32_t); blob_len -= sizeof(uint32_t); len = strnlen(blob, blob_len); if (len == blob_len) { gf_log(this->name, GF_LOG_ERROR, "gfid: %s. No null byte present.", args->gfid); goto err; } args->bname = GF_MALLOC(len + 1, gf_common_mt_char); if (args->bname == NULL) goto err; memcpy(args->bname, blob, (len + 1)); blob += (len + 1); blob_len -= (len + 1); if (S_ISDIR(args->st_mode)) { if (blob_len < sizeof(uint32_t)) { gf_log(this->name, GF_LOG_ERROR, "gfid: %s. Invalid length", args->gfid); goto err; } args->args.mkdir.mode = be32toh(*(uint32_t *)blob); blob += sizeof(uint32_t); blob_len -= sizeof(uint32_t); if (blob_len < sizeof(uint32_t)) { gf_log(this->name, GF_LOG_ERROR, "gfid: %s. Invalid length", args->gfid); goto err; } args->args.mkdir.umask = be32toh(*(uint32_t *)blob); blob_len -= sizeof(uint32_t); if (blob_len < 0) { gf_log(this->name, GF_LOG_ERROR, "gfid: %s. Invalid length", args->gfid); goto err; } } else if (S_ISLNK(args->st_mode)) { len = strnlen(blob, blob_len); if (len == blob_len) { gf_log(this->name, GF_LOG_ERROR, "gfid: %s. Invalid length", args->gfid); goto err; } args->args.symlink.linkpath = GF_MALLOC(len + 1, gf_common_mt_char); if (args->args.symlink.linkpath == NULL) goto err; memcpy(args->args.symlink.linkpath, blob, (len + 1)); blob_len -= (len + 1); } else { if (blob_len < sizeof(uint32_t)) { gf_log(this->name, GF_LOG_ERROR, "gfid: %s. Invalid length", args->gfid); goto err; } args->args.mknod.mode = be32toh(*(uint32_t *)blob); blob += sizeof(uint32_t); blob_len -= sizeof(uint32_t); if (blob_len < sizeof(uint32_t)) { gf_log(this->name, GF_LOG_ERROR, "gfid: %s. Invalid length", args->gfid); goto err; } args->args.mknod.rdev = be32toh(*(uint32_t *)blob); blob += sizeof(uint32_t); blob_len -= sizeof(uint32_t); if (blob_len < sizeof(uint32_t)) { gf_log(this->name, GF_LOG_ERROR, "gfid: %s. Invalid length", args->gfid); goto err; } args->args.mknod.umask = be32toh(*(uint32_t *)blob); blob_len -= sizeof(uint32_t); } if (blob_len) { gf_log(this->name, GF_LOG_ERROR, "gfid: %s. Invalid length", args->gfid); goto err; } return args; err: if (args) ga_newfile_args_free(args); return NULL; } ga_heal_args_t * ga_heal_parse_args(xlator_t *this, data_t *data) { ga_heal_args_t *args = NULL; ga_private_t *priv = NULL; void *blob = NULL; int len = 0; int blob_len = 0; blob = data->data; blob_len = data->len; priv = this->private; /* bname should at least contain a character */ if (blob_len < (sizeof(args->gfid) + 2)) goto err; args = mem_get0(priv->heal_args_pool); if (!args) goto err; memcpy(args->gfid, blob, sizeof(args->gfid)); blob += sizeof(args->gfid); blob_len -= sizeof(args->gfid); len = strnlen(blob, blob_len); if (len == blob_len) goto err; args->bname = GF_MALLOC(len + 1, gf_common_mt_char); if (!args->bname) goto err; memcpy(args->bname, blob, len); args->bname[len] = '\0'; blob_len -= (len + 1); if (blob_len) goto err; return args; err: if (args) ga_heal_args_free(args); return NULL; } static int32_t ga_fill_tmp_loc(loc_t *loc, xlator_t *this, uuid_t gfid, char *bname, dict_t *xdata, loc_t *new_loc) { int ret = -1; uint64_t value = 0; inode_t *parent = NULL; unsigned char *gfid_ptr = NULL; parent = loc->inode; ret = inode_ctx_get(loc->inode, this, &value); if (!ret) { parent = (void *)(uintptr_t)value; if (gf_uuid_is_null(parent->gfid)) parent = loc->inode; } /* parent itself should be looked up */ gf_uuid_copy(new_loc->pargfid, parent->gfid); new_loc->parent = inode_ref(parent); new_loc->inode = inode_grep(parent->table, parent, bname); if (!new_loc->inode) { new_loc->inode = inode_new(parent->table); gf_uuid_copy(new_loc->inode->gfid, gfid); } loc_path(new_loc, bname); if (new_loc->path) { new_loc->name = strrchr(new_loc->path, '/'); if (new_loc->name) new_loc->name++; } gfid_ptr = GF_MALLOC(sizeof(uuid_t), gf_common_mt_uuid_t); if (!gfid_ptr) { ret = -1; goto out; } gf_uuid_copy(gfid_ptr, gfid); ret = dict_set_gfuuid(xdata, "gfid-req", gfid_ptr, false); if (ret < 0) goto out; ret = 0; out: if (ret && gfid_ptr) GF_FREE(gfid_ptr); return ret; } static gf_boolean_t __is_gfid_access_dir(uuid_t gfid) { static uuid_t aux_gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GF_AUX_GFID}; if (gf_uuid_compare(gfid, aux_gfid) == 0) return _gf_true; return _gf_false; } int32_t ga_forget(xlator_t *this, inode_t *inode) { int ret = -1; uint64_t value = 0; inode_t *tmp_inode = NULL; ret = inode_ctx_del(inode, this, &value); if (ret) goto out; tmp_inode = (void *)(uintptr_t)value; inode_unref(tmp_inode); out: return 0; } static int ga_heal_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stat, dict_t *dict, struct iatt *postparent) { call_frame_t *orig_frame = NULL; orig_frame = frame->local; frame->local = NULL; /* don't worry about inode linking and other stuff. They'll happen on * the next lookup. */ STACK_DESTROY(frame->root); STACK_UNWIND_STRICT(setxattr, orig_frame, op_ret, op_errno, dict); return 0; } static int ga_newentry_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { ga_local_t *local = NULL; local = frame->local; /* don't worry about inode linking and other stuff. They'll happen on * the next lookup. */ frame->local = NULL; STACK_DESTROY(frame->root); STACK_UNWIND_STRICT(setxattr, local->orig_frame, op_ret, op_errno, xdata); if (local->xdata) dict_unref(local->xdata); loc_wipe(&local->loc); mem_put(local); return 0; } static int ga_newentry_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stat, dict_t *xdata, struct iatt *postparent) { ga_local_t *local = NULL; local = frame->local; if ((op_ret < 0) && ((op_errno != ENOENT) && (op_errno != ESTALE))) goto err; STACK_WIND(frame, ga_newentry_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, &local->loc, local->mode, local->rdev, local->umask, local->xdata); return 0; err: frame->local = NULL; STACK_DESTROY(frame->root); STACK_UNWIND_STRICT(setxattr, local->orig_frame, op_ret, op_errno, xdata); if (local->xdata) dict_unref(local->xdata); loc_wipe(&local->loc); mem_put(local); return 0; } int32_t ga_new_entry(call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data, dict_t *xdata) { int ret = -1; ga_newfile_args_t *args = NULL; loc_t tmp_loc = { 0, }; call_frame_t *new_frame = NULL; ga_local_t *local = NULL; uuid_t gfid = { 0, }; if (!xdata) { xdata = dict_new(); } else { xdata = dict_ref(xdata); } if (!xdata) { ret = -1; goto out; } args = ga_newfile_parse_args(this, data); if (!args) goto out; ret = gf_uuid_parse(args->gfid, gfid); if (ret) goto out; ret = ga_fill_tmp_loc(loc, this, gfid, args->bname, xdata, &tmp_loc); if (ret) goto out; new_frame = copy_frame(frame); if (!new_frame) goto out; local = mem_get0(this->local_pool); local->orig_frame = frame; loc_copy(&local->loc, &tmp_loc); new_frame->local = local; new_frame->root->uid = args->uid; new_frame->root->gid = args->gid; if (S_ISDIR(args->st_mode)) { STACK_WIND(new_frame, ga_newentry_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, &tmp_loc, args->args.mkdir.mode, args->args.mkdir.umask, xdata); } else if (S_ISLNK(args->st_mode)) { STACK_WIND(new_frame, ga_newentry_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, args->args.symlink.linkpath, &tmp_loc, 0, xdata); } else { /* use 07777 (4 7s) for considering the Sticky bits etc) */ ((ga_local_t *)new_frame->local)->mode = (S_IFMT & args->st_mode) | (07777 & args->args.mknod.mode); ((ga_local_t *)new_frame->local)->umask = args->args.mknod.umask; ((ga_local_t *)new_frame->local)->rdev = args->args.mknod.rdev; ((ga_local_t *)new_frame->local)->xdata = dict_ref(xdata); /* send a named lookup, so that dht can cleanup up stale linkto * files etc. */ STACK_WIND(new_frame, ga_newentry_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &tmp_loc, NULL); } ret = 0; out: ga_newfile_args_free(args); if (xdata) dict_unref(xdata); loc_wipe(&tmp_loc); return ret; } int32_t ga_heal_entry(call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data, dict_t *xdata) { int ret = -1; gf_boolean_t xdata_ref = _gf_false; ga_heal_args_t *args = NULL; loc_t tmp_loc = { 0, }; call_frame_t *new_frame = NULL; uuid_t gfid = { 0, }; args = ga_heal_parse_args(this, data); if (!args) goto out; ret = gf_uuid_parse(args->gfid, gfid); if (ret) goto out; if (!xdata) xdata = dict_new(); else xdata = dict_ref(xdata); if (!xdata) { ret = -1; goto out; } xdata_ref = _gf_true; ret = ga_fill_tmp_loc(loc, this, gfid, args->bname, xdata, &tmp_loc); if (ret) goto out; new_frame = copy_frame(frame); if (!new_frame) goto out; new_frame->local = (void *)frame; STACK_WIND(new_frame, ga_heal_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &tmp_loc, xdata); ret = 0; out: if (args) ga_heal_args_free(args); loc_wipe(&tmp_loc); if (xdata_ref && xdata) dict_unref(xdata); return ret; } int32_t ga_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); return 0; } int32_t ga_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { data_t *data = NULL; int op_errno = ENOMEM; int ret = 0; loc_t ga_loc = { 0, }; GFID_ACCESS_INODE_OP_CHECK(loc, op_errno, err); data = dict_get(dict, GF_FUSE_AUX_GFID_NEWFILE); if (data) { ret = ga_new_entry(frame, this, loc, data, xdata); if (ret) goto err; return 0; } data = dict_get(dict, GF_FUSE_AUX_GFID_HEAL); if (data) { ret = ga_heal_entry(frame, this, loc, data, xdata); if (ret) goto err; return 0; } // If the inode is a virtual inode change the inode otherwise perform // the operation on same inode ret = ga_valid_inode_loc_copy(&ga_loc, loc, this); if (ret < 0) goto err; STACK_WIND(frame, ga_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, &ga_loc, dict, flags, xdata); loc_wipe(&ga_loc); return 0; err: STACK_UNWIND_STRICT(setxattr, frame, -1, op_errno, xdata); return 0; } int32_t ga_virtual_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { int ret = 0; inode_t *cbk_inode = NULL; inode_t *true_inode = NULL; uuid_t random_gfid = { 0, }; inode_t *linked_inode = NULL; if (frame->local) cbk_inode = frame->local; else cbk_inode = inode_ref(inode); frame->local = NULL; if (op_ret) goto unwind; if (!IA_ISDIR(buf->ia_type)) goto unwind; /* need to send back a different inode for linking in itable */ if (cbk_inode == inode) { /* check if the inode is in the 'itable' or if its just previously discover()'d inode */ true_inode = inode_find(inode->table, buf->ia_gfid); if (!true_inode) { /* This unref is for 'inode_ref()' done in beginning. This is needed as cbk_inode is allocated new inode whose unref is taken at the end*/ inode_unref(cbk_inode); cbk_inode = inode_new(inode->table); if (!cbk_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } /* the inode is not present in itable, ie, the actual path is not yet looked up. Use the current inode itself for now */ linked_inode = inode_link(inode, NULL, NULL, buf); inode = linked_inode; } else { /* 'inode_ref()' has been done in inode_find() */ inode = true_inode; } ret = inode_ctx_put(cbk_inode, this, (uint64_t)(uintptr_t)inode); if (ret) { gf_log(this->name, GF_LOG_WARNING, "failed to set the inode ctx with" "the actual inode"); if (inode) inode_unref(inode); } inode = NULL; } if (!gf_uuid_is_null(cbk_inode->gfid)) { /* if the previous linked inode is used, use the same gfid */ gf_uuid_copy(random_gfid, cbk_inode->gfid); } else { /* replace the buf->ia_gfid to a random gfid for directory, for files, what we received is fine */ gf_uuid_generate(random_gfid); } gf_uuid_copy(buf->ia_gfid, random_gfid); buf->ia_ino = gfid_to_ino(buf->ia_gfid); unwind: /* Lookup on non-existing gfid returns ESTALE. Convert into ENOENT for virtual lookup*/ if (op_errno == ESTALE) op_errno = ENOENT; STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, cbk_inode, buf, xdata, postparent); /* Also handles inode_unref of frame->local if done in ga_lookup */ if (cbk_inode) inode_unref(cbk_inode); return 0; } int32_t ga_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { ga_private_t *priv = NULL; /* if the entry in question is not 'root', then follow the normal path */ if (op_ret || !__is_root_gfid(buf->ia_gfid)) goto unwind; priv = this->private; /* do we need to copy root stbuf every time? */ /* mostly yes, as we want to have the 'stat' info show latest in every _cbk() */ /* keep the reference for root stat buf */ priv->root_stbuf = *buf; priv->gfiddir_stbuf = priv->root_stbuf; priv->gfiddir_stbuf.ia_gfid[15] = GF_AUX_GFID; priv->gfiddir_stbuf.ia_ino = GF_AUX_GFID; unwind: STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata, postparent); return 0; } int32_t ga_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { ga_private_t *priv = NULL; int ret = -1; uuid_t tmp_gfid = { 0, }; loc_t tmp_loc = { 0, }; uint64_t value = 0; inode_t *inode = NULL; inode_t *true_inode = NULL; int32_t op_errno = ENOENT; priv = this->private; /* Handle nameless lookup on ".gfid" */ if (!loc->parent && __is_gfid_access_dir(loc->gfid)) { STACK_UNWIND_STRICT(lookup, frame, 0, 0, loc->inode, &priv->gfiddir_stbuf, xdata, &priv->root_stbuf); return 0; } /* if its discover(), no need for any action here */ if (!loc->name) goto wind; /* if its revalidate, and inode is not of type directory, proceed with 'wind' */ if (loc->inode && loc->inode->ia_type && !IA_ISDIR(loc->inode->ia_type)) { /* a revalidate on ".gfid/" is possible, check for it */ if (((loc->parent && __is_gfid_access_dir(loc->parent->gfid)) || __is_gfid_access_dir(loc->pargfid))) { /* here, just send 'loc->gfid' and 'loc->inode' */ tmp_loc.inode = inode_ref(loc->inode); gf_uuid_copy(tmp_loc.gfid, loc->inode->gfid); STACK_WIND(frame, default_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &tmp_loc, xdata); inode_unref(tmp_loc.inode); return 0; } /* not something to bother, continue the flow */ goto wind; } /* need to check if the lookup is on virtual dir */ if ((loc->name && !strcmp(GF_GFID_DIR, loc->name)) && ((loc->parent && __is_root_gfid(loc->parent->gfid)) || __is_root_gfid(loc->pargfid))) { /* this means, the query is on '/.gfid', return the fake stat, and say success */ STACK_UNWIND_STRICT(lookup, frame, 0, 0, loc->inode, &priv->gfiddir_stbuf, xdata, &priv->root_stbuf); return 0; } /* now, check if the lookup() is on an existing entry, but on gfid-path */ if (!((loc->parent && __is_gfid_access_dir(loc->parent->gfid)) || __is_gfid_access_dir(loc->pargfid))) { if (!loc->parent) goto wind; ret = inode_ctx_get(loc->parent, this, &value); if (ret) goto wind; inode = (inode_t *)(uintptr_t)value; ret = loc_copy_overload_parent(&tmp_loc, loc, inode); if (ret) goto err; STACK_WIND(frame, ga_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &tmp_loc, xdata); loc_wipe(&tmp_loc); return 0; } /* make sure the 'basename' is actually a 'canonical-gfid', otherwise, return error */ ret = gf_uuid_parse(loc->name, tmp_gfid); if (ret) goto err; /* if its fresh lookup, go ahead and send it down, if not, for directory, we need indirection to actual dir inode */ if (!(loc->inode && loc->inode->ia_type)) goto discover; /* revalidate on directory */ ret = inode_ctx_get(loc->inode, this, &value); if (ret) goto err; inode = (void *)(uintptr_t)value; /* valid inode, already looked up, work on that */ if (inode->ia_type) goto discover; /* check if the inode is in the 'itable' or if its just previously discover()'d inode */ true_inode = inode_find(loc->inode->table, tmp_gfid); if (true_inode) { /* time do another lookup and update the context with proper inode */ op_errno = ESTALE; /* 'inode_ref()' done in inode_find */ inode_unref(true_inode); goto err; } discover: /* for the virtual entries, we don't need to send 'gfid-req' key, as for these entries, we don't want to 'set' a new gfid */ if (xdata) dict_del(xdata, "gfid-req"); gf_uuid_copy(tmp_loc.gfid, tmp_gfid); /* if revalidate, then we need to have the proper reference */ if (inode) { tmp_loc.inode = inode_ref(inode); frame->local = inode_ref(loc->inode); } else { tmp_loc.inode = inode_ref(loc->inode); } STACK_WIND(frame, ga_virtual_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &tmp_loc, xdata); inode_unref(tmp_loc.inode); return 0; wind: /* used for all the normal lookup path */ STACK_WIND(frame, ga_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); return 0; err: STACK_UNWIND_STRICT(lookup, frame, -1, op_errno, loc->inode, &priv->gfiddir_stbuf, xdata, &priv->root_stbuf); return 0; } int ga_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { int op_errno = ENOMEM; GFID_ACCESS_ENTRY_OP_CHECK(loc, op_errno, err); STACK_WIND(frame, default_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; err: STACK_UNWIND_STRICT(mkdir, frame, -1, op_errno, loc->inode, NULL, NULL, NULL, xdata); return 0; } int ga_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { int op_errno = ENOMEM; GFID_ACCESS_ENTRY_OP_CHECK(loc, op_errno, err); STACK_WIND(frame, default_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; err: STACK_UNWIND_STRICT(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, xdata); return 0; } int ga_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { int op_errno = ENOMEM; GFID_ACCESS_ENTRY_OP_CHECK(loc, op_errno, err); STACK_WIND(frame, default_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkname, loc, umask, xdata); return 0; err: STACK_UNWIND_STRICT(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL, xdata); return 0; } int ga_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { int op_errno = ENOMEM; GFID_ACCESS_ENTRY_OP_CHECK(loc, op_errno, err); STACK_WIND(frame, default_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; err: STACK_UNWIND_STRICT(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, xdata); return 0; } int ga_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flag, dict_t *xdata) { int op_errno = ENOMEM; int ret = -1; loc_t ga_loc = { 0, }; GFID_ACCESS_ENTRY_OP_CHECK(loc, op_errno, err); ret = ga_valid_inode_loc_copy(&ga_loc, loc, this); if (ret < 0) goto err; STACK_WIND(frame, default_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, &ga_loc, flag, xdata); loc_wipe(&ga_loc); return 0; err: STACK_UNWIND_STRICT(rmdir, frame, -1, op_errno, NULL, NULL, xdata); return 0; } int ga_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag, dict_t *xdata) { int op_errno = ENOMEM; int ret = -1; loc_t ga_loc = { 0, }; GFID_ACCESS_ENTRY_OP_CHECK(loc, op_errno, err); ret = ga_valid_inode_loc_copy(&ga_loc, loc, this); if (ret < 0) goto err; STACK_WIND(frame, default_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &ga_loc, xflag, xdata); loc_wipe(&ga_loc); return 0; err: STACK_UNWIND_STRICT(unlink, frame, -1, op_errno, NULL, NULL, xdata); return 0; } int ga_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int op_errno = ENOMEM; int ret = 0; loc_t ga_oldloc = { 0, }; loc_t ga_newloc = { 0, }; GFID_ACCESS_ENTRY_OP_CHECK(oldloc, op_errno, err); GFID_ACCESS_ENTRY_OP_CHECK(newloc, op_errno, err); ret = ga_valid_inode_loc_copy(&ga_oldloc, oldloc, this); if (ret < 0) goto err; ret = ga_valid_inode_loc_copy(&ga_newloc, newloc, this); if (ret < 0) { loc_wipe(&ga_oldloc); goto err; } STACK_WIND(frame, default_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, &ga_oldloc, &ga_newloc, xdata); loc_wipe(&ga_newloc); loc_wipe(&ga_oldloc); return 0; err: STACK_UNWIND_STRICT(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, xdata); return 0; } int ga_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int op_errno = ENOMEM; int ret = 0; loc_t ga_oldloc = { 0, }; loc_t ga_newloc = { 0, }; GFID_ACCESS_ENTRY_OP_CHECK(oldloc, op_errno, err); GFID_ACCESS_ENTRY_OP_CHECK(newloc, op_errno, err); ret = ga_valid_inode_loc_copy(&ga_oldloc, oldloc, this); if (ret < 0) goto err; ret = ga_valid_inode_loc_copy(&ga_newloc, newloc, this); if (ret < 0) { loc_wipe(&ga_oldloc); goto err; } STACK_WIND(frame, default_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, &ga_oldloc, &ga_newloc, xdata); loc_wipe(&ga_newloc); loc_wipe(&ga_oldloc); return 0; err: STACK_UNWIND_STRICT(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, xdata); return 0; } int32_t ga_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { int op_errno = ENOMEM; GFID_ACCESS_INODE_OP_CHECK(loc, op_errno, err); /* also check if the loc->inode itself is virtual inode, if yes, return with failure, mainly because we can't handle all the readdirp and other things on it. */ if (inode_ctx_get(loc->inode, this, NULL) == 0) { op_errno = ENOTSUP; goto err; } STACK_WIND(frame, default_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); return 0; err: STACK_UNWIND_STRICT(opendir, frame, -1, op_errno, NULL, xdata); return 0; } int32_t ga_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int op_errno = ENOMEM; int ret = -1; loc_t ga_loc = { 0, }; GFID_ACCESS_INODE_OP_CHECK(loc, op_errno, err); ret = ga_valid_inode_loc_copy(&ga_loc, loc, this); if (ret < 0) goto err; STACK_WIND(frame, default_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, &ga_loc, name, xdata); loc_wipe(&ga_loc); return 0; err: STACK_UNWIND_STRICT(getxattr, frame, -1, op_errno, NULL, xdata); return 0; } int32_t ga_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int op_errno = ENOMEM; int ret = -1; loc_t ga_loc = { 0, }; ga_private_t *priv = NULL; priv = this->private; /* If stat is on ".gfid" itself, do not wind further, * return fake stat and return success. */ if (__is_gfid_access_dir(loc->gfid)) goto out; ret = ga_valid_inode_loc_copy(&ga_loc, loc, this); if (ret < 0) goto err; STACK_WIND(frame, default_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, &ga_loc, xdata); loc_wipe(&ga_loc); return 0; err: STACK_UNWIND_STRICT(stat, frame, -1, op_errno, NULL, xdata); return 0; out: STACK_UNWIND_STRICT(stat, frame, 0, 0, &priv->gfiddir_stbuf, xdata); return 0; } int32_t ga_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int op_errno = ENOMEM; int ret = -1; loc_t ga_loc = { 0, }; GFID_ACCESS_INODE_OP_CHECK(loc, op_errno, err); ret = ga_valid_inode_loc_copy(&ga_loc, loc, this); if (ret < 0) goto err; STACK_WIND(frame, default_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, &ga_loc, stbuf, valid, xdata); loc_wipe(&ga_loc); return 0; err: STACK_UNWIND_STRICT(setattr, frame, -1, op_errno, NULL, NULL, xdata); return 0; } int32_t ga_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int op_errno = ENOMEM; int ret = -1; loc_t ga_loc = { 0, }; GFID_ACCESS_INODE_OP_CHECK(loc, op_errno, err); ret = ga_valid_inode_loc_copy(&ga_loc, loc, this); if (ret < 0) goto err; STACK_WIND(frame, default_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, &ga_loc, name, xdata); loc_wipe(&ga_loc); return 0; err: STACK_UNWIND_STRICT(removexattr, frame, -1, op_errno, xdata); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_gfid_access_mt_end); if (ret != 0) { gf_log(this->name, GF_LOG_WARNING, "Memory accounting" " init failed"); return ret; } return ret; } int32_t init(xlator_t *this) { ga_private_t *priv = NULL; int ret = -1; if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "not configured with exactly one child. exiting"); goto out; } /* This can be the top of graph in certain cases */ if (!this->parents) { gf_log(this->name, GF_LOG_DEBUG, "dangling volume. check volfile "); } /* TODO: define a mem-type structure */ priv = GF_CALLOC(1, sizeof(*priv), gf_gfid_access_mt_priv_t); if (!priv) goto out; priv->newfile_args_pool = mem_pool_new(ga_newfile_args_t, 512); if (!priv->newfile_args_pool) goto out; priv->heal_args_pool = mem_pool_new(ga_heal_args_t, 512); if (!priv->heal_args_pool) goto out; this->local_pool = mem_pool_new(ga_local_t, 16); if (!this->local_pool) { gf_log(this->name, GF_LOG_ERROR, "failed to create local_t's memory pool"); goto out; } this->private = priv; ret = 0; out: if (ret && priv) { if (priv->newfile_args_pool) mem_pool_destroy(priv->newfile_args_pool); GF_FREE(priv); } return ret; } void fini(xlator_t *this) { ga_private_t *priv = NULL; priv = this->private; this->private = NULL; if (priv) { if (priv->newfile_args_pool) mem_pool_destroy(priv->newfile_args_pool); if (priv->heal_args_pool) mem_pool_destroy(priv->heal_args_pool); GF_FREE(priv); } return; } int32_t ga_dump_inodectx(xlator_t *this, inode_t *inode) { int ret = -1; uint64_t value = 0; inode_t *tmp_inode = NULL; char key_prefix[GF_DUMP_MAX_BUF_LEN] = { 0, }; ret = inode_ctx_get(inode, this, &value); if (ret == 0) { tmp_inode = (void *)(uintptr_t)value; gf_proc_dump_build_key(key_prefix, this->name, "inode"); gf_proc_dump_add_section("%s", key_prefix); gf_proc_dump_write("real-gfid", "%s", uuid_utoa(tmp_inode->gfid)); } return 0; } struct xlator_fops fops = { .lookup = ga_lookup, /* entry fops */ .mkdir = ga_mkdir, .mknod = ga_mknod, .create = ga_create, .symlink = ga_symlink, .link = ga_link, .unlink = ga_unlink, .rmdir = ga_rmdir, .rename = ga_rename, /* handle any other directory operations here */ .opendir = ga_opendir, .stat = ga_stat, .setattr = ga_setattr, .getxattr = ga_getxattr, .removexattr = ga_removexattr, /* special fop to handle more entry creations */ .setxattr = ga_setxattr, }; struct xlator_cbks cbks = { .forget = ga_forget, }; struct xlator_dumpops dumpops = { .inodectx = ga_dump_inodectx, }; struct volume_options options[] = { /* This translator doesn't take any options, or provide any options */ {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .mem_acct_init = mem_acct_init, .op_version = {1}, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "gfid-access", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/gfid-access/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464024702 xustar000000000000000030 mtime=1699284276.123058926 30 atime=1699284290.800103133 30 ctime=1699284304.542144523 glusterfs-11.1/xlators/features/gfid-access/src/Makefile.in0000664000175100017510000005745114522202464025175 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/gfid-access/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) gfid_access_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_gfid_access_la_OBJECTS = gfid-access.lo gfid_access_la_OBJECTS = $(am_gfid_access_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = gfid_access_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(gfid_access_la_LDFLAGS) $(LDFLAGS) -o \ $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(gfid_access_la_SOURCES) DIST_SOURCES = $(gfid_access_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = gfid-access.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features gfid_access_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) gfid_access_la_SOURCES = gfid-access.c gfid_access_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = gfid-access.h gfid-access-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/gfid-access/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/gfid-access/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } gfid-access.la: $(gfid_access_la_OBJECTS) $(gfid_access_la_DEPENDENCIES) $(EXTRA_gfid_access_la_DEPENDENCIES) $(AM_V_CCLD)$(gfid_access_la_LINK) -rpath $(xlatordir) $(gfid_access_la_OBJECTS) $(gfid_access_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gfid-access.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/gfid-access/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024665 xustar000000000000000030 mtime=1699284265.668027435 30 atime=1699284276.086058814 30 ctime=1699284304.544144529 glusterfs-11.1/xlators/features/gfid-access/src/Makefile.am0000664000175100017510000000077114522202451025151 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = gfid-access.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features gfid_access_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) gfid_access_la_SOURCES = gfid-access.c gfid_access_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = gfid-access.h gfid-access-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/gfid-access/src/PaxHeaders.9031/gfid-access-mem-types.h0000644000000000000000000000013214522202451027070 xustar000000000000000030 mtime=1699284265.668027435 30 atime=1699284265.668027435 30 ctime=1699284304.547144538 glusterfs-11.1/xlators/features/gfid-access/src/gfid-access-mem-types.h0000664000175100017510000000115214522202451027346 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GFID_ACCESS_MEM_TYPES_H #define _GFID_ACCESS_MEM_TYPES_H #include enum gf_changelog_mem_types { gf_gfid_access_mt_priv_t = gf_common_mt_end + 1, gf_gfid_access_mt_gfid_t, gf_gfid_access_mt_end }; #endif glusterfs-11.1/xlators/features/gfid-access/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202464024112 xustar000000000000000030 mtime=1699284276.075058781 29 atime=1699284290.77610306 30 ctime=1699284304.493144375 glusterfs-11.1/xlators/features/gfid-access/Makefile.in0000664000175100017510000005264414522202464024405 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/gfid-access DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/gfid-access/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/gfid-access/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/gfid-access/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024076 xustar000000000000000030 mtime=1699284265.668027435 30 atime=1699284276.052058712 30 ctime=1699284304.494144378 glusterfs-11.1/xlators/features/gfid-access/Makefile.am0000664000175100017510000000001614522202451024352 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/features/PaxHeaders.9031/simple-quota0000644000000000000000000000013214522202522022234 xustar000000000000000030 mtime=1699284306.033149013 30 atime=1699284309.687160019 30 ctime=1699284306.033149013 glusterfs-11.1/xlators/features/simple-quota/0002775000175100017510000000000014522202522022572 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/simple-quota/PaxHeaders.9031/src0000644000000000000000000000013014522202522023021 xustar000000000000000029 mtime=1699284306.07514914 30 atime=1699284309.687160019 29 ctime=1699284306.07514914 glusterfs-11.1/xlators/features/simple-quota/src/0002775000175100017510000000000014522202522023361 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/simple-quota/src/PaxHeaders.9031/simple-quota.h0000644000000000000000000000013214522202451025672 xustar000000000000000030 mtime=1699284265.691027504 30 atime=1699284265.691027504 30 ctime=1699284306.073149134 glusterfs-11.1/xlators/features/simple-quota/src/simple-quota.h0000664000175100017510000000176514522202451026162 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2020 Kadalu.IO This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __SIMPLE_QUOTA__ #define __SIMPLE_QUOTA__ typedef struct { gf_lock_t lock; pthread_t quota_set_thread; struct list_head ns_list; bool no_distribute; bool use_backend; bool take_cmd_from_all_client; bool allow_fops; } sq_private_t; typedef struct { struct list_head priv_list; /* list of ns entris in private */ inode_t *ns; /* namespace inode */ gf_atomic_t pending_update; int64_t xattr_size; int64_t hard_lim; int64_t total_size; /* total files used, will be useful only when using backend quota */ int64_t total_files; } sq_inode_t; #endif /* __SIMPLE_QUOTA_H__ */ glusterfs-11.1/xlators/features/simple-quota/src/PaxHeaders.9031/simple-quota.c0000644000000000000000000000013114522202451025664 xustar000000000000000030 mtime=1699284265.691027504 30 atime=1699284265.691027504 29 ctime=1699284306.07514914 glusterfs-11.1/xlators/features/simple-quota/src/simple-quota.c0000664000175100017510000010473514522202451026156 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2020 Kadalu.IO This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include "simple-quota.h" #define QUOTA_USAGE_KEY "glusterfs.quota.total-usage" #define QUOTA_FILES_KEY "glusterfs.quota.total-files" #define QUOTA_RESET_KEY "glusterfs.quota.reset" #define QUOTA_ALLOW_FOPS_KEY "glusterfs.quota.disable-check" static int64_t sync_data_to_disk(xlator_t *this, sq_inode_t *ictx) { sq_private_t *priv = this->private; loc_t loc = {0}; int ret = -1; if (priv->use_backend) return 0; if (!ictx || !ictx->ns) { return 0; } int64_t size = GF_ATOMIC_FETCH_AND(ictx->pending_update, 0); int64_t total_consumption = (ictx->xattr_size + size); if (!size) { /* No changes since last update, no need to update */ return total_consumption; } dict_t *dict = dict_new(); if (!dict) { GF_ATOMIC_ADD(ictx->pending_update, size); return total_consumption; } if (total_consumption < 0) { /* Some bug, this should have not happened */ gf_msg(this->name, GF_LOG_INFO, 0, 0, "quota usage is below zero (%" PRId64 "), resetting to 0", total_consumption); total_consumption = 0; } ret = dict_set_int64(dict, SQUOTA_SIZE_KEY, total_consumption); if (IS_ERROR(ret)) { dict_unref(dict); GF_ATOMIC_ADD(ictx->pending_update, size); return total_consumption; } /* Send the request to actual gfid */ loc.inode = inode_ref(ictx->ns); gf_uuid_copy(loc.gfid, ictx->ns->gfid); gf_msg(this->name, GF_LOG_DEBUG, 0, 0, "%s: Writing size of %" PRId64, uuid_utoa(ictx->ns->gfid), total_consumption); /* As we are doing only operation from server side */ ret = syncop_setxattr(FIRST_CHILD(this), &loc, dict, 0, NULL, NULL); if (IS_SUCCESS(ret)) { ictx->xattr_size = total_consumption; if (priv->no_distribute) ictx->total_size = total_consumption; } else { GF_ATOMIC_ADD(ictx->pending_update, size); gf_log(this->name, GF_LOG_ERROR, "%s: Quota value update failed %d %s", uuid_utoa(ictx->ns->gfid), ret, strerror(ret)); } inode_unref(ictx->ns); dict_unref(dict); return total_consumption; } static void sync_data_from_priv(xlator_t *this, sq_private_t *priv) { sq_inode_t *tmp; sq_inode_t *tmp2; if (list_empty(&priv->ns_list)) { return; } list_for_each_entry_safe(tmp, tmp2, &priv->ns_list, priv_list) { sync_data_to_disk(this, tmp); tmp = NULL; } return; } static sq_inode_t * sq_set_ns_hardlimit(xlator_t *this, inode_t *inode, int64_t limit, int64_t size, bool set_namespace) { sq_private_t *priv = this->private; sq_inode_t *sq_ctx; int ret = -1; sq_ctx = GF_MALLOC(sizeof(sq_inode_t), gf_common_mt_char); if (!sq_ctx) goto out; INIT_LIST_HEAD(&sq_ctx->priv_list); sq_ctx->hard_lim = limit; sq_ctx->xattr_size = size; sq_ctx->total_size = size; /* Initialize it to this number for now */ GF_ATOMIC_INIT(sq_ctx->pending_update, 0); sq_ctx->ns = NULL; if (set_namespace) sq_ctx->ns = inode; ret = inode_ctx_put(inode, this, (uint64_t)(uintptr_t)sq_ctx); if (IS_ERROR(ret)) { GF_FREE(sq_ctx); sq_ctx = NULL; goto out; } LOCK(&priv->lock); { list_add_tail(&sq_ctx->priv_list, &priv->ns_list); } UNLOCK(&priv->lock); gf_msg(this->name, GF_LOG_INFO, 0, 0, "%s: hardlimit set (%" PRId64 ", %" PRId64 ")", uuid_utoa(inode->gfid), limit, size); out: return sq_ctx; } static inline void sq_update_namespace(xlator_t *this, inode_t *ns, struct iatt *prebuf, struct iatt *postbuf, int64_t size, char *fop) { sq_private_t *priv = this->private; sq_inode_t *sq_ctx; uint64_t tmp_mq = 0; if (!ns || priv->use_backend) goto out; /* If the size is passed, use that instead */ if (!size && postbuf && prebuf) { size = (postbuf->ia_blocks - prebuf->ia_blocks) * 512; gf_msg_debug(this->name, 0, "%s: %" PRId64 " - %" PRId64, fop, postbuf->ia_blocks, prebuf->ia_blocks); } bool is_inode_linked = IATT_TYPE_VALID(ns->ia_type); inode_ctx_get(ns, this, &tmp_mq); sq_ctx = (sq_inode_t *)(uintptr_t)tmp_mq; if (!sq_ctx) { sq_ctx = sq_set_ns_hardlimit(this, ns, 0, size, is_inode_linked); if (!sq_ctx) goto out; } if (ns != sq_ctx->ns) { /* Set this, as it is possible to have linked a wrong inode pointer in lookup */ gf_msg_debug(this->name, 0, "namespace not being set - %p %p", ns, sq_ctx->ns); sq_ctx->ns = ns; } if (size) { GF_ATOMIC_ADD(sq_ctx->pending_update, size); } out: return; } static inline void sq_update_total_usage(xlator_t *this, inode_t *inode, int64_t val) { uint64_t tmp_mq = 0; inode_ctx_get(inode, this, &tmp_mq); sq_inode_t *sq_ctx = (sq_inode_t *)(uintptr_t)tmp_mq; if (!sq_ctx) { sq_ctx = sq_set_ns_hardlimit(this, inode, 0, 0, true); if (!sq_ctx) goto out; } sq_ctx->total_size = val; out: return; } static void sq_update_brick_usage(xlator_t *this, inode_t *inode) { uint64_t tmp_mq = 0; int64_t val; dict_t *dict = NULL; inode_ctx_get(inode, this, &tmp_mq); if (!tmp_mq) { goto out; } loc_t loc = { 0, }; loc.inode = inode_ref(inode); int ret = syncop_getxattr(FIRST_CHILD(this), &loc, &dict, SQUOTA_SIZE_KEY, NULL, NULL); inode_unref(inode); if (IS_ERROR(ret)) { goto out; } ret = dict_get_int64(dict, SQUOTA_SIZE_KEY, &val); if (IS_ERROR(ret)) { goto out; } sq_inode_t *sq_ctx = (sq_inode_t *)(uintptr_t)tmp_mq; sq_ctx->xattr_size = val; GF_ATOMIC_INIT(sq_ctx->pending_update, 0); out: if (dict) dict_unref(dict); return; } static void sq_update_hard_limit(xlator_t *this, inode_t *ns, int64_t limit, int64_t size) { sq_inode_t *sq_ctx; uint64_t tmp_mq = 0; if (!ns) goto out; inode_ctx_get(ns, this, &tmp_mq); sq_ctx = (sq_inode_t *)(uintptr_t)tmp_mq; if (!sq_ctx) { sq_ctx = sq_set_ns_hardlimit(this, ns, limit, size, IATT_TYPE_VALID(ns->ia_type)); if (!sq_ctx) goto out; } gf_msg(this->name, GF_LOG_INFO, 0, 0, "hardlimit update: %s %" PRId64 " %" PRId64, uuid_utoa(ns->gfid), limit, size); sq_ctx->hard_lim = limit; //GF_ASSERT(size > 0); out: return; } static inline int sq_check_usage(xlator_t *this, inode_t *inode, size_t new_size) { sq_private_t *priv = this->private; sq_inode_t *sq_ctx; uint64_t tmp_mq = 0; inode_ctx_get(inode, this, &tmp_mq); if (!tmp_mq) return 0; sq_ctx = (sq_inode_t *)(uintptr_t)tmp_mq; /* If hardlimit is not set, allow writes */ if (!sq_ctx->hard_lim) return 0; /* FIXME: lock? */ int64_t compare_size = sq_ctx->total_size + new_size + GF_ATOMIC_GET(sq_ctx->pending_update); if ((sq_ctx->hard_lim < compare_size) && !priv->allow_fops) return EDQUOT; return 0; } /* ====================================== */ static int sq_forget(xlator_t *this, inode_t *inode) { sq_private_t *priv = this->private; sq_inode_t *sq_ctx; uint64_t tmp_mq = 0; gf_log(this->name, GF_LOG_DEBUG, "%s: received forget, removing quota details", uuid_utoa(inode->gfid)); inode_ctx_get(inode, this, &tmp_mq); if (!tmp_mq) return 0; sq_ctx = (sq_inode_t *)(uintptr_t)tmp_mq; LOCK(&priv->lock); { list_del_init(&sq_ctx->priv_list); } UNLOCK(&priv->lock); GF_FREE(sq_ctx); return 0; } int32_t sq_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata) { sq_private_t *priv = this->private; inode_t *inode = NULL; sq_inode_t *ctx = NULL; uint64_t tmp_mq = 0; int64_t usage = -1; int64_t avail = -1; int64_t blocks = 0; int64_t used = 0; inode = frame->local; if (IS_ERROR(op_ret)) goto unwind; /* * We should never get here unless quota_statfs (below) sent us a * cookie, and it would only do so if the value was non-NULL. This * check is therefore just routine defensive coding. */ GF_VALIDATE_OR_GOTO("mq", inode, unwind); inode_ctx_get(inode, this, &tmp_mq); ctx = (sq_inode_t *)(uintptr_t)tmp_mq; if (!ctx || ctx->hard_lim <= 0) { goto unwind; } xdata = xdata ? dict_ref(xdata) : dict_new(); if (!xdata) { goto unwind; } int ret = dict_set_int32(xdata, "simple-quota", 1); if (IS_ERROR(ret)) { gf_log(this->name, GF_LOG_WARNING, "failed to set dict with 'simple-quota'. Quota limits may " "not be properly displayed on client"); } /* This check should be after setting the 'simple-quota' key in dict, so distribute can show the aggregate stats properly */ if (priv->use_backend) goto unwind; /* This step is crucial for a proper sync of xattr at right intervals */ if ((frame->root->pid == GF_CLIENT_PID_QUOTA_HELPER) || priv->take_cmd_from_all_client) { used = sync_data_to_disk(this, ctx); } else { used = ctx->xattr_size + GF_ATOMIC_GET(ctx->pending_update); } { /* statfs is adjusted in this code block */ usage = (used) / buf->f_bsize; blocks = (ctx->hard_lim / buf->f_bsize) + 1; buf->f_blocks = blocks; avail = buf->f_blocks - usage; avail = max(avail, 0); buf->f_bfree = avail; /* * We have to assume that the total assigned quota * won't cause us to dip into the reserved space, * because dealing with the overcommitted cases is * just too hairy (especially when different bricks * might be using different reserved percentages and * such). */ buf->f_bavail = buf->f_bfree; } unwind: frame->local = NULL; STACK_UNWIND_STRICT(statfs, frame, op_ret, op_errno, buf, xdata); if (xdata) dict_unref(xdata); if (inode) inode_unref(inode); return 0; } int32_t sq_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { frame->local = inode_ref(loc->inode->ns_inode); /* This is required for setting 'ns' inode in ctx */ sq_update_namespace(this, loc->inode->ns_inode, NULL, NULL, 0, "statfs"); STACK_WIND(frame, sq_statfs_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, loc, xdata); return 0; } static int32_t sq_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { sq_update_namespace(this, namespace, prebuf, postbuf, 0, "writev"); } frame->local = NULL; STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); inode_unref(namespace); return 0; } int32_t sq_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { size_t size = iov_length(vector, count); int32_t op_errno = sq_check_usage(this, fd->inode->ns_inode, size); if (op_errno) goto fail; frame->local = inode_ref(fd->inode->ns_inode); STACK_WIND(frame, sq_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; fail: STACK_UNWIND_STRICT(writev, frame, -1, op_errno, NULL, NULL, NULL); return 0; } static int32_t sq_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { sq_update_namespace(this, namespace, prebuf, postbuf, 0, "truncate"); } frame->local = NULL; inode_unref(namespace); STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t sq_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { frame->local = inode_ref(loc->inode->ns_inode); STACK_WIND(frame, sq_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } static int32_t sq_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { sq_update_namespace(this, namespace, prebuf, postbuf, 0, "ftruncate"); } frame->local = NULL; inode_unref(namespace); STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t sq_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { frame->local = inode_ref(fd->inode->ns_inode); STACK_WIND(frame, sq_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } int32_t sq_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { uint32_t nlink = 0; uint64_t blocks = 0; int ret = dict_get_uint32(xdata, GF_RESPONSE_LINK_COUNT_XDATA, &nlink); if ((nlink == 1)) { ret = dict_get_uint64(xdata, GF_GET_FILE_BLOCK_COUNT, &blocks); gf_msg(this->name, GF_LOG_DEBUG, 0, 0, "reduce size by %" PRIu64 " blocks (ret: %d)", blocks, ret); sq_update_namespace(this, namespace, preparent, postparent, -((blocks + 1) * 512), "unlink"); /* extra 1 for create offset */ } } frame->local = NULL; inode_unref(namespace); STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int sq_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag, dict_t *xdata) { /* Get the ns inode from parent, it won't cause any changes */ xdata = xdata ? dict_ref(xdata) : dict_new(); if (!xdata) goto wind; int ret = dict_set_uint32(xdata, GF_REQUEST_LINK_COUNT_XDATA, 1); if (IS_ERROR(ret)) gf_log(this->name, GF_LOG_ERROR, "dict set failed (pargfid: %s, name: %s), " "still continuing", uuid_utoa(loc->pargfid), loc->name); ret = dict_set_uint64(xdata, GF_GET_FILE_BLOCK_COUNT, 1); if (IS_ERROR(ret)) gf_log(this->name, GF_LOG_ERROR, "dict set failed (pargfid: %s, name: %s), " "still continuing", uuid_utoa(loc->pargfid), loc->name); wind: frame->local = inode_ref(loc->parent->ns_inode); STACK_WIND(frame, sq_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); if (xdata) dict_unref(xdata); return 0; } int32_t sq_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { /* Just remove 1 4k block */ // sq_update_namespace(this, namespace, preparent, postparent, -4096, // "rmdir"); } frame->local = NULL; inode_unref(namespace); STACK_UNWIND_STRICT(rmdir, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int sq_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flag, dict_t *xdata) { frame->local = inode_ref(loc->parent->ns_inode); STACK_WIND(frame, sq_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flag, xdata); return 0; } int32_t sq_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { sq_update_namespace(this, namespace, preparent, postparent, 512, "create"); } frame->local = NULL; STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent, xdata); inode_unref(namespace); return 0; } int32_t sq_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { /* Check for 4k size */ int32_t op_errno = sq_check_usage(this, loc->parent->ns_inode, 4096); if (op_errno) goto fail; frame->local = inode_ref(loc->parent->ns_inode); STACK_WIND(frame, sq_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; fail: STACK_UNWIND_STRICT(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t sq_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { // sq_update_namespace(this, namespace, preparent, postparent, 4096, // "mkdir"); } frame->local = NULL; STACK_UNWIND_STRICT(mkdir, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); inode_unref(namespace); return 0; } int32_t sq_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { int32_t op_errno = sq_check_usage(this, loc->parent->ns_inode, 4096); if (op_errno) goto fail; frame->local = inode_ref(loc->parent->ns_inode); STACK_WIND(frame, sq_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; fail: STACK_UNWIND_STRICT(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t sq_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *cbk_inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { inode_t *inode = frame->local; if (!inode || !xdata) goto unwind; if (IS_ERROR(op_ret)) goto unwind; int64_t limit = 0; int64_t size = 0; uint64_t val = 1; int ret = 0; ret = inode_ctx_set1(inode, this, &val); if (IS_ERROR(ret)) { gf_log(this->name, GF_LOG_WARNING, "failed to set the flag in inode ctx"); } /* If the Quota Limit is set on a non namespace dir, then this should be * ignored */ if (!dict_get_sizen(xdata, GF_NAMESPACE_KEY)) goto unwind; ret = dict_get_int64(xdata, SQUOTA_SIZE_KEY, &size); if (ret) { gf_log(this->name, GF_LOG_DEBUG, "quota size not set (%s), ignored", uuid_utoa(inode->gfid)); } ret = dict_get_int64(xdata, SQUOTA_LIMIT_KEY, &limit); if (ret) { gf_log(this->name, GF_LOG_DEBUG, "quota limit not set on namespace (%s), ignored", uuid_utoa(inode->gfid)); } sq_update_hard_limit(this, inode, limit, size); unwind: frame->local = NULL; STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, cbk_inode, buf, xdata, postparent); if (inode) inode_unref(inode); return 0; } int32_t sq_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { /* Only in 1 time in lookup for a directory, send namespace and quota xattr */ xdata = xdata ? dict_ref(xdata) : dict_new(); if (!xdata) goto wind; if (IATT_TYPE_VALID(loc->inode->ia_type) && !IA_ISDIR(loc->inode->ia_type)) { goto wind; } /* Only proceed on namespace inode */ /* This check is not valid, as on fresh lookup, namespace wouldn't be set. It will get set in _cbk() */ /* if (loc->inode->ns_inode != loc->inode) { goto wind; } */ /* If we have validated the directory inode, good to ignore this */ uint64_t val = 0; int ret = inode_ctx_get1(loc->inode, this, &val); if (val) { goto wind; } /* namespace key would be set in server-protocol's resolve itself */ ret = dict_set_int64(xdata, SQUOTA_LIMIT_KEY, 0); if (IS_ERROR(ret)) { gf_log(this->name, GF_LOG_ERROR, "BUG: dict set failed (pargfid: %s, name: %s), " "still continuing", uuid_utoa(loc->pargfid), loc->name); } ret = dict_set_int64(xdata, SQUOTA_SIZE_KEY, 0); if (IS_ERROR(ret)) { gf_log(this->name, GF_LOG_ERROR, "BUG: dict set (quota size key) failed (pargfid: %s, name: %s), " "still continuing", uuid_utoa(loc->pargfid), loc->name); } /* Assumption: 'namespace' key would be set in server protocol */ frame->local = inode_ref(loc->inode); wind: STACK_WIND(frame, sq_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); if (xdata) dict_unref(xdata); return 0; } int32_t sq_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { inode_t *inode = frame->local; if (!inode) goto unwind; if (IS_ERROR(op_ret)) { goto unwind; } int64_t val = (int64_t)(uintptr_t)cookie; uint64_t setval = 1; if (val) sq_update_hard_limit(this, inode, val, 0); /* Setting this flag wouldn't bother lookup() call much */ int ret = inode_ctx_set1(inode, this, &setval); if (IS_ERROR(ret)) { gf_log(this->name, GF_LOG_WARNING, "failed to set the flag in inode ctx"); } unwind: frame->local = NULL; STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); if (inode) inode_unref(inode); return 0; } int32_t sq_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { sq_private_t *priv = this->private; int64_t val = 0; int32_t op_errno = EPERM; int ret = dict_get_int64(dict, QUOTA_USAGE_KEY, &val); if (IS_SUCCESS(ret)) { /* if this operation is not sent on namespace, fail the operation */ if (loc->inode != loc->inode->ns_inode) { gf_log(this->name, GF_LOG_WARNING, "request sent on non-namespace inode (%s)", QUOTA_USAGE_KEY); goto err; } /* Fixes bug kadalu #476. Enable the check back after sometime. */ /* if (!(priv->take_cmd_from_all_client || (frame->root->pid == GF_CLIENT_PID_QUOTA_HELPER))) goto err; */ /* we now know there is distribute on client */ priv->no_distribute = false; sq_update_total_usage(this, loc->inode, val); /* CHECK: xdata NULL ok here ? */ STACK_UNWIND_STRICT(setxattr, frame, 0, 0, NULL); return 0; } if (dict_get(dict, QUOTA_RESET_KEY)) { /* if this operation is not sent on namespace, fail the operation */ if (loc->inode != loc->inode->ns_inode) { gf_log(this->name, GF_LOG_WARNING, "request sent on non-namespace inode (%s)", QUOTA_USAGE_KEY); goto err; } /* Fixes bug kadalu #476. Enable the check back after sometime. */ /* if (!(priv->take_cmd_from_all_client || (frame->root->pid == GF_CLIENT_PID_QUOTA_HELPER))) goto err; */ sq_update_brick_usage(this, loc->inode); /* CHECK: xdata NULL ok here ? */ STACK_UNWIND_STRICT(setxattr, frame, 0, 0, NULL); return 0; } ret = dict_get_int64(dict, QUOTA_ALLOW_FOPS_KEY, &val); if (IS_SUCCESS(ret)) { /* Fixes bug kadalu #476. Enable the check back after sometime. */ /* if (!(priv->take_cmd_from_all_client || (frame->root->pid == GF_CLIENT_PID_QUOTA_HELPER))) goto err; */ priv->allow_fops = val ? 1 : 0; STACK_UNWIND_STRICT(setxattr, frame, 0, 0, NULL); return 0; } ret = dict_get_int64(dict, SQUOTA_LIMIT_KEY, &val); if (IS_ERROR(ret)) goto wind; /* For timebeing */ /* if (!(priv->take_cmd_from_all_client || (frame->root->pid == GF_CLIENT_PID_QUOTA_HELPER))) goto err; */ /* if this operation is not sent on namespace, fail the operation */ if (loc->inode != loc->inode->ns_inode) { gf_log(this->name, GF_LOG_WARNING, "request sent on non-namespace inode (%s)", SQUOTA_LIMIT_KEY); goto err; } frame->local = inode_ref(loc->inode); wind: STACK_WIND_COOKIE(frame, sq_setxattr_cbk, (void *)(uintptr_t)val, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; err: STACK_UNWIND_STRICT(setxattr, frame, -1, op_errno, xdata); return 0; } int32_t sq_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { /* Just remove 1 4k block */ sq_update_namespace(this, namespace, prebuf, postbuf, 0, "fallocate"); } frame->local = NULL; STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, prebuf, postbuf, xdata); inode_unref(namespace); return 0; } int32_t sq_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { int32_t op_errno = sq_check_usage(this, fd->inode->ns_inode, len); if (op_errno) goto fail; frame->local = inode_ref(fd->inode->ns_inode); STACK_WIND(frame, sq_fallocate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, xdata); return 0; fail: STACK_UNWIND_STRICT(fallocate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int32_t sq_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { /* Just remove 1 4k block */ sq_update_namespace(this, namespace, prebuf, postbuf, 0, "discard"); } frame->local = NULL; STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, prebuf, postbuf, xdata); inode_unref(namespace); return 0; } int32_t sq_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { frame->local = inode_ref(fd->inode->ns_inode); STACK_WIND(frame, sq_discard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); return 0; } int32_t sq_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { inode_t *namespace = frame->local; if (IS_SUCCESS(op_ret)) { uint32_t nlink = 0; uint64_t blocks = 0; int ret = dict_get_uint32(xdata, GF_RESPONSE_LINK_COUNT_XDATA, &nlink); if ((nlink == 1)) { ret = dict_get_uint64(xdata, GF_GET_FILE_BLOCK_COUNT, &blocks); gf_msg(this->name, GF_LOG_DEBUG, 0, 0, "reduce size by %" PRIu64 " blocks (ret: %d)", blocks, ret); sq_update_namespace(this, namespace, prenewparent, postnewparent, -((blocks + 1) * 512), "unlink"); /* extra 1 for create offset */ } } frame->local = NULL; inode_unref(namespace); STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); return 0; } int32_t sq_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { /* Get the ns inode from parent, it won't cause any changes */ xdata = xdata ? dict_ref(xdata) : dict_new(); if (!xdata) goto wind; int ret = dict_set_uint32(xdata, GF_REQUEST_LINK_COUNT_XDATA, 1); if (IS_ERROR(ret)) gf_log(this->name, GF_LOG_ERROR, "dict set failed (pargfid: %s, name: %s), " "still continuing", uuid_utoa(newloc->pargfid), newloc->name); ret = dict_set_uint64(xdata, GF_GET_FILE_BLOCK_COUNT, 1); if (IS_ERROR(ret)) gf_log(this->name, GF_LOG_ERROR, "dict set failed (pargfid: %s, name: %s), " "still continuing", uuid_utoa(newloc->pargfid), newloc->name); wind: frame->local = inode_ref(newloc->parent->ns_inode); STACK_WIND(frame, sq_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); if (xdata) dict_unref(xdata); return 0; } int reconfigure(xlator_t *this, dict_t *options) { sq_private_t *priv = this->private; GF_OPTION_RECONF("pass-through", this->pass_through, options, bool, out); GF_OPTION_RECONF("use-backend", priv->use_backend, options, bool, out); out: return 0; } int32_t init(xlator_t *this) { sq_private_t *priv; int ret = -1; if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "FATAL: simple-quota should have exactly one child"); goto out; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); } priv = GF_CALLOC(sizeof(sq_private_t), 1, gf_common_mt_char); if (!priv) goto out; GF_OPTION_INIT("pass-through", this->pass_through, bool, out); GF_OPTION_INIT("use-backend", priv->use_backend, bool, out); GF_OPTION_INIT("cmd-from-all-client", priv->take_cmd_from_all_client, bool, out); /* By default assume this is true, if there is a setxattr to set the total usage, then mark it false */ priv->allow_fops = false; priv->no_distribute = true; INIT_LIST_HEAD(&priv->ns_list); LOCK_INIT(&priv->lock); this->private = priv; // quota_set_thread(this); gf_log(this->name, GF_LOG_DEBUG, "Simple Quota xlator loaded"); ret = 0; out: return ret; } void fini(xlator_t *this) { sq_private_t *priv = this->private; if (!priv) return; // sq_clear_thread(this, priv->quota_set_thread); gf_log(this->name, GF_LOG_TRACE, "calling fini, nothing major pending"); this->private = NULL; GF_FREE(priv); return; } int notify(xlator_t *this, int32_t event, void *data, ...) { if (GF_EVENT_PARENT_DOWN == event) { gf_log(this->name, GF_LOG_DEBUG, "sending all pending information to disk"); sync_data_from_priv(this, this->private); } return default_notify(this, event, data); } struct xlator_cbks cbks = { .forget = sq_forget, }; struct xlator_fops fops = { /* Very critical fop */ .statfs = sq_statfs, /* Required to handle hardlimit etc */ .setxattr = sq_setxattr, /* Set the inode context with limit etc during first lookup */ .lookup = sq_lookup, /* Implement a check for usage */ .writev = sq_writev, .create = sq_create, .mkdir = sq_mkdir, /* use for update */ .unlink = sq_unlink, .rmdir = sq_rmdir, .truncate = sq_truncate, /* not implementing a check as it would punch hole */ .ftruncate = sq_ftruncate, .fallocate = sq_fallocate, .discard = sq_discard, /* rename should reduce the space used of target entry if present */ .rename = sq_rename, }; struct volume_options options[] = { { .key = {"pass-through"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "true", .op_version = {GD_OP_VERSION_11_0}, .flags = OPT_FLAG_SETTABLE, .tags = {"quota", "simple-quota"}, .description = "Enable/Disable simple-quota translator", }, /* for handling 'inode quota', please use backend quota support */ /* TODO: implement a inode quota specific check in entry fops */ { .key = {"use-backend"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "false", .op_version = {GD_OP_VERSION_11_0}, .tags = {"quota", "simple-quota"}, .description = "use backend fs's quota for accounting", }, { .key = {"cmd-from-all-client"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "false", .op_version = {GD_OP_VERSION_11_0}, .tags = {"quota", "simple-quota"}, .description = "Allow all clients to send quota set commands.", }, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .op_version = {GD_OP_VERSION_11_0}, .fops = &fops, .cbks = &cbks, .options = options, .notify = notify, .reconfigure = reconfigure, .identifier = "simple-quota", .category = GF_EXPERIMENTAL, }; glusterfs-11.1/xlators/features/simple-quota/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465025153 xustar000000000000000030 mtime=1699284277.213062209 30 atime=1699284290.306101645 30 ctime=1699284306.070149125 glusterfs-11.1/xlators/features/simple-quota/src/Makefile.in0000664000175100017510000005751014522202465025442 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/simple-quota/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) simple_quota_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_simple_quota_la_OBJECTS = simple-quota.lo simple_quota_la_OBJECTS = $(am_simple_quota_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = simple_quota_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(simple_quota_la_LDFLAGS) $(LDFLAGS) \ -o $@ @WITH_SERVER_TRUE@am_simple_quota_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(simple_quota_la_SOURCES) DIST_SOURCES = $(simple_quota_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = simple-quota.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features simple_quota_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) simple_quota_la_SOURCES = simple-quota.c simple_quota_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = simple-quota.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/simple-quota/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/simple-quota/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } simple-quota.la: $(simple_quota_la_OBJECTS) $(simple_quota_la_DEPENDENCIES) $(EXTRA_simple_quota_la_DEPENDENCIES) $(AM_V_CCLD)$(simple_quota_la_LINK) $(am_simple_quota_la_rpath) $(simple_quota_la_OBJECTS) $(simple_quota_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple-quota.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/simple-quota/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451025135 xustar000000000000000030 mtime=1699284265.691027504 30 atime=1699284277.175062095 30 ctime=1699284306.072149131 glusterfs-11.1/xlators/features/simple-quota/src/Makefile.am0000664000175100017510000000070014522202451025411 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = simple-quota.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features simple_quota_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) simple_quota_la_SOURCES = simple-quota.c simple_quota_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = simple-quota.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/simple-quota/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465024364 xustar000000000000000030 mtime=1699284277.164062061 30 atime=1699284290.284101579 30 ctime=1699284306.026148992 glusterfs-11.1/xlators/features/simple-quota/Makefile.in0000664000175100017510000005274614522202465024661 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/simple-quota DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/simple-quota/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/simple-quota/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/simple-quota/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024346 xustar000000000000000030 mtime=1699284265.691027504 30 atime=1699284277.140061989 30 ctime=1699284306.028148998 glusterfs-11.1/xlators/features/simple-quota/Makefile.am0000664000175100017510000000003414522202451024622 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/trash0000644000000000000000000000013214522202520020733 xustar000000000000000030 mtime=1699284304.759145176 30 atime=1699284309.687160019 30 ctime=1699284304.759145176 glusterfs-11.1/xlators/features/trash/0002775000175100017510000000000014522202520021271 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/trash/PaxHeaders.9031/src0000644000000000000000000000012614522202520021525 xustar000000000000000028 mtime=1699284304.8001453 30 atime=1699284309.687160019 28 ctime=1699284304.8001453 glusterfs-11.1/xlators/features/trash/src/0002775000175100017510000000000014522202520022060 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/trash/src/PaxHeaders.9031/trash.h0000644000000000000000000000013214522202451023074 xustar000000000000000030 mtime=1699284265.696027519 30 atime=1699284265.696027519 30 ctime=1699284304.797145291 glusterfs-11.1/xlators/features/trash/src/trash.h0000664000175100017510000000737614522202451023370 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __TRASH_H__ #define __TRASH_H__ #include #include #include #include #include #include "inode.c" #include "fnmatch.h" #include #ifndef GF_BLOCK_READV_SIZE #define GF_BLOCK_READV_SIZE (128 * GF_UNIT_KB) #endif #ifndef GF_DEFAULT_MAX_FILE_SIZE #define GF_DEFAULT_MAX_FILE_SIZE (200 * GF_UNIT_MB) #endif struct trash_struct { fd_t *fd; /* for the fd of existing file */ fd_t *newfd; /* for the newly created file */ loc_t loc; /* to store the location of the existing file */ loc_t newloc; /* to store the location for the new file */ uint64_t fsize; /* for keeping the size of existing file */ off_t cur_offset; /* current offset for read and write ops */ off_t fop_offset; /* original offset received with the fop */ pid_t pid; char origpath[PATH_MAX]; char newpath[PATH_MAX]; int32_t loop_count; gf_boolean_t is_set_pid; struct iatt preparent; struct iatt postparent; gf_boolean_t ctr_link_count_req; }; typedef struct trash_struct trash_local_t; struct _trash_elim_path { struct _trash_elim_path *next; char *path; }; typedef struct _trash_elim_path trash_elim_path; struct trash_priv { char *oldtrash_dir; char *newtrash_dir; char *brick_path; trash_elim_path *eliminate; uint64_t max_trash_file_size; gf_boolean_t state; gf_boolean_t internal; inode_t *trash_inode; inode_table_t *trash_itable; }; typedef struct trash_priv trash_private_t; #define TRASH_SET_PID(frame, local) \ do { \ GF_ASSERT(!local->is_set_pid); \ if (!local->is_set_pid) { \ local->pid = frame->root->pid; \ frame->root->pid = GF_SERVER_PID_TRASH; \ local->is_set_pid = _gf_true; \ } \ } while (0) #define TRASH_UNSET_PID(frame, local) \ do { \ GF_ASSERT(local->is_set_pid); \ if (local->is_set_pid) { \ frame->root->pid = local->pid; \ local->is_set_pid = _gf_false; \ } \ } while (0) #define TRASH_STACK_UNWIND(op, frame, params...) \ do { \ trash_local_t *__local = NULL; \ __local = frame->local; \ frame->local = NULL; \ STACK_UNWIND_STRICT(op, frame, params); \ trash_local_wipe(__local); \ } while (0) #endif /* __TRASH_H__ */ glusterfs-11.1/xlators/features/trash/src/PaxHeaders.9031/trash-mem-types.h0000644000000000000000000000013214522202451025012 xustar000000000000000030 mtime=1699284265.696027519 30 atime=1699284265.696027519 30 ctime=1699284304.798145294 glusterfs-11.1/xlators/features/trash/src/trash-mem-types.h0000664000175100017510000000122014522202451025264 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __TRASH_MEM_TYPES_H__ #define __TRASH_MEM_TYPES_H__ #include enum gf_trash_mem_types_ { gf_trash_mt_trash_private_t = gf_common_mt_end + 1, gf_trash_mt_char, gf_trash_mt_uuid, gf_trash_mt_trash_elim_path, gf_trash_mt_end }; #endif glusterfs-11.1/xlators/features/trash/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465023654 xustar000000000000000030 mtime=1699284277.547063215 30 atime=1699284290.842103259 30 ctime=1699284304.793145279 glusterfs-11.1/xlators/features/trash/src/Makefile.in0000664000175100017510000005732214522202465024144 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/trash/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) trash_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_trash_la_OBJECTS = trash.lo trash_la_OBJECTS = $(am_trash_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = trash_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(trash_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_trash_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(trash_la_SOURCES) DIST_SOURCES = $(trash_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = trash.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features trash_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) trash_la_SOURCES = trash.c trash_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = trash.h trash-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/trash/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/trash/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } trash.la: $(trash_la_OBJECTS) $(trash_la_DEPENDENCIES) $(EXTRA_trash_la_DEPENDENCIES) $(AM_V_CCLD)$(trash_la_LINK) $(am_trash_la_rpath) $(trash_la_OBJECTS) $(trash_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trash.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/trash/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023636 xustar000000000000000030 mtime=1699284265.695027516 30 atime=1699284277.510063104 30 ctime=1699284304.795145285 glusterfs-11.1/xlators/features/trash/src/Makefile.am0000664000175100017510000000074714522202451024125 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = trash.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features trash_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) trash_la_SOURCES = trash.c trash_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = trash.h trash-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/trash/src/PaxHeaders.9031/trash.c0000644000000000000000000000013014522202451023065 xustar000000000000000030 mtime=1699284265.696027519 30 atime=1699284265.696027519 28 ctime=1699284304.8001453 glusterfs-11.1/xlators/features/trash/src/trash.c0000664000175100017510000023527214522202451023361 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "trash.h" #include "trash-mem-types.h" #include #define root_gfid \ (uuid_t) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } #define trash_gfid \ (uuid_t) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5 } #define internal_op_gfid \ (uuid_t) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 } int32_t trash_truncate_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata); int32_t trash_truncate_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata); int32_t trash_unlink_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata); /* Common routines used in this translator */ /** * When a directory/file is created under trash directory, it should have * the same permission as before. This function will fetch permission from * the existing directory and returns the same */ mode_t get_permission(char *path) { mode_t mode = 0755; struct stat sbuf = { 0, }; struct iatt ibuf = { 0, }; int ret = 0; ret = sys_stat(path, &sbuf); if (!ret) { iatt_from_stat(&ibuf, &sbuf); mode = st_mode_from_ia(ibuf.ia_prot, ibuf.ia_type); } else gf_log("trash", GF_LOG_DEBUG, "stat on %s failed" " using default", path); return mode; } /** * For normalization, trash directory name is stored inside priv structure as * '/trash_directory/'. As a result the trailing and leading slashes are being * striped out for additional usage. */ int extract_trash_directory(char *priv_value, const char **trash_directory) { char *tmp = NULL; int ret = 0; GF_VALIDATE_OR_GOTO("trash", priv_value, out); tmp = gf_strdup(priv_value + 1); if (!tmp) { ret = ENOMEM; goto out; } if (tmp[strlen(tmp) - 1] == '/') tmp[strlen(tmp) - 1] = '\0'; *trash_directory = gf_strdup(tmp); if (!(*trash_directory)) { ret = ENOMEM; goto out; } out: if (tmp) GF_FREE(tmp); return ret; } /** * The trash directory path should be append at beginning of file path for * delete or truncate operations. Normal trashing moves the contents to * trash directory and trashing done by internal operations are moved to * internal_op directory inside trash. */ void copy_trash_path(const char *priv_value, gf_boolean_t internal, char *path, size_t path_size) { char trash_path[PATH_MAX] = { 0, }; strncpy(trash_path, priv_value, sizeof(trash_path)); trash_path[sizeof(trash_path) - 1] = 0; if (internal) strncat(trash_path, "internal_op/", sizeof(trash_path) - strlen(trash_path) - 1); strncpy(path, trash_path, path_size); path[path_size - 1] = 0; } /** * This function performs the reverse operation of copy_trash_path(). It gives * out a pointer, whose starting value will be the path inside trash directory, * similar to original path. */ void remove_trash_path(const char *path, gf_boolean_t internal, char **rem_path) { if (rem_path == NULL) { return; } *rem_path = strchr(path + 1, '/'); if (internal) *rem_path = strchr(*rem_path + 1, '/'); } /** * Checks whether the given path reside under the specified eliminate path */ int check_whether_eliminate_path(trash_elim_path *trav, const char *path) { int match = 0; while (trav) { if (strncmp(path, trav->path, strlen(trav->path)) == 0) { match++; break; } trav = trav->next; } return match; } int32_t check_pathbuf(inode_t *inode, xlator_t *this, char **pathbuf, trash_local_t **local, const char *name) { trash_private_t *priv = this->private; int32_t match = 0; inode_path(inode, NULL, pathbuf); if (!(*pathbuf)) { gf_log(this->name, GF_LOG_DEBUG, "Inode path not found"); return -EINVAL; } match = check_whether_eliminate_path(priv->eliminate, *pathbuf); if ((strncmp(*pathbuf, priv->newtrash_dir, strlen(priv->newtrash_dir)) == 0) || (match)) { if (match) { gf_log(this->name, GF_LOG_DEBUG, "%s is a file comes under an eliminate path, " "so it is not moved to trash", name); } GF_FREE(*pathbuf); *pathbuf = NULL; return 0; } *local = mem_get0(this->local_pool); if (!(*local)) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); GF_FREE(*pathbuf); *pathbuf = NULL; return -ENOMEM; } return 1; } /** * Stores the eliminate path into internal eliminate path structure */ int store_eliminate_path(char *str, trash_elim_path **eliminate) { trash_elim_path *trav = NULL; char *component = NULL; char elm_path[PATH_MAX] = { 0, }; int ret = 0; char *strtokptr = NULL; if ((str == NULL) || (eliminate == NULL)) { ret = EINVAL; goto out; } component = strtok_r(str, ",", &strtokptr); while (component) { trav = GF_MALLOC(sizeof(*trav), gf_trash_mt_trash_elim_path); if (!trav) { ret = ENOMEM; goto out; } if (component[0] == '/') sprintf(elm_path, "%s", component); else sprintf(elm_path, "/%s", component); if (component[strlen(component) - 1] != '/') strncat(elm_path, "/", sizeof(elm_path) - strlen(elm_path) - 1); trav->path = gf_strdup(elm_path); if (!trav->path) { ret = ENOMEM; gf_log("trash", GF_LOG_DEBUG, "out of memory"); GF_FREE(trav); goto out; } trav->next = *eliminate; *eliminate = trav; component = strtok_r(NULL, ",", &strtokptr); } out: return ret; } /** * Appends time stamp to given string */ void append_time_stamp(char *name, size_t name_size) { int i; char timestr[GF_TIMESTR_SIZE] = { 0, }; gf_time_fmt(timestr, sizeof(timestr), gf_time(), gf_timefmt_F_HMS); /* removing white spaces in timestamp */ for (i = 0; i < strlen(timestr); i++) { if (timestr[i] == ' ') timestr[i] = '_'; } strncat(name, "_", name_size - strlen(name) - 1); strncat(name, timestr, name_size - strlen(name) - 1); } /* * * Check whether delete/rename operation is permitted on * trash directory */ gf_boolean_t check_whether_op_permitted(trash_private_t *priv, loc_t *loc) { if ((priv->state && (gf_uuid_compare(loc->inode->gfid, trash_gfid) == 0))) return _gf_false; if (priv->internal && (gf_uuid_compare(loc->inode->gfid, internal_op_gfid) == 0)) return _gf_false; return _gf_true; } /** * Wipe the memory used by trash location variable */ void trash_local_wipe(trash_local_t *local) { if (!local) goto out; loc_wipe(&local->loc); loc_wipe(&local->newloc); if (local->fd) fd_unref(local->fd); if (local->newfd) fd_unref(local->newfd); mem_put(local); out: return; } /** * Wipe the memory used by eliminate path through a * recursive call */ void wipe_eliminate_path(trash_elim_path **trav) { if (trav == NULL) { return; } if (*trav == NULL) { return; } wipe_eliminate_path(&(*trav)->next); GF_FREE((*trav)->path); GF_FREE(*trav); *trav = NULL; } /** * This is the call back of rename fop initated using STACK_WIND in * reconfigure/notify function which is used to rename trash directory * in the brick when it is required either in volume start or set. * This frame must destroyed from this function itself since it was * created by trash xlator */ int32_t trash_dir_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { trash_private_t *priv = NULL; trash_local_t *local = NULL; priv = this->private; local = frame->local; if (op_ret == -1) { gf_log(this->name, GF_LOG_ERROR, "rename trash directory " "failed: %s", strerror(op_errno)); goto out; } GF_FREE(priv->oldtrash_dir); priv->oldtrash_dir = gf_strdup(priv->newtrash_dir); if (!priv->oldtrash_dir) { op_ret = ENOMEM; gf_log(this->name, GF_LOG_DEBUG, "out of memory"); } out: frame->local = NULL; STACK_DESTROY(frame->root); trash_local_wipe(local); return op_ret; } int rename_trash_directory(xlator_t *this) { trash_private_t *priv = NULL; int ret = 0; loc_t loc = { 0, }; loc_t old_loc = { 0, }; call_frame_t *frame = NULL; trash_local_t *local = NULL; priv = this->private; frame = create_frame(this, this->ctx->pool); if (frame == NULL) { gf_log(this->name, GF_LOG_ERROR, "failed to create frame"); ret = ENOMEM; goto out; } local = mem_get0(this->local_pool); if (!local) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } frame->local = local; /* assign new location values to new_loc members */ gf_uuid_copy(loc.gfid, trash_gfid); gf_uuid_copy(loc.pargfid, root_gfid); ret = extract_trash_directory(priv->newtrash_dir, &loc.name); if (ret) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } loc.path = gf_strdup(priv->newtrash_dir); if (!loc.path) { ret = ENOMEM; gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } /* assign old location values to old_loc members */ gf_uuid_copy(old_loc.gfid, trash_gfid); gf_uuid_copy(old_loc.pargfid, root_gfid); ret = extract_trash_directory(priv->oldtrash_dir, &old_loc.name); if (ret) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } old_loc.path = gf_strdup(priv->oldtrash_dir); if (!old_loc.path) { ret = ENOMEM; gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } old_loc.inode = inode_ref(priv->trash_inode); gf_uuid_copy(old_loc.inode->gfid, old_loc.gfid); loc_copy(&local->loc, &old_loc); loc_copy(&local->newloc, &loc); STACK_WIND(frame, trash_dir_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, &old_loc, &loc, NULL); return 0; out: if (frame) { frame->local = NULL; STACK_DESTROY(frame->root); } trash_local_wipe(local); return ret; } int32_t trash_internal_op_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { trash_local_t *local = NULL; local = frame->local; if (op_ret != 0 && !(op_errno == EEXIST)) gf_log(this->name, GF_LOG_ERROR, "mkdir failed for " "internal op directory : %s", strerror(op_errno)); frame->local = NULL; STACK_DESTROY(frame->root); trash_local_wipe(local); return op_ret; } /** * This is the call back of mkdir fop initated using STACK_WIND in * notify/reconfigure function which is used to create trash directory * in the brick when "trash" is on. The frame of the mkdir must * destroyed from this function itself since it was created by trash xlator */ int32_t trash_dir_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { trash_private_t *priv = NULL; trash_local_t *local = NULL; priv = this->private; local = frame->local; if (op_ret == 0) { priv->oldtrash_dir = gf_strdup(priv->newtrash_dir); if (!priv->oldtrash_dir) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); op_ret = ENOMEM; } } else if (op_ret != 0 && errno != EEXIST) gf_log(this->name, GF_LOG_ERROR, "mkdir failed for trash" " directory : %s", strerror(op_errno)); frame->local = NULL; STACK_DESTROY(frame->root); trash_local_wipe(local); return op_ret; } /** * This getxattr calls returns existing trash directory path in * the dictionary */ int32_t trash_dir_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { data_t *data = NULL; trash_private_t *priv = NULL; int ret = 0; trash_local_t *local = NULL; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); local = frame->local; data = dict_get(dict, GET_ANCESTRY_PATH_KEY); if (!data) { goto out; } priv->oldtrash_dir = GF_MALLOC(PATH_MAX, gf_common_mt_char); if (!priv->oldtrash_dir) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = ENOMEM; goto out; } /* appending '/' if it is not present */ sprintf(priv->oldtrash_dir, "%s%c", data->data, data->data[strlen(data->data) - 1] != '/' ? '/' : '\0'); gf_log(this->name, GF_LOG_DEBUG, "old trash directory path " "is %s", priv->oldtrash_dir); if (strcmp(priv->newtrash_dir, priv->oldtrash_dir) != 0) { /* When user set a new name for trash directory, trash * xlator will perform a rename operation on old trash * directory to the new one using a STACK_WIND from here. * This option can be configured only when volume is in * started state */ ret = rename_trash_directory(this); } out: frame->local = NULL; STACK_DESTROY(frame->root); trash_local_wipe(local); return ret; } /** * This is a nameless look up for internal op directory * The lookup is based on gfid, because internal op directory * has fixed gfid. */ int32_t trash_internalop_dir_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { trash_private_t *priv = NULL; int ret = 0; uuid_t *gfid_ptr = NULL; loc_t loc = { 0, }; char internal_op_path[PATH_MAX] = { 0, }; dict_t *dict = NULL; trash_local_t *local = NULL; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); local = frame->local; if (op_ret != 0 && op_errno == ENOENT) { loc_wipe(&local->loc); gfid_ptr = GF_MALLOC(sizeof(uuid_t), gf_common_mt_uuid_t); if (!gfid_ptr) { ret = ENOMEM; goto out; } gf_uuid_copy(*gfid_ptr, internal_op_gfid); dict = dict_new(); if (!dict) { ret = ENOMEM; goto out; } ret = dict_set_gfuuid(dict, "gfid-req", *gfid_ptr, false); if (ret) { gf_log(this->name, GF_LOG_ERROR, "setting key gfid-req failed"); goto out; } gf_uuid_copy(loc.gfid, internal_op_gfid); gf_uuid_copy(loc.pargfid, trash_gfid); loc.inode = inode_new(priv->trash_itable); /* The mkdir call for creating internal op directory */ loc.name = gf_strdup("internal_op"); if (!loc.name) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } sprintf(internal_op_path, "%s%s/", priv->newtrash_dir, loc.name); loc.path = gf_strdup(internal_op_path); if (!loc.path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } loc_copy(&local->loc, &loc); STACK_WIND(frame, trash_internal_op_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, &loc, 0755, 0022, dict); return 0; } out: if (ret && gfid_ptr) GF_FREE(gfid_ptr); if (dict) dict_unref(dict); frame->local = NULL; STACK_DESTROY(frame->root); trash_local_wipe(local); return op_ret; } /** * This is a nameless look up for old trash directory * The lookup is based on gfid, because trash directory * has fixed gfid. */ int32_t trash_dir_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { trash_private_t *priv = NULL; loc_t loc = { 0, }; int ret = 0; uuid_t *gfid_ptr = NULL; dict_t *dict = NULL; trash_local_t *local = NULL; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); local = frame->local; loc_wipe(&local->loc); if (op_ret == 0) { gf_log(this->name, GF_LOG_DEBUG, "inode found with gfid %s", uuid_utoa(buf->ia_gfid)); gf_uuid_copy(loc.gfid, trash_gfid); /* Find trash inode using available information */ priv->trash_inode = inode_link(inode, NULL, NULL, buf); loc.inode = inode_ref(priv->trash_inode); loc_copy(&local->loc, &loc); /*Used to find path of old trash directory*/ STACK_WIND(frame, trash_dir_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, &loc, GET_ANCESTRY_PATH_KEY, xdata); return 0; } /* If there is no old trash directory we set its value to new one, * which is the valid condition for trash directory creation */ else { gf_log(this->name, GF_LOG_DEBUG, "Creating trash " "directory %s ", priv->newtrash_dir); gfid_ptr = GF_MALLOC(sizeof(uuid_t), gf_common_mt_uuid_t); if (!gfid_ptr) { ret = ENOMEM; goto out; } gf_uuid_copy(*gfid_ptr, trash_gfid); gf_uuid_copy(loc.gfid, trash_gfid); gf_uuid_copy(loc.pargfid, root_gfid); ret = extract_trash_directory(priv->newtrash_dir, &loc.name); if (ret) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } loc.path = gf_strdup(priv->newtrash_dir); if (!loc.path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } priv->trash_inode = inode_new(priv->trash_itable); priv->trash_inode->ia_type = IA_IFDIR; loc.inode = inode_ref(priv->trash_inode); dict = dict_new(); if (!dict) { ret = ENOMEM; goto out; } /* Fixed gfid is set for trash directory with * this function */ ret = dict_set_gfuuid(dict, "gfid-req", *gfid_ptr, false); if (ret) { gf_log(this->name, GF_LOG_ERROR, "setting key gfid-req failed"); goto out; } loc_copy(&local->loc, &loc); /* The mkdir call for creating trash directory */ STACK_WIND(frame, trash_dir_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, &loc, 0755, 0022, dict); return 0; } out: if (ret && gfid_ptr) GF_FREE(gfid_ptr); if (dict) dict_unref(dict); frame->local = NULL; STACK_DESTROY(frame->root); trash_local_wipe(local); return ret; } int create_or_rename_trash_directory(xlator_t *this) { trash_private_t *priv = NULL; int ret = 0; loc_t loc = { 0, }; call_frame_t *frame = NULL; trash_local_t *local = NULL; priv = this->private; frame = create_frame(this, this->ctx->pool); if (frame == NULL) { gf_log(this->name, GF_LOG_ERROR, "failed to create frame"); ret = ENOMEM; goto out; } local = mem_get0(this->local_pool); if (!local) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } frame->local = local; loc.inode = inode_new(priv->trash_itable); gf_uuid_copy(loc.gfid, trash_gfid); loc_copy(&local->loc, &loc); gf_log(this->name, GF_LOG_DEBUG, "nameless lookup for" "old trash directory"); STACK_WIND(frame, trash_dir_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &loc, NULL); out: return ret; } int create_internalop_directory(xlator_t *this) { trash_private_t *priv = NULL; int ret = 0; loc_t loc = { 0, }; call_frame_t *frame = NULL; trash_local_t *local = NULL; priv = this->private; frame = create_frame(this, this->ctx->pool); if (frame == NULL) { gf_log(this->name, GF_LOG_ERROR, "failed to create frame"); ret = ENOMEM; goto out; } local = mem_get0(this->local_pool); if (!local) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } frame->local = local; gf_uuid_copy(loc.gfid, internal_op_gfid); gf_uuid_copy(loc.pargfid, trash_gfid); loc.inode = inode_new(priv->trash_itable); loc.inode->ia_type = IA_IFDIR; loc_copy(&local->loc, &loc); STACK_WIND(frame, trash_internalop_dir_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &loc, NULL); out: return ret; } int32_t trash_common_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { STACK_UNWIND_STRICT(mkdir, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int32_t trash_common_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); return 0; } int32_t trash_common_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { STACK_UNWIND_STRICT(rmdir, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } /** * move backs from trash translator to unlink call */ int32_t trash_common_unwind_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { TRASH_STACK_UNWIND(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } /** * If the path is not present in the trash directory,it will recursively * call this call-back and one by one directories will be created from * the starting */ int32_t trash_unlink_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { trash_local_t *local = NULL; char *tmp_str = NULL; char *tmp_path = NULL; char *tmp_dirname = NULL; char *tmp_stat = NULL; char real_path[PATH_MAX] = { 0, }; char *dir_name = NULL; size_t count = 0; int32_t loop_count = 0; int i = 0; loc_t tmp_loc = { 0, }; trash_private_t *priv = NULL; int ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); TRASH_UNSET_PID(frame, local); tmp_str = gf_strdup(local->newpath); if (!tmp_str) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = -1; goto out; } loop_count = local->loop_count; /* The directory is not present , need to create it */ if ((op_ret == -1) && (op_errno == ENOENT)) { tmp_dirname = strchr(tmp_str, '/'); while (tmp_dirname) { count = tmp_dirname - tmp_str; if (count == 0) count = 1; i++; if (i > loop_count) break; tmp_dirname = strchr(tmp_str + count + 1, '/'); } tmp_path = gf_memdup(local->newpath, count + 1); if (!tmp_path) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = ENOMEM; goto out; } tmp_path[count] = '\0'; loc_copy(&tmp_loc, &local->loc); tmp_loc.path = gf_strdup(tmp_path); if (!tmp_loc.path) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = ENOMEM; goto out; } /* Stores the the name of directory to be created */ tmp_loc.name = gf_strdup(strrchr(tmp_path, '/') + 1); if (!tmp_loc.name) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = ENOMEM; goto out; } strncpy(real_path, priv->brick_path, sizeof(real_path)); real_path[sizeof(real_path) - 1] = 0; remove_trash_path(tmp_path, (frame->root->pid < 0), &tmp_stat); if (tmp_stat) strncat(real_path, tmp_stat, sizeof(real_path) - strlen(real_path) - 1); TRASH_SET_PID(frame, local); STACK_WIND_COOKIE(frame, trash_unlink_mkdir_cbk, tmp_path, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, &tmp_loc, get_permission(real_path), 0022, xdata); loc_wipe(&tmp_loc); goto out; } /* Given path is created , comparing to the required path */ if (op_ret == 0) { dir_name = dirname(tmp_str); if (strcmp((char *)cookie, dir_name) == 0) { /* File path exists we can rename it*/ loc_copy(&tmp_loc, &local->loc); tmp_loc.path = local->newpath; STACK_WIND(frame, trash_unlink_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, &local->loc, &tmp_loc, xdata); goto out; } } if ((op_ret == -1) && (op_errno != EEXIST)) { gf_log(this->name, GF_LOG_ERROR, "Directory creation failed [%s]. " "Therefore unlinking %s without moving to trash " "directory", strerror(op_errno), local->loc.name); STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &local->loc, 0, xdata); goto out; } LOCK(&frame->lock); { loop_count = ++local->loop_count; } UNLOCK(&frame->lock); tmp_dirname = strchr(tmp_str, '/'); /* Path is not completed , need to create remaining path */ while (tmp_dirname) { count = tmp_dirname - tmp_str; if (count == 0) count = 1; i++; if (i > loop_count) break; tmp_dirname = strchr(tmp_str + count + 1, '/'); } tmp_path = gf_memdup(local->newpath, count + 1); if (!tmp_path) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = -1; goto out; } tmp_path[count] = '\0'; loc_copy(&tmp_loc, &local->loc); tmp_loc.path = gf_strdup(tmp_path); if (!tmp_loc.path) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = -1; goto out; } /* Stores the the name of directory to be created */ tmp_loc.name = gf_strdup(strrchr(tmp_path, '/') + 1); if (!tmp_loc.name) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = -1; goto out; } strncpy(real_path, priv->brick_path, sizeof(real_path)); real_path[sizeof(real_path) - 1] = 0; remove_trash_path(tmp_path, (frame->root->pid < 0), &tmp_stat); if (tmp_stat) strncat(real_path, tmp_stat, sizeof(real_path) - strlen(real_path) - 1); TRASH_SET_PID(frame, local); STACK_WIND_COOKIE(frame, trash_unlink_mkdir_cbk, tmp_path, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, &tmp_loc, get_permission(real_path), 0022, xdata); out: if (tmp_path) GF_FREE(tmp_path); if (tmp_str) GF_FREE(tmp_str); return ret; } /** * The name of unlinking file should be renamed as starting * from trash directory as mentioned in the mount point */ int32_t trash_unlink_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { trash_local_t *local = NULL; trash_private_t *priv = NULL; char *tmp_str = NULL; char *dir_name = NULL; char *tmp_cookie = NULL; loc_t tmp_loc = { 0, }; dict_t *new_xdata = NULL; char *tmp_stat = NULL; char real_path[PATH_MAX] = { 0, }; int ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); if ((op_ret == -1) && (op_errno == ENOENT)) { /* the file path does not exist we want to create path * for the file */ tmp_str = gf_strdup(local->newpath); if (!tmp_str) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } dir_name = dirname(tmp_str); /* stores directory name */ loc_copy(&tmp_loc, &local->loc); tmp_loc.path = gf_strdup(dir_name); if (!tmp_loc.path) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = ENOMEM; goto out; } tmp_cookie = gf_strdup(dir_name); if (!tmp_cookie) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } strncpy(real_path, priv->brick_path, sizeof(real_path)); real_path[sizeof(real_path) - 1] = 0; remove_trash_path(tmp_str, (frame->root->pid < 0), &tmp_stat); if (tmp_stat) strncat(real_path, tmp_stat, sizeof(real_path) - strlen(real_path) - 1); TRASH_SET_PID(frame, local); /* create the directory with proper permissions */ STACK_WIND_COOKIE(frame, trash_unlink_mkdir_cbk, tmp_cookie, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, &tmp_loc, get_permission(real_path), 0022, xdata); loc_wipe(&tmp_loc); goto out; } if ((op_ret == -1) && (op_errno == ENOTDIR)) { /* if entry is already present in trash directory, * new one is not copied*/ gf_log(this->name, GF_LOG_DEBUG, "target(%s) exists, cannot keep the copy, deleting", local->newpath); STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &local->loc, 0, xdata); goto out; } if ((op_ret == -1) && (op_errno == EISDIR)) { /* if entry is directory,we remove directly */ gf_log(this->name, GF_LOG_DEBUG, "target(%s) exists as directory, cannot keep copy, " "deleting", local->newpath); STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &local->loc, 0, xdata); goto out; } /********************************************************************** * * CTR Xlator message handling done here! * **********************************************************************/ /** * If unlink is handled by trash translator, it should inform the * CTR Xlator. And trash translator only handles the unlink for * the last hardlink. * * Check if there is a GF_REQUEST_LINK_COUNT_XDATA from CTR Xlator * */ if (local->ctr_link_count_req) { /* Sending back inode link count to ctr_unlink * (changetimerecoder xlator) via * "GF_RESPONSE_LINK_COUNT_XDATA" key using xdata. * */ if (xdata) { ret = dict_set_uint32(xdata, GF_RESPONSE_LINK_COUNT_XDATA, 1); if (ret == -1) { gf_log(this->name, GF_LOG_WARNING, "Failed to set" " GF_RESPONSE_LINK_COUNT_XDATA"); } } else { new_xdata = dict_new(); if (!new_xdata) { gf_log(this->name, GF_LOG_WARNING, "Memory allocation failure while " "creating new_xdata"); goto ctr_out; } ret = dict_set_uint32(new_xdata, GF_RESPONSE_LINK_COUNT_XDATA, 1); if (ret == -1) { gf_log(this->name, GF_LOG_WARNING, "Failed to set" " GF_RESPONSE_LINK_COUNT_XDATA"); } ctr_out: TRASH_STACK_UNWIND(unlink, frame, 0, op_errno, preoldparent, postoldparent, new_xdata); goto out; } } /* All other cases, unlink should return success */ TRASH_STACK_UNWIND(unlink, frame, 0, op_errno, preoldparent, postoldparent, xdata); out: if (tmp_str) GF_FREE(tmp_str); if (tmp_cookie) GF_FREE(tmp_cookie); if (new_xdata) dict_unref(new_xdata); return ret; } /** * move backs from trash translator to truncate call */ int32_t trash_common_unwind_buf_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { TRASH_STACK_UNWIND(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t trash_unlink_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { trash_private_t *priv = NULL; trash_local_t *local = NULL; loc_t new_loc = { 0, }; int ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); if (op_ret == -1) { gf_log(this->name, GF_LOG_DEBUG, "%s: %s", local->loc.path, strerror(op_errno)); TRASH_STACK_UNWIND(unlink, frame, op_ret, op_errno, buf, NULL, xdata); ret = -1; goto out; } /* Only last hardlink will be moved to trash directory */ if (buf->ia_nlink > 1) { STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &local->loc, 0, xdata); goto out; } /* if the file is too big just unlink it */ if (buf->ia_size > (priv->max_trash_file_size)) { gf_log(this->name, GF_LOG_DEBUG, "%s: file size too big (%" PRId64 ") to " "move into trash directory", local->loc.path, buf->ia_size); STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &local->loc, 0, xdata); goto out; } /* Copies new path for renaming */ loc_copy(&new_loc, &local->loc); new_loc.path = gf_strdup(local->newpath); if (!new_loc.path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } STACK_WIND(frame, trash_unlink_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, &local->loc, &new_loc, xdata); out: loc_wipe(&new_loc); return ret; } /** * Unlink is called internally by rm system call and also * by internal operations of gluster such as self-heal */ int32_t trash_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { trash_private_t *priv = NULL; trash_local_t *local = NULL; /* files inside trash */ int32_t ctr_link_req = 0; char *pathbuf = NULL; int32_t ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); /* If trash is not active or not enabled through cli, then * we bypass and wind back */ if (!priv->state) { STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, 0, xdata); goto out; } /* The files removed by gluster internal operations such as self-heal, * should moved to trash directory , but files by client should not * moved */ if ((frame->root->pid < 0) && !priv->internal) { STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, 0, xdata); goto out; } /* loc need some gfid which will be present in inode */ gf_uuid_copy(loc->gfid, loc->inode->gfid); /* Checking for valid location */ if (gf_uuid_is_null(loc->gfid) && gf_uuid_is_null(loc->inode->gfid)) { gf_log(this->name, GF_LOG_DEBUG, "Bad address"); STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, 0, xdata); ret = EFAULT; goto out; } /* This will be more accurate */ ret = check_pathbuf(loc->inode, this, &pathbuf, &local, loc->name); if (ret == 0) { /* Trying to unlink from the trash-dir. So do the * actual unlink without moving to trash-dir. */ STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, 0, xdata); goto out; } else if (ret < 0) { TRASH_STACK_UNWIND(unlink, frame, -1, -ret, NULL, NULL, xdata); goto out; } frame->local = local; loc_copy(&local->loc, loc); /* rename new location of file as starting from trash directory */ copy_trash_path(priv->newtrash_dir, (frame->root->pid < 0), local->newpath, sizeof(local->newpath)); strncat(local->newpath, pathbuf, sizeof(local->newpath) - strlen(local->newpath) - 1); /* append timestamp to file name so that we can avoid * name collisions inside trash */ append_time_stamp(local->newpath, sizeof(local->newpath)); if (strlen(local->newpath) > PATH_MAX) { STACK_WIND(frame, trash_common_unwind_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, 0, xdata); goto out; } /* To know whether CTR xlator requested for the link count */ ret = dict_get_int32(xdata, GF_REQUEST_LINK_COUNT_XDATA, &ctr_link_req); if (ret) { local->ctr_link_count_req = _gf_false; ret = 0; } else local->ctr_link_count_req = _gf_true; STACK_WIND(frame, trash_unlink_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); out: if (pathbuf) GF_FREE(pathbuf); return ret; } /** * Use this when a failure occurs, and delete the newly created file */ int32_t trash_truncate_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { trash_local_t *local = NULL; local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); if (op_ret == -1) { gf_log(this->name, GF_LOG_DEBUG, "deleting the newly created file: %s", strerror(op_errno)); } STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &local->loc, local->fop_offset, xdata); out: return 0; } /** * Read from source file */ int32_t trash_truncate_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobuf, dict_t *xdata) { trash_local_t *local = NULL; local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); if (op_ret == -1) { gf_log(this->name, GF_LOG_DEBUG, "readv on the existing file failed: %s", strerror(op_errno)); STACK_WIND(frame, trash_truncate_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &local->newloc, 0, xdata); goto out; } local->fsize = stbuf->ia_size; STACK_WIND(frame, trash_truncate_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, local->newfd, vector, count, local->cur_offset, 0, iobuf, xdata); out: return 0; } /** * Write to file created in trash directory */ int32_t trash_truncate_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { trash_local_t *local = NULL; local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); if (op_ret == -1) { /* Let truncate work, but previous copy is not preserved. */ gf_log(this->name, GF_LOG_DEBUG, "writev on the existing file failed: %s", strerror(op_errno)); STACK_WIND(frame, trash_truncate_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &local->newloc, 0, xdata); goto out; } if (local->cur_offset < local->fsize) { local->cur_offset += GF_BLOCK_READV_SIZE; /* Loop back and Read the contents again. */ STACK_WIND(frame, trash_truncate_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, local->fd, (size_t)GF_BLOCK_READV_SIZE, local->cur_offset, 0, xdata); goto out; } /* OOFH.....Finally calling Truncate. */ STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &local->loc, local->fop_offset, xdata); out: return 0; } /** * The source file is opened for reading and writing */ int32_t trash_truncate_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { trash_local_t *local = NULL; local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); if (op_ret == -1) { /* Let truncate work, but previous copy is not preserved. */ gf_log(this->name, GF_LOG_DEBUG, "open on the existing file failed: %s", strerror(op_errno)); STACK_WIND(frame, trash_truncate_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, &local->newloc, 0, xdata); goto out; } fd_bind(fd); local->cur_offset = 0; STACK_WIND(frame, trash_truncate_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, local->fd, (size_t)GF_BLOCK_READV_SIZE, local->cur_offset, 0, xdata); out: return 0; } /** * Creates new file descriptor for read and write operations, * if the path is present in trash directory */ int32_t trash_truncate_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { trash_local_t *local = NULL; char *tmp_str = NULL; char *dir_name = NULL; char *tmp_path = NULL; int32_t flags = 0; loc_t tmp_loc = { 0, }; char *tmp_stat = NULL; char real_path[PATH_MAX] = { 0, }; trash_private_t *priv = NULL; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); TRASH_UNSET_PID(frame, local); /* Checks whether path is present in trash directory or not */ if ((op_ret == -1) && (op_errno == ENOENT)) { /* Creating the directory structure here. */ tmp_str = gf_strdup(local->newpath); if (!tmp_str) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } dir_name = dirname(tmp_str); tmp_path = gf_strdup(dir_name); if (!tmp_path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } loc_copy(&tmp_loc, &local->newloc); tmp_loc.path = gf_strdup(tmp_path); if (!tmp_loc.path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } strncpy(real_path, priv->brick_path, sizeof(real_path)); real_path[sizeof(real_path) - 1] = 0; remove_trash_path(tmp_path, (frame->root->pid < 0), &tmp_stat); if (tmp_stat) strncat(real_path, tmp_stat, sizeof(real_path) - strlen(real_path) - 1); TRASH_SET_PID(frame, local); /* create the directory with proper permissions */ STACK_WIND_COOKIE(frame, trash_truncate_mkdir_cbk, tmp_path, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, &tmp_loc, get_permission(real_path), 0022, xdata); loc_wipe(&tmp_loc); goto out; } if (op_ret == -1) { /* Let truncate work, but previous copy is not preserved. * Deleting the newly created copy. */ gf_log(this->name, GF_LOG_DEBUG, "creation of new file in trash-dir failed, " "when truncate was called: %s", strerror(op_errno)); STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &local->loc, local->fop_offset, xdata); goto out; } fd_bind(fd); flags = O_RDONLY; /* fd which represents source file for reading and writing from it */ local->fd = fd_create(local->loc.inode, frame->root->pid); STACK_WIND(frame, trash_truncate_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, &local->loc, flags, local->fd, 0); out: if (tmp_str) GF_FREE(tmp_str); if (tmp_path) GF_FREE(tmp_path); return 0; } /** * If the path is not present in the trash directory,it will recursively call * this call-back and one by one directories will be created from the * beginning */ int32_t trash_truncate_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { trash_local_t *local = NULL; trash_private_t *priv = NULL; char *tmp_str = NULL; char *tmp_path = NULL; char *tmp_dirname = NULL; char *dir_name = NULL; char *tmp_stat = NULL; char real_path[PATH_MAX] = { 0, }; size_t count = 0; int32_t flags = 0; int32_t loop_count = 0; int i = 0; loc_t tmp_loc = { 0, }; int ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); loop_count = local->loop_count; TRASH_UNSET_PID(frame, local); tmp_str = gf_strdup(local->newpath); if (!tmp_str) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } if ((op_ret == -1) && (op_errno == ENOENT)) { tmp_dirname = strchr(tmp_str, '/'); while (tmp_dirname) { count = tmp_dirname - tmp_str; if (count == 0) count = 1; i++; if (i > loop_count) break; tmp_dirname = strchr(tmp_str + count + 1, '/'); } tmp_path = gf_memdup(local->newpath, count + 1); if (!tmp_path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } tmp_path[count] = '\0'; loc_copy(&tmp_loc, &local->newloc); tmp_loc.path = gf_strdup(tmp_path); if (!tmp_loc.path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } /* Stores the the name of directory to be created */ tmp_loc.name = gf_strdup(strrchr(tmp_path, '/') + 1); if (!tmp_loc.name) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } strncpy(real_path, priv->brick_path, sizeof(real_path)); real_path[sizeof(real_path) - 1] = 0; remove_trash_path(tmp_path, (frame->root->pid < 0), &tmp_stat); if (tmp_stat) strncat(real_path, tmp_stat, sizeof(real_path) - strlen(real_path) - 1); TRASH_SET_PID(frame, local); STACK_WIND_COOKIE(frame, trash_truncate_mkdir_cbk, tmp_path, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, &tmp_loc, get_permission(real_path), 0022, xdata); loc_wipe(&tmp_loc); goto out; } if (op_ret == 0) { dir_name = dirname(tmp_str); if (strcmp((char *)cookie, dir_name) == 0) { flags = O_CREAT | O_EXCL | O_WRONLY; strncpy(real_path, priv->brick_path, sizeof(real_path)); real_path[sizeof(real_path) - 1] = 0; strncat(real_path, local->origpath, sizeof(real_path) - strlen(real_path) - 1); real_path[sizeof(real_path) - 1] = 0; /* Call create again once directory structure is created. */ TRASH_SET_PID(frame, local); STACK_WIND(frame, trash_truncate_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, &local->newloc, flags, get_permission(real_path), 0022, local->newfd, xdata); goto out; } } if ((op_ret == -1) && (op_errno != EEXIST)) { gf_log(this->name, GF_LOG_ERROR, "Directory creation failed [%s]. " "Therefore truncating %s without moving the " "original copy to trash directory", strerror(op_errno), local->loc.name); STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &local->loc, local->fop_offset, xdata); goto out; } LOCK(&frame->lock); { loop_count = ++local->loop_count; } UNLOCK(&frame->lock); tmp_dirname = strchr(tmp_str, '/'); while (tmp_dirname) { count = tmp_dirname - tmp_str; if (count == 0) count = 1; i++; if (i > loop_count) break; tmp_dirname = strchr(tmp_str + count + 1, '/'); } tmp_path = gf_memdup(local->newpath, count + 1); if (!tmp_path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } tmp_path[count] = '\0'; loc_copy(&tmp_loc, &local->newloc); tmp_loc.path = gf_strdup(tmp_path); if (!tmp_loc.path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } /* Stores the the name of directory to be created */ tmp_loc.name = gf_strdup(strrchr(tmp_path, '/') + 1); if (!tmp_loc.name) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } strncpy(real_path, priv->brick_path, sizeof(real_path)); real_path[sizeof(real_path) - 1] = 0; remove_trash_path(tmp_path, (frame->root->pid < 0), &tmp_stat); if (tmp_stat) strncat(real_path, tmp_stat, sizeof(real_path) - strlen(real_path) - 1); TRASH_SET_PID(frame, local); STACK_WIND_COOKIE(frame, trash_truncate_mkdir_cbk, tmp_path, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, &tmp_loc, get_permission(real_path), 0022, xdata); out: if (tmp_str) GF_FREE(tmp_str); if (tmp_path) GF_FREE(tmp_path); return ret; } int32_t trash_truncate_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { trash_private_t *priv = NULL; trash_local_t *local = NULL; char loc_newname[PATH_MAX] = { 0, }; int32_t flags = 0; dentry_t *dir_entry = NULL; inode_table_t *table = NULL; int ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); local = frame->local; GF_VALIDATE_OR_GOTO("trash", local, out); table = local->loc.inode->table; pthread_mutex_lock(&table->lock); { dir_entry = __dentry_search_arbit(local->loc.inode); } pthread_mutex_unlock(&table->lock); if (op_ret == -1) { gf_log(this->name, GF_LOG_DEBUG, "fstat on the file failed: %s", strerror(op_errno)); TRASH_STACK_UNWIND(truncate, frame, op_ret, op_errno, buf, NULL, xdata); goto out; } /* Only last hardlink will be moved to trash directory */ if (buf->ia_nlink > 1) { STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &local->loc, local->fop_offset, xdata); goto out; } /** * If the file is too big or if it is extended truncate, * just don't move it to trash directory. */ if (buf->ia_size > (priv->max_trash_file_size) || buf->ia_size <= local->fop_offset) { gf_log(this->name, GF_LOG_DEBUG, "%s: file is too large to move to trash", local->loc.path); STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &local->loc, local->fop_offset, xdata); goto out; } /* Retrieves the name of file from path */ local->loc.name = gf_strdup(strrchr(local->loc.path, '/')); if (!local->loc.name) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } /* Stores new path for source file */ copy_trash_path(priv->newtrash_dir, (frame->root->pid < 0), local->newpath, sizeof(local->newpath)); strncat(local->newpath, local->loc.path, sizeof(local->newpath) - strlen(local->newpath) - 1); /* append timestamp to file name so that we can avoid name collisions inside trash */ append_time_stamp(local->newpath, sizeof(local->newpath)); if (strlen(local->newpath) > PATH_MAX) { STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &local->loc, local->fop_offset, xdata); goto out; } strncpy(loc_newname, local->loc.name, sizeof(loc_newname)); loc_newname[sizeof(loc_newname) - 1] = 0; append_time_stamp(loc_newname, sizeof(loc_newname)); /* local->newloc represents old file(file inside trash), where as local->loc represents truncated file. We need to create new inode and fd for new file*/ local->newloc.name = gf_strdup(loc_newname); if (!local->newloc.name) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } local->newloc.path = gf_strdup(local->newpath); if (!local->newloc.path) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } local->newloc.inode = inode_new(local->loc.inode->table); local->newfd = fd_create(local->newloc.inode, frame->root->pid); /* Creating valid parent and pargfids for both files */ if (dir_entry == NULL) { ret = EINVAL; goto out; } local->loc.parent = inode_ref(dir_entry->parent); gf_uuid_copy(local->loc.pargfid, dir_entry->parent->gfid); local->newloc.parent = inode_ref(dir_entry->parent); gf_uuid_copy(local->newloc.pargfid, dir_entry->parent->gfid); flags = O_CREAT | O_EXCL | O_WRONLY; TRASH_SET_PID(frame, local); STACK_WIND(frame, trash_truncate_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, &local->newloc, flags, st_mode_from_ia(buf->ia_prot, local->loc.inode->ia_type), 0022, local->newfd, xdata); out: return ret; } /** * Truncate can be explicitly called or implicitly by some other applications * like text editors etc.. */ int32_t trash_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { trash_private_t *priv = NULL; trash_local_t *local = NULL; char *pathbuf = NULL; int32_t ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); /* If trash is not active or not enabled through cli, then * we bypass and wind back */ if (!priv->state) { STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); goto out; } /* The files removed by gluster operations such as self-heal, should moved to trash directory, but files by client should not moved */ if ((frame->root->pid < 0) && !priv->internal) { STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); goto out; } /* This will be more accurate */ ret = check_pathbuf(loc->inode, this, &pathbuf, &local, loc->path); if (ret == 0) { /* Trying to truncate from the trash-dir. So do the * actual truncate without moving to trash-dir. */ STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); goto out; } else if (ret < 0) { TRASH_STACK_UNWIND(truncate, frame, -1, -ret, NULL, NULL, xdata); goto out; } strncpy(local->origpath, pathbuf, sizeof(local->origpath)); local->origpath[sizeof(local->origpath) - 1] = 0; loc_copy(&local->loc, loc); local->loc.path = pathbuf; local->fop_offset = offset; frame->local = local; STACK_WIND(frame, trash_truncate_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); out: return ret; } /** * When we call truncate from terminal it comes to ftruncate of trash-xlator. * Since truncate internally calls ftruncate and we receive fd of the file, * other than that it also called by Rebalance operation */ int32_t trash_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { trash_private_t *priv = NULL; trash_local_t *local = NULL; /* file inside trash */ char *pathbuf = NULL; /* path of file from fd */ int32_t ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); /* If trash is not active or not enabled through cli, then * we bypass and wind back */ if (!priv->state) { STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); goto out; } /* The files removed by gluster operations such as self-heal, * should moved to trash directory, but files by client * should not moved */ if ((frame->root->pid < 0) && !priv->internal) { STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); goto out; } /* This will be more accurate */ ret = check_pathbuf(fd->inode, this, &pathbuf, &local, pathbuf); if (ret == 0) { STACK_WIND(frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); goto out; } else if (ret < 0) { TRASH_STACK_UNWIND(ftruncate, frame, -1, -ret, NULL, NULL, xdata); goto out; } strncpy(local->origpath, pathbuf, sizeof(local->origpath)); local->origpath[sizeof(local->origpath) - 1] = 0; /* To convert fd to location */ frame->local = local; local->loc.path = pathbuf; local->loc.inode = inode_ref(fd->inode); gf_uuid_copy(local->loc.gfid, local->loc.inode->gfid); local->fop_offset = offset; /* Else remains same to truncate code, so from here flow goes * to truncate_stat */ STACK_WIND(frame, trash_truncate_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); out: return ret; } /** * The mkdir call is intercepted to avoid creation of * trash directory in the mount by the user */ int32_t trash_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { int32_t op_ret = 0; int32_t op_errno = 0; trash_private_t *priv = NULL; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); if (!check_whether_op_permitted(priv, loc)) { gf_log(this->name, GF_LOG_WARNING, "mkdir issued on %s, which is not permitted", priv->newtrash_dir); op_errno = EPERM; op_ret = -1; STACK_UNWIND_STRICT(mkdir, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, xdata); } else { STACK_WIND(frame, trash_common_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); } out: return 0; } /** * The rename call is intercepted to avoid renaming * of trash directory in the mount by the user */ int trash_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int32_t op_ret = 0; int32_t op_errno = 0; trash_private_t *priv = NULL; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); if (!check_whether_op_permitted(priv, oldloc)) { gf_log(this->name, GF_LOG_WARNING, "rename issued on %s, which is not permitted", priv->newtrash_dir); op_errno = EPERM; op_ret = -1; STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL, xdata); } else { STACK_WIND(frame, trash_common_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); } out: return 0; } /** * The rmdir call is intercepted to avoid deletion of * trash directory in the mount by the user */ int32_t trash_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { int32_t op_ret = 0; int32_t op_errno = 0; trash_private_t *priv = NULL; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); if (!check_whether_op_permitted(priv, loc)) { gf_log(this->name, GF_LOG_WARNING, "rmdir issued on %s, which is not permitted", priv->newtrash_dir); op_errno = EPERM; op_ret = -1; STACK_UNWIND_STRICT(rmdir, frame, op_ret, op_errno, NULL, NULL, xdata); } else { STACK_WIND(frame, trash_common_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); } out: return 0; } /** * Volume set option is handled by the reconfigure function. * Here we checks whether each option is set or not ,if it * sets then corresponding modifciations will be made */ int reconfigure(xlator_t *this, dict_t *options) { uint64_t max_fsize = 0; int ret = 0; char *tmp = NULL; char *tmp_str = NULL; trash_private_t *priv = NULL; char trash_dir[PATH_MAX] = { 0, }; gf_boolean_t active_earlier = _gf_false; gf_boolean_t active_now = _gf_false; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); active_earlier = priv->state; GF_OPTION_RECONF("trash", active_now, options, bool, out); /* Disable of trash feature is not allowed at this point until we are not able to find an approach to cleanup resource gracefully. Here to disable the feature need to destroy inode table and currently it is difficult to ensure inode is not being used */ if (active_earlier && !active_now) { gf_log(this->name, GF_LOG_INFO, "Disable of trash feature is not allowed " "during graph reconfigure"); ret = 0; goto out; } if (!active_earlier && active_now) { if (!priv->trash_itable) { priv->trash_itable = inode_table_new(0, this, 0, 0); if (!priv->trash_itable) { ret = -ENOMEM; gf_log(this->name, GF_LOG_ERROR, "failed to create trash inode_table" " during graph reconfigure"); goto out; } } priv->state = active_now; } GF_OPTION_RECONF("trash-internal-op", priv->internal, options, bool, out); GF_OPTION_RECONF("trash-dir", tmp, options, str, out); if (priv->state) { ret = create_or_rename_trash_directory(this); if (tmp) sprintf(trash_dir, "/%s/", tmp); else sprintf(trash_dir, "%s", priv->oldtrash_dir); if (strcmp(priv->newtrash_dir, trash_dir) != 0) { /* When user set a new name for trash directory, trash * xlator will perform a rename operation on old trash * directory to the new one using a STACK_WIND from here. * This option can be configured only when volume is in * started state */ GF_FREE(priv->newtrash_dir); priv->newtrash_dir = gf_strdup(trash_dir); if (!priv->newtrash_dir) { ret = ENOMEM; gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } gf_log(this->name, GF_LOG_DEBUG, "Renaming %s -> %s from reconfigure", priv->oldtrash_dir, priv->newtrash_dir); if (!priv->newtrash_dir) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } ret = rename_trash_directory(this); } if (priv->internal) { ret = create_internalop_directory(this); } } tmp = NULL; GF_OPTION_RECONF("trash-max-filesize", max_fsize, options, size_uint64, out); if (max_fsize) { priv->max_trash_file_size = max_fsize; gf_log(this->name, GF_LOG_DEBUG, "%" PRIu64 " max-size", priv->max_trash_file_size); } GF_OPTION_RECONF("trash-eliminate-path", tmp, options, str, out); if (!tmp) { gf_log(this->name, GF_LOG_DEBUG, "no option specified for 'eliminate', using NULL"); } else { if (priv->eliminate) wipe_eliminate_path(&priv->eliminate); tmp_str = gf_strdup(tmp); if (!tmp_str) { gf_log(this->name, GF_LOG_DEBUG, "out of memory"); ret = ENOMEM; goto out; } ret = store_eliminate_path(tmp_str, &priv->eliminate); } out: return ret; } /** * Notify is used to create the trash directory with fixed gfid * using STACK_WIND only when posix xlator is up */ int notify(xlator_t *this, int event, void *data, ...) { trash_private_t *priv = NULL; int ret = 0; priv = this->private; GF_VALIDATE_OR_GOTO("trash", priv, out); /* Check whether posix is up not */ if (event == GF_EVENT_CHILD_UP) { if (!priv->state) { gf_log(this->name, GF_LOG_DEBUG, "trash xlator is off"); goto out; } /* Here there is two possibilities ,if trash directory already * exist ,then we need to perform a rename operation on the * old one. Otherwise, we need to create the trash directory * For both, we need to pass location variable, gfid of parent * and a frame for calling STACK_WIND.The location variable * requires name,path,gfid and inode */ if (!priv->oldtrash_dir) ret = create_or_rename_trash_directory(this); else if (strcmp(priv->newtrash_dir, priv->oldtrash_dir) != 0) ret = rename_trash_directory(this); if (ret) goto out; if (priv->internal) (void)create_internalop_directory(this); } out: ret = default_notify(this, event, data); if (ret) gf_log(this->name, GF_LOG_INFO, "default notify event failed"); return ret; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; GF_VALIDATE_OR_GOTO("trash", this, out); ret = xlator_mem_acct_init(this, gf_trash_mt_end); if (ret != 0) { gf_log(this->name, GF_LOG_ERROR, "Memory accounting init" "failed"); return ret; } out: return ret; } /** * trash_init */ int32_t init(xlator_t *this) { trash_private_t *priv = NULL; int ret = -1; char *tmp = NULL; char *tmp_str = NULL; char trash_dir[PATH_MAX] = { 0, }; uint64_t max_trash_file_size64 = 0; data_t *data = NULL; GF_VALIDATE_OR_GOTO("trash", this, out); if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "not configured with exactly one child. exiting"); ret = -1; goto out; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile"); } priv = GF_CALLOC(1, sizeof(*priv), gf_trash_mt_trash_private_t); if (!priv) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = ENOMEM; goto out; } /* Trash priv data members are initialized through the following * set of statements */ GF_OPTION_INIT("trash", priv->state, bool, out); GF_OPTION_INIT("trash-dir", tmp, str, out); /* We store trash dir value as path for easier manipulation*/ if (!tmp) { gf_log(this->name, GF_LOG_INFO, "no option specified for 'trash-dir', " "using \"/.trashcan/\""); priv->newtrash_dir = gf_strdup("/.trashcan/"); if (!priv->newtrash_dir) { ret = ENOMEM; gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } } else { sprintf(trash_dir, "/%s/", tmp); priv->newtrash_dir = gf_strdup(trash_dir); if (!priv->newtrash_dir) { ret = ENOMEM; gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } } tmp = NULL; GF_OPTION_INIT("trash-eliminate-path", tmp, str, out); if (!tmp) { gf_log(this->name, GF_LOG_INFO, "no option specified for 'eliminate', using NULL"); } else { tmp_str = gf_strdup(tmp); if (!tmp_str) { gf_log(this->name, GF_LOG_ERROR, "out of memory"); ret = ENOMEM; goto out; } ret = store_eliminate_path(tmp_str, &priv->eliminate); } tmp = NULL; GF_OPTION_INIT("trash-max-filesize", max_trash_file_size64, size_uint64, out); if (!max_trash_file_size64) { gf_log(this->name, GF_LOG_ERROR, "no option specified for 'max-trashable-file-size', " "using default = %lld MB", GF_DEFAULT_MAX_FILE_SIZE / GF_UNIT_MB); priv->max_trash_file_size = GF_DEFAULT_MAX_FILE_SIZE; } else { priv->max_trash_file_size = max_trash_file_size64; gf_log(this->name, GF_LOG_DEBUG, "%" PRIu64 " max-size", priv->max_trash_file_size); } GF_OPTION_INIT("trash-internal-op", priv->internal, bool, out); this->local_pool = mem_pool_new(trash_local_t, 64); if (!this->local_pool) { gf_log(this->name, GF_LOG_ERROR, "failed to create local_t's memory pool"); ret = ENOMEM; goto out; } /* For creating directories inside trash with proper permissions, * we need to perform stat on that directories, for this we use * brick path */ data = dict_get(this->options, "brick-path"); if (!data) { gf_log(this->name, GF_LOG_ERROR, "no option specified for 'brick-path'"); ret = ENOMEM; goto out; } priv->brick_path = gf_strdup(data->data); if (!priv->brick_path) { ret = ENOMEM; gf_log(this->name, GF_LOG_DEBUG, "out of memory"); goto out; } if (priv->state) { priv->trash_itable = inode_table_new(0, this, 0, 0); if (!priv->trash_itable) { ret = -ENOMEM; priv->state = _gf_false; gf_log(this->name, GF_LOG_ERROR, "failed to create trash inode_table disable trash"); goto out; } } gf_log(this->name, GF_LOG_DEBUG, "brick path is%s", priv->brick_path); this->private = (void *)priv; ret = 0; out: if (tmp_str) GF_FREE(tmp_str); if (ret) { if (priv) { if (priv->newtrash_dir) GF_FREE(priv->newtrash_dir); if (priv->oldtrash_dir) GF_FREE(priv->oldtrash_dir); if (priv->brick_path) GF_FREE(priv->brick_path); if (priv->eliminate) wipe_eliminate_path(&priv->eliminate); GF_FREE(priv); } mem_pool_destroy(this->local_pool); this->local_pool = NULL; } return ret; } /** * trash_fini */ void fini(xlator_t *this) { trash_private_t *priv = NULL; inode_table_t *inode_table = NULL; GF_VALIDATE_OR_GOTO("trash", this, out); priv = this->private; if (priv) { inode_table = priv->trash_itable; if (priv->newtrash_dir) { GF_FREE(priv->newtrash_dir); priv->newtrash_dir = NULL; } if (priv->oldtrash_dir) { GF_FREE(priv->oldtrash_dir); priv->oldtrash_dir = NULL; } if (priv->brick_path) { GF_FREE(priv->brick_path); priv->brick_path = NULL; } if (priv->eliminate) { wipe_eliminate_path(&priv->eliminate); priv->eliminate = NULL; } if (inode_table) { inode_table_destroy(inode_table); priv->trash_itable = NULL; } GF_FREE(priv); } if (this->local_pool) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; } this->private = NULL; out: return; } struct xlator_fops fops = { .unlink = trash_unlink, .truncate = trash_truncate, .ftruncate = trash_ftruncate, .rmdir = trash_rmdir, .mkdir = trash_mkdir, .rename = trash_rename, }; struct xlator_cbks cbks = {}; struct volume_options options[] = { { .key = {"trash"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "Enable/disable trash translator", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"backup"}, }, { .key = {"trash-dir"}, .type = GF_OPTION_TYPE_STR, .default_value = ".trashcan", .description = "Directory for trash files", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"backup"}, }, { .key = {"trash-eliminate-path"}, .type = GF_OPTION_TYPE_STR, .description = "Eliminate paths to be excluded " "from trashing", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"backup"}, }, { .key = {"trash-max-filesize"}, .type = GF_OPTION_TYPE_SIZET, .default_value = "5MB", .description = "Maximum size of file that can be " "moved to trash", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"backup"}, }, { .key = {"trash-internal-op"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "Enable/disable trash translator for " "internal operations", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"backup"}, }, {.key = {"brick-path"}, .type = GF_OPTION_TYPE_PATH, .default_value = "{{ brick.path }}"}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "trash", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/features/trash/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202465023064 xustar000000000000000029 mtime=1699284277.49906307 30 atime=1699284290.822103199 30 ctime=1699284304.754145161 glusterfs-11.1/xlators/features/trash/Makefile.in0000664000175100017510000005272114522202465023353 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/trash DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/trash/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/trash/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/trash/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023047 xustar000000000000000030 mtime=1699284265.695027516 30 atime=1699284277.475062998 30 ctime=1699284304.756145167 glusterfs-11.1/xlators/features/trash/Makefile.am0000664000175100017510000000003514522202451023324 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/Makefile.in0000644000000000000000000000013014522202463021740 xustar000000000000000030 mtime=1699284275.119055902 29 atime=1699284290.04210085 29 ctime=1699284303.19014045 glusterfs-11.1/xlators/features/Makefile.in0000664000175100017510000005377214522202463022237 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = locks quota read-only quiesce marker index barrier \ arbiter upcall compress changelog gfid-access snapview-client \ snapview-server trash shard bit-rot leases selinux sdfs \ namespace cloudsync thin-arbiter utime metadisp simple-quota DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @BUILD_CLOUDSYNC_TRUE@CLOUDSYNC_DIR = cloudsync @BUILD_METADISP_TRUE@METADISP_DIR = metadisp SUBDIRS = locks quota read-only quiesce marker index barrier arbiter upcall \ compress changelog gfid-access snapview-client snapview-server trash \ shard bit-rot leases selinux sdfs namespace $(CLOUDSYNC_DIR) thin-arbiter \ utime $(METADISP_DIR) simple-quota CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/PaxHeaders.9031/quota0000644000000000000000000000013014522202517020747 xustar000000000000000029 mtime=1699284303.34614092 30 atime=1699284309.687160019 29 ctime=1699284303.34614092 glusterfs-11.1/xlators/features/quota/0002775000175100017510000000000014522202517021307 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/quota/PaxHeaders.9031/src0000644000000000000000000000013214522202517021540 xustar000000000000000030 mtime=1699284303.408141107 30 atime=1699284309.687160019 30 ctime=1699284303.408141107 glusterfs-11.1/xlators/features/quota/src/0002775000175100017510000000000014522202517022076 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quota.c0000644000000000000000000000013114522202451023106 xustar000000000000000030 mtime=1699284265.684027483 29 atime=1699284265.68302748 30 ctime=1699284303.400141083 glusterfs-11.1/xlators/features/quota/src/quota.c0000664000175100017510000043026014522202451023373 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "quota.h" #include #include "quota-messages.h" #include struct volume_options options[]; static int32_t __quota_init_inode_ctx(inode_t *inode, xlator_t *this, quota_inode_ctx_t **context) { int32_t ret = -1; quota_inode_ctx_t *ctx = NULL; if (inode == NULL) { goto out; } QUOTA_ALLOC_OR_GOTO(ctx, quota_inode_ctx_t, out); LOCK_INIT(&ctx->lock); if (context != NULL) { *context = ctx; } INIT_LIST_HEAD(&ctx->parents); ret = __inode_ctx_put(inode, this, (uint64_t)(long)ctx); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_SET_FAILED, "cannot set quota context " "in inode (gfid:%s)", uuid_utoa(inode->gfid)); GF_FREE(ctx); } out: return ret; } static int32_t quota_inode_ctx_get(inode_t *inode, xlator_t *this, quota_inode_ctx_t **ctx, char create_if_absent) { int32_t ret = 0; uint64_t ctx_int; LOCK(&inode->lock); { ret = __inode_ctx_get(inode, this, &ctx_int); if ((ret == 0) && (ctx != NULL)) { *ctx = (quota_inode_ctx_t *)(unsigned long)ctx_int; } else if (create_if_absent) { ret = __quota_init_inode_ctx(inode, this, ctx); } } UNLOCK(&inode->lock); return ret; } int quota_loc_fill(loc_t *loc, inode_t *inode, inode_t *parent, char *path) { int ret = -1; if (!loc || (inode == NULL)) return ret; if (inode) { loc->inode = inode_ref(inode); gf_uuid_copy(loc->gfid, inode->gfid); } if (parent) { loc->parent = inode_ref(parent); } if (path != NULL) { loc->path = gf_strdup(path); loc->name = strrchr(loc->path, '/'); if (loc->name) { loc->name++; } } ret = 0; return ret; } int quota_inode_loc_fill(inode_t *inode, loc_t *loc) { char *resolvedpath = NULL; inode_t *parent = NULL; int ret = -1; xlator_t *this = NULL; if ((!inode) || (!loc)) { return ret; } this = THIS; if ((inode) && __is_root_gfid(inode->gfid)) { loc->parent = NULL; goto ignore_parent; } parent = inode_parent(inode, 0, NULL); if (!parent) { gf_msg_debug(this->name, 0, "cannot find parent for " "inode (gfid:%s)", uuid_utoa(inode->gfid)); } ignore_parent: ret = inode_path(inode, NULL, &resolvedpath); if (ret < 0) { gf_msg_debug(this->name, 0, "cannot construct path for " "inode (gfid:%s)", uuid_utoa(inode->gfid)); } ret = quota_loc_fill(loc, inode, parent, resolvedpath); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "cannot fill loc"); goto err; } err: if (parent) { inode_unref(parent); } GF_FREE(resolvedpath); return ret; } int32_t quota_local_cleanup(quota_local_t *local) { if (local == NULL) { goto out; } loc_wipe(&local->loc); loc_wipe(&local->newloc); loc_wipe(&local->oldloc); loc_wipe(&local->validate_loc); inode_unref(local->inode); if (local->xdata) dict_unref(local->xdata); if (local->validate_xdata) dict_unref(local->validate_xdata); if (local->stub) call_stub_destroy(local->stub); LOCK_DESTROY(&local->lock); mem_put(local); out: return 0; } static quota_local_t * quota_local_new(void) { quota_local_t *local = NULL; local = mem_get0(THIS->local_pool); if (local == NULL) goto out; LOCK_INIT(&local->lock); local->space_available = -1; out: return local; } quota_dentry_t * __quota_dentry_new(quota_inode_ctx_t *ctx, char *name, uuid_t par) { quota_dentry_t *dentry = NULL; GF_UNUSED int32_t ret = 0; QUOTA_ALLOC_OR_GOTO(dentry, quota_dentry_t, err); INIT_LIST_HEAD(&dentry->next); dentry->name = gf_strdup(name); if (dentry->name == NULL) { GF_FREE(dentry); dentry = NULL; goto err; } gf_uuid_copy(dentry->par, par); if (ctx != NULL) list_add_tail(&dentry->next, &ctx->parents); err: return dentry; } void __quota_dentry_free(quota_dentry_t *dentry) { if (dentry == NULL) { goto out; } list_del_init(&dentry->next); GF_FREE(dentry->name); GF_FREE(dentry); out: return; } void __quota_dentry_del(quota_inode_ctx_t *ctx, const char *name, uuid_t par) { quota_dentry_t *dentry = NULL; quota_dentry_t *tmp = NULL; list_for_each_entry_safe(dentry, tmp, &ctx->parents, next) { if ((strcmp(dentry->name, name) == 0) && (gf_uuid_compare(dentry->par, par) == 0)) { __quota_dentry_free(dentry); break; } } } void quota_dentry_del(quota_inode_ctx_t *ctx, const char *name, uuid_t par) { LOCK(&ctx->lock); { __quota_dentry_del(ctx, name, par); } UNLOCK(&ctx->lock); } static inode_t * __quota_inode_parent(inode_t *inode, uuid_t pargfid, const char *name) { inode_t *parent = NULL; parent = inode_parent(inode, pargfid, name); inode_unref(inode); return parent; } static inode_t * quota_inode_parent(inode_t *inode, uuid_t pargfid, const char *name) { inode_t *parent = NULL; parent = __quota_inode_parent(inode, pargfid, name); if (!parent) gf_msg_callingfn(THIS->name, GF_LOG_ERROR, 0, Q_MSG_PARENT_NULL, "Failed to find " "ancestor for inode (%s)", uuid_utoa(inode->gfid)); return parent; } int32_t quota_inode_depth(inode_t *inode) { int depth = 0; inode_t *cur_inode = NULL; cur_inode = inode_ref(inode); while (cur_inode && !__is_root_gfid(cur_inode->gfid)) { depth++; cur_inode = quota_inode_parent(cur_inode, 0, NULL); if (!cur_inode) depth = -1; } if (cur_inode) inode_unref(cur_inode); return depth; } int32_t quota_find_common_ancestor(inode_t *inode1, inode_t *inode2, uuid_t *common_ancestor) { int32_t depth1 = 0; int32_t depth2 = 0; int32_t ret = -1; inode_t *cur_inode1 = NULL; inode_t *cur_inode2 = NULL; depth1 = quota_inode_depth(inode1); if (depth1 < 0) goto out; depth2 = quota_inode_depth(inode2); if (depth2 < 0) goto out; cur_inode1 = inode_ref(inode1); cur_inode2 = inode_ref(inode2); while (cur_inode1 && depth1 > depth2) { cur_inode1 = quota_inode_parent(cur_inode1, 0, NULL); depth1--; } while (cur_inode2 && depth2 > depth1) { cur_inode2 = quota_inode_parent(cur_inode2, 0, NULL); depth2--; } while (depth1 && cur_inode1 && cur_inode2 && cur_inode1 != cur_inode2) { cur_inode1 = quota_inode_parent(cur_inode1, 0, NULL); cur_inode2 = quota_inode_parent(cur_inode2, 0, NULL); depth1--; } if (cur_inode1 && cur_inode2) { gf_uuid_copy(*common_ancestor, cur_inode1->gfid); ret = 0; } out: if (cur_inode1) inode_unref(cur_inode1); if (cur_inode2) inode_unref(cur_inode2); return ret; } void check_ancestory_continue(struct list_head *parents, inode_t *inode, int32_t op_ret, int32_t op_errno, void *data) { call_frame_t *frame = NULL; quota_local_t *local = NULL; uint32_t link_count = 0; frame = data; local = frame->local; if (parents && list_empty(parents)) { gf_msg(THIS->name, GF_LOG_WARNING, EIO, Q_MSG_ANCESTRY_BUILD_FAILED, "Couldn't build ancestry for inode (gfid:%s). " "Without knowing ancestors till root, quota " "cannot be enforced. " "Hence, failing fop with EIO", uuid_utoa(inode->gfid)); op_errno = EIO; op_ret = -1; } LOCK(&local->lock); { link_count = --local->link_count; if (op_ret < 0) { local->op_ret = op_ret; local->op_errno = op_errno; } } UNLOCK(&local->lock); if (link_count == 0) local->fop_continue_cbk(frame); } void check_ancestory(call_frame_t *frame, inode_t *inode) { inode_t *cur_inode = NULL; inode_t *parent = NULL; cur_inode = inode_ref(inode); while (cur_inode && !__is_root_gfid(cur_inode->gfid)) { parent = inode_parent(cur_inode, 0, NULL); if (!parent) { quota_build_ancestry(cur_inode, check_ancestory_continue, frame); inode_unref(cur_inode); return; } inode_unref(cur_inode); cur_inode = parent; } if (cur_inode) { inode_unref(cur_inode); check_ancestory_continue(NULL, NULL, 0, 0, frame); } else { check_ancestory_continue(NULL, NULL, -1, ESTALE, frame); } } void check_ancestory_2_cbk(struct list_head *parents, inode_t *inode, int32_t op_ret, int32_t op_errno, void *data) { inode_t *this_inode = NULL; quota_inode_ctx_t *ctx = NULL; this_inode = data; if (op_ret < 0) goto out; if (parents == NULL || list_empty(parents)) { gf_msg(THIS->name, GF_LOG_WARNING, 0, Q_MSG_ENFORCEMENT_FAILED, "Couldn't build ancestry for inode (gfid:%s). " "Without knowing ancestors till root, quota " "cannot be enforced.", uuid_utoa(this_inode->gfid)); goto out; } quota_inode_ctx_get(this_inode, THIS, &ctx, 0); if (ctx) ctx->ancestry_built = _gf_true; out: inode_unref(this_inode); } void check_ancestory_2(xlator_t *this, quota_local_t *local, inode_t *inode) { inode_t *cur_inode = NULL; inode_t *parent = NULL; quota_inode_ctx_t *ctx = NULL; char *name = NULL; uuid_t pgfid = {0}; name = (char *)local->loc.name; if (local->loc.parent) { gf_uuid_copy(pgfid, local->loc.parent->gfid); } cur_inode = inode_ref(inode); while (cur_inode && !__is_root_gfid(cur_inode->gfid)) { quota_inode_ctx_get(cur_inode, this, &ctx, 0); /* build ancestry is required only on the first lookup, * so stop crawling when the inode_ctx is set for an inode */ if (ctx && ctx->ancestry_built) goto setctx; parent = inode_parent(cur_inode, pgfid, name); if (!parent) { quota_build_ancestry(cur_inode, check_ancestory_2_cbk, inode_ref(inode)); goto out; } if (name != NULL) { name = NULL; gf_uuid_clear(pgfid); } inode_unref(cur_inode); cur_inode = parent; } setctx: if (cur_inode && cur_inode != inode) { quota_inode_ctx_get(inode, this, &ctx, 0); if (ctx) ctx->ancestry_built = _gf_true; } out: if (cur_inode) inode_unref(cur_inode); } static void quota_link_count_decrement(call_frame_t *frame) { call_frame_t *tmpframe = NULL; quota_local_t *local = NULL; call_stub_t *stub = NULL; int link_count = -1; local = frame->local; if (local && local->par_frame) { local = local->par_frame->local; tmpframe = frame; } if (local == NULL) goto out; LOCK(&local->lock); { link_count = --local->link_count; if (link_count == 0) { stub = local->stub; local->stub = NULL; } } UNLOCK(&local->lock); if (stub != NULL) { call_resume(stub); } out: if (tmpframe) { local = tmpframe->local; tmpframe->local = NULL; STACK_DESTROY(frame->root); if (local) quota_local_cleanup(local); } return; } static void quota_handle_validate_error(call_frame_t *frame, int32_t op_ret, int32_t op_errno) { quota_local_t *local; local = frame->local; if (local && local->par_frame) local = local->par_frame->local; if (local == NULL) goto out; if (op_ret < 0) { LOCK(&local->lock); { local->op_ret = op_ret; local->op_errno = op_errno; } UNLOCK(&local->lock); } /* we abort checking limits on this path to root */ quota_link_count_decrement(frame); out: return; } int32_t quota_validate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { quota_local_t *local = NULL; int32_t ret = 0; quota_inode_ctx_t *ctx = NULL; uint64_t value = 0; quota_meta_t size = { 0, }; local = frame->local; if (op_ret < 0) { goto unwind; } GF_ASSERT(local); GF_ASSERT(frame); GF_VALIDATE_OR_GOTO_WITH_ERROR("quota", this, unwind, op_errno, EINVAL); GF_VALIDATE_OR_GOTO_WITH_ERROR(this->name, xdata, unwind, op_errno, EINVAL); ret = inode_ctx_get(local->validate_loc.inode, this, &value); ctx = (quota_inode_ctx_t *)(unsigned long)value; if ((ret == -1) || (ctx == NULL)) { gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_INODE_CTX_GET_FAILED, "quota context is" " not present in inode (gfid:%s)", uuid_utoa(local->validate_loc.inode->gfid)); op_errno = EINVAL; goto unwind; } ret = quota_dict_get_meta(xdata, QUOTA_SIZE_KEY, SLEN(QUOTA_SIZE_KEY), &size); if (ret == -1) { gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_SIZE_KEY_MISSING, "quota size key not present " "in dict"); op_errno = EINVAL; } local->just_validated = 1; /* so that we don't go into infinite * loop of validation and checking * limit when timeout is zero. */ LOCK(&ctx->lock); { ctx->size = size.size; ctx->validate_time = gf_time(); ctx->file_count = size.file_count; ctx->dir_count = size.dir_count; } UNLOCK(&ctx->lock); quota_check_limit(frame, local->validate_loc.inode, this); return 0; unwind: quota_handle_validate_error(frame, op_ret, op_errno); return 0; } static inline gf_boolean_t quota_timeout(time_t t, time_t timeout) { return (gf_time() - t) >= timeout; } /* Return: 1 if new entry added * 0 no entry added * -1 on errors */ static int32_t quota_add_parent(struct list_head *list, char *name, uuid_t pgfid) { quota_dentry_t *entry = NULL; gf_boolean_t found = _gf_false; int ret = 0; if (!list_empty(list)) { list_for_each_entry(entry, list, next) { if (gf_uuid_compare(pgfid, entry->par) == 0) { found = _gf_true; goto out; } } } entry = __quota_dentry_new(NULL, name, pgfid); if (entry) list_add_tail(&entry->next, list); else ret = -1; out: if (found) return 0; else if (ret == 0) return 1; else return -1; } /* This function iterates the parent list in inode * context and add unique parent to the list * Returns number of dentry added to the list, or -1 on errors */ static int32_t quota_add_parents_from_ctx(quota_inode_ctx_t *ctx, struct list_head *list) { int ret = 0; quota_dentry_t *dentry = NULL; int32_t count = 0; if (ctx == NULL || list == NULL) goto out; LOCK(&ctx->lock); { list_for_each_entry(dentry, &ctx->parents, next) { ret = quota_add_parent(list, dentry->name, dentry->par); if (ret == 1) count++; else if (ret == -1) break; } } UNLOCK(&ctx->lock); out: return (ret == -1) ? -1 : count; } int32_t quota_build_ancestry_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { inode_t *parent = NULL; inode_t *tmp_parent = NULL; inode_t *linked_inode = NULL; inode_t *tmp_inode = NULL; gf_dirent_t *entry = NULL; loc_t loc = { 0, }; quota_dentry_t *dentry = NULL; quota_dentry_t *tmp = NULL; quota_inode_ctx_t *ctx = NULL; struct list_head parents; quota_local_t *local = NULL; int ret; INIT_LIST_HEAD(&parents); local = frame->local; frame->local = NULL; if (op_ret < 0) goto err; if ((op_ret > 0) && (entries != NULL)) { list_for_each_entry(entry, &entries->list, list) { if (__is_root_gfid(entry->inode->gfid)) { /* The list contains a sub-list for each * possible path to the target inode. Each * sub-list starts with the root entry of the * tree and is followed by the child entries * for a particular path to the target entry. * The root entry is an implied sub-list * delimiter, as it denotes we have started * processing a new path. Reset the parent * pointer and continue */ tmp_parent = NULL; } else { /* For a non-root entry, link this inode */ linked_inode = inode_link(entry->inode, tmp_parent, entry->d_name, &entry->d_stat); if (linked_inode) { tmp_inode = entry->inode; entry->inode = linked_inode; inode_unref(tmp_inode); } else { gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_PARENT_NULL, "inode link failed"); op_errno = EINVAL; goto err; } } gf_uuid_copy(loc.gfid, entry->d_stat.ia_gfid); loc.inode = inode_ref(entry->inode); loc.parent = inode_ref(tmp_parent); loc.name = entry->d_name; quota_fill_inodectx(this, entry->inode, entry->dict, &loc, &entry->d_stat, &op_errno); /* For non-directory, posix_get_ancestry_non_directory * returns all hard-links that are represented by nodes * adjacent to each other in the dentry-list. * (Unlike the directory case where adjacent nodes * either have a parent/child relationship or belong to * different paths). */ if (entry->inode->ia_type == IA_IFDIR) tmp_parent = entry->inode; loc_wipe(&loc); } } parent = inode_parent(local->loc.inode, 0, NULL); if (parent == NULL) { gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_PARENT_NULL, "parent is NULL"); op_errno = EINVAL; goto err; } quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); ret = quota_add_parents_from_ctx(ctx, &parents); if (ret == -1) { op_errno = errno; goto err; } if (list_empty(&parents)) { /* we built ancestry for a directory */ list_for_each_entry(entry, &entries->list, list) { if (entry->inode == local->loc.inode) break; } /* Getting assertion here, need to investigate comment for now GF_ASSERT (&entry->list != &entries->list); */ ret = quota_add_parent(&parents, entry->d_name, parent->gfid); if (ret == -1) { op_errno = errno; goto err; } } local->ancestry_cbk(&parents, local->loc.inode, 0, 0, local->ancestry_data); goto cleanup; err: local->ancestry_cbk(NULL, NULL, -1, op_errno, local->ancestry_data); cleanup: STACK_DESTROY(frame->root); quota_local_cleanup(local); if (parent != NULL) { inode_unref(parent); parent = NULL; } if (!list_empty(&parents)) { list_for_each_entry_safe(dentry, tmp, &parents, next) { __quota_dentry_free(dentry); } } return 0; } int quota_build_ancestry(inode_t *inode, quota_ancestry_built_t ancestry_cbk, void *data) { fd_t *fd = NULL; quota_local_t *local = NULL; call_frame_t *new_frame = NULL; int op_errno = ENOMEM; int op_ret = -1; xlator_t *this = NULL; dict_t *xdata_req = NULL; this = THIS; xdata_req = dict_new(); if (xdata_req == NULL) goto err; fd = fd_anonymous(inode); if (fd == NULL) goto err; new_frame = create_frame(this, this->ctx->pool); if (new_frame == NULL) goto err; local = quota_local_new(); if (local == NULL) goto err; new_frame->root->uid = new_frame->root->gid = 0; new_frame->local = local; local->ancestry_cbk = ancestry_cbk; local->ancestry_data = data; local->loc.inode = inode_ref(inode); op_ret = dict_set_int8(xdata_req, QUOTA_LIMIT_KEY, 1); if (op_ret < 0) { op_errno = -op_ret; goto err; } op_ret = dict_set_int8(xdata_req, QUOTA_LIMIT_OBJECTS_KEY, 1); if (op_ret < 0) { op_errno = -op_ret; goto err; } op_ret = dict_set_int8(xdata_req, GET_ANCESTRY_DENTRY_KEY, 1); if (op_ret < 0) { op_errno = -op_ret; goto err; } /* This would ask posix layer to construct dentry chain till root * We don't need to do a opendir, we can use the anonymous fd * here for the readidrp. * avoiding opendir also reduces the window size where another FOP * can be executed before completion of build ancestry */ STACK_WIND(new_frame, quota_build_ancestry_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, 0, 0, xdata_req); op_ret = 0; err: if (fd) fd_unref(fd); if (xdata_req) dict_unref(xdata_req); if (op_ret < 0) { ancestry_cbk(NULL, NULL, -1, op_errno, data); if (new_frame) { local = new_frame->local; new_frame->local = NULL; STACK_DESTROY(new_frame->root); } if (local) quota_local_cleanup(local); } return 0; } int quota_validate(call_frame_t *frame, inode_t *inode, xlator_t *this, fop_lookup_cbk_t cbk_fn) { quota_local_t *local = NULL; int ret = 0; dict_t *xdata = NULL; quota_priv_t *priv = NULL; local = frame->local; priv = this->private; LOCK(&local->lock); { loc_wipe(&local->validate_loc); ret = quota_inode_loc_fill(inode, &local->validate_loc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENFORCEMENT_FAILED, "cannot fill loc for inode (gfid:%s), hence " "aborting quota-checks and continuing with fop", uuid_utoa(inode->gfid)); } } UNLOCK(&local->lock); if (ret < 0) { ret = -ENOMEM; goto err; } xdata = dict_new(); if (xdata == NULL) { ret = -ENOMEM; goto err; } ret = dict_set_int8(xdata, QUOTA_SIZE_KEY, 1); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "dict set failed"); ret = -ENOMEM; goto err; } ret = dict_set_str(xdata, "volume-uuid", priv->volume_uuid); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "dict set failed"); ret = -ENOMEM; goto err; } ret = quota_enforcer_lookup(frame, this, xdata, cbk_fn); if (ret < 0) { ret = -ENOTCONN; goto err; } ret = 0; err: if (xdata) dict_unref(xdata); return ret; } void quota_check_limit_continuation(struct list_head *parents, inode_t *inode, int32_t op_ret, int32_t op_errno, void *data) { call_frame_t *frame = NULL; xlator_t *this = NULL; quota_local_t *local = NULL; quota_local_t *par_local = NULL; quota_dentry_t *entry = NULL; inode_t *parent = NULL; int parent_count = 0; frame = data; local = frame->local; this = THIS; if (local->par_frame) par_local = local->par_frame->local; else par_local = local; if ((op_ret < 0) || list_empty(parents)) { if (op_ret >= 0) { gf_msg(this->name, GF_LOG_WARNING, EIO, Q_MSG_ANCESTRY_BUILD_FAILED, "Couldn't build ancestry for inode (gfid:%s). " "Without knowing ancestors till root, quota" "cannot be enforced. " "Hence, failing fop with EIO", uuid_utoa(inode->gfid)); op_errno = EIO; } quota_handle_validate_error(frame, -1, op_errno); goto out; } list_for_each_entry(entry, parents, next) { parent_count++; } LOCK(&par_local->lock); { par_local->link_count += (parent_count - 1); } UNLOCK(&par_local->lock); if (local->par_frame) { list_for_each_entry(entry, parents, next) { parent = inode_find(inode->table, entry->par); quota_check_limit(frame, parent, this); inode_unref(parent); } } else { list_for_each_entry(entry, parents, next) { parent = do_quota_check_limit(frame, inode, this, entry, _gf_true); if (parent) inode_unref(parent); else quota_link_count_decrement(frame); } } out: return; } int32_t quota_check_object_limit(call_frame_t *frame, quota_inode_ctx_t *ctx, quota_priv_t *priv, inode_t *_inode, xlator_t *this, int32_t *op_errno, int just_validated, quota_local_t *local, gf_boolean_t *skip_check) { int32_t ret = -1; uint32_t timeout = 0; char need_validate = 0; gf_boolean_t hard_limit_exceeded = 0; int64_t object_aggr_count = 0; GF_ASSERT(frame); GF_ASSERT(priv); GF_ASSERT(_inode); GF_ASSERT(this); GF_ASSERT(local); if (ctx != NULL && (ctx->object_hard_lim > 0 || ctx->object_soft_lim)) { LOCK(&ctx->lock); { timeout = priv->soft_timeout; object_aggr_count = ctx->file_count + ctx->dir_count + 1; if (((ctx->object_soft_lim >= 0) && (object_aggr_count) > ctx->object_soft_lim)) { timeout = priv->hard_timeout; } if (!just_validated && quota_timeout(ctx->validate_time, timeout)) { need_validate = 1; } else if ((object_aggr_count) > ctx->object_hard_lim) { hard_limit_exceeded = 1; } } UNLOCK(&ctx->lock); if (need_validate && *skip_check != _gf_true) { *skip_check = _gf_true; ret = quota_validate(frame, _inode, this, quota_validate_cbk); if (ret < 0) { *op_errno = -ret; *skip_check = _gf_false; } goto out; } if (hard_limit_exceeded) { local->op_ret = -1; local->op_errno = EDQUOT; *op_errno = EDQUOT; goto out; } /*We log usage only if quota limit is configured on that inode */ quota_log_usage(this, ctx, _inode, 0); } ret = 0; out: return ret; } int32_t quota_check_size_limit(call_frame_t *frame, quota_inode_ctx_t *ctx, quota_priv_t *priv, inode_t *_inode, xlator_t *this, int32_t *op_errno, int just_validated, int64_t delta, quota_local_t *local, gf_boolean_t *skip_check) { int32_t ret = -1; uint32_t timeout = 0; char need_validate = 0; gf_boolean_t hard_limit_exceeded = 0; int64_t space_available = 0; int64_t wouldbe_size = 0; GF_ASSERT(frame); GF_ASSERT(priv); GF_ASSERT(_inode); GF_ASSERT(this); GF_ASSERT(local); if (ctx != NULL && (ctx->hard_lim > 0 || ctx->soft_lim > 0)) { wouldbe_size = ctx->size + delta; LOCK(&ctx->lock); { timeout = priv->soft_timeout; if ((ctx->soft_lim >= 0) && (wouldbe_size > ctx->soft_lim)) { timeout = priv->hard_timeout; } if (!just_validated && quota_timeout(ctx->validate_time, timeout)) { need_validate = 1; } else if (wouldbe_size >= ctx->hard_lim) { hard_limit_exceeded = 1; } } UNLOCK(&ctx->lock); if (need_validate && *skip_check != _gf_true) { *skip_check = _gf_true; ret = quota_validate(frame, _inode, this, quota_validate_cbk); if (ret < 0) { *op_errno = -ret; *skip_check = _gf_false; } goto out; } if (hard_limit_exceeded) { local->op_ret = -1; local->op_errno = EDQUOT; space_available = ctx->hard_lim - ctx->size; if (space_available < 0) space_available = 0; if ((local->space_available < 0) || (local->space_available > space_available)) { local->space_available = space_available; } if (space_available == 0) { *op_errno = EDQUOT; goto out; } } /* We log usage only if quota limit is configured on that inode. */ quota_log_usage(this, ctx, _inode, delta); } ret = 0; out: return ret; } int32_t quota_check_limit(call_frame_t *frame, inode_t *inode, xlator_t *this) { int32_t ret = -1, op_errno = EINVAL; inode_t *_inode = NULL, *parent = NULL; quota_inode_ctx_t *ctx = NULL; quota_priv_t *priv = NULL; quota_local_t *local = NULL; quota_local_t *par_local = NULL; char just_validated = 0; int64_t delta = 0; int8_t object_delta = 0; uint64_t value = 0; gf_boolean_t skip_check = _gf_false; GF_VALIDATE_OR_GOTO("quota", this, err); GF_VALIDATE_OR_GOTO(this->name, frame, err); GF_VALIDATE_OR_GOTO(this->name, inode, err); local = frame->local; GF_VALIDATE_OR_GOTO(this->name, local, err); if (local->par_frame) { par_local = local->par_frame->local; GF_VALIDATE_OR_GOTO(this->name, par_local, err); } else { par_local = local; } delta = par_local->delta; object_delta = par_local->object_delta; GF_VALIDATE_OR_GOTO(this->name, par_local->stub, err); /* Allow all the trusted clients * Don't block the gluster internal processes like rebalance, gsyncd, * self heal etc from the disk quotas. * * Method: Allow all the clients with PID negative. This is by the * assumption that any kernel assigned pid doesn't have the negative * number. */ if (0 > frame->root->pid) { ret = 0; quota_link_count_decrement(frame); goto done; } priv = this->private; inode_ctx_get(inode, this, &value); ctx = (quota_inode_ctx_t *)(unsigned long)value; _inode = inode_ref(inode); LOCK(&local->lock); { just_validated = local->just_validated; local->just_validated = 0; } UNLOCK(&local->lock); do { /* In a rename operation, enforce should be stopped at common ancestor */ if (!gf_uuid_is_null(par_local->common_ancestor) && !gf_uuid_compare(_inode->gfid, par_local->common_ancestor)) { quota_link_count_decrement(frame); break; } if (object_delta <= 0) goto skip_check_object_limit; ret = quota_check_object_limit(frame, ctx, priv, _inode, this, &op_errno, just_validated, par_local, &skip_check); if (skip_check == _gf_true) goto done; if (ret) { if (op_errno != EDQUOT) gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_ENFORCEMENT_FAILED, "Failed to " "check quota object limit"); goto err; } skip_check_object_limit: ret = quota_check_size_limit(frame, ctx, priv, _inode, this, &op_errno, just_validated, delta, par_local, &skip_check); if (skip_check == _gf_true) goto done; if (ret) { if (op_errno != EDQUOT) gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_ENFORCEMENT_FAILED, "Failed to " "check quota size limit"); goto err; } if (__is_root_gfid(_inode->gfid)) { quota_link_count_decrement(frame); break; } parent = inode_parent(_inode, 0, NULL); if (parent == NULL) { ret = quota_build_ancestry(_inode, quota_check_limit_continuation, frame); if (ret < 0) { op_errno = -ret; goto err; } break; } inode_unref(_inode); _inode = parent; just_validated = 0; value = 0; inode_ctx_get(_inode, this, &value); ctx = (quota_inode_ctx_t *)(unsigned long)value; } while (1); done: if (_inode != NULL) { inode_unref(_inode); _inode = NULL; } return 0; err: quota_handle_validate_error(frame, -1, op_errno); inode_unref(_inode); return 0; } inode_t * do_quota_check_limit(call_frame_t *frame, inode_t *inode, xlator_t *this, quota_dentry_t *dentry, gf_boolean_t force) { int32_t ret = -1; inode_t *parent = NULL; call_frame_t *new_frame = NULL; quota_local_t *new_local = NULL; parent = inode_parent(inode, dentry->par, dentry->name); if (parent == NULL) { if (force) parent = inode_find(inode->table, dentry->par); else goto out; } if (parent == NULL) goto out; new_frame = copy_frame(frame); if (new_frame == NULL) goto out; new_local = quota_local_new(); if (new_local == NULL) goto out; new_frame->local = new_local; new_local->par_frame = frame; quota_check_limit(new_frame, parent, this); ret = 0; out: if (ret < 0) { if (parent) { /* Caller should decrement link_count, in case parent is * NULL */ quota_handle_validate_error(frame, -1, ENOMEM); } if (new_frame) { new_frame->local = NULL; STACK_DESTROY(new_frame->root); } } return parent; } static int quota_get_limits(xlator_t *this, dict_t *dict, int64_t *hard_lim, int64_t *soft_lim, int64_t *object_hard_limit, int64_t *object_soft_limit) { quota_limits_t *limit = NULL; quota_limits_t *object_limit = NULL; quota_priv_t *priv = NULL; int64_t soft_lim_percent = 0; int64_t *ptr = NULL; int ret = 0; if ((this == NULL) || (dict == NULL) || (hard_lim == NULL) || (soft_lim == NULL)) goto out; priv = this->private; ret = dict_get_bin(dict, QUOTA_LIMIT_KEY, (void **)&ptr); limit = (quota_limits_t *)ptr; if (limit) { *hard_lim = be64toh(limit->hl); soft_lim_percent = be64toh(limit->sl); } if (soft_lim_percent < 0) { soft_lim_percent = priv->default_soft_lim; } if ((*hard_lim > 0) && (soft_lim_percent > 0)) { *soft_lim = (soft_lim_percent * (*hard_lim)) / 100; } ret = dict_get_bin(dict, QUOTA_LIMIT_OBJECTS_KEY, (void **)&ptr); if (ret) return 0; object_limit = (quota_limits_t *)ptr; if (object_limit) { *object_hard_limit = be64toh(object_limit->hl); soft_lim_percent = be64toh(object_limit->sl); } if (soft_lim_percent < 0) { soft_lim_percent = priv->default_soft_lim; } if ((*object_hard_limit > 0) && (soft_lim_percent > 0)) { *object_soft_limit = (soft_lim_percent * (*object_hard_limit)) / 100; } out: return 0; } int quota_fill_inodectx(xlator_t *this, inode_t *inode, dict_t *dict, loc_t *loc, struct iatt *buf, int32_t *op_errno) { int32_t ret = -1; char found = 0; quota_inode_ctx_t *ctx = NULL; quota_dentry_t *dentry = NULL; uint64_t value = 0; int64_t hard_lim = 0; int64_t soft_lim = 0; int64_t object_hard_limit = 0; int64_t object_soft_limit = 0; quota_get_limits(this, dict, &hard_lim, &soft_lim, &object_hard_limit, &object_soft_limit); inode_ctx_get(inode, this, &value); ctx = (quota_inode_ctx_t *)(unsigned long)value; if ((((ctx == NULL) || (ctx->hard_lim == hard_lim)) && (hard_lim < 0) && !QUOTA_REG_OR_LNK_FILE(buf->ia_type))) { ret = 0; goto out; } ret = quota_inode_ctx_get(inode, this, &ctx, 1); if ((ret == -1) || (ctx == NULL)) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_INODE_CTX_GET_FAILED, "cannot create quota " "context in inode(gfid:%s)", uuid_utoa(inode->gfid)); ret = -1; *op_errno = ENOMEM; goto out; } LOCK(&ctx->lock); { ctx->hard_lim = hard_lim; ctx->soft_lim = soft_lim; ctx->object_hard_lim = object_hard_limit; ctx->object_soft_lim = object_soft_limit; ctx->buf = *buf; if (!QUOTA_REG_OR_LNK_FILE(buf->ia_type)) { goto unlock; } /* do nothing if it is a nameless lookup */ if (loc->name == NULL || !loc->parent) goto unlock; list_for_each_entry(dentry, &ctx->parents, next) { if ((strcmp(dentry->name, loc->name) == 0) && (gf_uuid_compare(loc->parent->gfid, dentry->par) == 0)) { found = 1; break; } } if (!found) { dentry = __quota_dentry_new(ctx, (char *)loc->name, loc->parent->gfid); if (dentry == NULL) { /* gf_msg (this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "cannot create a new dentry (par:%" - PRId64", name:%s) for inode(ino:%" - PRId64", gfid:%s)", - uuid_utoa (local->loc.inode->gfid)); */ ret = -1; *op_errno = ENOMEM; goto unlock; } } } unlock: UNLOCK(&ctx->lock); out: return ret; } /* * return _gf_true if enforcement is needed and _gf_false otherwise */ gf_boolean_t should_quota_enforce(xlator_t *this, dict_t *dict, glusterfs_fop_t fop) { int ret = 0; ret = dict_check_flag(dict, GF_INTERNAL_CTX_KEY, GF_DHT_HEAL_DIR); if (fop == GF_FOP_MKDIR && ret == DICT_FLAG_SET) { return _gf_false; } else if (ret == -ENOENT) { gf_msg(this->name, GF_LOG_DEBUG, EINVAL, Q_MSG_INTERNAL_FOP_KEY_MISSING, "No internal fop context present"); goto out; } out: return _gf_true; } int32_t quota_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *dict, struct iatt *postparent) { quota_local_t *local = NULL; inode_t *this_inode = NULL; local = frame->local; frame->local = NULL; if (op_ret >= 0 && inode) { this_inode = inode_ref(inode); op_ret = quota_fill_inodectx(this, inode, dict, &local->loc, buf, &op_errno); if (op_ret < 0) op_errno = ENOMEM; } QUOTA_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, buf, dict, postparent); if (op_ret < 0 || this_inode == NULL || gf_uuid_is_null(this_inode->gfid)) goto out; check_ancestory_2(this, local, this_inode); out: if (this_inode) inode_unref(this_inode); quota_local_cleanup(local); return 0; } int32_t quota_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { quota_priv_t *priv = NULL; int32_t ret = -1; quota_local_t *local = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); xattr_req = xattr_req ? dict_ref(xattr_req) : dict_new(); if (!xattr_req) goto err; local = quota_local_new(); if (local == NULL) { goto err; } frame->local = local; loc_copy(&local->loc, loc); ret = dict_set_int8(xattr_req, QUOTA_LIMIT_KEY, 1); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "dict set of key for " "hard-limit failed"); goto err; } ret = dict_set_int8(xattr_req, QUOTA_LIMIT_OBJECTS_KEY, 1); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "dict set of key for quota object limit failed"); goto err; } STACK_WIND(frame, quota_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xattr_req); ret = 0; err: if (xattr_req) dict_unref(xattr_req); if (ret < 0) { QUOTA_STACK_UNWIND(lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL); } return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xattr_req); return 0; } int32_t quota_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { int32_t ret = 0; uint64_t ctx_int = 0; quota_inode_ctx_t *ctx = NULL; quota_local_t *local = NULL; local = frame->local; if ((op_ret < 0) || (local == NULL) || (postbuf == NULL)) { goto out; } ret = inode_ctx_get(local->loc.inode, this, &ctx_int); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED, "%s: failed to get the " "context", local->loc.path); goto out; } ctx = (quota_inode_ctx_t *)(unsigned long)ctx_int; if (ctx == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED, "quota context not set in %s (gfid:%s)", local->loc.path, uuid_utoa(local->loc.inode->gfid)); goto out; } LOCK(&ctx->lock); { ctx->buf = *postbuf; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } static int gf_quota_enforcer_log; int32_t quota_writev_helper(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { quota_local_t *local = NULL; int32_t op_errno = EINVAL; struct iovec *new_vector = NULL; int32_t new_count = 0; local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, unwind); if (local->op_ret == -1) { op_errno = local->op_errno; if ((op_errno == EDQUOT) && (local->space_available > 0)) { new_count = iov_subset(vector, count, 0, local->space_available, &new_vector, 0); if (new_count < 0) { local->op_ret = -1; local->op_errno = ENOMEM; goto unwind; } vector = new_vector; count = new_count; } else if (op_errno == ENOENT || op_errno == ESTALE) { /* We may get ENOENT/ESTALE in case of below scenario * fd = open file.txt * unlink file.txt * write on fd * Here build_ancestry can fail as the file is removed. * For now ignore ENOENT/ESTALE with writes on active fd * We need to re-visit this code once we understand * how other file-system behave in this scenario */ gf_msg_debug(this->name, 0, "quota enforcer failed " "with ENOENT/ESTALE on %s, cannot check " "quota limits and allowing writes", uuid_utoa(fd->inode->gfid)); } else if ((op_errno == EINVAL) && !inode_parent(local->loc.inode, 0, NULL)) { /* We may get INVAL with parent == NULL, * in case of below scenario * 1. enable quota * 2. glusterfsd stop/start * 3. nameless lookup * 4. write on fd * Here build_ancestry can fail as the file's pgfid * is't exist. * For now ignore EINVAL with writes on active fd * untils the pgfid is created at name lookup */ GF_LOG_OCCASIONALLY(gf_quota_enforcer_log, this->name, GF_LOG_CRITICAL, "Quota cannot be enforced as " "parent is not available and writes are being " "allowed without checking whether they are " "within quota limits. This can happen if Quota " "crawl is not complete. If crawl has been " "completed, please file a bug."); } else { goto unwind; } } STACK_WIND(frame, quota_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, iobref, xdata); if (new_vector != NULL) GF_FREE(new_vector); return 0; unwind: QUOTA_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int32_t quota_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t op_errno = EINVAL; int32_t parents = 0; int32_t fail_count = 0; uint64_t size = 0; quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; quota_dentry_t *dentry = NULL, *tmp = NULL; call_stub_t *stub = NULL; struct list_head head; inode_t *par_inode = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); INIT_LIST_HEAD(&head); GF_ASSERT(frame); GF_VALIDATE_OR_GOTO("quota", this, unwind); GF_VALIDATE_OR_GOTO(this->name, fd, unwind); local = quota_local_new(); if (local == NULL) { goto unwind; } frame->local = local; local->loc.inode = inode_ref(fd->inode); (void)quota_inode_ctx_get(fd->inode, this, &ctx, 0); if (ctx == NULL) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(fd->inode->gfid)); } stub = fop_writev_stub(frame, quota_writev_helper, fd, vector, count, off, flags, iobref, xdata); if (stub == NULL) { op_errno = ENOMEM; goto unwind; } priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, unwind); parents = quota_add_parents_from_ctx(ctx, &head); if (parents == -1) { op_errno = errno; goto unwind; } size = iov_length(vector, count); LOCK(&local->lock); { local->delta = size; local->object_delta = 0; local->link_count = (parents != 0) ? parents : 1; local->stub = stub; } UNLOCK(&local->lock); if (parents == 0) { /* nameless lookup on this inode, allow quota to reconstruct * ancestry as part of check_limit. */ quota_check_limit(frame, fd->inode, this); } else { list_for_each_entry_safe(dentry, tmp, &head, next) { par_inode = do_quota_check_limit(frame, fd->inode, this, dentry, _gf_false); if (par_inode == NULL) { if (ctx) { /* remove stale entry from inode ctx */ quota_dentry_del(ctx, dentry->name, dentry->par); parents--; fail_count++; } } else { inode_unref(par_inode); } __quota_dentry_free(dentry); } if (parents == 0) { LOCK(&local->lock); { local->link_count++; } UNLOCK(&local->lock); quota_check_limit(frame, fd->inode, this); } while (fail_count != 0) { quota_link_count_decrement(frame); fail_count--; } } return 0; unwind: QUOTA_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, iobref, xdata); return 0; } int32_t quota_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { QUOTA_STACK_UNWIND(mkdir, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int32_t quota_mkdir_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { quota_local_t *local = NULL; int32_t op_errno = EINVAL; local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, unwind); op_errno = local->op_errno; if (local->op_ret == -1) { goto unwind; } STACK_WIND(frame, quota_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; unwind: QUOTA_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t quota_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t ret = 0, op_errno = 0; quota_local_t *local = NULL; call_stub_t *stub = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); if (!should_quota_enforce(this, xdata, GF_FOP_MKDIR)) { gf_msg(this->name, GF_LOG_DEBUG, 0, Q_MSG_ENFORCEMENT_SKIPPED, "Enforcement has been skipped(internal fop)."); goto off; } local = quota_local_new(); if (local == NULL) { op_errno = ENOMEM; goto err; } frame->local = local; ret = loc_copy(&local->loc, loc); if (ret) { op_errno = ENOMEM; gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } stub = fop_mkdir_stub(frame, quota_mkdir_helper, loc, mode, umask, xdata); if (stub == NULL) { op_errno = ENOMEM; goto err; } LOCK(&local->lock); { local->stub = stub; local->delta = 0; local->object_delta = 1; local->link_count = 1; } UNLOCK(&local->lock); quota_check_limit(frame, loc->parent, this); return 0; err: QUOTA_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; } int32_t quota_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int32_t ret = -1; quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; quota_dentry_t *dentry = NULL; local = frame->local; if (op_ret < 0) { goto unwind; } ret = quota_inode_ctx_get(inode, this, &ctx, 1); if ((ret == -1) || (ctx == NULL)) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_INODE_CTX_GET_FAILED, "cannot create quota " "context in inode(gfid:%s)", uuid_utoa(inode->gfid)); op_ret = -1; op_errno = ENOMEM; goto unwind; } LOCK(&ctx->lock); { ctx->buf = *buf; dentry = __quota_dentry_new(ctx, (char *)local->loc.name, local->loc.parent->gfid); if (dentry == NULL) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "cannot create a new dentry " "(name:%s) for inode(gfid:%s)", local->loc.name, uuid_utoa(local->loc.inode->gfid)); op_ret = -1; op_errno = ENOMEM; goto unlock; } } unlock: UNLOCK(&ctx->lock); unwind: QUOTA_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent, xdata); return 0; } int32_t quota_create_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { quota_local_t *local = NULL; int32_t op_errno = EINVAL; local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, unwind); if (local->op_ret == -1) { op_errno = local->op_errno; goto unwind; } STACK_WIND(frame, quota_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; unwind: QUOTA_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t quota_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t ret = -1; quota_local_t *local = NULL; int32_t op_errno = 0; call_stub_t *stub = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); QUOTA_WIND_FOR_INTERNAL_FOP(xdata, off); local = quota_local_new(); if (local == NULL) { op_errno = ENOMEM; goto err; } frame->local = local; ret = loc_copy(&local->loc, loc); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); op_errno = ENOMEM; goto err; } stub = fop_create_stub(frame, quota_create_helper, loc, flags, mode, umask, fd, xdata); if (stub == NULL) { goto err; } LOCK(&local->lock); { local->link_count = 1; local->stub = stub; local->delta = 0; local->object_delta = 1; } UNLOCK(&local->lock); quota_check_limit(frame, loc->parent, this); return 0; err: QUOTA_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; } int32_t quota_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; uint64_t value = 0; if (op_ret < 0) { goto out; } local = (quota_local_t *)frame->local; inode_ctx_get(local->loc.inode, this, &value); ctx = (quota_inode_ctx_t *)(unsigned long)value; if (ctx == NULL) { gf_msg(this->name, GF_LOG_INFO, EINVAL, Q_MSG_INODE_CTX_GET_FAILED, "quota context not set inode (gfid:%s)", uuid_utoa(local->loc.gfid)); goto out; } quota_dentry_del(ctx, local->loc.name, local->loc.parent->gfid); out: QUOTA_STACK_UNWIND(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int32_t quota_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t ret = -1; quota_local_t *local = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto err; } frame->local = local; ret = loc_copy(&local->loc, loc); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } STACK_WIND(frame, quota_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); ret = 0; err: if (ret == -1) { QUOTA_STACK_UNWIND(unlink, frame, -1, 0, NULL, NULL, NULL); } return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; } int32_t quota_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int32_t ret = -1; quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; quota_dentry_t *dentry = NULL; char found = 0; if (op_ret < 0) { goto out; } local = (quota_local_t *)frame->local; ret = quota_inode_ctx_get(inode, this, &ctx, 0); if ((ret == -1) || (ctx == NULL)) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(inode->gfid)); goto out; } LOCK(&ctx->lock); { list_for_each_entry(dentry, &ctx->parents, next) { if ((strcmp(dentry->name, local->loc.name) == 0) && (gf_uuid_compare(local->loc.parent->gfid, dentry->par) == 0)) { found = 1; gf_msg_debug(this->name, 0, "new entry being" " linked (name:%s) for inode " "(gfid:%s) is already present " "in inode-dentry-list", dentry->name, uuid_utoa(local->loc.inode->gfid)); break; } } if (!found) { dentry = __quota_dentry_new(ctx, (char *)local->loc.name, local->loc.parent->gfid); if (dentry == NULL) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "cannot create a new dentry (name:%s)" "for inode(gfid:%s)", local->loc.name, uuid_utoa(local->loc.inode->gfid)); op_ret = -1; op_errno = ENOMEM; goto unlock; } } ctx->buf = *buf; } unlock: UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(link, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int32_t quota_link_helper(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { quota_local_t *local = NULL; int32_t op_errno = EINVAL; local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, unwind); op_errno = local->op_errno; if (local->op_ret == -1) { goto unwind; } STACK_WIND(frame, quota_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; unwind: QUOTA_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } void quota_link_continue(call_frame_t *frame) { int32_t ret = -1; int32_t op_errno = EIO; quota_local_t *local = NULL; uuid_t common_ancestor = {0}; xlator_t *this = NULL; quota_inode_ctx_t *ctx = NULL; inode_t *src_parent = NULL; inode_t *dst_parent = NULL; local = frame->local; this = THIS; if (local->op_ret < 0) { op_errno = local->op_errno; goto err; } if (local->xdata && dict_get(local->xdata, GLUSTERFS_INTERNAL_FOP_KEY)) { /* Treat link as rename, crawl upwards only till common ancestor */ ret = quota_find_common_ancestor( local->oldloc.inode, local->newloc.parent, &common_ancestor); if (ret < 0 || gf_uuid_is_null(common_ancestor)) { gf_msg(this->name, GF_LOG_ERROR, ESTALE, Q_MSG_ANCESTRY_BUILD_FAILED, "failed to get " "common_ancestor for %s and %s", local->oldloc.path, local->newloc.path); op_errno = ESTALE; goto err; } } else { /* Treat link as a new file. * TODO: Currently marker accounts twice for the links created * across directories. * This needs re-visit if marker accounts only once * for the links created across directories */ if (local->oldloc.parent) src_parent = inode_ref(local->oldloc.parent); else src_parent = inode_parent(local->oldloc.inode, 0, NULL); dst_parent = local->newloc.parent; /* No need to check quota limit if src and dst parents are same */ if (src_parent == dst_parent || gf_uuid_compare(src_parent->gfid, dst_parent->gfid) == 0) { inode_unref(src_parent); goto wind; } inode_unref(src_parent); } quota_inode_ctx_get(local->oldloc.inode, this, &ctx, 0); if (ctx == NULL) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->oldloc.inode->gfid)); } LOCK(&local->lock); { local->link_count = 1; local->delta = (ctx != NULL) ? ctx->buf.ia_blocks * 512 : 0; local->object_delta = 1; gf_uuid_copy(local->common_ancestor, common_ancestor); } UNLOCK(&local->lock); quota_check_limit(frame, local->newloc.parent, this); return; err: QUOTA_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return; wind: STACK_WIND(frame, quota_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, &(local->oldloc), &(local->newloc), local->xdata); return; } int32_t quota_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t ret = -1; int32_t op_errno = ENOMEM; quota_local_t *local = NULL; call_stub_t *stub = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto err; } frame->local = (void *)local; if (xdata) local->xdata = dict_ref(xdata); ret = loc_copy(&local->loc, newloc); if (ret == -1) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } ret = loc_copy(&local->oldloc, oldloc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } ret = loc_copy(&local->newloc, newloc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } /* No need to check quota limit if src and dst parents are same */ if (oldloc->parent && newloc->parent && !gf_uuid_compare(oldloc->parent->gfid, newloc->parent->gfid)) { gf_msg_debug(this->name, GF_LOG_DEBUG, "link %s -> %s are " "in the same directory, so skip check limit", oldloc->path, newloc->path); goto wind; } stub = fop_link_stub(frame, quota_link_helper, oldloc, newloc, xdata); if (stub == NULL) { goto err; } LOCK(&local->lock); { local->link_count = 2; local->fop_continue_cbk = quota_link_continue; local->stub = stub; } UNLOCK(&local->lock); check_ancestory(frame, newloc->parent); /* source parent can be NULL, so do check_ancestry on a file */ if (oldloc->parent) check_ancestory(frame, oldloc->parent); else check_ancestory(frame, oldloc->inode); return 0; err: QUOTA_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; wind: STACK_WIND(frame, quota_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; } int32_t quota_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { int32_t ret = -1; quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; quota_dentry_t *old_dentry = NULL, *dentry = NULL; char new_dentry_found = 0; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); if (!QUOTA_REG_OR_LNK_FILE(local->oldloc.inode->ia_type)) goto out; ret = quota_inode_ctx_get(local->oldloc.inode, this, &ctx, 0); if ((ret == -1) || (ctx == NULL)) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->oldloc.inode->gfid)); goto out; } LOCK(&ctx->lock); { list_for_each_entry(dentry, &ctx->parents, next) { if ((strcmp(dentry->name, local->oldloc.name) == 0) && (gf_uuid_compare(local->oldloc.parent->gfid, dentry->par) == 0)) { old_dentry = dentry; } else if ((strcmp(dentry->name, local->newloc.name) == 0) && (gf_uuid_compare(local->newloc.parent->gfid, dentry->par) == 0)) { new_dentry_found = 1; gf_msg_debug(this->name, 0, "new entry being " "linked (name:%s) for inode (gfid:%s) " "is in inode-dentry-list", dentry->name, uuid_utoa(local->oldloc.inode->gfid)); } if (old_dentry && new_dentry_found) break; } if (old_dentry != NULL) { __quota_dentry_free(old_dentry); } else { gf_msg_debug(this->name, 0, "dentry corresponding" "the path just renamed (name:%s) is not" " present", local->oldloc.name); } if (!new_dentry_found) { dentry = __quota_dentry_new(ctx, (char *)local->newloc.name, local->newloc.parent->gfid); if (dentry == NULL) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "cannot create a new dentry (name:%s) " "for inode(gfid:%s)", local->newloc.name, uuid_utoa(local->newloc.inode->gfid)); op_ret = -1; op_errno = ENOMEM; goto unlock; } } ctx->buf = *buf; } unlock: UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(rename, frame, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); return 0; } int32_t quota_rename_helper(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { quota_local_t *local = NULL; int32_t op_errno = EINVAL; local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, unwind); op_errno = local->op_errno; if (local->op_ret == -1) { goto unwind; } STACK_WIND(frame, quota_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; unwind: QUOTA_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t quota_rename_get_size_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { quota_local_t *local = NULL; int32_t ret = 0; int64_t *size = 0; GF_ASSERT(frame); GF_VALIDATE_OR_GOTO_WITH_ERROR("quota", this, out, op_errno, EINVAL); GF_VALIDATE_OR_GOTO_WITH_ERROR(this->name, xdata, out, op_errno, EINVAL); local = frame->local; GF_ASSERT(local); local->link_count = 1; if (op_ret < 0) goto out; ret = dict_get_bin(xdata, QUOTA_SIZE_KEY, (void **)&size); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_SIZE_KEY_MISSING, "size key not present in dict"); op_errno = EINVAL; goto out; } local->delta = be64toh(*size); local->object_delta = 1; quota_check_limit(frame, local->newloc.parent, this); return 0; out: quota_handle_validate_error(frame, -1, op_errno); return 0; } void quota_rename_continue(call_frame_t *frame) { int32_t ret = -1; int32_t op_errno = EIO; quota_local_t *local = NULL; uuid_t common_ancestor = {0}; xlator_t *this = NULL; quota_inode_ctx_t *ctx = NULL; local = frame->local; this = THIS; if (local->op_ret < 0) { op_errno = local->op_errno; goto err; } ret = quota_find_common_ancestor(local->oldloc.parent, local->newloc.parent, &common_ancestor); if (ret < 0 || gf_uuid_is_null(common_ancestor)) { gf_msg(this->name, GF_LOG_ERROR, ESTALE, Q_MSG_ANCESTRY_BUILD_FAILED, "failed to get " "common_ancestor for %s and %s", local->oldloc.path, local->newloc.path); op_errno = ESTALE; goto err; } LOCK(&local->lock); { local->link_count = 1; gf_uuid_copy(local->common_ancestor, common_ancestor); } UNLOCK(&local->lock); if (QUOTA_REG_OR_LNK_FILE(local->oldloc.inode->ia_type)) { ret = quota_inode_ctx_get(local->oldloc.inode, this, &ctx, 0); if (ctx == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED, "quota context not set in inode (gfid:%s), " "considering file size as zero while enforcing " "quota on new ancestry", uuid_utoa(local->oldloc.inode->gfid)); local->delta = 0; local->object_delta = 1; } else { /* FIXME: We need to account for the size occupied by * this inode on the target directory. To avoid double * accounting, we need to modify enforcer to perform * quota_check_limit only up till the least common * ancestor directory inode*/ /* FIXME: The following code assumes that regular files * and link files are present, in their entirety, in a * single brick. This *assumption is invalid in the * case of stripe.*/ local->delta = ctx->buf.ia_blocks * 512; local->object_delta = 1; } } else if (IA_ISDIR(local->oldloc.inode->ia_type)) { ret = quota_validate(frame, local->oldloc.inode, this, quota_rename_get_size_cbk); if (ret) { op_errno = -ret; goto err; } return; } quota_check_limit(frame, local->newloc.parent, this); return; err: QUOTA_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return; } int32_t quota_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t ret = -1; int32_t op_errno = ENOMEM; quota_local_t *local = NULL; call_stub_t *stub = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto err; } frame->local = local; ret = loc_copy(&local->oldloc, oldloc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } ret = loc_copy(&local->newloc, newloc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } /* No need to check quota limit if src and dst parents are same */ if (oldloc->parent && newloc->parent && !gf_uuid_compare(oldloc->parent->gfid, newloc->parent->gfid)) { gf_msg_debug(this->name, 0, "rename %s -> %s are " "in the same directory, so skip check limit", oldloc->path, newloc->path); goto wind; } stub = fop_rename_stub(frame, quota_rename_helper, oldloc, newloc, xdata); if (stub == NULL) { goto err; } LOCK(&local->lock); { /* link_count here tell how many check_ancestry should be done * before continuing the FOP */ local->link_count = 2; local->stub = stub; local->fop_continue_cbk = quota_rename_continue; } UNLOCK(&local->lock); check_ancestory(frame, newloc->parent); check_ancestory(frame, oldloc->parent); return 0; err: QUOTA_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; wind: STACK_WIND(frame, quota_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; } int32_t quota_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; quota_dentry_t *dentry = NULL; int32_t ret = -1; if (op_ret < 0) { goto out; } local = frame->local; ret = quota_inode_ctx_get(local->loc.inode, this, &ctx, 1); if ((ret == -1) || (ctx == NULL)) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); goto out; } LOCK(&ctx->lock); { ctx->buf = *buf; dentry = __quota_dentry_new(ctx, (char *)local->loc.name, local->loc.parent->gfid); if (dentry == NULL) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "cannot create " "a new dentry (name:%s) for inode(gfid:%s)", local->loc.name, uuid_utoa(local->loc.inode->gfid)); op_ret = -1; op_errno = ENOMEM; } } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(symlink, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int quota_symlink_helper(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { quota_local_t *local = NULL; int32_t op_errno = EINVAL; local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, unwind); if (local->op_ret == -1) { op_errno = local->op_errno; goto unwind; } STACK_WIND(frame, quota_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); return 0; unwind: QUOTA_STACK_UNWIND(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int quota_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t ret = -1; int32_t op_errno = ENOMEM; quota_local_t *local = NULL; call_stub_t *stub = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto err; } frame->local = local; ret = loc_copy(&local->loc, loc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } stub = fop_symlink_stub(frame, quota_symlink_helper, linkpath, loc, umask, xdata); if (stub == NULL) { goto err; } LOCK(&local->lock); { local->stub = stub; local->delta = strlen(linkpath); local->object_delta = 1; local->link_count = 1; } UNLOCK(&local->lock); quota_check_limit(frame, loc->parent, this); return 0; err: QUOTA_STACK_UNWIND(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); return 0; } int32_t quota_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); if (ctx == NULL) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); goto out; } LOCK(&ctx->lock); { ctx->buf = *postbuf; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t quota_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t ret = -1; quota_local_t *local = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto err; } frame->local = local; ret = loc_copy(&local->loc, loc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } STACK_WIND(frame, quota_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; err: QUOTA_STACK_UNWIND(truncate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } int32_t quota_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); if (ctx == NULL) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); goto out; } LOCK(&ctx->lock); { ctx->buf = *postbuf; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t quota_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { quota_priv_t *priv = NULL; quota_local_t *local = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) goto err; frame->local = local; local->loc.inode = inode_ref(fd->inode); STACK_WIND(frame, quota_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; err: QUOTA_STACK_UNWIND(ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } static int32_t quota_send_dir_limit_to_cli(call_frame_t *frame, xlator_t *this, inode_t *inode, const char *name, const int namelen) { int32_t ret = 0; int dir_limit_len = 0; char dir_limit[64] = { 0, }; dict_t *dict = NULL; quota_inode_ctx_t *ctx = NULL; uint64_t value = 0; quota_priv_t *priv = NULL; priv = this->private; if (!priv->is_quota_on) { dir_limit_len = snprintf(dir_limit, sizeof(dir_limit), "Quota is disabled please turn on"); goto dict_set; } ret = inode_ctx_get(inode, this, &value); if (ret < 0) goto out; ctx = (quota_inode_ctx_t *)(unsigned long)value; dir_limit_len = snprintf(dir_limit, sizeof(dir_limit), "%" PRId64 ",%" PRId64, ctx->size, ctx->hard_lim); dict_set: dict = dict_new(); if (dict == NULL) { ret = -1; goto out; } ret = dict_set_nstrn(dict, (char *)name, namelen, dir_limit, dir_limit_len); if (ret < 0) goto out; gf_msg_debug(this->name, 0, "str = %s", dir_limit); QUOTA_STACK_UNWIND(getxattr, frame, 0, 0, dict, NULL); ret = 0; out: if (dict) dict_unref(dict); return ret; } int32_t quota_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int32_t ret = 0; if (name && strcasecmp(name, "trusted.limit.list") == 0) { ret = quota_send_dir_limit_to_cli(frame, this, fd->inode, "trusted.limit.list", SLEN("trusted.limit.list")); if (ret == 0) { return 0; } } STACK_WIND(frame, default_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); return 0; } int32_t quota_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int32_t ret = 0; if ((name != NULL) && strcasecmp(name, "trusted.limit.list") == 0) { ret = quota_send_dir_limit_to_cli(frame, this, loc->inode, "trusted.limit.list", SLEN("trusted.limit.list")); if (ret == 0) return 0; } STACK_WIND(frame, default_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); return 0; } int32_t quota_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); if (ctx == NULL) { if (!IA_ISDIR(buf->ia_type)) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); } goto out; } if (buf) { LOCK(&ctx->lock); ctx->buf = *buf; UNLOCK(&ctx->lock); } out: QUOTA_STACK_UNWIND(stat, frame, op_ret, op_errno, buf, xdata); return 0; } int32_t quota_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { quota_priv_t *priv = NULL; quota_local_t *local = NULL; int32_t ret = -1; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto unwind; } frame->local = local; ret = loc_copy(&local->loc, loc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto unwind; } STACK_WIND(frame, quota_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; unwind: QUOTA_STACK_UNWIND(stat, frame, -1, ENOMEM, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; } int32_t quota_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); if (ctx == NULL) { if (!IA_ISDIR(buf->ia_type)) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); } goto out; } if (buf) { LOCK(&ctx->lock); ctx->buf = *buf; UNLOCK(&ctx->lock); } out: QUOTA_STACK_UNWIND(fstat, frame, op_ret, op_errno, buf, xdata); return 0; } int32_t quota_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { quota_priv_t *priv = NULL; quota_local_t *local = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto unwind; } frame->local = local; local->loc.inode = inode_ref(fd->inode); STACK_WIND(frame, quota_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; unwind: QUOTA_STACK_UNWIND(fstat, frame, -1, ENOMEM, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; } int32_t quota_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, const char *path, struct iatt *buf, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); if (ctx == NULL) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); goto out; } LOCK(&ctx->lock); { ctx->buf = *buf; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(readlink, frame, op_ret, op_errno, path, buf, xdata); return 0; } int32_t quota_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { quota_priv_t *priv = NULL; quota_local_t *local = NULL; int32_t ret = -1; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto unwind; } frame->local = local; ret = loc_copy(&local->loc, loc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto unwind; } STACK_WIND(frame, quota_readlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink, loc, size, xdata); return 0; unwind: QUOTA_STACK_UNWIND(readlink, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink, loc, size, xdata); return 0; } int32_t quota_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *buf, struct iobref *iobref, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); if (ctx == NULL) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); goto out; } LOCK(&ctx->lock); { ctx->buf = *buf; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, buf, iobref, xdata); return 0; } int32_t quota_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { quota_priv_t *priv = NULL; quota_local_t *local = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto unwind; } frame->local = local; local->loc.inode = inode_ref(fd->inode); STACK_WIND(frame, quota_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; unwind: QUOTA_STACK_UNWIND(readv, frame, -1, ENOMEM, NULL, -1, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; } int32_t quota_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); if (ctx == NULL) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); goto out; } LOCK(&ctx->lock); { ctx->buf = *postbuf; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t quota_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { quota_priv_t *priv = NULL; quota_local_t *local = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto unwind; } local->loc.inode = inode_ref(fd->inode); frame->local = local; STACK_WIND(frame, quota_fsync_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); return 0; unwind: QUOTA_STACK_UNWIND(fsync, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); return 0; } int32_t quota_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); if (ctx == NULL) { if (!IA_ISDIR(statpost->ia_type)) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); } goto out; } if (statpost) { LOCK(&ctx->lock); ctx->buf = *statpost; UNLOCK(&ctx->lock); } out: QUOTA_STACK_UNWIND(setattr, frame, op_ret, op_errno, statpre, statpost, xdata); return 0; } int32_t quota_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { quota_priv_t *priv = NULL; quota_local_t *local = NULL; int32_t ret = -1; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto unwind; } frame->local = local; ret = loc_copy(&local->loc, loc); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto unwind; } STACK_WIND(frame, quota_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; unwind: QUOTA_STACK_UNWIND(setattr, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } int32_t quota_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; if (op_ret < 0) { goto out; } local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, out); quota_inode_ctx_get(local->loc.inode, this, &ctx, 0); if (ctx == NULL) { if (!IA_ISDIR(statpost->ia_type)) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); } goto out; } LOCK(&ctx->lock); { ctx->buf = *statpost; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(fsetattr, frame, op_ret, op_errno, statpre, statpost, xdata); return 0; } int32_t quota_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { quota_priv_t *priv = NULL; quota_local_t *local = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto unwind; } frame->local = local; local->loc.inode = inode_ref(fd->inode); STACK_WIND(frame, quota_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; unwind: QUOTA_STACK_UNWIND(fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } int32_t quota_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int32_t ret = -1; quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; quota_dentry_t *dentry = NULL; local = frame->local; if (op_ret < 0) { goto unwind; } ret = quota_inode_ctx_get(inode, this, &ctx, 1); if ((ret == -1) || (ctx == NULL)) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED, "cannot create quota context in " "inode(gfid:%s)", uuid_utoa(inode->gfid)); op_ret = -1; op_errno = ENOMEM; goto unwind; } LOCK(&ctx->lock); { ctx->buf = *buf; dentry = __quota_dentry_new(ctx, (char *)local->loc.name, local->loc.parent->gfid); if (dentry == NULL) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "cannot create a new dentry " "(name:%s) for inode(gfid:%s)", local->loc.name, uuid_utoa(local->loc.inode->gfid)); op_ret = -1; op_errno = ENOMEM; goto unlock; } } unlock: UNLOCK(&ctx->lock); unwind: QUOTA_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int quota_mknod_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { quota_local_t *local = NULL; int32_t op_errno = EINVAL; local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, unwind); if (local->op_ret == -1) { op_errno = local->op_errno; goto unwind; } STACK_WIND(frame, quota_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; unwind: QUOTA_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } int quota_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t ret = -1; quota_local_t *local = NULL; call_stub_t *stub = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); QUOTA_WIND_FOR_INTERNAL_FOP(xdata, off); local = quota_local_new(); if (local == NULL) { goto err; } frame->local = local; ret = loc_copy(&local->loc, loc); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "loc_copy failed"); goto err; } stub = fop_mknod_stub(frame, quota_mknod_helper, loc, mode, rdev, umask, xdata); if (stub == NULL) { goto err; } LOCK(&local->lock); { local->link_count = 1; local->stub = stub; local->delta = 0; local->object_delta = 1; } UNLOCK(&local->lock); quota_check_limit(frame, loc->parent, this); return 0; err: QUOTA_STACK_UNWIND(mknod, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; } int quota_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; int ret = 0; if (op_ret < 0) { goto out; } local = frame->local; if (!local) goto out; ret = quota_inode_ctx_get(local->loc.inode, this, &ctx, 1); if ((ret < 0) || (ctx == NULL)) { op_errno = -1; goto out; } LOCK(&ctx->lock); { ctx->hard_lim = local->limit.hl; ctx->soft_lim = local->limit.sl; ctx->object_hard_lim = local->object_limit.hl; ctx->object_soft_lim = local->object_limit.sl; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); return 0; } int quota_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int flags, dict_t *xdata) { quota_priv_t *priv = NULL; int op_errno = EINVAL; int op_ret = -1; int64_t hard_lim = -1; int64_t soft_lim = -1; int64_t object_hard_limit = -1; int64_t object_soft_limit = -1; quota_local_t *local = NULL; gf_boolean_t internal_fop = _gf_false; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(loc, err); if (xdata && dict_get_sizen(xdata, GLUSTERFS_INTERNAL_FOP_KEY)) internal_fop = _gf_true; if (frame->root->pid >= 0 && internal_fop == _gf_false) { GF_IF_INTERNAL_XATTR_GOTO("trusted.glusterfs.quota*", dict, op_errno, err); GF_IF_INTERNAL_XATTR_GOTO("trusted.pgfid*", dict, op_errno, err); } quota_get_limits(this, dict, &hard_lim, &soft_lim, &object_hard_limit, &object_soft_limit); if (hard_lim > 0 || object_hard_limit > 0) { local = quota_local_new(); if (local == NULL) { op_errno = ENOMEM; goto err; } frame->local = local; loc_copy(&local->loc, loc); } if (hard_lim > 0) { local->limit.hl = hard_lim; local->limit.sl = soft_lim; } if (object_hard_limit > 0) { local->object_limit.hl = object_hard_limit; local->object_limit.sl = object_soft_limit; } STACK_WIND(frame, quota_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; err: QUOTA_STACK_UNWIND(setxattr, frame, op_ret, op_errno, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; } int quota_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) { quota_inode_ctx_t *ctx = NULL; quota_local_t *local = NULL; if (op_ret < 0) goto out; local = frame->local; if (!local) goto out; op_ret = quota_inode_ctx_get(local->loc.inode, this, &ctx, 1); if ((op_ret < 0) || (ctx == NULL)) { op_errno = ENOMEM; goto out; } LOCK(&ctx->lock); { ctx->hard_lim = local->limit.hl; ctx->soft_lim = local->limit.sl; ctx->object_hard_lim = local->object_limit.hl; ctx->object_soft_lim = local->object_limit.sl; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, xdata); return 0; } int quota_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int flags, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; quota_local_t *local = NULL; int64_t hard_lim = -1; int64_t soft_lim = -1; int64_t object_hard_limit = -1; int64_t object_soft_limit = -1; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); if (0 <= frame->root->pid) { GF_IF_INTERNAL_XATTR_GOTO("trusted.glusterfs.quota*", dict, op_errno, err); GF_IF_INTERNAL_XATTR_GOTO("trusted.pgfid*", dict, op_errno, err); } quota_get_limits(this, dict, &hard_lim, &soft_lim, &object_hard_limit, &object_soft_limit); if (hard_lim > 0 || object_hard_limit > 0) { local = quota_local_new(); if (local == NULL) { op_errno = ENOMEM; goto err; } frame->local = local; local->loc.inode = inode_ref(fd->inode); } if (hard_lim > 0) { local->limit.hl = hard_lim; local->limit.sl = soft_lim; } if (object_hard_limit > 0) { local->object_limit.hl = object_hard_limit; local->object_limit.sl = object_soft_limit; } STACK_WIND(frame, quota_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; err: QUOTA_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; } int quota_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { QUOTA_STACK_UNWIND(removexattr, frame, op_ret, op_errno, xdata); return 0; } int quota_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t op_errno = EINVAL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); VALIDATE_OR_GOTO(this, err); /* all quota xattrs can be cleaned up by doing setxattr on special key. * Hence its ok that we don't allow removexattr on quota keys here. */ if (frame->root->pid >= 0) { GF_IF_NATIVE_XATTR_GOTO("trusted.glusterfs.quota*", name, op_errno, err); GF_IF_NATIVE_XATTR_GOTO("trusted.pgfid*", name, op_errno, err); } VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(loc, err); STACK_WIND(frame, quota_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; err: QUOTA_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; } int quota_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { QUOTA_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, xdata); return 0; } int quota_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { quota_priv_t *priv = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); VALIDATE_OR_GOTO(frame, err); VALIDATE_OR_GOTO(this, err); VALIDATE_OR_GOTO(fd, err); if (frame->root->pid >= 0) { GF_IF_NATIVE_XATTR_GOTO("trusted.glusterfs.quota*", name, op_errno, err); GF_IF_NATIVE_XATTR_GOTO("trusted.pgfid*", name, op_errno, err); } STACK_WIND(frame, quota_fremovexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; err: QUOTA_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; } int32_t quota_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata) { inode_t *inode = NULL; uint64_t value = 0; int64_t usage = -1; int64_t avail = -1; int64_t blocks = 0; quota_inode_ctx_t *ctx = NULL; int ret = 0; inode = cookie; /* This fop will fail mostly in case of client disconnect, * which is already logged. Hence, not logging here */ if (op_ret == -1) goto unwind; /* * We should never get here unless quota_statfs (below) sent us a * cookie, and it would only do so if the value was non-NULL. This * check is therefore just routine defensive coding. */ GF_VALIDATE_OR_GOTO("quota", inode, unwind); inode_ctx_get(inode, this, &value); ctx = (quota_inode_ctx_t *)(unsigned long)value; if (!ctx || ctx->hard_lim <= 0) goto unwind; { /* statfs is adjusted in this code block */ usage = (ctx->size) / buf->f_bsize; blocks = ctx->hard_lim / buf->f_bsize; buf->f_blocks = blocks; avail = buf->f_blocks - usage; avail = max(avail, 0); buf->f_bfree = avail; /* * We have to assume that the total assigned quota * won't cause us to dip into the reserved space, * because dealing with the overcommitted cases is * just too hairy (especially when different bricks * might be using different reserved percentages and * such). */ buf->f_bavail = buf->f_bfree; } xdata = xdata ? dict_ref(xdata) : dict_new(); if (!xdata) goto unwind; ret = dict_set_int8(xdata, "quota-deem-statfs", 1); if (-1 == ret) gf_msg(this->name, GF_LOG_ERROR, ENOMEM, Q_MSG_ENOMEM, "Dict set failed, deem-statfs option may " "have no effect"); unwind: QUOTA_STACK_UNWIND(statfs, frame, op_ret, op_errno, buf, xdata); if (xdata) dict_unref(xdata); return 0; } int32_t quota_statfs_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { quota_local_t *local = frame->local; int op_errno = EINVAL; GF_VALIDATE_OR_GOTO("quota", local, err); if (-1 == local->op_ret) { op_errno = local->op_errno; goto err; } STACK_WIND_COOKIE(frame, quota_statfs_cbk, local->inode, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, loc, xdata); return 0; err: QUOTA_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); return 0; } int32_t quota_statfs_validate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { quota_local_t *local = NULL; int32_t ret = 0; quota_inode_ctx_t *ctx = NULL; uint64_t value = 0; quota_meta_t size = { 0, }; local = frame->local; if (op_ret < 0) goto resume; GF_ASSERT(local); GF_ASSERT(frame); GF_VALIDATE_OR_GOTO_WITH_ERROR("quota", this, resume, op_errno, EINVAL); GF_VALIDATE_OR_GOTO_WITH_ERROR(this->name, xdata, resume, op_errno, EINVAL); ret = inode_ctx_get(local->validate_loc.inode, this, &value); ctx = (quota_inode_ctx_t *)(unsigned long)value; if ((ret == -1) || (ctx == NULL)) { gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_INODE_CTX_GET_FAILED, "quota context is not present in inode (gfid:%s)", uuid_utoa(local->validate_loc.inode->gfid)); op_errno = EINVAL; goto resume; } ret = quota_dict_get_meta(xdata, QUOTA_SIZE_KEY, SLEN(QUOTA_SIZE_KEY), &size); if (ret == -1) { gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_SIZE_KEY_MISSING, "size key not present in " "dict"); op_errno = EINVAL; } LOCK(&ctx->lock); { ctx->size = size.size; ctx->validate_time = gf_time(); ctx->file_count = size.file_count; ctx->dir_count = size.dir_count; } UNLOCK(&ctx->lock); resume: local->op_errno = op_errno; quota_link_count_decrement(frame); return 0; } void quota_get_limit_dir_continuation(struct list_head *parents, inode_t *inode, int32_t op_ret, int32_t op_errno, void *data) { call_frame_t *frame = NULL; xlator_t *this = NULL; quota_dentry_t *entry = NULL; inode_t *parent = NULL; frame = data; this = THIS; if ((op_ret < 0) || list_empty(parents)) { if (op_ret >= 0) { gf_msg(this->name, GF_LOG_WARNING, EIO, Q_MSG_ANCESTRY_BUILD_FAILED, "Couldn't build ancestry for inode (gfid:%s). " "Without knowing ancestors till root, quota " "cannot be enforced. " "Hence, failing fop with EIO", uuid_utoa(inode->gfid)); op_errno = EIO; } quota_handle_validate_error(frame, -1, op_errno); goto out; } entry = list_entry(parents, quota_dentry_t, next); parent = inode_find(inode->table, entry->par); quota_get_limit_dir(frame, parent, this); inode_unref(parent); out: return; } void quota_statfs_continue(call_frame_t *frame, xlator_t *this, inode_t *inode) { quota_local_t *local = frame->local; int ret = -1; LOCK(&local->lock); { local->inode = inode_ref(inode); } UNLOCK(&local->lock); ret = quota_validate(frame, local->inode, this, quota_statfs_validate_cbk); if (0 > ret) quota_handle_validate_error(frame, -1, -ret); } void quota_get_limit_dir(call_frame_t *frame, inode_t *cur_inode, xlator_t *this) { inode_t *inode = NULL; inode_t *parent = NULL; uint64_t value = 0; quota_inode_ctx_t *ctx = NULL; quota_local_t *local = frame->local; if (!cur_inode) goto out; inode = inode_ref(cur_inode); while (inode) { value = 0; inode_ctx_get(inode, this, &value); if (value) { ctx = (quota_inode_ctx_t *)(unsigned long)value; if (ctx->hard_lim > 0) break; } if (__is_root_gfid(inode->gfid)) goto off; parent = inode_parent(inode, 0, NULL); if (!parent) { (void)quota_build_ancestry(inode, quota_get_limit_dir_continuation, frame); goto out; } inode_unref(inode); inode = parent; } quota_statfs_continue(frame, this, inode); inode_unref(inode); return; off: gf_msg_debug(this->name, 0, "No limit set on the inode or it's parents."); QUOTA_STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, &local->loc, local->xdata); out: inode_unref(inode); return; } int32_t quota_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int op_errno = 0; int ret = -1; int8_t ignore_deem_statfs = 0; quota_priv_t *priv = NULL; quota_local_t *local = NULL; call_stub_t *stub = NULL; priv = this->private; GF_ASSERT(loc); WIND_IF_QUOTAOFF(priv->is_quota_on, off); ret = dict_get_int8(xdata, GF_INTERNAL_IGNORE_DEEM_STATFS, &ignore_deem_statfs); ret = 0; if (ignore_deem_statfs) goto off; if (priv->consider_statfs && loc->inode) { local = quota_local_new(); if (!local) { op_errno = ENOMEM; goto err; } frame->local = local; ret = loc_copy(&local->loc, loc); if (-1 == ret) { op_errno = ENOMEM; goto err; } if (xdata) local->xdata = dict_ref(xdata); stub = fop_statfs_stub(frame, quota_statfs_helper, &local->loc, local->xdata); if (!stub) { op_errno = ENOMEM; goto err; } LOCK(&local->lock); { local->link_count = 1; local->stub = stub; } UNLOCK(&local->lock); quota_get_limit_dir(frame, loc->inode, this); return 0; } /* * We have to make sure that we never get to quota_statfs_cbk * with a cookie that points to something other than an inode, * which is exactly what would happen with STACK_UNWIND using * that as a callback. Therefore, use default_statfs_cbk in * this case instead. * * Also if the option deem-statfs is not set to "on" don't * bother calculating quota limit on / in statfs_cbk. */ if (priv->consider_statfs) gf_log(this->name, GF_LOG_ERROR, "Missing inode, can't adjust for quota"); off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, loc, xdata); return 0; err: QUOTA_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); return 0; } int quota_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata) { gf_dirent_t *entry = NULL; quota_local_t *local = NULL; loc_t loc = { 0, }; if (op_ret <= 0) goto unwind; local = frame->local; list_for_each_entry(entry, &entries->list, list) { /* skip . and .. */ if (entry->inode == NULL || inode_dir_or_parentdir(entry)) continue; gf_uuid_copy(loc.gfid, entry->d_stat.ia_gfid); loc.inode = inode_ref(entry->inode); loc.parent = inode_ref(local->loc.inode); gf_uuid_copy(loc.pargfid, loc.parent->gfid); loc.name = entry->d_name; quota_fill_inodectx(this, entry->inode, entry->dict, &loc, &entry->d_stat, &op_errno); loc_wipe(&loc); } unwind: QUOTA_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata); return 0; } int quota_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *dict) { quota_priv_t *priv = NULL; int ret = 0; gf_boolean_t new_dict = _gf_false; quota_local_t *local = NULL; priv = this->private; WIND_IF_QUOTAOFF(priv->is_quota_on, off); local = quota_local_new(); if (local == NULL) { goto err; } frame->local = local; local->loc.inode = inode_ref(fd->inode); if (dict == NULL) { dict = dict_new(); new_dict = _gf_true; } if (dict) { ret = dict_set_int8(dict, QUOTA_LIMIT_KEY, 1); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "dict set of key for hard-limit"); goto err; } } if (dict) { ret = dict_set_int8(dict, QUOTA_LIMIT_OBJECTS_KEY, 1); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "dict set of key for hard-limit " "failed"); goto err; } } STACK_WIND(frame, quota_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); if (new_dict) { dict_unref(dict); } return 0; err: STACK_UNWIND_STRICT(readdirp, frame, -1, EINVAL, NULL, NULL); if (new_dict) { dict_unref(dict); } return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); return 0; } int32_t quota_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { int32_t ret = 0; uint64_t ctx_int = 0; quota_inode_ctx_t *ctx = NULL; quota_local_t *local = NULL; local = frame->local; if ((op_ret < 0) || (local == NULL)) { goto out; } ret = inode_ctx_get(local->loc.inode, this, &ctx_int); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED, "%s: failed to get the context", local->loc.path); goto out; } ctx = (quota_inode_ctx_t *)(unsigned long)ctx_int; if (ctx == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED, "quota context not set in %s (gfid:%s)", local->loc.path, uuid_utoa(local->loc.inode->gfid)); goto out; } LOCK(&ctx->lock); { ctx->buf = *postbuf; } UNLOCK(&ctx->lock); out: QUOTA_STACK_UNWIND(fallocate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t quota_fallocate_helper(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { quota_local_t *local = NULL; int32_t op_errno = EINVAL; local = frame->local; GF_VALIDATE_OR_GOTO("quota", local, unwind); if (local->op_ret == -1) { op_errno = local->op_errno; if (op_errno == ENOENT || op_errno == ESTALE) { /* We may get ENOENT/ESTALE in case of below scenario * fd = open file.txt * unlink file.txt * fallocate on fd * Here build_ancestry can fail as the file is removed. * For now ignore ENOENT/ESTALE on active fd * We need to re-visit this code once we understand * how other file-system behave in this scenario */ gf_msg_debug(this->name, 0, "quota enforcer failed " "with ENOENT/ESTALE on %s, cannot check " "quota limits and allowing fallocate", uuid_utoa(fd->inode->gfid)); } else { goto unwind; } } STACK_WIND(frame, quota_fallocate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, xdata); return 0; unwind: QUOTA_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); return 0; } int32_t quota_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { int32_t op_errno = EINVAL; int32_t parents = 0; int32_t fail_count = 0; quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; quota_priv_t *priv = NULL; quota_dentry_t *dentry = NULL; quota_dentry_t *tmp = NULL; call_stub_t *stub = NULL; struct list_head head = { 0, }; inode_t *par_inode = NULL; priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, unwind); WIND_IF_QUOTAOFF(priv->is_quota_on, off); INIT_LIST_HEAD(&head); GF_ASSERT(frame); GF_VALIDATE_OR_GOTO("quota", this, unwind); GF_VALIDATE_OR_GOTO(this->name, fd, unwind); local = quota_local_new(); if (local == NULL) { goto unwind; } frame->local = local; local->loc.inode = inode_ref(fd->inode); (void)quota_inode_ctx_get(fd->inode, this, &ctx, 0); if (ctx == NULL) { gf_msg_debug(this->name, 0, "quota context is NULL on inode" " (%s). If quota is not enabled recently and " "crawler has finished crawling, its an error", uuid_utoa(local->loc.inode->gfid)); } stub = fop_fallocate_stub(frame, quota_fallocate_helper, fd, mode, offset, len, xdata); if (stub == NULL) { op_errno = ENOMEM; goto unwind; } priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, unwind); parents = quota_add_parents_from_ctx(ctx, &head); if (parents == -1) { op_errno = errno; goto unwind; } /* * Note that by using len as the delta we're assuming the range from * offset to offset+len has not already been allocated. This can result * in ENOSPC errors attempting to allocate an already allocated range. */ local->delta = len; local->object_delta = 0; local->stub = stub; local->link_count = parents; if (parents == 0) { local->link_count = 1; quota_check_limit(frame, fd->inode, this); } else { list_for_each_entry_safe(dentry, tmp, &head, next) { par_inode = do_quota_check_limit(frame, fd->inode, this, dentry, _gf_false); if (par_inode == NULL) { /* remove stale entry from inode_ctx */ quota_dentry_del(ctx, dentry->name, dentry->par); parents--; fail_count++; } else { inode_unref(par_inode); } __quota_dentry_free(dentry); } if (parents == 0) { LOCK(&local->lock); { local->link_count++; } UNLOCK(&local->lock); quota_check_limit(frame, fd->inode, this); } while (fail_count != 0) { quota_link_count_decrement(frame); fail_count--; } } return 0; unwind: QUOTA_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); return 0; off: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, xdata); return 0; } void quota_log_helper(char **usage_str, int64_t cur_size, inode_t *inode, char **path, time_t *cur_time) { xlator_t *this = THIS; if (!usage_str || !inode || !path || !cur_time) { gf_log(this->name, GF_LOG_ERROR, "Received null argument"); return; } *usage_str = gf_uint64_2human_readable(cur_size); if (!(*usage_str)) gf_msg(this->name, GF_LOG_ERROR, ENOMEM, Q_MSG_ENOMEM, "integer to string conversion failed Reason" ":\"Cannot allocate memory\""); inode_path(inode, NULL, path); if (!(*path)) *path = uuid_utoa(inode->gfid); *cur_time = gf_time(); } /* Logs if * i. Usage crossed soft limit * ii. Usage above soft limit and alert-time elapsed */ void quota_log_usage(xlator_t *this, quota_inode_ctx_t *ctx, inode_t *inode, int64_t delta) { time_t cur_time = 0; char *usage_str = NULL; char *path = NULL; int64_t cur_size = 0; quota_priv_t *priv = NULL; priv = this->private; cur_size = ctx->size + delta; if ((ctx->soft_lim <= 0) || cur_size < ctx->soft_lim) return; /* Usage crossed/reached soft limit */ if (DID_REACH_LIMIT(ctx->soft_lim, ctx->size, cur_size)) { quota_log_helper(&usage_str, cur_size, inode, &path, &cur_time); gf_msg(this->name, GF_LOG_ALERT, 0, Q_MSG_CROSSED_SOFT_LIMIT, "Usage crossed soft limit: " "%s used by %s", usage_str, path); gf_event(EVENT_QUOTA_CROSSED_SOFT_LIMIT, "Usage=%s;volume=%s;" "path=%s", usage_str, priv->volume_uuid, path); ctx->prev_log_time = cur_time; } /* Usage is above soft limit */ else if (cur_size > ctx->soft_lim && quota_timeout(ctx->prev_log_time, priv->log_timeout)) { quota_log_helper(&usage_str, cur_size, inode, &path, &cur_time); gf_msg(this->name, GF_LOG_ALERT, 0, Q_MSG_CROSSED_SOFT_LIMIT, "Usage is above soft limit: %s used by %s", usage_str, path); gf_event(EVENT_QUOTA_CROSSED_SOFT_LIMIT, "Usage=%s;volume=%s;" "path=%s", usage_str, priv->volume_uuid, path); ctx->prev_log_time = cur_time; } if (path) GF_FREE(path); if (usage_str) GF_FREE(usage_str); } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_quota_mt_end); if (ret != 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "Memory accounting init failed"); return ret; } return ret; } int32_t quota_forget(xlator_t *this, inode_t *inode) { int32_t ret = 0; uint64_t ctx_int = 0; quota_inode_ctx_t *ctx = NULL; quota_dentry_t *dentry = NULL, *tmp; ret = inode_ctx_del(inode, this, &ctx_int); if (ret < 0) { return 0; } ctx = (quota_inode_ctx_t *)(long)ctx_int; LOCK(&ctx->lock); { list_for_each_entry_safe(dentry, tmp, &ctx->parents, next) { __quota_dentry_free(dentry); } } UNLOCK(&ctx->lock); LOCK_DESTROY(&ctx->lock); GF_FREE(ctx); return 0; } int notify(xlator_t *this, int event, void *data, ...) { quota_priv_t *priv = NULL; int ret = 0; rpc_clnt_t *rpc = NULL; gf_boolean_t conn_status = _gf_true; xlator_t *victim = data; priv = this->private; if (!priv || !priv->is_quota_on) goto out; if (event == GF_EVENT_PARENT_DOWN) { rpc = priv->rpc_clnt; if (rpc) { rpc_clnt_disable(rpc); pthread_mutex_lock(&priv->conn_mutex); { conn_status = priv->conn_status; while (conn_status) { (void)pthread_cond_wait(&priv->conn_cond, &priv->conn_mutex); conn_status = priv->conn_status; } } pthread_mutex_unlock(&priv->conn_mutex); gf_log(this->name, GF_LOG_INFO, "Notify GF_EVENT_PARENT_DOWN for brick %s", victim->name); } } out: ret = default_notify(this, event, data); return ret; } int32_t init(xlator_t *this) { int32_t ret = -1; quota_priv_t *priv = NULL; rpc_clnt_t *rpc = NULL; if ((this->children == NULL) || this->children->next) { gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_INVALID_VOLFILE, "FATAL: quota (%s) not configured with " "exactly one child", this->name); return -1; } if (this->parents == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INVALID_VOLFILE, "dangling volume. check volfile"); } QUOTA_ALLOC_OR_GOTO(priv, quota_priv_t, err); LOCK_INIT(&priv->lock); this->private = priv; GF_OPTION_INIT("deem-statfs", priv->consider_statfs, bool, err); GF_OPTION_INIT("server-quota", priv->is_quota_on, bool, err); GF_OPTION_INIT("default-soft-limit", priv->default_soft_lim, percent, err); GF_OPTION_INIT("soft-timeout", priv->soft_timeout, time, err); GF_OPTION_INIT("hard-timeout", priv->hard_timeout, time, err); GF_OPTION_INIT("alert-time", priv->log_timeout, time, err); GF_OPTION_INIT("volume-uuid", priv->volume_uuid, str, err); this->local_pool = mem_pool_new(quota_local_t, 64); if (!this->local_pool) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, Q_MSG_ENOMEM, "failed to create local_t's memory pool"); goto err; } pthread_mutex_init(&priv->conn_mutex, NULL); pthread_cond_init(&priv->conn_cond, NULL); priv->conn_status = _gf_false; if (priv->is_quota_on) { rpc = quota_enforcer_init(this, this->options); if (rpc == NULL) { ret = -1; gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_QUOTA_ENFORCER_RPC_INIT_FAILED, "quota enforcer rpc init failed"); goto err; } LOCK(&priv->lock); { priv->rpc_clnt = rpc; } UNLOCK(&priv->lock); } ret = 0; err: return ret; } int reconfigure(xlator_t *this, dict_t *options) { int32_t ret = -1; quota_priv_t *priv = NULL; gf_boolean_t quota_on = _gf_false; rpc_clnt_t *rpc = NULL; priv = this->private; GF_OPTION_RECONF("deem-statfs", priv->consider_statfs, options, bool, out); GF_OPTION_RECONF("server-quota", quota_on, options, bool, out); GF_OPTION_RECONF("default-soft-limit", priv->default_soft_lim, options, percent, out); GF_OPTION_RECONF("alert-time", priv->log_timeout, options, time, out); GF_OPTION_RECONF("soft-timeout", priv->soft_timeout, options, time, out); GF_OPTION_RECONF("hard-timeout", priv->hard_timeout, options, time, out); if (quota_on) { priv->rpc_clnt = quota_enforcer_init(this, this->options); if (priv->rpc_clnt == NULL) { ret = -1; gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_QUOTA_ENFORCER_RPC_INIT_FAILED, "quota enforcer rpc init failed"); goto out; } } else { LOCK(&priv->lock); { rpc = priv->rpc_clnt; priv->rpc_clnt = NULL; } UNLOCK(&priv->lock); if (rpc != NULL) { // Quotad is shutdown when there is no started volume // which has quota enabled. So, we should disable the // enforcer client when quota is disabled on a volume, // to avoid spurious reconnect attempts to a service // (quotad), that is known to be down. rpc_clnt_unref(rpc); } } priv->is_quota_on = quota_on; ret = 0; out: return ret; } int32_t quota_priv_dump(xlator_t *this) { quota_priv_t *priv = NULL; int32_t ret = -1; GF_ASSERT(this); priv = this->private; if (!priv) goto out; gf_proc_dump_add_section("xlators.features.quota.priv"); ret = TRY_LOCK(&priv->lock); if (ret) goto out; else { gf_proc_dump_write("soft-timeout", "%ld", priv->soft_timeout); gf_proc_dump_write("hard-timeout", "%ld", priv->hard_timeout); gf_proc_dump_write("alert-time", "%ld", priv->log_timeout); gf_proc_dump_write("quota-on", "%d", priv->is_quota_on); gf_proc_dump_write("statfs", "%d", priv->consider_statfs); gf_proc_dump_write("volume-uuid", "%s", priv->volume_uuid); gf_proc_dump_write("validation-count", "%" PRIu64, priv->validation_count); } UNLOCK(&priv->lock); out: return 0; } void fini(xlator_t *this) { quota_priv_t *priv = NULL; rpc_clnt_t *rpc = NULL; priv = this->private; if (!priv) return; rpc = priv->rpc_clnt; priv->rpc_clnt = NULL; if (rpc) { rpc_clnt_connection_cleanup(&rpc->conn); rpc_clnt_unref(rpc); } this->private = NULL; LOCK_DESTROY(&priv->lock); pthread_mutex_destroy(&priv->conn_mutex); pthread_cond_destroy(&priv->conn_cond); GF_FREE(priv); if (this->local_pool) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; } return; } struct xlator_fops fops = { .statfs = quota_statfs, .lookup = quota_lookup, .writev = quota_writev, .create = quota_create, .mkdir = quota_mkdir, .truncate = quota_truncate, .ftruncate = quota_ftruncate, .unlink = quota_unlink, .symlink = quota_symlink, .link = quota_link, .rename = quota_rename, .getxattr = quota_getxattr, .fgetxattr = quota_fgetxattr, .stat = quota_stat, .fstat = quota_fstat, .readlink = quota_readlink, .readv = quota_readv, .fsync = quota_fsync, .setattr = quota_setattr, .fsetattr = quota_fsetattr, .mknod = quota_mknod, .setxattr = quota_setxattr, .fsetxattr = quota_fsetxattr, .removexattr = quota_removexattr, .fremovexattr = quota_fremovexattr, .readdirp = quota_readdirp, .fallocate = quota_fallocate, }; struct xlator_cbks cbks = {.forget = quota_forget}; struct xlator_dumpops dumpops = { .priv = quota_priv_dump, }; struct volume_options options[] = { { .key = {"enable"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "enable is the volume option that can be used " "to turn on quota.", .op_version = {1}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .level = OPT_STATUS_BASIC, .tags = {}, }, { .key = {"deem-statfs"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", .description = "If set to on, it takes quota limits into" " consideration while estimating fs size. (df command)" " (Default is on).", .op_version = {2}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {}, }, { .key = {"server-quota"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "Skip the quota enforcement if the feature is" " not turned on. This is not a user exposed option.", .flags = OPT_FLAG_NONE, }, { .key = {"default-soft-limit"}, .type = GF_OPTION_TYPE_PERCENT, .default_value = "80%", .op_version = {3}, .description = "Soft limit is expressed as a proportion of hard limit." " Default-soft-limit is the proportion used when the " " user does not supply any soft limit value.", .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {}, }, { .key = {"soft-timeout"}, .type = GF_OPTION_TYPE_TIME, .min = 0, .max = 1800, .default_value = "60", .description = "quota caches the directory sizes on client. " "soft-timeout indicates the timeout for the validity of" " cache before soft-limit has been crossed.", .op_version = {3}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {}, }, { .key = {"hard-timeout"}, .type = GF_OPTION_TYPE_TIME, .min = 0, .max = 60, .default_value = "5", .description = "quota caches the directory sizes on client. " "hard-timeout indicates the timeout for the validity of" " cache after soft-limit has been crossed.", .op_version = {3}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {}, }, {.key = {"volume-uuid"}, .type = GF_OPTION_TYPE_STR, .default_value = "{{ volume.id }}", .description = "uuid of the volume this brick is part of."}, { .key = {"alert-time"}, .type = GF_OPTION_TYPE_TIME, .min = 0, .max = 7 * 86400, .default_value = "86400", .op_version = {3}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .description = "Frequency of limit breach messages in log.", .tags = {}, }, {.key = {NULL}}}; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "quota", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quotad.c0000644000000000000000000000013214522202451023253 xustar000000000000000030 mtime=1699284265.685027486 30 atime=1699284265.685027486 30 ctime=1699284303.404141095 glusterfs-11.1/xlators/features/quota/src/quotad.c0000664000175100017510000001240414522202451023533 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "quota.h" #include "quotad-aggregator.h" int qd_notify(xlator_t *this, int32_t event, void *data, ...) { switch (event) { case GF_EVENT_PARENT_UP: quotad_aggregator_init(this); } default_notify(this, event, data); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_quota_mt_end); if (0 != ret) { gf_log(this->name, GF_LOG_WARNING, "Memory accounting " "init failed"); return ret; } return ret; } int32_t qd_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { quotad_aggregator_lookup_cbk_t lookup_cbk = NULL; gfs3_lookup_rsp rsp = { 0, }; lookup_cbk = cookie; rsp.op_ret = op_ret; rsp.op_errno = op_errno; gf_stat_from_iatt(&rsp.postparent, postparent); GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&rsp.xdata.xdata_val), rsp.xdata.xdata_len, rsp.op_errno, out); gf_stat_from_iatt(&rsp.stat, buf); out: lookup_cbk(this, frame, &rsp); GF_FREE(rsp.xdata.xdata_val); inode_unref(inode); return 0; } xlator_t * qd_find_subvol(xlator_t *this, char *volume_uuid) { xlator_list_t *child = NULL; xlator_t *subvol = NULL; char key[1024]; int keylen = 0; char *optstr = NULL; if (!this || !volume_uuid) goto out; for (child = this->children; child; child = child->next) { keylen = snprintf(key, sizeof(key), "%s.volume-id", child->xlator->name); if (dict_get_strn(this->options, key, keylen, &optstr) < 0) continue; if (strcmp(optstr, volume_uuid) == 0) { subvol = child->xlator; break; } } out: return subvol; } int qd_nameless_lookup(xlator_t *this, call_frame_t *frame, char *gfid, dict_t *xdata, char *volume_uuid, quotad_aggregator_lookup_cbk_t lookup_cbk) { gfs3_lookup_rsp rsp = { 0, }; int op_errno = 0, ret = -1; loc_t loc = { 0, }; quotad_aggregator_state_t *state = NULL; xlator_t *subvol = NULL; state = frame->root->state; frame->root->op = GF_FOP_LOOKUP; loc.inode = inode_new(state->itable); if (loc.inode == NULL) { op_errno = ENOMEM; goto out; } memcpy(loc.gfid, gfid, 16); ret = dict_set_int8(xdata, QUOTA_READ_ONLY_KEY, 1); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM, "dict set failed"); ret = -ENOMEM; goto out; } subvol = qd_find_subvol(this, volume_uuid); if (subvol == NULL) { op_errno = EINVAL; goto out; } STACK_WIND_COOKIE(frame, qd_lookup_cbk, lookup_cbk, subvol, subvol->fops->lookup, &loc, xdata); return 0; out: rsp.op_ret = -1; rsp.op_errno = op_errno; lookup_cbk(this, frame, &rsp); inode_unref(loc.inode); return 0; } int qd_reconfigure(xlator_t *this, dict_t *options) { /* As of now quotad is restarted upon alteration of volfile */ return 0; } void qd_fini(xlator_t *this) { quota_priv_t *priv = NULL; if (this == NULL || this->private == NULL) goto out; priv = this->private; if (priv->rpcsvc) { GF_FREE(priv->rpcsvc); priv->rpcsvc = NULL; } GF_FREE(priv); out: return; } int32_t qd_init(xlator_t *this) { int32_t ret = -1; quota_priv_t *priv = NULL; if (NULL == this->children) { gf_log(this->name, GF_LOG_ERROR, "FATAL: quota (%s) not configured for min of 1 child", this->name); ret = -1; goto err; } QUOTA_ALLOC_OR_GOTO(priv, quota_priv_t, err); LOCK_INIT(&priv->lock); this->private = priv; ret = 0; err: if (ret) { GF_FREE(priv); } return ret; } struct xlator_fops fops = {}; struct xlator_cbks cbks = {}; struct volume_options options[] = { {.key = {"transport-type"}, .value = {"rpc", "rpc-over-rdma", "tcp", "socket", "ib-verbs", "unix", "ib-sdp", "tcp/server", "ib-verbs/server", "rdma", "rdma*([ \t]),*([ \t])socket", "rdma*([ \t]),*([ \t])tcp", "tcp*([ \t]),*([ \t])rdma", "socket*([ \t]),*([ \t])rdma"}, .type = GF_OPTION_TYPE_STR}, { .key = {"transport.*"}, .type = GF_OPTION_TYPE_ANY, }, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = qd_init, .fini = qd_fini, .reconfigure = qd_reconfigure, .notify = qd_notify, .mem_acct_init = mem_acct_init, .op_version = {1}, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "quotad", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quota.h0000644000000000000000000000013214522202451023114 xustar000000000000000030 mtime=1699284265.684027483 30 atime=1699284265.684027483 30 ctime=1699284303.393141062 glusterfs-11.1/xlators/features/quota/src/quota.h0000664000175100017510000002467314522202451023407 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _QUOTA_H #define _QUOTA_H #include #include "quota-mem-types.h" #include #include #include #include #include "rpc-clnt.h" #include "glusterfs3.h" #include #include #include "quota-messages.h" #define DIRTY "dirty" #define SIZE "size" #define CONTRIBUTION "contri" #define VAL_LENGTH 8 #define READDIR_BUF 4096 #define WIND_IF_QUOTAOFF(is_quota_on, label) \ if (!is_quota_on) \ goto label; #define QUOTA_WIND_FOR_INTERNAL_FOP(xdata, label) \ do { \ if (xdata && dict_get_sizen(xdata, GLUSTERFS_INTERNAL_FOP_KEY)) \ goto label; \ } while (0) #define DID_REACH_LIMIT(lim, prev_size, cur_size) \ ((cur_size) >= (lim) && (prev_size) < (lim)) #define QUOTA_SAFE_INCREMENT(lock, var) \ do { \ LOCK(lock); \ var++; \ UNLOCK(lock); \ } while (0) #define QUOTA_SAFE_DECREMENT(lock, var) \ do { \ LOCK(lock); \ var--; \ UNLOCK(lock); \ } while (0) #define QUOTA_ALLOC_OR_GOTO(var, type, label) \ do { \ var = GF_CALLOC(sizeof(type), 1, gf_quota_mt_##type); \ if (!var) { \ gf_msg("", GF_LOG_ERROR, ENOMEM, Q_MSG_ENOMEM, "out of memory"); \ ret = -1; \ goto label; \ } \ } while (0); #define QUOTA_STACK_WIND_TAIL(frame, params...) \ do { \ quota_local_t *_local = NULL; \ \ if (frame) { \ _local = frame->local; \ frame->local = NULL; \ } \ \ STACK_WIND_TAIL(frame, params); \ \ if (_local) \ quota_local_cleanup(_local); \ } while (0) #define QUOTA_STACK_UNWIND(fop, frame, params...) \ do { \ quota_local_t *_local = NULL; \ if (frame) { \ _local = frame->local; \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ quota_local_cleanup(_local); \ } while (0) #define QUOTA_FREE_CONTRIBUTION_NODE(_contribution) \ do { \ list_del(&_contribution->contri_list); \ GF_FREE(_contribution); \ } while (0) #define GET_CONTRI_KEY(var, _vol_name, _gfid, _ret) \ do { \ char _gfid_unparsed[40]; \ if (_gfid != NULL) { \ gf_uuid_unparse(_gfid, _gfid_unparsed); \ _ret = gf_asprintf(var, QUOTA_XATTR_PREFIX "%s.%s." CONTRIBUTION, \ _vol_name, _gfid_unparsed); \ } else { \ _ret = gf_asprintf(var, QUOTA_XATTR_PREFIX "%s.." CONTRIBUTION, \ _vol_name); \ } \ } while (0) #define GET_CONTRI_KEY_OR_GOTO(var, _vol_name, _gfid, label) \ do { \ GET_CONTRI_KEY(var, _vol_name, _gfid, ret); \ if (ret == -1) \ goto label; \ } while (0) #define GET_DIRTY_KEY_OR_GOTO(var, _vol_name, label) \ do { \ ret = gf_asprintf(var, QUOTA_XATTR_PREFIX "%s." DIRTY, _vol_name); \ if (ret == -1) \ goto label; \ } while (0) #define QUOTA_REG_OR_LNK_FILE(ia_type) (IA_ISREG(ia_type) || IA_ISLNK(ia_type)) struct quota_dentry { char *name; uuid_t par; struct list_head next; }; typedef struct quota_dentry quota_dentry_t; struct quota_inode_ctx { int64_t size; int64_t hard_lim; int64_t soft_lim; int64_t file_count; int64_t dir_count; int64_t object_hard_lim; int64_t object_soft_lim; struct iatt buf; struct list_head parents; time_t validate_time; time_t prev_log_time; gf_boolean_t ancestry_built; gf_lock_t lock; }; typedef struct quota_inode_ctx quota_inode_ctx_t; typedef void (*quota_ancestry_built_t)(struct list_head *parents, inode_t *inode, int32_t op_ret, int32_t op_errno, void *data); typedef void (*quota_fop_continue_t)(call_frame_t *frame); struct quota_local { gf_lock_t lock; uint32_t link_count; loc_t loc; loc_t oldloc; loc_t newloc; loc_t validate_loc; int64_t delta; int8_t object_delta; int32_t op_ret; int32_t op_errno; char just_validated; fop_lookup_cbk_t validate_cbk; quota_fop_continue_t fop_continue_cbk; inode_t *inode; uuid_t common_ancestor; /* Used by quota_rename */ call_stub_t *stub; quota_limits_t limit; quota_limits_t object_limit; int64_t space_available; quota_ancestry_built_t ancestry_cbk; void *ancestry_data; dict_t *xdata; dict_t *validate_xdata; int32_t quotad_conn_retry; xlator_t *this; call_frame_t *par_frame; }; typedef struct quota_local quota_local_t; struct quota_priv { time_t soft_timeout; time_t hard_timeout; time_t log_timeout; double default_soft_lim; gf_boolean_t is_quota_on; gf_boolean_t consider_statfs; gf_lock_t lock; rpc_clnt_prog_t *quota_enforcer; struct rpcsvc_program *quotad_aggregator; struct rpc_clnt *rpc_clnt; rpcsvc_t *rpcsvc; inode_table_t *itable; char *volume_uuid; uint64_t validation_count; int32_t quotad_conn_status; pthread_mutex_t conn_mutex; pthread_cond_t conn_cond; gf_boolean_t conn_status; }; typedef struct quota_priv quota_priv_t; int quota_enforcer_lookup(call_frame_t *frame, xlator_t *this, dict_t *xdata, fop_lookup_cbk_t cbk); void _quota_enforcer_lookup(void *data); struct rpc_clnt * quota_enforcer_init(xlator_t *this, dict_t *options); void quota_log_usage(xlator_t *this, quota_inode_ctx_t *ctx, inode_t *inode, int64_t delta); int quota_build_ancestry(inode_t *inode, quota_ancestry_built_t ancestry_cbk, void *data); void quota_get_limit_dir(call_frame_t *frame, inode_t *cur_inode, xlator_t *this); int32_t quota_check_limit(call_frame_t *frame, inode_t *inode, xlator_t *this); inode_t * do_quota_check_limit(call_frame_t *frame, inode_t *inode, xlator_t *this, quota_dentry_t *dentry, gf_boolean_t force); int quota_fill_inodectx(xlator_t *this, inode_t *inode, dict_t *dict, loc_t *loc, struct iatt *buf, int32_t *op_errno); int32_t quota_check_size_limit(call_frame_t *frame, quota_inode_ctx_t *ctx, quota_priv_t *priv, inode_t *_inode, xlator_t *this, int32_t *op_errno, int just_validated, int64_t delta, quota_local_t *local, gf_boolean_t *skip_check); int32_t quota_check_object_limit(call_frame_t *frame, quota_inode_ctx_t *ctx, quota_priv_t *priv, inode_t *_inode, xlator_t *this, int32_t *op_errno, int just_validated, quota_local_t *local, gf_boolean_t *skip_check); #endif glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quotad-helpers.h0000644000000000000000000000013214522202451024720 xustar000000000000000030 mtime=1699284265.685027486 30 atime=1699284265.685027486 30 ctime=1699284303.397141074 glusterfs-11.1/xlators/features/quota/src/quotad-helpers.h0000664000175100017510000000116514522202451025202 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef QUOTAD_HELPERS_H #define QUOTAD_HELPERS_H #include "rpcsvc.h" #include "quotad-aggregator.h" void quotad_aggregator_free_state(quotad_aggregator_state_t *state); call_frame_t * quotad_aggregator_get_frame_from_req(rpcsvc_request_t *req); #endif glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quota-mem-types.h0000644000000000000000000000013014522202451025030 xustar000000000000000029 mtime=1699284265.68302748 29 atime=1699284265.68302748 30 ctime=1699284303.391141056 glusterfs-11.1/xlators/features/quota/src/quota-mem-types.h0000664000175100017510000000133514522202451025313 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __QUOTA_MEM_TYPES_H__ #define __QUOTA_MEM_TYPES_H__ #include enum gf_quota_mem_types_ { /* Those are used by QUOTA_ALLOC_OR_GOTO macro */ gf_quota_mt_quota_priv_t = gf_common_mt_end + 1, gf_quota_mt_quota_inode_ctx_t, gf_quota_mt_quota_dentry_t, gf_quota_mt_aggregator_state_t, gf_quota_mt_end }; #endif glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quotad-aggregator.h0000644000000000000000000000013214522202451025400 xustar000000000000000030 mtime=1699284265.684027483 30 atime=1699284265.684027483 30 ctime=1699284303.395141068 glusterfs-11.1/xlators/features/quota/src/quotad-aggregator.h0000664000175100017510000000204114522202451025654 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _QUOTAD_AGGREGATOR_H #define _QUOTAD_AGGREGATOR_H #include "quota.h" #include typedef struct { void *pool; xlator_t *this; xlator_t *active_subvol; inode_table_t *itable; loc_t loc; dict_t *xdata; dict_t *req_xdata; } quotad_aggregator_state_t; typedef int (*quotad_aggregator_lookup_cbk_t)(xlator_t *this, call_frame_t *frame, void *rsp); int qd_nameless_lookup(xlator_t *this, call_frame_t *frame, char *gfid, dict_t *xdata, char *volume_uuid, quotad_aggregator_lookup_cbk_t lookup_cbk); int quotad_aggregator_init(xlator_t *this); #endif glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quotad-aggregator.c0000644000000000000000000000013214522202451025373 xustar000000000000000030 mtime=1699284265.684027483 30 atime=1699284265.684027483 30 ctime=1699284303.408141107 glusterfs-11.1/xlators/features/quota/src/quotad-aggregator.c0000664000175100017510000003173014522202451025656 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "cli1-xdr.h" #include "quota.h" #include "quotad-helpers.h" #include "quotad-aggregator.h" static char *qd_ext_xattrs[] = { QUOTA_SIZE_KEY, QUOTA_LIMIT_KEY, QUOTA_LIMIT_OBJECTS_KEY, NULL, }; static struct rpcsvc_program quotad_aggregator_prog; struct iobuf * quotad_serialize_reply(rpcsvc_request_t *req, void *arg, struct iovec *outmsg, xdrproc_t xdrproc) { struct iobuf *iob = NULL; ssize_t retlen = 0; ssize_t xdr_size = 0; GF_VALIDATE_OR_GOTO("server", req, ret); /* First, get the io buffer into which the reply in arg will * be serialized. */ if (arg && xdrproc) { xdr_size = xdr_sizeof(xdrproc, arg); iob = iobuf_get2(req->svc->ctx->iobuf_pool, xdr_size); if (!iob) { gf_log_callingfn(THIS->name, GF_LOG_ERROR, "Failed to get iobuf"); goto ret; }; iobuf_to_iovec(iob, outmsg); /* Use the given serializer to translate the given C structure * in arg to XDR format which will be written into the buffer * in outmsg. */ /* retlen is used to received the error since size_t is unsigned and we * need -1 for error notification during encoding. */ retlen = xdr_serialize_generic(*outmsg, arg, xdrproc); if (retlen == -1) { /* Failed to Encode 'GlusterFS' msg in RPC is not exactly failure of RPC return values.. Client should get notified about this, so there are no missing frames */ gf_log_callingfn("", GF_LOG_ERROR, "Failed to encode message"); req->rpc_err = GARBAGE_ARGS; retlen = 0; } } outmsg->iov_len = retlen; ret: return iob; } int quotad_aggregator_submit_reply(call_frame_t *frame, rpcsvc_request_t *req, void *arg, struct iovec *payload, int payloadcount, struct iobref *iobref, xdrproc_t xdrproc) { struct iobuf *iob = NULL; int ret = -1; struct iovec rsp = { 0, }; quotad_aggregator_state_t *state = NULL; char new_iobref = 0; GF_VALIDATE_OR_GOTO("server", req, ret); if (frame) { state = frame->root->state; frame->local = NULL; } if (!iobref) { iobref = iobref_new(); if (!iobref) { goto ret; } new_iobref = 1; } iob = quotad_serialize_reply(req, arg, &rsp, xdrproc); if (!iob) { gf_msg("", GF_LOG_ERROR, 0, Q_MSG_DICT_SERIALIZE_FAIL, "Failed to serialize reply"); goto ret; } iobref_add(iobref, iob); ret = rpcsvc_submit_generic(req, &rsp, 1, payload, payloadcount, iobref); iobuf_unref(iob); ret = 0; ret: if (state) { quotad_aggregator_free_state(state); } if (frame) STACK_DESTROY(frame->root); if (new_iobref) { iobref_unref(iobref); } return ret; } int quotad_aggregator_getlimit_cbk(xlator_t *this, call_frame_t *frame, void *lookup_rsp) { gfs3_lookup_rsp *rsp = lookup_rsp; gf_cli_rsp cli_rsp = { 0, }; dict_t *xdata = NULL; quotad_aggregator_state_t *state = NULL; int ret = -1; int type = 0; if (!rsp || (rsp->op_ret == -1)) goto reply; GF_PROTOCOL_DICT_UNSERIALIZE(frame->this, xdata, (rsp->xdata.xdata_val), (rsp->xdata.xdata_len), rsp->op_ret, rsp->op_errno, out); if (xdata) { state = frame->root->state; ret = dict_get_int32n(state->req_xdata, "type", SLEN("type"), &type); if (ret < 0) goto out; ret = dict_set_int32_sizen(xdata, "type", type); if (ret < 0) goto out; } ret = 0; out: rsp->op_ret = ret; if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_DICT_UNSERIALIZE_FAIL, "failed to unserialize " "nameless lookup rsp"); goto reply; } cli_rsp.op_ret = rsp->op_ret; cli_rsp.op_errno = rsp->op_errno; cli_rsp.op_errstr = ""; if (xdata) { GF_PROTOCOL_DICT_SERIALIZE(frame->this, xdata, (&cli_rsp.dict.dict_val), (cli_rsp.dict.dict_len), cli_rsp.op_errno, reply); } reply: quotad_aggregator_submit_reply(frame, (frame) ? frame->local : NULL, (void *)&cli_rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_cli_rsp); dict_unref(xdata); GF_FREE(cli_rsp.dict.dict_val); return 0; } int quotad_aggregator_getlimit(rpcsvc_request_t *req) { call_frame_t *frame = NULL; gf_cli_req cli_req = { {0}, }; gf_cli_rsp cli_rsp = {0}; quotad_aggregator_state_t *state = NULL; xlator_t *this = NULL; dict_t *dict = NULL; int ret = -1, op_errno = 0; char *gfid_str = NULL; uuid_t gfid = {0}; char *volume_uuid = NULL; GF_VALIDATE_OR_GOTO("quotad-aggregator", req, err); this = THIS; cli_req.dict.dict_val = alloca(req->msg[0].iov_len); ret = xdr_to_generic(req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); if (ret < 0) { // failed to decode msg; gf_msg("this->name", GF_LOG_ERROR, 0, Q_MSG_XDR_DECODE_ERROR, "xdr decoding error"); req->rpc_err = GARBAGE_ARGS; goto err; } if (cli_req.dict.dict_len) { dict = dict_new(); ret = dict_unserialize(cli_req.dict.dict_val, cli_req.dict.dict_len, &dict); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_DICT_UNSERIALIZE_FAIL, "Failed to unserialize req-buffer to " "dictionary"); goto err; } } ret = dict_get_strn(dict, "gfid", SLEN("gfid"), &gfid_str); if (ret) { goto err; } ret = dict_get_strn(dict, "volume-uuid", SLEN("volume-uuid"), &volume_uuid); if (ret) { goto err; } gf_uuid_parse((const char *)gfid_str, gfid); frame = quotad_aggregator_get_frame_from_req(req); if (frame == NULL) { cli_rsp.op_errno = ENOMEM; goto errx; } state = frame->root->state; state->req_xdata = dict; state->xdata = dict_new(); dict = NULL; ret = dict_set_int32_sizen(state->xdata, QUOTA_LIMIT_KEY, 42); if (ret) goto err; ret = dict_set_int32_sizen(state->xdata, QUOTA_LIMIT_OBJECTS_KEY, 42); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, Q_MSG_ENOMEM, "Failed to set QUOTA_LIMIT_OBJECTS_KEY"); goto err; } ret = dict_set_int32_sizen(state->xdata, QUOTA_SIZE_KEY, 42); if (ret) goto err; ret = dict_set_int32_sizen(state->xdata, GET_ANCESTRY_PATH_KEY, 42); if (ret) goto err; ret = qd_nameless_lookup(this, frame, (char *)gfid, state->xdata, volume_uuid, quotad_aggregator_getlimit_cbk); if (ret) { cli_rsp.op_errno = ret; goto errx; } return ret; err: cli_rsp.op_errno = op_errno; errx: cli_rsp.op_ret = -1; cli_rsp.op_errstr = ""; quotad_aggregator_getlimit_cbk(this, frame, &cli_rsp); if (dict) dict_unref(dict); return ret; } int quotad_aggregator_lookup_cbk(xlator_t *this, call_frame_t *frame, void *rsp) { quotad_aggregator_submit_reply(frame, frame ? frame->local : NULL, rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_lookup_rsp); return 0; } int quotad_aggregator_lookup(rpcsvc_request_t *req) { call_frame_t *frame = NULL; gfs3_lookup_req args = { { 0, }, }; int i = 0, ret = -1, op_errno = 0; gfs3_lookup_rsp rsp = { 0, }; quotad_aggregator_state_t *state = NULL; xlator_t *this = NULL; dict_t *dict = NULL; char *volume_uuid = NULL; GF_VALIDATE_OR_GOTO("quotad-aggregator", req, err); this = THIS; args.bname = alloca(req->msg[0].iov_len); args.xdata.xdata_val = alloca(req->msg[0].iov_len); ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gfs3_lookup_req); if (ret < 0) { rsp.op_errno = EINVAL; goto err; } frame = quotad_aggregator_get_frame_from_req(req); if (frame == NULL) { rsp.op_errno = ENOMEM; goto err; } state = frame->root->state; GF_PROTOCOL_DICT_UNSERIALIZE(this, dict, (args.xdata.xdata_val), (args.xdata.xdata_len), ret, op_errno, err); ret = dict_get_str(dict, "volume-uuid", &volume_uuid); if (ret) { goto err; } state->xdata = dict_new(); for (i = 0; qd_ext_xattrs[i]; i++) { if (dict_get(dict, qd_ext_xattrs[i])) { ret = dict_set_uint32(state->xdata, qd_ext_xattrs[i], 1); if (ret < 0) goto err; } } ret = qd_nameless_lookup(this, frame, args.gfid, state->xdata, volume_uuid, quotad_aggregator_lookup_cbk); if (ret) { rsp.op_errno = ret; goto err; } if (dict) dict_unref(dict); return ret; err: rsp.op_ret = -1; rsp.op_errno = op_errno; quotad_aggregator_lookup_cbk(this, frame, &rsp); if (dict) dict_unref(dict); return ret; } int quotad_aggregator_rpc_notify(rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, void *data) { if (!xl || !data) { gf_log_callingfn("server", GF_LOG_WARNING, "Calling rpc_notify without initializing"); goto out; } switch (event) { case RPCSVC_EVENT_ACCEPT: break; case RPCSVC_EVENT_DISCONNECT: break; default: break; } out: return 0; } int quotad_aggregator_init(xlator_t *this) { quota_priv_t *priv = NULL; int ret = -1; priv = this->private; if (priv->rpcsvc) { /* Listener already created */ return 0; } ret = dict_set_nstrn(this->options, "transport.address-family", SLEN("transport.address-family"), "unix", SLEN("unix")); if (ret) goto out; ret = dict_set_nstrn(this->options, "transport-type", SLEN("transport-type"), "socket", SLEN("socket")); if (ret) goto out; ret = dict_set_nstrn(this->options, "transport.socket.listen-path", SLEN("transport.socket.listen-path"), "/var/run/gluster/quotad.socket", SLEN("/var/run/gluster/quotad.socket")); if (ret) goto out; /* RPC related */ priv->rpcsvc = rpcsvc_init(this, this->ctx, this->options, 0); if (priv->rpcsvc == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_RPCSVC_INIT_FAILED, "creation of rpcsvc failed"); ret = -1; goto out; } ret = rpcsvc_create_listeners(priv->rpcsvc, this->options, this->name); if (ret < 1) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_RPCSVC_LISTENER_CREATION_FAILED, "creation of listener failed"); ret = -1; goto out; } priv->quotad_aggregator = "ad_aggregator_prog; quotad_aggregator_prog.options = this->options; ret = rpcsvc_program_register(priv->rpcsvc, "ad_aggregator_prog, _gf_false); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_RPCSVC_REGISTER_FAILED, "registration of program (name:%s, prognum:%d, " "progver:%d) failed", quotad_aggregator_prog.progname, quotad_aggregator_prog.prognum, quotad_aggregator_prog.progver); goto out; } ret = 0; out: if (ret && priv->rpcsvc) { GF_FREE(priv->rpcsvc); priv->rpcsvc = NULL; } return ret; } static rpcsvc_actor_t quotad_aggregator_actors[GF_AGGREGATOR_MAXVALUE] = { [GF_AGGREGATOR_NULL] = {"NULL", NULL, NULL, GF_AGGREGATOR_NULL, DRC_NA, 0}, [GF_AGGREGATOR_LOOKUP] = {"LOOKUP", quotad_aggregator_lookup, NULL, GF_AGGREGATOR_NULL, DRC_NA, 0}, [GF_AGGREGATOR_GETLIMIT] = {"GETLIMIT", quotad_aggregator_getlimit, NULL, GF_AGGREGATOR_GETLIMIT, DRC_NA, 0}, }; static struct rpcsvc_program quotad_aggregator_prog = { .progname = "GlusterFS 3.3", .prognum = GLUSTER_AGGREGATOR_PROGRAM, .progver = GLUSTER_AGGREGATOR_VERSION, .numactors = GF_AGGREGATOR_MAXVALUE, .actors = quotad_aggregator_actors}; glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023663 xustar000000000000000030 mtime=1699284276.793060944 30 atime=1699284290.347101768 30 ctime=1699284303.388141047 glusterfs-11.1/xlators/features/quota/src/Makefile.in0000664000175100017510000006273114522202464024153 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/quota/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) quota_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la am_quota_la_OBJECTS = quota.lo quota-enforcer-client.lo quota_la_OBJECTS = $(am_quota_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = quota_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(quota_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_quota_la_rpath = -rpath $(xlatordir) quotad_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la am_quotad_la_OBJECTS = quotad.lo quotad-helpers.lo \ quotad-aggregator.lo quotad_la_OBJECTS = $(am_quotad_la_OBJECTS) quotad_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(quotad_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_quotad_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(quota_la_SOURCES) $(quotad_la_SOURCES) DIST_SOURCES = $(quota_la_SOURCES) $(quotad_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = quota.la quotad.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features quota_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) quotad_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) quota_la_SOURCES = quota.c quota-enforcer-client.c quota_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la quotad_la_SOURCES = quotad.c quotad-helpers.c quotad-aggregator.c quotad_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la noinst_HEADERS = quota-mem-types.h quota.h quotad-aggregator.h \ quotad-helpers.h quota-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/xlators/cluster/dht/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/quota/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/quota/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } quota.la: $(quota_la_OBJECTS) $(quota_la_DEPENDENCIES) $(EXTRA_quota_la_DEPENDENCIES) $(AM_V_CCLD)$(quota_la_LINK) $(am_quota_la_rpath) $(quota_la_OBJECTS) $(quota_la_LIBADD) $(LIBS) quotad.la: $(quotad_la_OBJECTS) $(quotad_la_DEPENDENCIES) $(EXTRA_quotad_la_DEPENDENCIES) $(AM_V_CCLD)$(quotad_la_LINK) $(am_quotad_la_rpath) $(quotad_la_OBJECTS) $(quotad_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quota-enforcer-client.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quota.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quotad-aggregator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quotad-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quotad.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quota-messages.h0000644000000000000000000000013014522202451024717 xustar000000000000000029 mtime=1699284265.68302748 29 atime=1699284265.68302748 30 ctime=1699284303.398141077 glusterfs-11.1/xlators/features/quota/src/quota-messages.h0000664000175100017510000000320314522202451025176 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _QUOTA_MESSAGES_H_ #define _QUOTA_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(QUOTA, Q_MSG_ENFORCEMENT_FAILED, Q_MSG_ENOMEM, Q_MSG_PARENT_NULL, Q_MSG_CROSSED_SOFT_LIMIT, Q_MSG_QUOTA_ENFORCER_RPC_INIT_FAILED, Q_MSG_REMOTE_OPERATION_FAILED, Q_MSG_FAILED_TO_SEND_FOP, Q_MSG_INVALID_VOLFILE, Q_MSG_INODE_PARENT_NOT_FOUND, Q_MSG_XDR_DECODE_ERROR, Q_MSG_DICT_UNSERIALIZE_FAIL, Q_MSG_DICT_SERIALIZE_FAIL, Q_MSG_RPCSVC_INIT_FAILED, Q_MSG_RPCSVC_LISTENER_CREATION_FAILED, Q_MSG_RPCSVC_REGISTER_FAILED, Q_MSG_XDR_DECODING_FAILED, Q_MSG_RPCCLNT_REGISTER_NOTIFY_FAILED, Q_MSG_ANCESTRY_BUILD_FAILED, Q_MSG_SIZE_KEY_MISSING, Q_MSG_INODE_CTX_GET_FAILED, Q_MSG_INODE_CTX_SET_FAILED, Q_MSG_LOOKUP_FAILED, Q_MSG_RPC_SUBMIT_FAILED, Q_MSG_ENFORCEMENT_SKIPPED, Q_MSG_INTERNAL_FOP_KEY_MISSING); #endif /* !_QUOTA_MESSAGES_H_ */ glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023646 xustar000000000000000030 mtime=1699284265.682027477 30 atime=1699284276.754060827 30 ctime=1699284303.390141053 glusterfs-11.1/xlators/features/quota/src/Makefile.am0000664000175100017510000000211114522202451024120 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = quota.la quotad.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features quota_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) quotad_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) quota_la_SOURCES = quota.c quota-enforcer-client.c quota_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la quotad_la_SOURCES = quotad.c quotad-helpers.c quotad-aggregator.c quotad_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la noinst_HEADERS = quota-mem-types.h quota.h quotad-aggregator.h \ quotad-helpers.h quota-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/xlators/cluster/dht/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quota-enforcer-client.c0000644000000000000000000000013114522202451026163 xustar000000000000000029 mtime=1699284265.68302748 30 atime=1699284265.682027477 30 ctime=1699284303.402141089 glusterfs-11.1/xlators/features/quota/src/quota-enforcer-client.c0000664000175100017510000003014014522202451026441 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2010-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_MALLOC_H #include #endif #include "quota.h" #include "quota-messages.h" static struct rpc_clnt_program quota_enforcer_clnt; static int quota_enforcer_submit_request(void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc) { int ret = -1; int count = 0; struct iovec iov = { 0, }; struct iobuf *iobuf = NULL; struct iobref *iobref = NULL; ssize_t xdr_size = 0; quota_priv_t *priv = NULL; GF_ASSERT(req); GF_ASSERT(this); priv = this->private; xdr_size = xdr_sizeof(xdrproc, req); iobuf = iobuf_get2(this->ctx->iobuf_pool, xdr_size); if (!iobuf) { goto out; } iobref = iobref_new(); if (!iobref) { goto out; } iobref_add(iobref, iobuf); iov.iov_base = iobuf->ptr; iov.iov_len = iobuf_size(iobuf); /* Create the xdr payload */ ret = xdr_serialize_generic(iov, req, xdrproc); if (ret == -1) { goto out; } iov.iov_len = ret; count = 1; /* Send the msg */ ret = rpc_clnt_submit(priv->rpc_clnt, prog, procnum, cbkfn, &iov, count, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL); out: if (iobref) iobref_unref(iobref); if (iobuf) iobuf_unref(iobuf); return ret; } int quota_enforcer_lookup_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { quota_local_t *local = NULL; call_frame_t *frame = NULL; int ret = 0; gfs3_lookup_rsp rsp = { 0, }; struct iatt stbuf = { 0, }; struct iatt postparent = { 0, }; int op_errno = EINVAL; dict_t *xdata = NULL; inode_t *inode = NULL; xlator_t *this = NULL; quota_priv_t *priv = NULL; struct timespec retry_delay = { 0, }; gf_timer_t *timer = NULL; this = THIS; frame = myframe; local = frame->local; inode = local->validate_loc.inode; priv = this->private; if (-1 == req->rpc_status) { rsp.op_ret = -1; op_errno = ENOTCONN; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfs3_lookup_rsp); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_XDR_DECODING_FAILED, "XDR decoding failed"); rsp.op_ret = -1; op_errno = EINVAL; goto out; } op_errno = gf_error_to_errno(rsp.op_errno); gf_stat_to_iatt(&rsp.postparent, &postparent); if (rsp.op_ret == -1) goto out; rsp.op_ret = -1; gf_stat_to_iatt(&rsp.stat, &stbuf); GF_PROTOCOL_DICT_UNSERIALIZE(frame->this, xdata, (rsp.xdata.xdata_val), (rsp.xdata.xdata_len), rsp.op_ret, op_errno, out); if ((!gf_uuid_is_null(inode->gfid)) && (gf_uuid_compare(stbuf.ia_gfid, inode->gfid) != 0)) { gf_msg_debug(frame->this->name, ESTALE, "gfid changed for %s", local->validate_loc.path); rsp.op_ret = -1; op_errno = ESTALE; goto out; } rsp.op_ret = 0; out: rsp.op_errno = op_errno; /* We need to retry connecting to quotad on ENOTCONN error. * Suppose if there are two volumes vol1 and vol2, * and quota is enabled and limit is set on vol1. * Now if IO is happening on vol1 and quota is enabled/disabled * on vol2, quotad gets restarted and client will receive * ENOTCONN in the IO path of vol1 */ if (rsp.op_ret == -1 && rsp.op_errno == ENOTCONN) { if (local->quotad_conn_retry >= 12) { priv->quotad_conn_status = 1; gf_log(this->name, GF_LOG_WARNING, "failed to connect " "to quotad after retry count %d)", local->quotad_conn_retry); } else { local->quotad_conn_retry++; } if (priv->quotad_conn_status == 0) { /* retry connecting after 5secs for 12 retries * (up to 60sec). */ gf_log(this->name, GF_LOG_DEBUG, "retry connecting to " "quotad (retry count %d)", local->quotad_conn_retry); retry_delay.tv_sec = 5; retry_delay.tv_nsec = 0; timer = gf_timer_call_after(this->ctx, retry_delay, _quota_enforcer_lookup, (void *)frame); if (timer == NULL) { gf_log(this->name, GF_LOG_WARNING, "failed to " "set quota_enforcer_lookup with timer"); } else { goto clean; } } } else { priv->quotad_conn_status = 0; } if (rsp.op_ret == -1) { /* any error other than ENOENT */ if (rsp.op_errno != ENOENT) gf_msg( this->name, GF_LOG_WARNING, rsp.op_errno, Q_MSG_LOOKUP_FAILED, "Getting cluster-wide size of directory failed " "(path: %s gfid:%s)", local->validate_loc.path, loc_gfid_utoa(&local->validate_loc)); else gf_msg_trace(this->name, ENOENT, "not found on remote node"); } else if (local->quotad_conn_retry) { gf_log(this->name, GF_LOG_DEBUG, "connected to quotad after " "retry count %d", local->quotad_conn_retry); } local->validate_cbk(frame, NULL, this, rsp.op_ret, rsp.op_errno, inode, &stbuf, xdata, &postparent); clean: if (xdata) dict_unref(xdata); free(rsp.xdata.xdata_val); return 0; } void _quota_enforcer_lookup(void *data) { quota_local_t *local = NULL; gfs3_lookup_req req = { { 0, }, }; int ret = 0; int op_errno = ESTALE; quota_priv_t *priv = NULL; call_frame_t *frame = NULL; loc_t *loc = NULL; xlator_t *this = NULL; char *dir_path = NULL; frame = data; local = frame->local; this = local->this; loc = &local->validate_loc; priv = this->private; if (!(loc && loc->inode)) goto unwind; if (!gf_uuid_is_null(loc->inode->gfid)) memcpy(req.gfid, loc->inode->gfid, 16); else memcpy(req.gfid, loc->gfid, 16); if (local->validate_xdata) { GF_PROTOCOL_DICT_SERIALIZE(this, local->validate_xdata, (&req.xdata.xdata_val), req.xdata.xdata_len, op_errno, unwind); } if (loc->name) req.bname = (char *)loc->name; else req.bname = ""; if (loc->path) dir_path = (char *)loc->path; else dir_path = ""; ret = quota_enforcer_submit_request( &req, frame, priv->quota_enforcer, GF_AGGREGATOR_LOOKUP, this, quota_enforcer_lookup_cbk, (xdrproc_t)xdr_gfs3_lookup_req); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_RPC_SUBMIT_FAILED, "Couldn't send the request to " "fetch cluster wide size of directory (path:%s gfid:%s)", dir_path, req.gfid); } GF_FREE(req.xdata.xdata_val); return; unwind: local->validate_cbk(frame, NULL, this, -1, op_errno, NULL, NULL, NULL, NULL); GF_FREE(req.xdata.xdata_val); return; } int quota_enforcer_lookup(call_frame_t *frame, xlator_t *this, dict_t *xdata, fop_lookup_cbk_t validate_cbk) { quota_local_t *local = NULL; if (!frame || !this) goto unwind; local = frame->local; local->this = this; local->validate_cbk = validate_cbk; local->validate_xdata = dict_ref(xdata); _quota_enforcer_lookup(frame); return 0; unwind: validate_cbk(frame, NULL, this, -1, ESTALE, NULL, NULL, NULL, NULL); return 0; } int quota_enforcer_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, void *data) { xlator_t *this = NULL; int ret = 0; quota_priv_t *priv = NULL; this = mydata; priv = this->private; switch (event) { case RPC_CLNT_CONNECT: { pthread_mutex_lock(&priv->conn_mutex); { priv->conn_status = _gf_true; } pthread_mutex_unlock(&priv->conn_mutex); gf_msg_trace(this->name, 0, "got RPC_CLNT_CONNECT"); break; } case RPC_CLNT_DISCONNECT: { pthread_mutex_lock(&priv->conn_mutex); { priv->conn_status = _gf_false; pthread_cond_signal(&priv->conn_cond); } pthread_mutex_unlock(&priv->conn_mutex); gf_msg_trace(this->name, 0, "got RPC_CLNT_DISCONNECT"); break; } default: gf_msg_trace(this->name, 0, "got some other RPC event %d", event); ret = 0; break; } return ret; } int quota_enforcer_blocking_connect(rpc_clnt_t *rpc) { dict_t *options = NULL; int ret = -1; options = dict_new(); if (options == NULL) goto out; ret = dict_set_sizen_str_sizen(options, "non-blocking-io", "no"); if (ret) goto out; rpc->conn.trans->reconfigure(rpc->conn.trans, options); rpc_clnt_start(rpc); ret = dict_set_sizen_str_sizen(options, "non-blocking-io", "yes"); if (ret) goto out; rpc->conn.trans->reconfigure(rpc->conn.trans, options); ret = 0; out: if (options) dict_unref(options); return ret; } // Returns a started rpc_clnt. Creates a new rpc_clnt if quota_priv doesn't have // one already struct rpc_clnt * quota_enforcer_init(xlator_t *this, dict_t *options) { struct rpc_clnt *rpc = NULL; quota_priv_t *priv = NULL; int ret = -1; priv = this->private; LOCK(&priv->lock); { if (priv->rpc_clnt) { ret = 0; rpc = priv->rpc_clnt; } } UNLOCK(&priv->lock); if (rpc) goto out; priv->quota_enforcer = "a_enforcer_clnt; ret = dict_set_sizen_str_sizen(options, "transport.address-family", "unix"); if (ret) goto out; ret = dict_set_sizen_str_sizen(options, "transport-type", "socket"); if (ret) goto out; ret = dict_set_sizen_str_sizen(options, "transport.socket.connect-path", "/var/run/gluster/quotad.socket"); if (ret) goto out; rpc = rpc_clnt_new(options, this, this->name, 16); if (!rpc) { ret = -1; goto out; } ret = rpc_clnt_register_notify(rpc, quota_enforcer_notify, this); if (ret) { gf_msg("quota", GF_LOG_ERROR, 0, Q_MSG_RPCCLNT_REGISTER_NOTIFY_FAILED, "failed to register notify"); goto out; } ret = quota_enforcer_blocking_connect(rpc); if (ret) goto out; ret = 0; out: if (ret) { if (rpc) rpc_clnt_unref(rpc); rpc = NULL; } return rpc; } static struct rpc_clnt_procedure quota_enforcer_actors[GF_AGGREGATOR_MAXVALUE] = { [GF_AGGREGATOR_NULL] = {"NULL", NULL}, [GF_AGGREGATOR_LOOKUP] = {"LOOKUP", NULL}, }; static struct rpc_clnt_program quota_enforcer_clnt = { .progname = "Quota enforcer", .prognum = GLUSTER_AGGREGATOR_PROGRAM, .progver = GLUSTER_AGGREGATOR_VERSION, .numproc = GF_AGGREGATOR_MAXVALUE, .proctable = quota_enforcer_actors, }; glusterfs-11.1/xlators/features/quota/src/PaxHeaders.9031/quotad-helpers.c0000644000000000000000000000013214522202451024713 xustar000000000000000030 mtime=1699284265.684027483 30 atime=1699284265.684027483 30 ctime=1699284303.406141101 glusterfs-11.1/xlators/features/quota/src/quotad-helpers.c0000664000175100017510000000472614522202451025203 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "quotad-helpers.h" quotad_aggregator_state_t * get_quotad_aggregator_state(xlator_t *this, rpcsvc_request_t *req) { quotad_aggregator_state_t *state = NULL; xlator_t *active_subvol = NULL; quota_priv_t *priv = NULL; state = (void *)GF_CALLOC(1, sizeof(*state), gf_quota_mt_aggregator_state_t); if (!state) return NULL; state->this = THIS; priv = this->private; LOCK(&priv->lock); { active_subvol = state->active_subvol = FIRST_CHILD(this); } UNLOCK(&priv->lock); if (active_subvol->itable == NULL) active_subvol->itable = inode_table_new(4096, active_subvol, 0, 0); state->itable = active_subvol->itable; state->pool = this->ctx->pool; return state; } void quotad_aggregator_free_state(quotad_aggregator_state_t *state) { if (state->xdata) dict_unref(state->xdata); if (state->req_xdata) dict_unref(state->req_xdata); GF_FREE(state); } call_frame_t * quotad_aggregator_alloc_frame(rpcsvc_request_t *req) { call_frame_t *frame = NULL; quotad_aggregator_state_t *state = NULL; xlator_t *this = NULL; GF_VALIDATE_OR_GOTO("server", req, out); GF_VALIDATE_OR_GOTO("server", req->trans, out); GF_VALIDATE_OR_GOTO("server", req->svc, out); GF_VALIDATE_OR_GOTO("server", req->svc->ctx, out); this = req->svc->xl; frame = create_frame(this, req->svc->ctx->pool); if (!frame) goto out; state = get_quotad_aggregator_state(this, req); if (!state) goto out; frame->root->state = state; frame->this = this; out: return frame; } call_frame_t * quotad_aggregator_get_frame_from_req(rpcsvc_request_t *req) { call_frame_t *frame = NULL; GF_VALIDATE_OR_GOTO("server", req, out); frame = quotad_aggregator_alloc_frame(req); if (!frame) goto out; frame->root->op = req->procnum; frame->root->uid = req->uid; frame->root->gid = req->gid; frame->root->pid = req->pid; lk_owner_copy(&frame->root->lk_owner, &req->lk_owner); frame->local = req; out: return frame; } glusterfs-11.1/xlators/features/quota/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023074 xustar000000000000000030 mtime=1699284276.743060793 30 atime=1699284290.328101711 30 ctime=1699284303.340140902 glusterfs-11.1/xlators/features/quota/Makefile.in0000664000175100017510000005272114522202464023362 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/quota DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/quota/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/quota/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/quota/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023057 xustar000000000000000030 mtime=1699284265.682027477 30 atime=1699284276.719060721 30 ctime=1699284303.342140908 glusterfs-11.1/xlators/features/quota/Makefile.am0000664000175100017510000000003514522202451023334 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451021726 xustar000000000000000030 mtime=1699284265.649027378 30 atime=1699284275.094055827 30 ctime=1699284303.192140457 glusterfs-11.1/xlators/features/Makefile.am0000664000175100017510000000057614522202451022215 0ustar00jenkinsjenkins00000000000000if BUILD_CLOUDSYNC CLOUDSYNC_DIR = cloudsync endif if BUILD_METADISP METADISP_DIR = metadisp endif SUBDIRS = locks quota read-only quiesce marker index barrier arbiter upcall \ compress changelog gfid-access snapview-client snapview-server trash \ shard bit-rot leases selinux sdfs namespace $(CLOUDSYNC_DIR) thin-arbiter \ utime $(METADISP_DIR) simple-quota CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/changelog0000644000000000000000000000013214522202520021541 xustar000000000000000030 mtime=1699284304.346143932 30 atime=1699284309.687160019 30 ctime=1699284304.346143932 glusterfs-11.1/xlators/features/changelog/0002775000175100017510000000000014522202520022077 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/changelog/PaxHeaders.9031/src0000644000000000000000000000013214522202520022330 xustar000000000000000030 mtime=1699284304.343143923 30 atime=1699284309.687160019 30 ctime=1699284304.343143923 glusterfs-11.1/xlators/features/changelog/src/0002775000175100017510000000000014522202520022666 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-messages.h0000644000000000000000000000013214522202451026315 xustar000000000000000030 mtime=1699284265.661027414 30 atime=1699284265.660027411 30 ctime=1699284304.329143881 glusterfs-11.1/xlators/features/changelog/src/changelog-messages.h0000664000175100017510000002444414522202451026604 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CHANGELOG_MESSAGES_H_ #define _CHANGELOG_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID( CHANGELOG, CHANGELOG_MSG_OPEN_FAILED, CHANGELOG_MSG_BARRIER_FOP_FAILED, CHANGELOG_MSG_VOL_MISCONFIGURED, CHANGELOG_MSG_RENAME_ERROR, CHANGELOG_MSG_READ_ERROR, CHANGELOG_MSG_HTIME_ERROR, CHANGELOG_MSG_PTHREAD_MUTEX_INIT_FAILED, CHANGELOG_MSG_PTHREAD_COND_INIT_FAILED, CHANGELOG_MSG_CHILD_MISCONFIGURED, CHANGELOG_MSG_DIR_OPTIONS_NOT_SET, CHANGELOG_MSG_CLOSE_ERROR, CHANGELOG_MSG_PIPE_CREATION_ERROR, CHANGELOG_MSG_DICT_GET_FAILED, CHANGELOG_MSG_BARRIER_INFO, CHANGELOG_MSG_BARRIER_ERROR, CHANGELOG_MSG_GET_TIME_OP_FAILED, CHANGELOG_MSG_WRITE_FAILED, CHANGELOG_MSG_PTHREAD_ERROR, CHANGELOG_MSG_INODE_NOT_FOUND, CHANGELOG_MSG_FSYNC_OP_FAILED, CHANGELOG_MSG_TOTAL_LOG_INFO, CHANGELOG_MSG_SNAP_INFO, CHANGELOG_MSG_SELECT_FAILED, CHANGELOG_MSG_FCNTL_FAILED, CHANGELOG_MSG_BNOTIFY_INFO, CHANGELOG_MSG_ENTRY_BUF_INFO, CHANGELOG_MSG_CHANGELOG_NOT_ACTIVE, CHANGELOG_MSG_LOCAL_INIT_FAILED, CHANGELOG_MSG_NOTIFY_REGISTER_FAILED, CHANGELOG_MSG_PROGRAM_NAME_REG_FAILED, CHANGELOG_MSG_HANDLE_PROBE_ERROR, CHANGELOG_MSG_SET_FD_CONTEXT, CHANGELOG_MSG_FREEUP_FAILED, CHANGELOG_MSG_RECONFIGURE, CHANGELOG_MSG_RPC_SUBMIT_REPLY_FAILED, CHANGELOG_MSG_RPC_BUILD_ERROR, CHANGELOG_MSG_RPC_CONNECT_ERROR, CHANGELOG_MSG_RPC_START_ERROR, CHANGELOG_MSG_BUFFER_STARVATION_ERROR, CHANGELOG_MSG_SCAN_DIR_FAILED, CHANGELOG_MSG_FSETXATTR_FAILED, CHANGELOG_MSG_FGETXATTR_FAILED, CHANGELOG_MSG_CLEANUP_ON_ACTIVE_REF, CHANGELOG_MSG_DISPATCH_EVENT_FAILED, CHANGELOG_MSG_PUT_BUFFER_FAILED, CHANGELOG_MSG_PTHREAD_COND_WAIT_FAILED, CHANGELOG_MSG_PTHREAD_CANCEL_FAILED, CHANGELOG_MSG_INJECT_FSYNC_FAILED, CHANGELOG_MSG_CREATE_FRAME_FAILED, CHANGELOG_MSG_FSTAT_OP_FAILED, CHANGELOG_MSG_LSEEK_OP_FAILED, CHANGELOG_MSG_STRSTR_OP_FAILED, CHANGELOG_MSG_UNLINK_OP_FAILED, CHANGELOG_MSG_DETECT_EMPTY_CHANGELOG_FAILED, CHANGELOG_MSG_READLINK_OP_FAILED, CHANGELOG_MSG_EXPLICIT_ROLLOVER_FAILED, CHANGELOG_MSG_RPCSVC_NOTIFY_FAILED, CHANGELOG_MSG_MEMORY_INIT_FAILED, CHANGELOG_MSG_NO_MEMORY, CHANGELOG_MSG_HTIME_STAT_ERROR, CHANGELOG_MSG_HTIME_CURRENT_ERROR, CHANGELOG_MSG_BNOTIFY_COND_INFO, CHANGELOG_MSG_NO_HTIME_CURRENT, CHANGELOG_MSG_HTIME_CURRENT, CHANGELOG_MSG_NEW_HTIME_FILE, CHANGELOG_MSG_MKDIR_ERROR, CHANGELOG_MSG_PATH_NOT_FOUND, CHANGELOG_MSG_XATTR_INIT_FAILED, CHANGELOG_MSG_WROTE_TO_CSNAP, CHANGELOG_MSG_UNUSED_0, CHANGELOG_MSG_GET_BUFFER_FAILED, CHANGELOG_MSG_BARRIER_STATE_NOTIFY, CHANGELOG_MSG_BARRIER_DISABLED, CHANGELOG_MSG_BARRIER_ALREADY_DISABLED, CHANGELOG_MSG_BARRIER_ON_ERROR, CHANGELOG_MSG_BARRIER_ENABLE, CHANGELOG_MSG_BARRIER_KEY_NOT_FOUND, CHANGELOG_MSG_ERROR_IN_DICT_GET, CHANGELOG_MSG_UNUSED_1, CHANGELOG_MSG_UNUSED_2, CHANGELOG_MSG_DEQUEUING_BARRIER_FOPS, CHANGELOG_MSG_DEQUEUING_BARRIER_FOPS_FINISHED, CHANGELOG_MSG_BARRIER_TIMEOUT, CHANGELOG_MSG_TIMEOUT_ADD_FAILED, CHANGELOG_MSG_CLEANUP_ALREADY_SET); #define CHANGELOG_MSG_BARRIER_FOP_FAILED_STR \ "failed to barrier FOPs, disabling changelog barrier" #define CHANGELOG_MSG_MEMORY_INIT_FAILED_STR "memory accounting init failed" #define CHANGELOG_MSG_NO_MEMORY_STR "failed to create local memory pool" #define CHANGELOG_MSG_ENTRY_BUF_INFO_STR \ "Entry cannot be captured for gfid, Capturing DATA entry." #define CHANGELOG_MSG_PTHREAD_ERROR_STR "pthread error" #define CHANGELOG_MSG_PTHREAD_MUTEX_INIT_FAILED_STR "pthread_mutex_init failed" #define CHANGELOG_MSG_PTHREAD_COND_INIT_FAILED_STR "pthread_cond_init failed" #define CHANGELOG_MSG_HTIME_ERROR_STR "failed to update HTIME file" #define CHANGELOG_MSG_HTIME_STAT_ERROR_STR "unable to stat htime file" #define CHANGELOG_MSG_HTIME_CURRENT_ERROR_STR "Error extracting HTIME_CURRENT." #define CHANGELOG_MSG_UNLINK_OP_FAILED_STR "error unlinking empty changelog" #define CHANGELOG_MSG_RENAME_ERROR_STR "error renaming" #define CHANGELOG_MSG_MKDIR_ERROR_STR "unable to create directory" #define CHANGELOG_MSG_BNOTIFY_INFO_STR \ "Explicit rollover changelog signaling bnotify" #define CHANGELOG_MSG_BNOTIFY_COND_INFO_STR "Woke up: bnotify conditional wait" #define CHANGELOG_MSG_RECONFIGURE_STR "Reconfigure: Changelog Enable" #define CHANGELOG_MSG_NO_HTIME_CURRENT_STR \ "HTIME_CURRENT not found. Changelog enabled before init" #define CHANGELOG_MSG_HTIME_CURRENT_STR "HTIME_CURRENT" #define CHANGELOG_MSG_NEW_HTIME_FILE_STR \ "Changelog enable: Creating new HTIME file" #define CHANGELOG_MSG_FGETXATTR_FAILED_STR "fgetxattr failed" #define CHANGELOG_MSG_TOTAL_LOG_INFO_STR "changelog info" #define CHANGELOG_MSG_PTHREAD_COND_WAIT_FAILED_STR "pthread cond wait failed" #define CHANGELOG_MSG_INODE_NOT_FOUND_STR "inode not found" #define CHANGELOG_MSG_READLINK_OP_FAILED_STR \ "could not read the link from the gfid handle" #define CHANGELOG_MSG_OPEN_FAILED_STR "unable to open file" #define CHANGELOG_MSG_RPC_CONNECT_ERROR_STR "failed to connect back" #define CHANGELOG_MSG_BUFFER_STARVATION_ERROR_STR \ "Failed to get buffer for RPC dispatch" #define CHANGELOG_MSG_PTHREAD_CANCEL_FAILED_STR "could not cancel thread" #define CHANGELOG_MSG_FSTAT_OP_FAILED_STR "Could not stat (CHANGELOG)" #define CHANGELOG_MSG_LSEEK_OP_FAILED_STR "Could not lseek (changelog)" #define CHANGELOG_MSG_PATH_NOT_FOUND_STR \ "Could not find CHANGELOG in changelog path" #define CHANGELOG_MSG_FSYNC_OP_FAILED_STR "fsync failed" #define CHANGELOG_MSG_DETECT_EMPTY_CHANGELOG_FAILED_STR \ "Error detecting empty changelog" #define CHANGELOG_MSG_EXPLICIT_ROLLOVER_FAILED_STR \ "Fail snapshot because of previous errors" #define CHANGELOG_MSG_SCAN_DIR_FAILED_STR "scandir failed" #define CHANGELOG_MSG_FSETXATTR_FAILED_STR "fsetxattr failed" #define CHANGELOG_MSG_XATTR_INIT_FAILED_STR "Htime xattr initialization failed" #define CHANGELOG_MSG_SNAP_INFO_STR "log in call path" #define CHANGELOG_MSG_WRITE_FAILED_STR "error writing to disk" #define CHANGELOG_MSG_WROTE_TO_CSNAP_STR "Successfully wrote to csnap" #define CHANGELOG_MSG_GET_TIME_OP_FAILED_STR "Problem rolling over changelog(s)" #define CHANGELOG_MSG_BARRIER_INFO_STR "Explicit wakeup on barrier notify" #define CHANGELOG_MSG_SELECT_FAILED_STR "pthread_cond_timedwait failed" #define CHANGELOG_MSG_INJECT_FSYNC_FAILED_STR "failed to inject fsync event" #define CHANGELOG_MSG_LOCAL_INIT_FAILED_STR \ "changelog local initialization failed" #define CHANGELOG_MSG_GET_BUFFER_FAILED_STR "Failed to get buffer" #define CHANGELOG_MSG_SET_FD_CONTEXT_STR \ "could not set fd context(for release cbk)" #define CHANGELOG_MSG_DICT_GET_FAILED_STR "Barrier failed" #define CHANGELOG_MSG_BARRIER_STATE_NOTIFY_STR "Barrier notification" #define CHANGELOG_MSG_BARRIER_ERROR_STR \ "Received another barrier off notification while already off" #define CHANGELOG_MSG_BARRIER_DISABLED_STR "disabled changelog barrier" #define CHANGELOG_MSG_BARRIER_ALREADY_DISABLED_STR \ "Changelog barrier already disabled" #define CHANGELOG_MSG_BARRIER_ON_ERROR_STR \ "Received another barrier on notification when last one is not served yet" #define CHANGELOG_MSG_BARRIER_ENABLE_STR "Enabled changelog barrier" #define CHANGELOG_MSG_BARRIER_KEY_NOT_FOUND_STR "barrier key not found" #define CHANGELOG_MSG_ERROR_IN_DICT_GET_STR \ "Something went wrong in dict_get_str_boolean" #define CHANGELOG_MSG_DIR_OPTIONS_NOT_SET_STR "changelog-dir option is not set" #define CHANGELOG_MSG_FREEUP_FAILED_STR "could not cleanup bootstrapper" #define CHANGELOG_MSG_CHILD_MISCONFIGURED_STR \ "translator needs a single subvolume" #define CHANGELOG_MSG_VOL_MISCONFIGURED_STR \ "dangling volume. please check volfile" #define CHANGELOG_MSG_DEQUEUING_BARRIER_FOPS_STR \ "Dequeuing all the changelog barriered fops" #define CHANGELOG_MSG_DEQUEUING_BARRIER_FOPS_FINISHED_STR \ "Dequeuing changelog barriered fops is finished" #define CHANGELOG_MSG_BARRIER_TIMEOUT_STR \ "Disabling changelog barrier because of the timeout" #define CHANGELOG_MSG_TIMEOUT_ADD_FAILED_STR \ "Couldn't add changelog barrier timeout event" #define CHANGELOG_MSG_RPC_BUILD_ERROR_STR "failed to build rpc options" #define CHANGELOG_MSG_NOTIFY_REGISTER_FAILED_STR "failed to register notify" #define CHANGELOG_MSG_RPC_START_ERROR_STR "failed to start rpc" #define CHANGELOG_MSG_CREATE_FRAME_FAILED_STR "failed to create frame" #define CHANGELOG_MSG_RPC_SUBMIT_REPLY_FAILED_STR "failed to serialize reply" #define CHANGELOG_MSG_PROGRAM_NAME_REG_FAILED_STR "cannot register program" #define CHANGELOG_MSG_CHANGELOG_NOT_ACTIVE_STR \ "Changelog is not active, return success" #define CHANGELOG_MSG_PUT_BUFFER_FAILED_STR \ "failed to put buffer after consumption" #define CHANGELOG_MSG_CLEANUP_ALREADY_SET_STR \ "cleanup_starting flag is already set for xl" #define CHANGELOG_MSG_HANDLE_PROBE_ERROR_STR "xdr decoding error" #endif /* !_CHANGELOG_MESSAGES_H_ */ glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-ev-handle.c0000644000000000000000000000013214522202451026344 xustar000000000000000030 mtime=1699284265.659027408 30 atime=1699284265.659027408 30 ctime=1699284304.343143923 glusterfs-11.1/xlators/features/changelog/src/changelog-ev-handle.c0000664000175100017510000002565214522202451026635 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "changelog-ev-handle.h" #include "changelog-rpc-common.h" #include "changelog-helpers.h" struct rpc_clnt_program changelog_ev_program; #define NR_IOVEC (MAX_IOVEC - 3) struct ev_rpc_vec { int count; struct iovec vector[NR_IOVEC]; /* sequence number */ unsigned long seq; }; struct ev_rpc { rbuf_list_t *rlist; struct rpc_clnt *rpc; struct ev_rpc_vec vec; }; /** * As of now this just does the minimal (retval logging). Going further * un-acknowledges sequence numbers can be retransmitted and other * intelligence can be built into the server. */ int changelog_event_dispatch_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { return 0; } /* dispatcher RPC */ int changelog_dispatch_vec(call_frame_t *frame, xlator_t *this, struct rpc_clnt *rpc, struct ev_rpc_vec *vec) { struct timeval tv = { 0, }; changelog_event_req req = { 0, }; (void)gettimeofday(&tv, NULL); /** * Event dispatch RPC header contains a sequence number for each * dispatch. This allows the receiver to order the request before * processing. */ req.seq = vec->seq; req.tv_sec = tv.tv_sec; req.tv_usec = tv.tv_usec; return changelog_rpc_sumbit_req( rpc, (void *)&req, frame, &changelog_ev_program, CHANGELOG_REV_PROC_EVENT, vec->vector, vec->count, NULL, this, changelog_event_dispatch_cbk, (xdrproc_t)xdr_changelog_event_req); } int changelog_event_dispatch_rpc(call_frame_t *frame, xlator_t *this, void *data) { int idx = 0; int count = 0; int ret = 0; unsigned long sequence = 0; rbuf_iovec_t *rvec = NULL; struct ev_rpc *erpc = NULL; struct rlist_iter riter = { { 0, }, }; /* dispatch NR_IOVEC IO vectors at a time. */ erpc = data; sequence = erpc->rlist->seq[0]; rlist_iter_init(&riter, erpc->rlist); rvec_for_each_entry(rvec, &riter) { idx = count % NR_IOVEC; if (++count == NR_IOVEC) { erpc->vec.vector[idx] = rvec->iov; erpc->vec.seq = sequence++; erpc->vec.count = NR_IOVEC; ret = changelog_dispatch_vec(frame, this, erpc->rpc, &erpc->vec); if (ret) break; count = 0; continue; } erpc->vec.vector[idx] = rvec->iov; } if (ret) goto error_return; idx = count % NR_IOVEC; if (idx) { erpc->vec.seq = sequence; erpc->vec.count = idx; ret = changelog_dispatch_vec(frame, this, erpc->rpc, &erpc->vec); } error_return: return ret; } int changelog_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, void *data) { xlator_t *this = NULL; changelog_rpc_clnt_t *crpc = NULL; changelog_clnt_t *c_clnt = NULL; changelog_priv_t *priv = NULL; changelog_ev_selector_t *selection = NULL; uint64_t clntcnt = 0; uint64_t xprtcnt = 0; crpc = mydata; this = crpc->this; c_clnt = crpc->c_clnt; priv = this->private; switch (event) { case RPC_CLNT_CONNECT: selection = &priv->ev_selection; GF_ATOMIC_INC(priv->clntcnt); LOCK(&crpc->lock); { LOCK(&c_clnt->active_lock); { changelog_select_event(this, selection, crpc->filter); list_move_tail(&crpc->list, &c_clnt->active); } UNLOCK(&c_clnt->active_lock); } UNLOCK(&crpc->lock); break; case RPC_CLNT_DISCONNECT: rpc_clnt_disable(crpc->rpc); /* rpc_clnt_disable doesn't unref the rpc. It just marks * the rpc as disabled and cancels reconnection timer. * Hence unref the rpc object to free it. */ rpc_clnt_unref(crpc->rpc); if (priv) selection = &priv->ev_selection; LOCK(&crpc->lock); { if (selection) changelog_deselect_event(this, selection, crpc->filter); changelog_set_disconnect_flag(crpc, _gf_true); list_del_init(&crpc->list); } UNLOCK(&crpc->lock); break; case RPC_CLNT_MSG: case RPC_CLNT_DESTROY: /* Free up mydata */ changelog_rpc_clnt_unref(crpc); clntcnt = GF_ATOMIC_DEC(priv->clntcnt); xprtcnt = GF_ATOMIC_GET(priv->xprtcnt); if (this->cleanup_starting) { if (!clntcnt && !xprtcnt) changelog_process_cleanup_event(this); } break; case RPC_CLNT_PING: break; } return 0; } void * changelog_ev_connector(void *data) { xlator_t *this = NULL; changelog_clnt_t *c_clnt = NULL; changelog_rpc_clnt_t *crpc = NULL; gf_boolean_t lock_flag = _gf_false; c_clnt = data; this = c_clnt->this; while (1) { pthread_mutex_lock(&c_clnt->pending_lock); { while (list_empty(&c_clnt->pending)) pthread_cond_wait(&c_clnt->pending_cond, &c_clnt->pending_lock); crpc = list_first_entry(&c_clnt->pending, changelog_rpc_clnt_t, list); crpc->rpc = changelog_rpc_client_init(this, crpc, crpc->sock, changelog_rpc_notify); if (!crpc->rpc) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_RPC_CONNECT_ERROR, "path=%s", crpc->sock, NULL); crpc->cleanup(crpc); lock_flag = _gf_true; goto mutex_unlock; } } pthread_mutex_unlock(&c_clnt->pending_lock); LOCK(&crpc->lock); { if (crpc->disconnected != _gf_true) { LOCK(&c_clnt->wait_lock); { list_move_tail(&crpc->list, &c_clnt->waitq); } UNLOCK(&c_clnt->wait_lock); } } UNLOCK(&crpc->lock); mutex_unlock: if (lock_flag) { pthread_mutex_unlock(&c_clnt->pending_lock); lock_flag = _gf_false; } } return NULL; } void changelog_ev_cleanup_connections(xlator_t *this, changelog_clnt_t *c_clnt) { changelog_rpc_clnt_t *crpc = NULL; /* cleanup active connections */ LOCK(&c_clnt->active_lock); { list_for_each_entry(crpc, &c_clnt->active, list) { rpc_clnt_disable(crpc->rpc); } } UNLOCK(&c_clnt->active_lock); } /** * TODO: granularize lock * * If we have multiple threads dispatching events, doing it this way is * a performance bottleneck. */ static changelog_rpc_clnt_t * get_client(changelog_clnt_t *c_clnt, struct list_head **next) { changelog_rpc_clnt_t *crpc = NULL; LOCK(&c_clnt->active_lock); { if (*next == &c_clnt->active) goto unblock; crpc = list_entry(*next, changelog_rpc_clnt_t, list); /* ref rpc as DISCONNECT might unref the rpc asynchronously */ changelog_rpc_clnt_ref(crpc); rpc_clnt_ref(crpc->rpc); *next = (*next)->next; } unblock: UNLOCK(&c_clnt->active_lock); return crpc; } static void put_client(changelog_clnt_t *c_clnt, changelog_rpc_clnt_t *crpc) { LOCK(&c_clnt->active_lock); { rpc_clnt_unref(crpc->rpc); changelog_rpc_clnt_unref(crpc); } UNLOCK(&c_clnt->active_lock); } void _dispatcher(rbuf_list_t *rlist, void *arg) { xlator_t *this = NULL; changelog_clnt_t *c_clnt = NULL; changelog_rpc_clnt_t *crpc = NULL; struct ev_rpc erpc = { 0, }; struct list_head *next = NULL; c_clnt = arg; this = c_clnt->this; erpc.rlist = rlist; next = c_clnt->active.next; while (1) { crpc = get_client(c_clnt, &next); if (!crpc) break; erpc.rpc = crpc->rpc; (void)changelog_invoke_rpc(this, crpc->rpc, &changelog_ev_program, CHANGELOG_REV_PROC_EVENT, &erpc); put_client(c_clnt, crpc); } } /** this is called under rotbuff's lock */ void sequencer(rbuf_list_t *rlist, void *mydata) { unsigned long range = 0; changelog_clnt_t *c_clnt = 0; c_clnt = mydata; range = (RLIST_ENTRY_COUNT(rlist)) / NR_IOVEC; if ((RLIST_ENTRY_COUNT(rlist)) % NR_IOVEC) range++; RLIST_STORE_SEQ(rlist, c_clnt->sequence, range); c_clnt->sequence += range; } void * changelog_ev_dispatch(void *data) { int ret = 0; void *opaque = NULL; xlator_t *this = NULL; changelog_clnt_t *c_clnt = NULL; struct timeval tv = { 0, }; c_clnt = data; this = c_clnt->this; while (1) { /* TODO: change this to be pthread cond based.. later */ tv.tv_sec = 1; tv.tv_usec = 0; select(0, NULL, NULL, NULL, &tv); ret = rbuf_get_buffer(c_clnt->rbuf, &opaque, sequencer, c_clnt); if (ret != RBUF_CONSUMABLE) { if (ret != RBUF_EMPTY) gf_smsg(this->name, GF_LOG_WARNING, 0, CHANGELOG_MSG_BUFFER_STARVATION_ERROR, "Failed to get buffer for RPC dispatch", "rbuf_retval=%d", ret, NULL); continue; } ret = rbuf_wait_for_completion(c_clnt->rbuf, opaque, _dispatcher, c_clnt); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, CHANGELOG_MSG_PUT_BUFFER_FAILED, NULL); } return NULL; } void changelog_ev_queue_connection(changelog_clnt_t *c_clnt, changelog_rpc_clnt_t *crpc) { LOCK(&crpc->lock); { pthread_mutex_lock(&c_clnt->pending_lock); { list_add_tail(&crpc->list, &c_clnt->pending); pthread_cond_signal(&c_clnt->pending_cond); } pthread_mutex_unlock(&c_clnt->pending_lock); } UNLOCK(&crpc->lock); } struct rpc_clnt_procedure changelog_ev_procs[CHANGELOG_REV_PROC_MAX] = { [CHANGELOG_REV_PROC_NULL] = {"NULL", NULL}, [CHANGELOG_REV_PROC_EVENT] = {"EVENT DISPATCH", changelog_event_dispatch_rpc}, }; struct rpc_clnt_program changelog_ev_program = { .progname = "CHANGELOG EVENT DISPATCHER", .prognum = CHANGELOG_REV_RPC_PROCNUM, .progver = CHANGELOG_REV_RPC_PROCVER, .numproc = CHANGELOG_REV_PROC_MAX, .proctable = changelog_ev_procs, }; glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-rt.c0000644000000000000000000000013214522202451025126 xustar000000000000000030 mtime=1699284265.661027414 30 atime=1699284265.661027414 30 ctime=1699284304.333143893 glusterfs-11.1/xlators/features/changelog/src/changelog-rt.c0000664000175100017510000000262514522202451025412 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "changelog-rt.h" #include "changelog-mem-types.h" int changelog_rt_init(xlator_t *this, changelog_dispatcher_t *cd) { changelog_rt_t *crt = NULL; crt = GF_CALLOC(1, sizeof(*crt), gf_changelog_mt_rt_t); if (!crt) return -1; LOCK_INIT(&crt->lock); cd->cd_data = crt; cd->dispatchfn = &changelog_rt_enqueue; return 0; } int changelog_rt_fini(xlator_t *this, changelog_dispatcher_t *cd) { changelog_rt_t *crt = NULL; crt = cd->cd_data; LOCK_DESTROY(&crt->lock); GF_FREE(crt); return 0; } int changelog_rt_enqueue(xlator_t *this, changelog_priv_t *priv, void *cbatch, changelog_log_data_t *cld_0, changelog_log_data_t *cld_1) { int ret = 0; changelog_rt_t *crt = NULL; crt = (changelog_rt_t *)cbatch; LOCK(&crt->lock); { ret = changelog_handle_change(this, priv, cld_0); if (!ret && cld_1) ret = changelog_handle_change(this, priv, cld_1); } UNLOCK(&crt->lock); return ret; } glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-rpc.c0000644000000000000000000000013214522202451025265 xustar000000000000000030 mtime=1699284265.661027414 30 atime=1699284265.661027414 30 ctime=1699284304.338143908 glusterfs-11.1/xlators/features/changelog/src/changelog-rpc.c0000664000175100017510000002736114522202451025555 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "changelog-rpc.h" #include "changelog-mem-types.h" #include "changelog-ev-handle.h" #include "socket.h" static struct rpcsvc_program *changelog_programs[]; static void changelog_cleanup_dispatchers(xlator_t *this, changelog_priv_t *priv, int count) { for (count--; count >= 0; count--) { (void)changelog_thread_cleanup(this, priv->ev_dispatcher[count]); priv->ev_dispatcher[count] = 0; } } int changelog_cleanup_rpc_threads(xlator_t *this, changelog_priv_t *priv) { int ret = 0; changelog_clnt_t *conn = NULL; conn = &priv->connections; if (!conn) return 0; /** terminate RPC thread(s) */ ret = changelog_thread_cleanup(this, priv->connector); if (ret != 0) goto error_return; priv->connector = 0; /** terminate dispatcher thread(s) */ changelog_cleanup_dispatchers(this, priv, priv->nr_dispatchers); /* destroy locks */ ret = pthread_mutex_destroy(&conn->pending_lock); if (ret != 0) goto error_return; ret = pthread_cond_destroy(&conn->pending_cond); if (ret != 0) goto error_return; ret = LOCK_DESTROY(&conn->active_lock); if (ret != 0) goto error_return; ret = LOCK_DESTROY(&conn->wait_lock); if (ret != 0) goto error_return; return 0; error_return: return -1; } static int changelog_init_rpc_threads(xlator_t *this, changelog_priv_t *priv, rbuf_t *rbuf, int nr_dispatchers) { int j = 0; int ret = 0; changelog_clnt_t *conn = NULL; conn = &priv->connections; conn->this = this; conn->rbuf = rbuf; conn->sequence = 1; /* start with sequence number one */ INIT_LIST_HEAD(&conn->pending); INIT_LIST_HEAD(&conn->active); INIT_LIST_HEAD(&conn->waitq); ret = pthread_mutex_init(&conn->pending_lock, NULL); if (ret) goto error_return; ret = pthread_cond_init(&conn->pending_cond, NULL); if (ret) goto cleanup_pending_lock; ret = LOCK_INIT(&conn->active_lock); if (ret) goto cleanup_pending_cond; ret = LOCK_INIT(&conn->wait_lock); if (ret) goto cleanup_active_lock; /* spawn reverse connection thread */ ret = gf_thread_create(&priv->connector, NULL, changelog_ev_connector, conn, "clogecon"); if (ret != 0) goto cleanup_wait_lock; /* spawn dispatcher thread(s) */ priv->ev_dispatcher = GF_CALLOC(nr_dispatchers, sizeof(pthread_t), gf_changelog_mt_ev_dispatcher_t); if (!priv->ev_dispatcher) goto cleanup_connector; /* spawn dispatcher threads */ for (; j < nr_dispatchers; j++) { ret = gf_thread_create(&priv->ev_dispatcher[j], NULL, changelog_ev_dispatch, conn, "clogd%03hx", j & 0x3ff); if (ret != 0) { changelog_cleanup_dispatchers(this, priv, j); break; } } if (ret != 0) goto cleanup_connector; priv->nr_dispatchers = nr_dispatchers; return 0; cleanup_connector: (void)pthread_cancel(priv->connector); cleanup_wait_lock: LOCK_DESTROY(&conn->wait_lock); cleanup_active_lock: LOCK_DESTROY(&conn->active_lock); cleanup_pending_cond: (void)pthread_cond_destroy(&conn->pending_cond); cleanup_pending_lock: (void)pthread_mutex_destroy(&conn->pending_lock); error_return: return -1; } int changelog_rpcsvc_notify(rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, void *data) { xlator_t *this = NULL; rpc_transport_t *trans = NULL; rpc_transport_t *xprt = NULL; rpc_transport_t *xp_next = NULL; changelog_priv_t *priv = NULL; uint64_t listnercnt = 0; uint64_t xprtcnt = 0; uint64_t clntcnt = 0; rpcsvc_listener_t *listener = NULL; rpcsvc_listener_t *next = NULL; gf_boolean_t listner_found = _gf_false; socket_private_t *sockpriv = NULL; if (!xl || !data || !rpc) { gf_msg_callingfn("changelog", GF_LOG_WARNING, 0, CHANGELOG_MSG_RPCSVC_NOTIFY_FAILED, "Calling rpc_notify without initializing"); goto out; } this = xl; trans = data; priv = this->private; if (!priv) { gf_msg_callingfn("changelog", GF_LOG_WARNING, 0, CHANGELOG_MSG_RPCSVC_NOTIFY_FAILED, "Calling rpc_notify without priv initializing"); goto out; } if (event == RPCSVC_EVENT_ACCEPT) { GF_ATOMIC_INC(priv->xprtcnt); LOCK(&priv->lock); { list_add_tail(&trans->list, &priv->xprt_list); } UNLOCK(&priv->lock); goto out; } if (event == RPCSVC_EVENT_DISCONNECT) { list_for_each_entry_safe(listener, next, &rpc->listeners, list) { if (listener && listener->trans) { if (listener->trans == trans) { listnercnt = GF_ATOMIC_DEC(priv->listnercnt); listner_found = _gf_true; rpcsvc_listener_destroy(listener); } } } if (listnercnt > 0) { goto out; } if (listner_found) { LOCK(&priv->lock); list_for_each_entry_safe(xprt, xp_next, &priv->xprt_list, list) { sockpriv = (socket_private_t *)(xprt->private); gf_log("changelog", GF_LOG_INFO, "Send disconnect" " on socket %d", sockpriv->sock); rpc_transport_disconnect(xprt, _gf_false); } UNLOCK(&priv->lock); goto out; } LOCK(&priv->lock); { list_del_init(&trans->list); } UNLOCK(&priv->lock); xprtcnt = GF_ATOMIC_DEC(priv->xprtcnt); clntcnt = GF_ATOMIC_GET(priv->clntcnt); if (!xprtcnt && !clntcnt) { changelog_process_cleanup_event(this); } } out: return 0; } void changelog_process_cleanup_event(xlator_t *this) { gf_boolean_t cleanup_notify = _gf_false; changelog_priv_t *priv = NULL; char sockfile[UNIX_PATH_MAX] = { 0, }; if (!this) return; priv = this->private; if (!priv) return; LOCK(&priv->lock); { cleanup_notify = priv->notify_down; priv->notify_down = _gf_true; } UNLOCK(&priv->lock); if (priv->victim && !cleanup_notify) { default_notify(this, GF_EVENT_PARENT_DOWN, priv->victim); if (priv->rpc) { /* sockfile path could have been saved to avoid this */ CHANGELOG_MAKE_SOCKET_PATH(priv->changelog_brick, sockfile, UNIX_PATH_MAX); sys_unlink(sockfile); (void)rpcsvc_unregister_notify(priv->rpc, changelog_rpcsvc_notify, this); if (priv->rpc->rxpool) { mem_pool_destroy(priv->rpc->rxpool); priv->rpc->rxpool = NULL; } GF_FREE(priv->rpc); priv->rpc = NULL; } } } void changelog_destroy_rpc_listner(xlator_t *this, changelog_priv_t *priv) { char sockfile[UNIX_PATH_MAX] = { 0, }; /* sockfile path could have been saved to avoid this */ CHANGELOG_MAKE_SOCKET_PATH(priv->changelog_brick, sockfile, UNIX_PATH_MAX); changelog_rpc_server_destroy(this, priv->rpc, sockfile, changelog_rpcsvc_notify, changelog_programs); } rpcsvc_t * changelog_init_rpc_listener(xlator_t *this, changelog_priv_t *priv, rbuf_t *rbuf, int nr_dispatchers) { int ret = 0; char sockfile[UNIX_PATH_MAX] = { 0, }; rpcsvc_t *svcp; ret = changelog_init_rpc_threads(this, priv, rbuf, nr_dispatchers); if (ret) return NULL; CHANGELOG_MAKE_SOCKET_PATH(priv->changelog_brick, sockfile, UNIX_PATH_MAX); (void)sys_unlink(sockfile); svcp = changelog_rpc_server_init( this, sockfile, NULL, changelog_rpcsvc_notify, changelog_programs); return svcp; } void changelog_rpc_clnt_cleanup(changelog_rpc_clnt_t *crpc) { if (!crpc) return; crpc->c_clnt = NULL; LOCK_DESTROY(&crpc->lock); GF_FREE(crpc); } static changelog_rpc_clnt_t * changelog_rpc_clnt_init(xlator_t *this, changelog_probe_req *rpc_req, changelog_clnt_t *c_clnt) { int ret = 0; changelog_rpc_clnt_t *crpc = NULL; crpc = GF_CALLOC(1, sizeof(*crpc), gf_changelog_mt_rpc_clnt_t); if (!crpc) goto error_return; INIT_LIST_HEAD(&crpc->list); /* Take a ref, the last unref will be on RPC_CLNT_DESTROY * which comes as a result of last rpc_clnt_unref. */ GF_ATOMIC_INIT(crpc->ref, 1); changelog_set_disconnect_flag(crpc, _gf_false); crpc->filter = rpc_req->filter; (void)memcpy(crpc->sock, rpc_req->sock, strlen(rpc_req->sock)); crpc->this = this; crpc->c_clnt = c_clnt; crpc->cleanup = changelog_rpc_clnt_cleanup; ret = LOCK_INIT(&crpc->lock); if (ret != 0) goto dealloc_crpc; return crpc; dealloc_crpc: GF_FREE(crpc); error_return: return NULL; } /** * Actor declarations */ /** * @probe_handler * A probe RPC call spawns a connect back to the caller. Caller also * passes an hint which acts as a filter for selecting updates. */ int changelog_handle_probe(rpcsvc_request_t *req) { int ret = 0; xlator_t *this = NULL; rpcsvc_t *svc = NULL; changelog_priv_t *priv = NULL; changelog_clnt_t *c_clnt = NULL; changelog_rpc_clnt_t *crpc = NULL; changelog_probe_req rpc_req = { 0, }; changelog_probe_rsp rpc_rsp = { 0, }; this = req->trans->xl; if (this->cleanup_starting) { gf_smsg(this->name, GF_LOG_DEBUG, 0, CHANGELOG_MSG_CLEANUP_ALREADY_SET, NULL); return 0; } ret = xdr_to_generic(req->msg[0], &rpc_req, (xdrproc_t)xdr_changelog_probe_req); if (ret < 0) { gf_smsg("", GF_LOG_ERROR, 0, CHANGELOG_MSG_HANDLE_PROBE_ERROR, NULL); req->rpc_err = GARBAGE_ARGS; goto handle_xdr_error; } /* ->xl hidden in rpcsvc */ svc = rpcsvc_request_service(req); this = svc->xl; priv = this->private; c_clnt = &priv->connections; crpc = changelog_rpc_clnt_init(this, &rpc_req, c_clnt); if (!crpc) goto handle_xdr_error; changelog_ev_queue_connection(c_clnt, crpc); rpc_rsp.op_ret = 0; goto submit_rpc; handle_xdr_error: rpc_rsp.op_ret = -1; submit_rpc: (void)changelog_rpc_sumbit_reply(req, &rpc_rsp, NULL, 0, NULL, (xdrproc_t)xdr_changelog_probe_rsp); return 0; } /** * RPC declarations */ static rpcsvc_actor_t changelog_svc_actors[CHANGELOG_RPC_PROC_MAX] = { [CHANGELOG_RPC_PROBE_FILTER] = {"CHANGELOG PROBE FILTER", changelog_handle_probe, NULL, CHANGELOG_RPC_PROBE_FILTER, DRC_NA, 0}, }; static struct rpcsvc_program changelog_svc_prog = { .progname = CHANGELOG_RPC_PROGNAME, .prognum = CHANGELOG_RPC_PROGNUM, .progver = CHANGELOG_RPC_PROGVER, .numactors = CHANGELOG_RPC_PROC_MAX, .actors = changelog_svc_actors, .synctask = _gf_true, }; static struct rpcsvc_program *changelog_programs[] = { &changelog_svc_prog, NULL, }; glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-barrier.c0000644000000000000000000000013214522202451026127 xustar000000000000000030 mtime=1699284265.659027408 30 atime=1699284265.659027408 30 ctime=1699284304.340143914 glusterfs-11.1/xlators/features/changelog/src/changelog-barrier.c0000664000175100017510000000573514522202451026420 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "changelog-helpers.h" #include "changelog-messages.h" #include /* Enqueue a stub*/ void __chlog_barrier_enqueue(xlator_t *this, call_stub_t *stub) { changelog_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); list_add_tail(&stub->list, &priv->queue); priv->queue_size++; return; } /* Dequeue a stub */ call_stub_t * __chlog_barrier_dequeue(xlator_t *this, struct list_head *queue) { call_stub_t *stub = NULL; changelog_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (list_empty(queue)) goto out; stub = list_entry(queue->next, call_stub_t, list); list_del_init(&stub->list); out: return stub; } /* Dequeue all the stubs and call corresponding resume functions */ void chlog_barrier_dequeue_all(xlator_t *this, struct list_head *queue) { call_stub_t *stub = NULL; gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_DEQUEUING_BARRIER_FOPS, NULL); while ((stub = __chlog_barrier_dequeue(this, queue))) call_resume(stub); gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_DEQUEUING_BARRIER_FOPS_FINISHED, NULL); return; } /* Function called on changelog barrier timeout */ void chlog_barrier_timeout(void *data) { xlator_t *this = NULL; changelog_priv_t *priv = NULL; struct list_head queue = { 0, }; this = data; THIS = this; priv = this->private; INIT_LIST_HEAD(&queue); gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_BARRIER_TIMEOUT, NULL); LOCK(&priv->lock); { __chlog_barrier_disable(this, &queue); } UNLOCK(&priv->lock); chlog_barrier_dequeue_all(this, &queue); return; } /* Disable changelog barrier enable flag */ void __chlog_barrier_disable(xlator_t *this, struct list_head *queue) { changelog_priv_t *priv = this->private; GF_ASSERT(priv); if (priv->timer) { gf_timer_call_cancel(this->ctx, priv->timer); priv->timer = NULL; } list_splice_init(&priv->queue, queue); priv->queue_size = 0; priv->barrier_enabled = _gf_false; } /* Enable chagelog barrier enable with timer */ int __chlog_barrier_enable(xlator_t *this, changelog_priv_t *priv) { int ret = -1; priv->timer = gf_timer_call_after(this->ctx, priv->timeout, chlog_barrier_timeout, (void *)this); if (!priv->timer) { gf_smsg(this->name, GF_LOG_CRITICAL, 0, CHANGELOG_MSG_TIMEOUT_ADD_FAILED, NULL); goto out; } priv->barrier_enabled = _gf_true; ret = 0; out: return ret; } glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-helpers.c0000644000000000000000000000013214522202451026143 xustar000000000000000030 mtime=1699284265.660027411 30 atime=1699284265.659027408 30 ctime=1699284304.335143899 glusterfs-11.1/xlators/features/changelog/src/changelog-helpers.c0000664000175100017510000016002114522202451026422 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "changelog-helpers.h" #include "changelog-encoders.h" #include "changelog-mem-types.h" #include "changelog-messages.h" #include "changelog-encoders.h" #include "changelog-rpc-common.h" #include #include static void changelog_cleanup_free_mutex(void *arg_mutex) { pthread_mutex_t *p_mutex = (pthread_mutex_t *)arg_mutex; if (p_mutex) pthread_mutex_unlock(p_mutex); } int changelog_thread_cleanup(xlator_t *this, pthread_t thr_id) { int ret = 0; void *retval = NULL; /* send a cancel request to the thread */ ret = pthread_cancel(thr_id); if (ret != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_CANCEL_FAILED, NULL); goto out; } ret = pthread_join(thr_id, &retval); if ((ret != 0) || (retval != PTHREAD_CANCELED)) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_CANCEL_FAILED, NULL); } out: return ret; } void * changelog_get_usable_buffer(changelog_local_t *local) { changelog_log_data_t *cld = NULL; if (!local) return NULL; cld = &local->cld; if (!cld->cld_iobuf) return NULL; return cld->cld_iobuf->ptr; } static int changelog_selector_index(unsigned int selector) { return (ffs(selector) - 1); } int changelog_ev_selected(xlator_t *this, changelog_ev_selector_t *selection, unsigned int selector) { int idx = 0; idx = changelog_selector_index(selector); gf_msg_debug(this->name, 0, "selector ref count for %d (idx: %d): %d", selector, idx, selection->ref[idx]); /* this can be lockless */ return (idx < CHANGELOG_EV_SELECTION_RANGE && (selection->ref[idx] > 0)); } void changelog_select_event(xlator_t *this, changelog_ev_selector_t *selection, unsigned int selector) { int idx = 0; LOCK(&selection->reflock); { while (selector) { idx = changelog_selector_index(selector); if (idx < CHANGELOG_EV_SELECTION_RANGE) { selection->ref[idx]++; gf_msg_debug(this->name, 0, "selecting event %d", idx); } selector &= ~(1 << idx); } } UNLOCK(&selection->reflock); } void changelog_deselect_event(xlator_t *this, changelog_ev_selector_t *selection, unsigned int selector) { int idx = 0; LOCK(&selection->reflock); { while (selector) { idx = changelog_selector_index(selector); if (idx < CHANGELOG_EV_SELECTION_RANGE) { selection->ref[idx]--; gf_msg_debug(this->name, 0, "de-selecting event %d", idx); } selector &= ~(1 << idx); } } UNLOCK(&selection->reflock); } int changelog_init_event_selection(xlator_t *this, changelog_ev_selector_t *selection) { int ret = 0; int j = CHANGELOG_EV_SELECTION_RANGE; ret = LOCK_INIT(&selection->reflock); if (ret != 0) return -1; LOCK(&selection->reflock); { while (j--) { selection->ref[j] = 0; } } UNLOCK(&selection->reflock); return 0; } static void changelog_perform_dispatch(xlator_t *this, changelog_priv_t *priv, void *mem, size_t size) { char *buf = NULL; void *opaque = NULL; buf = rbuf_reserve_write_area(priv->rbuf, size, &opaque); if (!buf) { gf_msg_callingfn(this->name, GF_LOG_WARNING, 0, CHANGELOG_MSG_DISPATCH_EVENT_FAILED, "failed to dispatch event"); return; } memcpy(buf, mem, size); rbuf_write_complete(opaque); } void changelog_dispatch_event(xlator_t *this, changelog_priv_t *priv, changelog_event_t *ev) { changelog_ev_selector_t *selection = NULL; selection = &priv->ev_selection; if (changelog_ev_selected(this, selection, ev->ev_type)) { changelog_perform_dispatch(this, priv, ev, CHANGELOG_EV_SIZE); } } void changelog_set_usable_record_and_length(changelog_local_t *local, size_t len, int xr) { changelog_log_data_t *cld = NULL; cld = &local->cld; cld->cld_ptr_len = len; cld->cld_xtra_records = xr; } void changelog_local_cleanup(xlator_t *xl, changelog_local_t *local) { int i = 0; changelog_opt_t *co = NULL; changelog_log_data_t *cld = NULL; if (!local) return; cld = &local->cld; /* cleanup dynamic allocation for extra records */ if (cld->cld_xtra_records) { co = (changelog_opt_t *)cld->cld_ptr; for (; i < cld->cld_xtra_records; i++, co++) if (co->co_free) co->co_free(co); } CHANGELOG_IOBUF_UNREF(cld->cld_iobuf); if (local->inode) inode_unref(local->inode); mem_put(local); } int changelog_write(int fd, char *buffer, size_t len) { ssize_t size = 0; size_t written = 0; while (written < len) { size = sys_write(fd, buffer + written, len - written); if (size <= 0) break; written += size; } return (written != len); } int htime_update(xlator_t *this, changelog_priv_t *priv, time_t ts, char *buffer) { char changelog_path[PATH_MAX + 1] = { 0, }; int len = -1; char x_value[25] = { 0, }; /* time stamp(10) + : (1) + rolltime (12 ) + buffer (2) */ int ret = 0; if (priv->htime_fd == -1) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_HTIME_ERROR, "reason=fd not available", NULL); ret = -1; goto out; } len = snprintf(changelog_path, PATH_MAX, "%s", buffer); if (len >= PATH_MAX) { ret = -1; goto out; } if (changelog_write(priv->htime_fd, (void *)changelog_path, len + 1) < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_HTIME_ERROR, "reason=write failed", NULL); ret = -1; goto out; } len = snprintf(x_value, sizeof(x_value), "%ld:%d", ts, priv->rollover_count); if (len >= sizeof(x_value)) { ret = -1; goto out; } if (sys_fsetxattr(priv->htime_fd, HTIME_KEY, x_value, len, XATTR_REPLACE)) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_HTIME_ERROR, "reason=xattr updation failed", "XATTR_REPLACE=true", "changelog=%s", changelog_path, NULL); if (sys_fsetxattr(priv->htime_fd, HTIME_KEY, x_value, len, 0)) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_HTIME_ERROR, "reason=xattr updation failed", "changelog=%s", changelog_path, NULL); ret = -1; goto out; } } priv->rollover_count += 1; out: return ret; } /* * Description: Check if the changelog to rollover is empty or not. * It is assumed that fd passed is already verified. * * Returns: * 1 : If found empty, changed path from "CHANGELOG." to "changelog." * 0 : If NOT empty, proceed usual. */ int cl_is_empty(xlator_t *this, int fd) { int ret = -1; size_t elen = 0; int encoding = -1; char buffer[1024] = { 0, }; struct stat stbuf = { 0, }; int major_version = -1; int minor_version = -1; ret = sys_fstat(fd, &stbuf); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FSTAT_OP_FAILED, NULL); goto out; } ret = sys_lseek(fd, 0, SEEK_SET); if (ret == -1) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_LSEEK_OP_FAILED, NULL); goto out; } CHANGELOG_GET_HEADER_INFO(fd, buffer, sizeof(buffer), encoding, major_version, minor_version, elen); if (elen == stbuf.st_size) { ret = 1; } else { ret = 0; } out: return ret; } /* * Description: Updates "CHANGELOG" to "changelog" for writing changelog path * to htime file. * * Returns: * 0 : Success * -1 : Error */ int update_path(xlator_t *this, char *cl_path) { const char low_cl[] = "changelog"; const char up_cl[] = "CHANGELOG"; char *found = NULL; int ret = -1; found = strstr(cl_path, up_cl); if (found == NULL) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PATH_NOT_FOUND, NULL); goto out; } else { memcpy(found, low_cl, sizeof(low_cl) - 1); } ret = 0; out: return ret; } static int changelog_rollover_changelog(xlator_t *this, changelog_priv_t *priv, time_t ts) { int ret = -1; int notify = 0; int cl_empty_flag = 0; struct tm *gmt; char yyyymmdd[40]; char ofile[PATH_MAX] = { 0, }; char nfile[PATH_MAX] = { 0, }; char nfile_dir[PATH_MAX] = { 0, }; changelog_event_t ev = { 0, }; if (priv->changelog_fd != -1) { ret = sys_fsync(priv->changelog_fd); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FSYNC_OP_FAILED, NULL); } ret = cl_is_empty(this, priv->changelog_fd); if (ret == 1) { cl_empty_flag = 1; } else if (ret == -1) { /* Log error but proceed as usual */ gf_smsg(this->name, GF_LOG_WARNING, 0, CHANGELOG_MSG_DETECT_EMPTY_CHANGELOG_FAILED, NULL); } sys_close(priv->changelog_fd); priv->changelog_fd = -1; } /* Get GMT time. */ gmt = gmtime(&ts); strftime(yyyymmdd, sizeof(yyyymmdd), "%Y/%m/%d", gmt); (void)snprintf(ofile, PATH_MAX, "%s/" CHANGELOG_FILE_NAME, priv->changelog_dir); (void)snprintf(nfile, PATH_MAX, "%s/%s/" CHANGELOG_FILE_NAME ".%ld", priv->changelog_dir, yyyymmdd, ts); (void)snprintf(nfile_dir, PATH_MAX, "%s/%s", priv->changelog_dir, yyyymmdd); if (cl_empty_flag == 1) { ret = sys_unlink(ofile); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_UNLINK_OP_FAILED, "path=%s", ofile, NULL); ret = 0; /* Error in unlinking empty changelog should not break further changelog operation, so reset return value to 0*/ } } else { ret = sys_rename(ofile, nfile); /* Changelog file rename gets ENOENT when parent dir doesn't exist */ if (errno == ENOENT) { ret = mkdir_p(nfile_dir, 0600, _gf_true); if ((ret == -1) && (EEXIST != errno)) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_MKDIR_ERROR, "%s", nfile_dir, NULL); goto out; } ret = sys_rename(ofile, nfile); } if (ret && (errno == ENOENT)) { ret = 0; goto out; } if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_RENAME_ERROR, "from=%s", ofile, "to=%s", nfile, NULL); } } if (!ret && (cl_empty_flag == 0)) { notify = 1; } if (!ret) { if (cl_empty_flag) { update_path(this, nfile); } ret = htime_update(this, priv, ts, nfile); if (ret == -1) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_HTIME_ERROR, NULL); goto out; } } if (notify) { ev.ev_type = CHANGELOG_OP_TYPE_JOURNAL; memcpy(ev.u.journal.path, nfile, strlen(nfile) + 1); changelog_dispatch_event(this, priv, &ev); } out: /* If this is explicit rollover initiated by snapshot, * wakeup reconfigure thread waiting for changelog to * rollover. This should happen even in failure cases as * well otherwise snapshot will timeout and fail. Hence * moved under out. */ if (priv->explicit_rollover) { priv->explicit_rollover = _gf_false; pthread_mutex_lock(&priv->bn.bnotify_mutex); { if (ret) { priv->bn.bnotify_error = _gf_true; gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_EXPLICIT_ROLLOVER_FAILED, NULL); } else { gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_BNOTIFY_INFO, "changelog=%s", nfile, NULL); } priv->bn.bnotify = _gf_false; pthread_cond_signal(&priv->bn.bnotify_cond); } pthread_mutex_unlock(&priv->bn.bnotify_mutex); } return ret; } int filter_cur_par_dirs(const struct dirent *entry) { if (entry == NULL) return 0; if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) return 0; else return 1; } /* * find_current_htime: * It finds the latest htime file and sets the HTIME_CURRENT * xattr. * RETURN VALUE: * -1 : Error * ret: Number of directory entries; */ int find_current_htime(int ht_dir_fd, const char *ht_dir_path, char *ht_file_bname) { struct dirent **namelist = NULL; int ret = 0; int cnt = 0; int i = 0; xlator_t *this = NULL; this = THIS; GF_ASSERT(this); GF_ASSERT(ht_dir_path); cnt = scandir(ht_dir_path, &namelist, filter_cur_par_dirs, alphasort); if (cnt < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_SCAN_DIR_FAILED, NULL); } else if (cnt > 0) { if (snprintf(ht_file_bname, NAME_MAX, "%s", namelist[cnt - 1]->d_name) >= NAME_MAX) { ret = -1; goto out; } if (sys_fsetxattr(ht_dir_fd, HTIME_CURRENT, ht_file_bname, strlen(ht_file_bname), 0)) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FSETXATTR_FAILED, "HTIME_CURRENT", NULL); ret = -1; goto out; } if (sys_fsync(ht_dir_fd) < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FSYNC_OP_FAILED, NULL); ret = -1; goto out; } } out: for (i = 0; i < cnt; i++) free(namelist[i]); free(namelist); if (ret) cnt = ret; return cnt; } /* Returns 0 on successful open of htime file * returns -1 on failure or error */ int htime_open(xlator_t *this, changelog_priv_t *priv, time_t ts) { int ht_file_fd = -1; int ht_dir_fd = -1; int ret = 0; int cnt = 0; char ht_dir_path[PATH_MAX] = { 0, }; char ht_file_path[PATH_MAX] = { 0, }; char ht_file_bname[NAME_MAX] = { 0, }; char x_value[NAME_MAX] = { 0, }; int flags = 0; unsigned long min_ts = 0; unsigned long max_ts = 0; unsigned long total = 0; unsigned long total1 = 0; ssize_t size = 0; struct stat stat_buf = { 0, }; unsigned long record_len = 0; int32_t len = 0; CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, ht_dir_path); /* Open htime directory to get HTIME_CURRENT */ ht_dir_fd = open(ht_dir_path, O_RDONLY); if (ht_dir_fd == -1) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_OPEN_FAILED, "path=%s", ht_dir_path, NULL); ret = -1; goto out; } size = sys_fgetxattr(ht_dir_fd, HTIME_CURRENT, ht_file_bname, sizeof(ht_file_bname)); if (size < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FGETXATTR_FAILED, "name=HTIME_CURRENT", NULL); /* If upgrade scenario, find the latest HTIME.TSTAMP file * and use the same. If error, create a new HTIME.TSTAMP * file. */ cnt = find_current_htime(ht_dir_fd, ht_dir_path, ht_file_bname); if (cnt <= 0) { gf_smsg(this->name, GF_LOG_INFO, errno, CHANGELOG_MSG_NO_HTIME_CURRENT, NULL); sys_close(ht_dir_fd); return htime_create(this, priv, ts); } gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_HTIME_CURRENT_ERROR, NULL); } gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_HTIME_CURRENT, "path=%s", ht_file_bname, NULL); len = snprintf(ht_file_path, PATH_MAX, "%s/%s", ht_dir_path, ht_file_bname); if ((len < 0) || (len >= PATH_MAX)) { ret = -1; goto out; } /* Open in append mode as existing htime file is used */ flags |= (O_RDWR | O_SYNC | O_APPEND); ht_file_fd = open(ht_file_path, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (ht_file_fd < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_OPEN_FAILED, "path=%s", ht_file_path, NULL); ret = -1; goto out; } /* save this htime_fd in priv->htime_fd */ priv->htime_fd = ht_file_fd; ret = sys_fstat(ht_file_fd, &stat_buf); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_HTIME_STAT_ERROR, "path=%s", ht_file_path, NULL); ret = -1; goto out; } /* Initialize rollover-number in priv to current number */ size = sys_fgetxattr(ht_file_fd, HTIME_KEY, x_value, sizeof(x_value)); if (size < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FGETXATTR_FAILED, "name=%s", HTIME_KEY, "path=%s", ht_file_path, NULL); ret = -1; goto out; } sscanf(x_value, "%lu:%lu", &max_ts, &total); /* 22 = 1(/) + 20(CHANGELOG.TIMESTAMP) + 1(\x00) */ record_len = strlen(priv->changelog_dir) + 22; total1 = stat_buf.st_size / record_len; if (total != total1) { gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_TOTAL_LOG_INFO, "xattr_total=%lu", total, "size_total=%lu", total1, NULL); } gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_TOTAL_LOG_INFO, "min=%lu", min_ts, "max=%lu", max_ts, "total_changelogs=%lu", total, NULL); if (total < total1) priv->rollover_count = total1 + 1; else priv->rollover_count = total + 1; out: if (ht_dir_fd != -1) sys_close(ht_dir_fd); return ret; } /* Returns 0 on successful creation of htime file * returns -1 on failure or error */ int htime_create(xlator_t *this, changelog_priv_t *priv, time_t ts) { int ht_file_fd = -1; int ht_dir_fd = -1; int ret = 0; char ht_dir_path[PATH_MAX] = { 0, }; char ht_file_path[PATH_MAX] = { 0, }; char ht_file_bname[NAME_MAX + 1] = { 0, }; int flags = 0; int32_t len = 0; gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_NEW_HTIME_FILE, "name=%ld", ts, NULL); CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, ht_dir_path); /* get the htime file name in ht_file_path */ len = snprintf(ht_file_path, PATH_MAX, "%s/%s.%ld", ht_dir_path, HTIME_FILE_NAME, ts); if ((len < 0) || (len >= PATH_MAX)) { ret = -1; goto out; } flags |= (O_CREAT | O_RDWR | O_SYNC); ht_file_fd = open(ht_file_path, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (ht_file_fd < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_OPEN_FAILED, "path=%s", ht_file_path, NULL); ret = -1; goto out; } if (sys_fsetxattr(ht_file_fd, HTIME_KEY, HTIME_INITIAL_VALUE, sizeof(HTIME_INITIAL_VALUE) - 1, 0)) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_XATTR_INIT_FAILED, NULL); ret = -1; goto out; } ret = sys_fsync(ht_file_fd); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FSYNC_OP_FAILED, NULL); goto out; } /* save this htime_fd in priv->htime_fd */ priv->htime_fd = ht_file_fd; ht_file_fd = -1; /* Set xattr HTIME_CURRENT on htime directory to htime filename */ ht_dir_fd = open(ht_dir_path, O_RDONLY); if (ht_dir_fd == -1) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_OPEN_FAILED, "path=%s", ht_dir_path, NULL); ret = -1; goto out; } (void)snprintf(ht_file_bname, sizeof(ht_file_bname), "%s.%ld", HTIME_FILE_NAME, ts); if (sys_fsetxattr(ht_dir_fd, HTIME_CURRENT, ht_file_bname, strlen(ht_file_bname), 0)) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FSETXATTR_FAILED, " HTIME_CURRENT", NULL); ret = -1; goto out; } ret = sys_fsync(ht_dir_fd); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FSYNC_OP_FAILED, NULL); goto out; } /* initialize rollover-number in priv to 1 */ priv->rollover_count = 1; out: if (ht_dir_fd != -1) sys_close(ht_dir_fd); if (ht_file_fd != -1) sys_close(ht_file_fd); return ret; } /* Description: * Opens the snap changelog to log call path fops in it. * This changelos name is "CHANGELOG.SNAP", stored in * path ".glusterfs/changelogs/csnap". * Returns: * 0 : On success. * -1 : On failure. */ int changelog_snap_open(xlator_t *this, changelog_priv_t *priv) { int fd = -1; int ret = 0; int flags = 0; char buffer[1024] = { 0, }; char c_snap_path[PATH_MAX] = { 0, }; char csnap_dir_path[PATH_MAX] = { 0, }; int32_t len = 0; CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir_path); len = snprintf(c_snap_path, PATH_MAX, "%s/" CSNAP_FILE_NAME, csnap_dir_path); if ((len < 0) || (len >= PATH_MAX)) { ret = -1; goto out; } flags |= (O_CREAT | O_RDWR | O_TRUNC); fd = open(c_snap_path, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_OPEN_FAILED, "path=%s", c_snap_path, NULL); ret = -1; goto out; } priv->c_snap_fd = fd; (void)snprintf(buffer, 1024, CHANGELOG_HEADER, CHANGELOG_VERSION_MAJOR, CHANGELOG_VERSION_MINOR, priv->ce->encoder); ret = changelog_snap_write_change(priv, buffer, strlen(buffer)); if (ret < 0) { sys_close(priv->c_snap_fd); priv->c_snap_fd = -1; goto out; } out: return ret; } /* * Description: * Starts logging fop details in CSNAP journal. * Returns: * 0 : On success. * -1 : On Failure. */ int changelog_snap_logging_start(xlator_t *this, changelog_priv_t *priv) { int ret = 0; ret = changelog_snap_open(this, priv); gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_SNAP_INFO, "starting", NULL); return ret; } /* * Description: * Stops logging fop details in CSNAP journal. * Returns: * 0 : On success. * -1 : On Failure. */ int changelog_snap_logging_stop(xlator_t *this, changelog_priv_t *priv) { int ret = 0; sys_close(priv->c_snap_fd); priv->c_snap_fd = -1; gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_SNAP_INFO, "Stopped", NULL); return ret; } int changelog_open_journal(xlator_t *this, changelog_priv_t *priv) { int fd = 0; int ret = -1; int flags = 0; char buffer[1024] = { 0, }; char changelog_path[PATH_MAX] = { 0, }; (void)snprintf(changelog_path, PATH_MAX, "%s/" CHANGELOG_FILE_NAME, priv->changelog_dir); flags |= (O_CREAT | O_RDWR); if (priv->fsync_interval == 0) flags |= O_SYNC; fd = open(changelog_path, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_OPEN_FAILED, "path=%s", changelog_path, NULL); goto out; } priv->changelog_fd = fd; (void)snprintf(buffer, 1024, CHANGELOG_HEADER, CHANGELOG_VERSION_MAJOR, CHANGELOG_VERSION_MINOR, priv->ce->encoder); ret = changelog_write_change(priv, buffer, strlen(buffer)); if (ret) { sys_close(priv->changelog_fd); priv->changelog_fd = -1; goto out; } ret = 0; out: return ret; } int changelog_start_next_change(xlator_t *this, changelog_priv_t *priv, time_t ts, gf_boolean_t finale) { int ret = -1; ret = changelog_rollover_changelog(this, priv, ts); if (!ret && !finale) ret = changelog_open_journal(this, priv); return ret; } /** * return the length of entry */ size_t changelog_entry_length(void) { return sizeof(changelog_log_data_t); } void changelog_fill_rollover_data(changelog_log_data_t *cld, gf_boolean_t is_last) { cld->cld_type = CHANGELOG_TYPE_ROLLOVER; cld->cld_roll_time = gf_time(); cld->cld_finale = is_last; } int changelog_snap_write_change(changelog_priv_t *priv, char *buffer, size_t len) { return changelog_write(priv->c_snap_fd, buffer, len); } int changelog_write_change(changelog_priv_t *priv, char *buffer, size_t len) { return changelog_write(priv->changelog_fd, buffer, len); } /* * Descriptions: * Writes fop details in ascii format to CSNAP. * Issues: * Not Encoding agnostic. * Returns: * 0 : On Success. * -1 : On Failure. */ int changelog_snap_handle_ascii_change(xlator_t *this, changelog_log_data_t *cld) { size_t off = 0; size_t gfid_len = 0; char *gfid_str = NULL; char *buffer = NULL; changelog_priv_t *priv = NULL; int ret = 0; if (this == NULL) { ret = -1; goto out; } priv = this->private; if (priv == NULL) { ret = -1; goto out; } gfid_str = uuid_utoa(cld->cld_gfid); gfid_len = strlen(gfid_str); /* extra bytes for decorations */ buffer = alloca(gfid_len + cld->cld_ptr_len + 10); CHANGELOG_STORE_ASCII(priv, buffer, off, gfid_str, gfid_len, cld); CHANGELOG_FILL_BUFFER(buffer, off, "\0", 1); ret = changelog_snap_write_change(priv, buffer, off); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_WRITE_FAILED, "csnap", NULL); } gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_WROTE_TO_CSNAP, NULL); ret = 0; out: return ret; } int changelog_handle_change(xlator_t *this, changelog_priv_t *priv, changelog_log_data_t *cld) { int ret = 0; if (CHANGELOG_TYPE_IS_ROLLOVER(cld->cld_type)) { changelog_encode_change(priv); ret = changelog_start_next_change(this, priv, cld->cld_roll_time, cld->cld_finale); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_GET_TIME_OP_FAILED, NULL); goto out; } /** * case when there is reconfigure done (disabling changelog) and there * are still fops that have updates in prgress. */ if (priv->changelog_fd == -1) return 0; if (CHANGELOG_TYPE_IS_FSYNC(cld->cld_type)) { ret = sys_fsync(priv->changelog_fd); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_FSYNC_OP_FAILED, NULL); } goto out; } ret = priv->ce->encode(this, cld); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_WRITE_FAILED, "changelog", NULL); } out: return ret; } changelog_local_t * changelog_local_init(xlator_t *this, inode_t *inode, uuid_t gfid, int xtra_records, gf_boolean_t update_flag) { changelog_local_t *local = NULL; struct iobuf *iobuf = NULL; /** * We relax the presence of inode if @update_flag is true. * The caller (implementation of the fop) needs to be careful to * not blindly use local->inode. */ if (!update_flag && !inode) { gf_msg_callingfn(this->name, GF_LOG_WARNING, 0, CHANGELOG_MSG_INODE_NOT_FOUND, "inode needed for version checking !!!"); goto out; } if (xtra_records) { iobuf = iobuf_get2(this->ctx->iobuf_pool, xtra_records * CHANGELOG_OPT_RECORD_LEN); if (!iobuf) goto out; } local = mem_get0(this->local_pool); if (!local) { CHANGELOG_IOBUF_UNREF(iobuf); goto out; } local->update_no_check = update_flag; gf_uuid_copy(local->cld.cld_gfid, gfid); local->cld.cld_iobuf = iobuf; local->cld.cld_xtra_records = 0; /* set by the caller */ if (inode) local->inode = inode_ref(inode); out: return local; } int changelog_forget(xlator_t *this, inode_t *inode) { uint64_t ctx_addr = 0; changelog_inode_ctx_t *ctx = NULL; inode_ctx_del(inode, this, &ctx_addr); if (!ctx_addr) return 0; ctx = (changelog_inode_ctx_t *)(long)ctx_addr; GF_FREE(ctx); return 0; } int changelog_inject_single_event(xlator_t *this, changelog_priv_t *priv, changelog_log_data_t *cld) { return priv->cd.dispatchfn(this, priv, priv->cd.cd_data, cld, NULL); } /* Wait till all the black fops are drained */ void changelog_drain_black_fops(xlator_t *this, changelog_priv_t *priv) { int ret = 0; /* clean up framework of pthread_mutex is required here as * 'reconfigure' terminates the changelog_rollover thread * on graph change. */ pthread_cleanup_push(changelog_cleanup_free_mutex, &priv->dm.drain_black_mutex); ret = pthread_mutex_lock(&priv->dm.drain_black_mutex); if (ret) gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_ERROR, "error=%d", ret, NULL); while (priv->dm.black_fop_cnt > 0) { gf_msg_debug(this->name, 0, "Conditional wait on black fops: %ld", priv->dm.black_fop_cnt); priv->dm.drain_wait_black = _gf_true; ret = pthread_cond_wait(&priv->dm.drain_black_cond, &priv->dm.drain_black_mutex); if (ret) gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_COND_WAIT_FAILED, "error=%d", ret, NULL); } priv->dm.drain_wait_black = _gf_false; ret = pthread_mutex_unlock(&priv->dm.drain_black_mutex); if (ret) gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_ERROR, "error=%d", ret, NULL); pthread_cleanup_pop(0); gf_msg_debug(this->name, 0, "Woke up: Conditional wait on black fops"); } /* Wait till all the white fops are drained */ void changelog_drain_white_fops(xlator_t *this, changelog_priv_t *priv) { int ret = 0; /* clean up framework of pthread_mutex is required here as * 'reconfigure' terminates the changelog_rollover thread * on graph change. */ pthread_cleanup_push(changelog_cleanup_free_mutex, &priv->dm.drain_white_mutex); ret = pthread_mutex_lock(&priv->dm.drain_white_mutex); if (ret) gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_ERROR, "error=%d", ret, NULL); while (priv->dm.white_fop_cnt > 0) { gf_msg_debug(this->name, 0, "Conditional wait on white fops : %ld", priv->dm.white_fop_cnt); priv->dm.drain_wait_white = _gf_true; ret = pthread_cond_wait(&priv->dm.drain_white_cond, &priv->dm.drain_white_mutex); if (ret) gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_COND_WAIT_FAILED, "error=%d", ret, NULL); } priv->dm.drain_wait_white = _gf_false; ret = pthread_mutex_unlock(&priv->dm.drain_white_mutex); if (ret) gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_ERROR, "error=%d", ret, NULL); pthread_cleanup_pop(0); gf_msg_debug(this->name, 0, "Woke up: Conditional wait on white fops"); } /** * TODO: these threads have many thing in common (wake up after * a certain time etc..). move them into separate routine. */ void * changelog_rollover(void *data) { int ret = 0; xlator_t *this = NULL; struct timespec tv = { 0, }; changelog_log_data_t cld = { 0, }; changelog_time_slice_t *slice = NULL; changelog_priv_t *priv = data; this = priv->cr.this; slice = &priv->slice; while (1) { (void)pthread_testcancel(); tv.tv_sec = gf_time() + priv->rollover_time; tv.tv_nsec = 0; ret = 0; /* Reset ret to zero */ /* The race between actual rollover and explicit rollover is * handled. If actual rollover is being done and the * explicit rollover event comes, the event is not missed. * Since explicit rollover sets 'cr.notify' to true, this * thread doesn't wait on 'pthread_cond_timedwait'. */ pthread_cleanup_push(changelog_cleanup_free_mutex, &priv->cr.lock); pthread_mutex_lock(&priv->cr.lock); { while (ret == 0 && !priv->cr.notify) ret = pthread_cond_timedwait(&priv->cr.cond, &priv->cr.lock, &tv); if (ret == 0) priv->cr.notify = _gf_false; } pthread_mutex_unlock(&priv->cr.lock); pthread_cleanup_pop(0); if (ret == 0) { gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_BARRIER_INFO, NULL); priv->explicit_rollover = _gf_true; } else if (ret && ret != ETIMEDOUT) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_SELECT_FAILED, NULL); continue; } else if (ret && ret == ETIMEDOUT) { gf_msg_debug(this->name, 0, "Wokeup on timeout"); } /* Reading curent_color without lock is fine here * as it is only modified here and is next to reading. */ if (priv->current_color == FOP_COLOR_BLACK) { LOCK(&priv->lock); priv->current_color = FOP_COLOR_WHITE; UNLOCK(&priv->lock); gf_msg_debug(this->name, 0, "Black fops" " to be drained:%ld", priv->dm.black_fop_cnt); changelog_drain_black_fops(this, priv); } else { LOCK(&priv->lock); priv->current_color = FOP_COLOR_BLACK; UNLOCK(&priv->lock); gf_msg_debug(this->name, 0, "White fops" " to be drained:%ld", priv->dm.white_fop_cnt); changelog_drain_white_fops(this, priv); } /* Adding delay of 1 second only during explicit rollover: * * Changelog rollover can happen either due to actual * or the explicit rollover during snapshot. Actual * rollover is controlled by tuneable called 'rollover-time'. * The minimum granularity for rollover-time is 1 second. * Explicit rollover is asynchronous in nature and happens * during snapshot. * * Basically, rollover renames the current CHANGELOG file * to CHANGELOG.TIMESTAMP. Let's assume, at time 't1', * actual and explicit rollover raced against each * other and actual rollover won the race renaming the * CHANGELOG file to CHANGELOG.t1 and opens a new * CHANGELOG file. There is high chance that, an immediate * explicit rollover at time 't1' can happen with in the same * second to rename CHANGELOG file to CHANGELOG.t1 resulting in * purging the earlier CHANGELOG.t1 file created by actual * rollover. So adding a delay of 1 second guarantees unique * CHANGELOG.TIMESTAMP during explicit rollover. */ if (priv->explicit_rollover == _gf_true) sleep(1); changelog_fill_rollover_data(&cld, _gf_false); _mask_cancellation(); LOCK(&priv->lock); { ret = changelog_inject_single_event(this, priv, &cld); if (!ret) SLICE_VERSION_UPDATE(slice); } UNLOCK(&priv->lock); _unmask_cancellation(); } return NULL; } void * changelog_fsync_thread(void *data) { int ret = 0; xlator_t *this = NULL; struct timeval tv = { 0, }; changelog_log_data_t cld = { 0, }; changelog_priv_t *priv = data; this = priv->cf.this; cld.cld_type = CHANGELOG_TYPE_FSYNC; while (1) { (void)pthread_testcancel(); tv.tv_sec = priv->fsync_interval; tv.tv_usec = 0; ret = select(0, NULL, NULL, NULL, &tv); if (ret) continue; _mask_cancellation(); ret = changelog_inject_single_event(this, priv, &cld); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_INJECT_FSYNC_FAILED, NULL); _unmask_cancellation(); } return NULL; } /* macros for inode/changelog version checks */ #define INODE_VERSION_UPDATE(priv, inode, iver, slice, type) \ do { \ LOCK(&inode->lock); \ { \ LOCK(&priv->lock); \ { \ *iver = slice->changelog_version[type]; \ } \ UNLOCK(&priv->lock); \ } \ UNLOCK(&inode->lock); \ } while (0) #define INODE_VERSION_EQUALS_SLICE(priv, ver, slice, type, upd) \ do { \ LOCK(&priv->lock); \ { \ upd = (ver == slice->changelog_version[type]) ? _gf_false \ : _gf_true; \ } \ UNLOCK(&priv->lock); \ } while (0) static int __changelog_inode_ctx_set(xlator_t *this, inode_t *inode, changelog_inode_ctx_t *ctx) { uint64_t ctx_addr = (uint64_t)(uintptr_t)ctx; return __inode_ctx_set(inode, this, &ctx_addr); } /** * one shot routine to get the address and the value of a inode version * for a particular type. */ changelog_inode_ctx_t * __changelog_inode_ctx_get(xlator_t *this, inode_t *inode, unsigned long **iver, unsigned long *version, changelog_log_type type) { int ret = 0; uint64_t ctx_addr = 0; changelog_inode_ctx_t *ctx = NULL; ret = __inode_ctx_get(inode, this, &ctx_addr); if (ret < 0) ctx_addr = 0; if (ctx_addr != 0) { ctx = (changelog_inode_ctx_t *)(long)ctx_addr; goto out; } ctx = GF_CALLOC(1, sizeof(*ctx), gf_changelog_mt_inode_ctx_t); if (!ctx) goto out; ret = __changelog_inode_ctx_set(this, inode, ctx); if (ret) { GF_FREE(ctx); ctx = NULL; } out: if (ctx && iver && version) { *iver = CHANGELOG_INODE_VERSION_TYPE(ctx, type); *version = **iver; } return ctx; } static changelog_inode_ctx_t * changelog_inode_ctx_get(xlator_t *this, inode_t *inode, unsigned long **iver, unsigned long *version, changelog_log_type type) { changelog_inode_ctx_t *ctx = NULL; LOCK(&inode->lock); { ctx = __changelog_inode_ctx_get(this, inode, iver, version, type); } UNLOCK(&inode->lock); return ctx; } /** * This is the main update routine. Locking has been made granular so as to * maximize parallelism of fops - I'll try to explain it below using execution * timelines. * * Basically, the contention is between multiple execution threads of this * routine and the roll-over thread. So, instead of having a big lock, we hold * granular locks: inode->lock and priv->lock. Now I'll explain what happens * when there is an update and a roll-over at just about the same time. * NOTE: * - the dispatcher itself synchronizes updates via it's own lock * - the slice version in incremented by the roll-over thread * * Case 1: When the rollover thread wins before the inode version can be * compared with the slice version. * * [updater] | [rollover] * | * | * | * | * | * | * | LOCK (&priv->lock) * | * | * | UNLOCK (&priv->lock) * | * LOCK (&priv->lock) | * | * I: 1 <-> S: 2 | * update: true | * UNLOCK (&priv->lock) | * | * | * | * | * LOCK (&inode->lock) | * LOCK (&priv->lock) | * | * UNLOCK (&priv->lock) | * UNLOCK (&inode->lock) | * * Therefore, the change gets recorded in the next change (no lost change). If * the slice version was ahead of the inode version (say I:1, S: 2), then * anyway the comparison would result in a update (I: 1, S: 3). * * If the rollover time is too less, then there is another contention when the * updater tries to bring up inode version to the slice version (this is also * the case when the roll-over thread wakes up during INODE_VERSION_UPDATE. * * | * | * | * | * | * LOCK (&inode->lock) | * LOCK (&priv->lock) | * | * UNLOCK (&priv->lock) | * UNLOCK (&inode->lock) | * | * | LOCK (&priv->lock) * | * | * | UNLOCK (&priv->lock) * * * Case 2: When the fop thread wins * * [updater] | [rollover] * | * | * | * | * | * | * LOCK (&priv->lock) | * | * I: 0 <-> S: 1 | * update: true | * UNLOCK (&priv->lock) | * | * | LOCK (&priv->lock) * | * | * | UNLOCK (&priv->lock) * | * | * | * LOCK (&inode->lock) | * LOCK (&priv->lock) | * | * UNLOCK (&priv->lock) | * UNLOCK (&inode->lock) | * * Here again, if the inode version was equal to the slice version (I: 1, S: 1) * then there is no need to record an update (as the equality of the two version * signifies an update was recorded in the current time slice). */ void changelog_update(xlator_t *this, changelog_priv_t *priv, changelog_local_t *local, changelog_log_type type) { int ret = 0; unsigned long *iver = NULL; unsigned long version = 0; inode_t *inode = NULL; changelog_time_slice_t *slice = NULL; changelog_inode_ctx_t *ctx = NULL; changelog_log_data_t *cld_0 = NULL; changelog_log_data_t *cld_1 = NULL; changelog_local_t *next_local = NULL; gf_boolean_t need_upd = _gf_true; slice = &priv->slice; /** * for fops that do not require inode version checking */ if (local->update_no_check) goto update; inode = local->inode; ctx = changelog_inode_ctx_get(this, inode, &iver, &version, type); if (!ctx) goto update; INODE_VERSION_EQUALS_SLICE(priv, version, slice, type, need_upd); update: if (need_upd) { cld_0 = &local->cld; cld_0->cld_type = type; if ((next_local = local->prev_entry) != NULL) { cld_1 = &next_local->cld; cld_1->cld_type = type; } ret = priv->cd.dispatchfn(this, priv, priv->cd.cd_data, cld_0, cld_1); /** * update after the dispatcher has successfully done * it's job. */ if (!local->update_no_check && iver && !ret) INODE_VERSION_UPDATE(priv, inode, iver, slice, type); } return; } /* Begin: Geo-rep snapshot dependency changes */ /* changelog_color_fop_and_inc_cnt: Assign color and inc fop cnt. * * Assigning color and increment of corresponding fop count should happen * in a lock (i.e., there should be no window between them). If it does not, * we might miss draining those fops which are colored but not yet incremented * the count. Let's assume black fops are draining. If the black fop count * reaches zero, we say draining is completed but we miss black fops which are * not incremented fop count but color is assigned black. */ void changelog_color_fop_and_inc_cnt(xlator_t *this, changelog_priv_t *priv, changelog_local_t *local) { if (!priv || !local) return; LOCK(&priv->lock); { local->color = priv->current_color; changelog_inc_fop_cnt(this, priv, local); } UNLOCK(&priv->lock); } /* Increments the respective fop counter based on the fop color */ void changelog_inc_fop_cnt(xlator_t *this, changelog_priv_t *priv, changelog_local_t *local) { int ret = 0; if (local) { if (local->color == FOP_COLOR_BLACK) { ret = pthread_mutex_lock(&priv->dm.drain_black_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); { priv->dm.black_fop_cnt++; } ret = pthread_mutex_unlock(&priv->dm.drain_black_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); } else { ret = pthread_mutex_lock(&priv->dm.drain_white_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); { priv->dm.white_fop_cnt++; } ret = pthread_mutex_unlock(&priv->dm.drain_white_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); } } out: return; } /* Decrements the respective fop counter based on the fop color */ void changelog_dec_fop_cnt(xlator_t *this, changelog_priv_t *priv, changelog_local_t *local) { int ret = 0; if (local) { if (local->color == FOP_COLOR_BLACK) { ret = pthread_mutex_lock(&priv->dm.drain_black_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); { priv->dm.black_fop_cnt--; if (priv->dm.black_fop_cnt == 0 && priv->dm.drain_wait_black == _gf_true) { ret = pthread_cond_signal(&priv->dm.drain_black_cond); CHANGELOG_PTHREAD_ERROR_HANDLE_2( ret, out, priv->dm.drain_black_mutex); gf_msg_debug(this->name, 0, "Signalled " "draining of black"); } } ret = pthread_mutex_unlock(&priv->dm.drain_black_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); } else { ret = pthread_mutex_lock(&priv->dm.drain_white_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); { priv->dm.white_fop_cnt--; if (priv->dm.white_fop_cnt == 0 && priv->dm.drain_wait_white == _gf_true) { ret = pthread_cond_signal(&priv->dm.drain_white_cond); CHANGELOG_PTHREAD_ERROR_HANDLE_2( ret, out, priv->dm.drain_white_mutex); gf_msg_debug(this->name, 0, "Signalled " "draining of white"); } } ret = pthread_mutex_unlock(&priv->dm.drain_white_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); } } out: return; } /* Write to a pipe setup between changelog main thread and changelog * rollover thread to initiate explicit rollover of changelog journal. */ int changelog_barrier_notify(changelog_priv_t *priv, char *buf) { int ret = 0; pthread_mutex_lock(&priv->cr.lock); { ret = pthread_cond_signal(&priv->cr.cond); priv->cr.notify = _gf_true; } pthread_mutex_unlock(&priv->cr.lock); return ret; } /* Clean up flags set on barrier notification */ void changelog_barrier_cleanup(xlator_t *this, changelog_priv_t *priv, struct list_head *queue) { int ret = 0; LOCK(&priv->bflags.lock); priv->bflags.barrier_ext = _gf_false; UNLOCK(&priv->bflags.lock); ret = pthread_mutex_lock(&priv->bn.bnotify_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); { priv->bn.bnotify = _gf_false; } ret = pthread_mutex_unlock(&priv->bn.bnotify_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, out); /* Disable changelog barrier and dequeue fops */ LOCK(&priv->lock); { if (priv->barrier_enabled == _gf_true) __chlog_barrier_disable(this, queue); else ret = -1; } UNLOCK(&priv->lock); if (ret == 0) chlog_barrier_dequeue_all(this, queue); out: return; } /* End: Geo-Rep snapshot dependency changes */ int32_t changelog_fill_entry_buf(call_frame_t *frame, xlator_t *this, loc_t *loc, changelog_local_t **local) { changelog_opt_t *co = NULL; size_t xtra_len = 0; char *dup_path = NULL; char *bname = NULL; inode_t *parent = NULL; GF_ASSERT(this); parent = inode_parent(loc->inode, 0, 0); if (!parent) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_INODE_NOT_FOUND, "type=parent", "gfid=%s", uuid_utoa(loc->inode->gfid), NULL); goto err; } CHANGELOG_INIT_NOCHECK(this, *local, loc->inode, loc->inode->gfid, 5); if (!(*local)) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_LOCAL_INIT_FAILED, NULL); goto err; } co = changelog_get_usable_buffer(*local); if (!co) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_GET_BUFFER_FAILED, NULL); goto err; } if (loc->inode->ia_type == IA_IFDIR) { CHANGLOG_FILL_FOP_NUMBER(co, GF_FOP_MKDIR, fop_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, S_IFDIR | 0755, number_fn, xtra_len); co++; } else { CHANGLOG_FILL_FOP_NUMBER(co, GF_FOP_CREATE, fop_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, S_IFREG | 0644, number_fn, xtra_len); co++; } CHANGELOG_FILL_UINT32(co, frame->root->uid, number_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, frame->root->gid, number_fn, xtra_len); co++; dup_path = gf_strdup(loc->path); bname = basename(dup_path); CHANGELOG_FILL_ENTRY(co, parent->gfid, bname, entry_fn, entry_free_fn, xtra_len, err); changelog_set_usable_record_and_length(*local, xtra_len, 5); if (dup_path) GF_FREE(dup_path); if (parent) inode_unref(parent); return 0; err: if (dup_path) GF_FREE(dup_path); if (parent) inode_unref(parent); return -1; } /* * resolve_pargfid_to_path: * It converts given pargfid to path by doing recursive readlinks at the * backend. If bname is given, it suffixes bname to pargfid to form the * complete path else it doesn't. It allocates memory for the path and is * caller's responsibility to free the same. If bname is NULL and pargfid * is ROOT, then it returns "." */ int resolve_pargfid_to_path(xlator_t *this, const uuid_t pgfid, char **path, char *bname) { char *linkname = NULL; char *dir_handle = NULL; char *pgfidstr = NULL; char *saveptr = NULL; ssize_t len = 0; int ret = 0; uuid_t tmp_gfid = { 0, }; uuid_t pargfid = { 0, }; changelog_priv_t *priv = NULL; char gpath[PATH_MAX] = { 0, }; char result[PATH_MAX] = { 0, }; char *dir_name = NULL; char pre_dir_name[PATH_MAX] = { 0, }; GF_ASSERT(this); priv = this->private; GF_ASSERT(priv); gf_uuid_copy(pargfid, pgfid); if (!path || gf_uuid_is_null(pargfid)) { ret = -1; goto out; } if (__is_root_gfid(pargfid)) { if (bname) *path = gf_strdup(bname); else *path = gf_strdup("."); return ret; } dir_handle = alloca(PATH_MAX); linkname = alloca(PATH_MAX); (void)snprintf(gpath, PATH_MAX, "%s/.glusterfs/", priv->changelog_brick); while (!(__is_root_gfid(pargfid))) { len = snprintf(dir_handle, PATH_MAX, "%s/%02x/%02x/%s", gpath, pargfid[0], pargfid[1], uuid_utoa(pargfid)); if ((len < 0) || (len >= PATH_MAX)) { ret = -1; goto out; } len = sys_readlink(dir_handle, linkname, PATH_MAX); if (len < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_READLINK_OP_FAILED, "could not read the " "link from the gfid handle", "handle=%s", dir_handle, NULL); ret = -1; goto out; } linkname[len] = '\0'; pgfidstr = strtok_r(linkname + strlen("../../00/00/"), "/", &saveptr); dir_name = strtok_r(NULL, "/", &saveptr); len = snprintf(result, PATH_MAX, "%s/%s", dir_name, pre_dir_name); if ((len < 0) || (len >= PATH_MAX)) { ret = -1; goto out; } if (snprintf(pre_dir_name, len + 1, "%s", result) >= len + 1) { ret = -1; goto out; } gf_uuid_parse(pgfidstr, tmp_gfid); gf_uuid_copy(pargfid, tmp_gfid); } if (bname) snprintf(result + len, sizeof(result) - len, "%s", bname); *path = gf_strdup(result); out: return ret; } glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-mem-types.h0000644000000000000000000000013214522202451026426 xustar000000000000000030 mtime=1699284265.660027411 30 atime=1699284265.660027411 30 ctime=1699284304.317143845 glusterfs-11.1/xlators/features/changelog/src/changelog-mem-types.h0000664000175100017510000000251714522202451026712 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CHANGELOG_MEM_TYPES_H #define _CHANGELOG_MEM_TYPES_H #include enum gf_changelog_mem_types { gf_changelog_mt_priv_t = gf_common_mt_end + 1, gf_changelog_mt_str_t = gf_common_mt_end + 2, gf_changelog_mt_batch_t = gf_common_mt_end + 3, gf_changelog_mt_rt_t = gf_common_mt_end + 4, gf_changelog_mt_inode_ctx_t = gf_common_mt_end + 5, gf_changelog_mt_rpc_clnt_t = gf_common_mt_end + 6, gf_changelog_mt_libgfchangelog_t = gf_common_mt_end + 7, gf_changelog_mt_libgfchangelog_entry_t = gf_common_mt_end + 8, gf_changelog_mt_libgfchangelog_rl_t = gf_common_mt_end + 9, gf_changelog_mt_changelog_buffer_t = gf_common_mt_end + 10, gf_changelog_mt_history_data_t = gf_common_mt_end + 11, gf_changelog_mt_libgfchangelog_call_pool_t = gf_common_mt_end + 12, gf_changelog_mt_libgfchangelog_event_t = gf_common_mt_end + 13, gf_changelog_mt_ev_dispatcher_t = gf_common_mt_end + 14, gf_changelog_mt_end }; #endif glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-rpc.h0000644000000000000000000000013214522202451025272 xustar000000000000000030 mtime=1699284265.661027414 30 atime=1699284265.661027414 30 ctime=1699284304.326143872 glusterfs-11.1/xlators/features/changelog/src/changelog-rpc.h0000664000175100017510000000143314522202451025552 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __CHANGELOG_RPC_H #define __CHANGELOG_RPC_H #include "changelog-helpers.h" /* one time */ #include "changelog-rpc-common.h" #define CHANGELOG_RPC_PROGNAME "GlusterFS Changelog" rpcsvc_t * changelog_init_rpc_listener(xlator_t *, changelog_priv_t *, rbuf_t *, int); void changelog_destroy_rpc_listner(xlator_t *, changelog_priv_t *); int changelog_cleanup_rpc_threads(xlator_t *this, changelog_priv_t *priv); #endif glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-rt.h0000644000000000000000000000013214522202451025133 xustar000000000000000030 mtime=1699284265.662027417 30 atime=1699284265.661027414 30 ctime=1699284304.319143851 glusterfs-11.1/xlators/features/changelog/src/changelog-rt.h0000664000175100017510000000167514522202451025423 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CHANGELOG_RT_H #define _CHANGELOG_RT_H #include #include #include "changelog-helpers.h" /* unused as of now - may be you would need it later */ typedef struct changelog_rt { gf_lock_t lock; } changelog_rt_t; int changelog_rt_init(xlator_t *this, changelog_dispatcher_t *cd); int changelog_rt_fini(xlator_t *this, changelog_dispatcher_t *cd); int changelog_rt_enqueue(xlator_t *this, changelog_priv_t *priv, void *cbatch, changelog_log_data_t *cld_0, changelog_log_data_t *cld_1); #endif /* _CHANGELOG_RT_H */ glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-encoders.h0000644000000000000000000000013214522202451026310 xustar000000000000000030 mtime=1699284265.659027408 30 atime=1699284265.659027408 30 ctime=1699284304.324143866 glusterfs-11.1/xlators/features/changelog/src/changelog-encoders.h0000664000175100017510000000322414522202451026570 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CHANGELOG_ENCODERS_H #define _CHANGELOG_ENCODERS_H #include "changelog-helpers.h" #define CHANGELOG_STORE_ASCII(priv, buf, off, gfid, gfid_len, cld) \ do { \ CHANGELOG_FILL_BUFFER(buffer, off, priv->maps[cld->cld_type], 1); \ CHANGELOG_FILL_BUFFER(buffer, off, gfid, gfid_len); \ } while (0) #define CHANGELOG_STORE_BINARY(priv, buf, off, gfid, cld) \ do { \ CHANGELOG_FILL_BUFFER(buffer, off, priv->maps[cld->cld_type], 1); \ CHANGELOG_FILL_BUFFER(buffer, off, gfid, sizeof(uuid_t)); \ } while (0) size_t entry_fn(void *data, char *buffer, gf_boolean_t encode); size_t del_entry_fn(void *data, char *buffer, gf_boolean_t encode); size_t fop_fn(void *data, char *buffer, gf_boolean_t encode); size_t number_fn(void *data, char *buffer, gf_boolean_t encode); void entry_free_fn(void *data); void del_entry_free_fn(void *data); int changelog_encode_binary(xlator_t *, changelog_log_data_t *); int changelog_encode_ascii(xlator_t *, changelog_log_data_t *); void changelog_encode_change(changelog_priv_t *); #endif /* _CHANGELOG_ENCODERS_H */ glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463024460 xustar000000000000000030 mtime=1699284275.628057435 30 atime=1699284290.173101244 30 ctime=1699284304.311143827 glusterfs-11.1/xlators/features/changelog/src/Makefile.in0000664000175100017510000006222314522202463024744 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/changelog/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) changelog_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la am_changelog_la_OBJECTS = changelog.lo changelog-rt.lo \ changelog-helpers.lo changelog-encoders.lo changelog-rpc.lo \ changelog-barrier.lo changelog-rpc-common.lo \ changelog-ev-handle.lo changelog_la_OBJECTS = $(am_changelog_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = changelog_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(changelog_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(changelog_la_SOURCES) DIST_SOURCES = $(changelog_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = changelog.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features noinst_HEADERS = changelog-helpers.h changelog-mem-types.h changelog-rt.h \ changelog-rpc-common.h changelog-misc.h changelog-encoders.h \ changelog-rpc-common.h changelog-rpc.h changelog-ev-handle.h \ changelog-messages.h changelog_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) changelog_la_SOURCES = changelog.c changelog-rt.c changelog-helpers.c \ changelog-encoders.c changelog-rpc.c changelog-barrier.c \ changelog-rpc-common.c changelog-ev-handle.c changelog_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/rpc-transport/socket/src \ -I$(top_srcdir)/xlators/features/changelog/lib/src/ \ -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE \ -DDATADIR=\"$(localstatedir)\" AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/changelog/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/changelog/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } changelog.la: $(changelog_la_OBJECTS) $(changelog_la_DEPENDENCIES) $(EXTRA_changelog_la_DEPENDENCIES) $(AM_V_CCLD)$(changelog_la_LINK) -rpath $(xlatordir) $(changelog_la_OBJECTS) $(changelog_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changelog-barrier.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changelog-encoders.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changelog-ev-handle.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changelog-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changelog-rpc-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changelog-rpc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changelog-rt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changelog.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-rpc-common.c0000644000000000000000000000013114522202451026552 xustar000000000000000030 mtime=1699284265.661027414 30 atime=1699284265.661027414 29 ctime=1699284304.34214392 glusterfs-11.1/xlators/features/changelog/src/changelog-rpc-common.c0000664000175100017510000002105214522202451027032 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "changelog-rpc-common.h" #include "changelog-messages.h" #include /** ***************************************************** Client Interface ***************************************************** */ /** * Initialize and return an RPC client object for a given unix * domain socket. */ void * changelog_rpc_poller(void *arg) { xlator_t *this = arg; (void)gf_event_dispatch(this->ctx->event_pool); return NULL; } struct rpc_clnt * changelog_rpc_client_init(xlator_t *this, void *cbkdata, char *sockfile, rpc_clnt_notify_t fn) { int ret = 0; struct rpc_clnt *rpc = NULL; dict_t *options = NULL; if (!cbkdata) cbkdata = this; options = dict_new(); if (!options) goto error_return; ret = rpc_transport_unix_options_build(options, sockfile, 0); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_RPC_BUILD_ERROR, NULL); goto dealloc_dict; } rpc = rpc_clnt_new(options, this, this->name, 16); if (!rpc) goto dealloc_dict; ret = rpc_clnt_register_notify(rpc, fn, cbkdata); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_NOTIFY_REGISTER_FAILED, NULL); goto dealloc_rpc_clnt; } ret = rpc_clnt_start(rpc); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_RPC_START_ERROR, NULL); goto dealloc_rpc_clnt; } dict_unref(options); return rpc; dealloc_rpc_clnt: rpc_clnt_unref(rpc); dealloc_dict: if (options) dict_unref(options); error_return: return NULL; } /** * Generic RPC client routine to dispatch a request to an * RPC server. */ int changelog_rpc_sumbit_req(struct rpc_clnt *rpc, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, struct iovec *payload, int payloadcnt, struct iobref *iobref, xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc) { int ret = 0; int count = 0; struct iovec iov = { 0, }; struct iobuf *iobuf = NULL; char new_iobref = 0; ssize_t xdr_size = 0; GF_ASSERT(this); if (req) { xdr_size = xdr_sizeof(xdrproc, req); iobuf = iobuf_get2(this->ctx->iobuf_pool, xdr_size); if (!iobuf) { goto out; }; if (!iobref) { iobref = iobref_new(); if (!iobref) { goto out; } new_iobref = 1; } iobref_add(iobref, iobuf); iov.iov_base = iobuf->ptr; iov.iov_len = iobuf_size(iobuf); /* Create the xdr payload */ ret = xdr_serialize_generic(iov, req, xdrproc); if (ret == -1) { goto out; } iov.iov_len = ret; count = 1; } ret = rpc_clnt_submit(rpc, prog, procnum, cbkfn, &iov, count, payload, payloadcnt, iobref, frame, NULL, 0, NULL, 0, NULL); out: if (new_iobref) iobref_unref(iobref); if (iobuf) iobuf_unref(iobuf); return ret; } /** * Entry point to perform a remote procedure call */ int changelog_invoke_rpc(xlator_t *this, struct rpc_clnt *rpc, rpc_clnt_prog_t *prog, int procidx, void *arg) { int ret = 0; call_frame_t *frame = NULL; rpc_clnt_procedure_t *proc = NULL; if (!this || !prog) goto error_return; frame = create_frame(this, this->ctx->pool); if (!frame) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_CREATE_FRAME_FAILED, NULL); goto error_return; } proc = &prog->proctable[procidx]; if (proc->fn) ret = proc->fn(frame, this, arg); STACK_DESTROY(frame->root); return ret; error_return: return -1; } /** ***************************************************** Server Interface ***************************************************** */ struct iobuf * __changelog_rpc_serialize_reply(rpcsvc_request_t *req, void *arg, struct iovec *outmsg, xdrproc_t xdrproc) { struct iobuf *iob = NULL; ssize_t retlen = 0; ssize_t rsp_size = 0; rsp_size = xdr_sizeof(xdrproc, arg); iob = iobuf_get2(req->svc->ctx->iobuf_pool, rsp_size); if (!iob) goto error_return; iobuf_to_iovec(iob, outmsg); retlen = xdr_serialize_generic(*outmsg, arg, xdrproc); if (retlen == -1) goto unref_iob; outmsg->iov_len = retlen; return iob; unref_iob: iobuf_unref(iob); error_return: return NULL; } int changelog_rpc_sumbit_reply(rpcsvc_request_t *req, void *arg, struct iovec *payload, int payloadcount, struct iobref *iobref, xdrproc_t xdrproc) { int ret = -1; struct iobuf *iob = NULL; struct iovec iov = { 0, }; char new_iobref = 0; if (!req) goto return_ret; if (!iobref) { iobref = iobref_new(); if (!iobref) goto return_ret; new_iobref = 1; } iob = __changelog_rpc_serialize_reply(req, arg, &iov, xdrproc); if (!iob) gf_smsg("", GF_LOG_ERROR, 0, CHANGELOG_MSG_RPC_SUBMIT_REPLY_FAILED, NULL); else iobref_add(iobref, iob); ret = rpcsvc_submit_generic(req, &iov, 1, payload, payloadcount, iobref); if (new_iobref) iobref_unref(iobref); if (iob) iobuf_unref(iob); return_ret: return ret; } void changelog_rpc_server_destroy(xlator_t *this, rpcsvc_t *rpc, char *sockfile, rpcsvc_notify_t fn, struct rpcsvc_program **progs) { rpcsvc_listener_t *listener = NULL; rpcsvc_listener_t *next = NULL; struct rpcsvc_program *prog = NULL; rpc_transport_t *trans = NULL; if (!rpc) return; while (*progs) { prog = *progs; (void)rpcsvc_program_unregister(rpc, prog); progs++; } list_for_each_entry_safe(listener, next, &rpc->listeners, list) { if (listener->trans) { trans = listener->trans; rpc_transport_disconnect(trans, _gf_false); } } (void)rpcsvc_unregister_notify(rpc, fn, this); /* TODO Avoid freeing rpc object in case of brick multiplex after freeing rpc object svc->rpclock corrupted and it takes more time to detach a brick */ if (!this->cleanup_starting) { if (rpc->rxpool) { mem_pool_destroy(rpc->rxpool); rpc->rxpool = NULL; } GF_FREE(rpc); } } rpcsvc_t * changelog_rpc_server_init(xlator_t *this, char *sockfile, void *cbkdata, rpcsvc_notify_t fn, struct rpcsvc_program **progs) { int ret = 0; rpcsvc_t *rpc = NULL; dict_t *options = NULL; struct rpcsvc_program *prog = NULL; if (!cbkdata) cbkdata = this; options = dict_new(); if (!options) return NULL; ret = rpcsvc_transport_unix_options_build(options, sockfile); if (ret) goto dealloc_dict; rpc = rpcsvc_init(this, this->ctx, options, 8); if (rpc == NULL) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_RPC_START_ERROR, NULL); goto dealloc_dict; } ret = rpcsvc_register_notify(rpc, fn, cbkdata); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_NOTIFY_REGISTER_FAILED, NULL); goto dealloc_rpc; } ret = rpcsvc_create_listeners(rpc, options, this->name); if (ret != 1) { gf_msg_debug(this->name, 0, "failed to create listeners"); goto dealloc_rpc; } while (*progs) { prog = *progs; ret = rpcsvc_program_register(rpc, prog, _gf_false); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_PROGRAM_NAME_REG_FAILED, "name%s", prog->progname, "prognum=%d", prog->prognum, "pogver=%d", prog->progver, NULL); goto dealloc_rpc; } progs++; } dict_unref(options); return rpc; dealloc_rpc: GF_FREE(rpc); dealloc_dict: dict_unref(options); return NULL; } glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-rpc-common.h0000644000000000000000000000013214522202451026560 xustar000000000000000030 mtime=1699284265.661027414 30 atime=1699284265.661027414 30 ctime=1699284304.321143857 glusterfs-11.1/xlators/features/changelog/src/changelog-rpc-common.h0000664000175100017510000000425114522202451027041 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __CHANGELOG_RPC_COMMON_H #define __CHANGELOG_RPC_COMMON_H #include "rpcsvc.h" #include "rpc-clnt.h" #include #include "changelog-xdr.h" /** * Let's keep this non-configurable for now. */ #define NR_ROTT_BUFFS 4 #define NR_DISPATCHERS (NR_ROTT_BUFFS - 1) enum changelog_rpc_procnum { CHANGELOG_RPC_PROC_NULL = 0, CHANGELOG_RPC_PROBE_FILTER = 1, CHANGELOG_RPC_PROC_MAX = 2, }; #define CHANGELOG_RPC_PROGNUM 1885957735 #define CHANGELOG_RPC_PROGVER 1 /** * reverse connection: data xfer path */ enum changelog_reverse_rpc_procnum { CHANGELOG_REV_PROC_NULL = 0, CHANGELOG_REV_PROC_EVENT = 1, CHANGELOG_REV_PROC_MAX = 2, }; #define CHANGELOG_REV_RPC_PROCNUM 1886350951 #define CHANGELOG_REV_RPC_PROCVER 1 typedef struct changelog_rpc { rpcsvc_t *svc; struct rpc_clnt *rpc; char sock[UNIX_PATH_MAX]; /* tied to server */ } changelog_rpc_t; /* event poller */ void * changelog_rpc_poller(void *); /* CLIENT API */ struct rpc_clnt * changelog_rpc_client_init(xlator_t *, void *, char *, rpc_clnt_notify_t); int changelog_rpc_sumbit_req(struct rpc_clnt *, void *, call_frame_t *, rpc_clnt_prog_t *, int, struct iovec *, int, struct iobref *, xlator_t *, fop_cbk_fn_t, xdrproc_t); int changelog_invoke_rpc(xlator_t *, struct rpc_clnt *, rpc_clnt_prog_t *, int, void *); /* SERVER API */ int changelog_rpc_sumbit_reply(rpcsvc_request_t *, void *, struct iovec *, int, struct iobref *, xdrproc_t); rpcsvc_t * changelog_rpc_server_init(xlator_t *, char *, void *, rpcsvc_notify_t, struct rpcsvc_program **); void changelog_rpc_server_destroy(xlator_t *, rpcsvc_t *, char *, rpcsvc_notify_t, struct rpcsvc_program **); #endif glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451024443 xustar000000000000000030 mtime=1699284265.659027408 29 atime=1699284275.59005732 30 ctime=1699284304.313143833 glusterfs-11.1/xlators/features/changelog/src/Makefile.am0000664000175100017510000000213614522202451024725 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = changelog.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features noinst_HEADERS = changelog-helpers.h changelog-mem-types.h changelog-rt.h \ changelog-rpc-common.h changelog-misc.h changelog-encoders.h \ changelog-rpc-common.h changelog-rpc.h changelog-ev-handle.h \ changelog-messages.h changelog_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) changelog_la_SOURCES = changelog.c changelog-rt.c changelog-helpers.c \ changelog-encoders.c changelog-rpc.c changelog-barrier.c \ changelog-rpc-common.c changelog-ev-handle.c changelog_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/rpc-transport/socket/src \ -I$(top_srcdir)/xlators/features/changelog/lib/src/ \ -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE \ -DDATADIR=\"$(localstatedir)\" AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog.c0000644000000000000000000000013214522202451024503 xustar000000000000000030 mtime=1699284265.662027417 30 atime=1699284265.662027417 30 ctime=1699284304.331143887 glusterfs-11.1/xlators/features/changelog/src/changelog.c0000664000175100017510000025547214522202451025001 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "changelog-rt.h" #include "changelog-encoders.h" #include "changelog-mem-types.h" #include "changelog-messages.h" #include #include #include "changelog-rpc.h" #include "errno.h" static struct changelog_bootstrap cb_bootstrap[] = { { .mode = CHANGELOG_MODE_RT, .ctor = changelog_rt_init, .dtor = changelog_rt_fini, }, }; static int changelog_init_rpc(xlator_t *this, changelog_priv_t *priv); static int changelog_init(xlator_t *this, changelog_priv_t *priv); /* Entry operations - TYPE III */ /** * entry operations do not undergo inode version checking. */ /* {{{ */ /* rmdir */ int32_t changelog_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_ENTRY); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(rmdir, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int32_t changelog_rmdir_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { changelog_priv_t *priv = NULL; priv = this->private; gf_msg_debug(this->name, 0, "Dequeue rmdir"); changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, xflags, xdata); return 0; } int32_t changelog_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { size_t xtra_len = 0; changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; call_stub_t *stub = NULL; struct list_head queue = { 0, }; gf_boolean_t barrier_enabled = _gf_false; INIT_LIST_HEAD(&queue); priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_INIT_NOCHECK(this, frame->local, NULL, loc->inode->gfid, 2); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); co++; if (priv->capture_del_path) { CHANGELOG_FILL_ENTRY_DIR_PATH(co, loc->pargfid, loc->name, del_entry_fn, del_entry_free_fn, xtra_len, wind, _gf_true); } else { CHANGELOG_FILL_ENTRY_DIR_PATH(co, loc->pargfid, loc->name, del_entry_fn, del_entry_free_fn, xtra_len, wind, _gf_false); } changelog_set_usable_record_and_length(frame->local, xtra_len, 2); /* changelog barrier */ /* Color assignment and increment of fop_cnt for rmdir/unlink/rename * should be made with in priv lock if changelog barrier is not enabled. * Because if counter is not incremented yet, draining wakes up and * publishes the changelog but later these fops might hit the disk and * present in snapped volume but where as the intention is these fops * should not be present in snapped volume. */ LOCK(&priv->lock); { if ((barrier_enabled = priv->barrier_enabled)) { stub = fop_rmdir_stub(frame, changelog_rmdir_resume, loc, xflags, xdata); if (!stub) __chlog_barrier_disable(this, &queue); else __chlog_barrier_enqueue(this, stub); } else { ((changelog_local_t *)frame->local)->color = priv->current_color; changelog_inc_fop_cnt(this, priv, frame->local); } } UNLOCK(&priv->lock); if (barrier_enabled && stub) { gf_msg_debug(this->name, 0, "Enqueue rmdir"); goto out; } if (barrier_enabled && !stub) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, CHANGELOG_MSG_BARRIER_FOP_FAILED, "fop=rmdir", NULL); chlog_barrier_dequeue_all(this, &queue); } /* changelog barrier */ wind: STACK_WIND(frame, changelog_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, xflags, xdata); out: return 0; } /* unlink */ int32_t changelog_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_ENTRY); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int32_t changelog_unlink_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { changelog_priv_t *priv = NULL; priv = this->private; gf_msg_debug(this->name, 0, "Dequeue unlink"); changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflags, xdata); return 0; } int32_t changelog_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { size_t xtra_len = 0; changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; call_stub_t *stub = NULL; struct list_head queue = { 0, }; gf_boolean_t barrier_enabled = _gf_false; dht_changelog_rename_info_t *info = NULL; int ret = 0; char *old_name = NULL; char *new_name = NULL; char *nname = NULL; INIT_LIST_HEAD(&queue); priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); ret = dict_get_bin(xdata, DHT_CHANGELOG_RENAME_OP_KEY, (void **)&info); if (!ret) { /* special case: unlink considered as rename */ /* 3 == fop + oldloc + newloc */ old_name = alloca(info->oldname_len); new_name = alloca(info->newname_len); CHANGELOG_INIT_NOCHECK(this, frame->local, NULL, loc->inode->gfid, 3); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, GF_FOP_RENAME, fop_fn, xtra_len); co++; strncpy(old_name, info->buffer, info->oldname_len); CHANGELOG_FILL_ENTRY(co, info->old_pargfid, old_name, entry_fn, entry_free_fn, xtra_len, wind); co++; /* new name resides just after old name */ nname = info->buffer + info->oldname_len; strncpy(new_name, nname, info->newname_len); CHANGELOG_FILL_ENTRY(co, info->new_pargfid, new_name, entry_fn, entry_free_fn, xtra_len, wind); changelog_set_usable_record_and_length(frame->local, xtra_len, 3); } else { /* default unlink */ CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, wind); CHANGELOG_INIT_NOCHECK(this, frame->local, NULL, loc->inode->gfid, 2); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); co++; if (priv->capture_del_path) { CHANGELOG_FILL_ENTRY_DIR_PATH(co, loc->pargfid, loc->name, del_entry_fn, del_entry_free_fn, xtra_len, wind, _gf_true); } else { CHANGELOG_FILL_ENTRY_DIR_PATH(co, loc->pargfid, loc->name, del_entry_fn, del_entry_free_fn, xtra_len, wind, _gf_false); } changelog_set_usable_record_and_length(frame->local, xtra_len, 2); } /* changelog barrier */ LOCK(&priv->lock); { if ((barrier_enabled = priv->barrier_enabled)) { stub = fop_unlink_stub(frame, changelog_unlink_resume, loc, xflags, xdata); if (!stub) __chlog_barrier_disable(this, &queue); else __chlog_barrier_enqueue(this, stub); } else { ((changelog_local_t *)frame->local)->color = priv->current_color; changelog_inc_fop_cnt(this, priv, frame->local); } } UNLOCK(&priv->lock); if (barrier_enabled && stub) { gf_msg_debug(this->name, 0, "Enqueue unlink"); goto out; } if (barrier_enabled && !stub) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, CHANGELOG_MSG_BARRIER_FOP_FAILED, "fop=unlink", NULL); chlog_barrier_dequeue_all(this, &queue); } /* changelog barrier */ wind: STACK_WIND(frame, changelog_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflags, xdata); out: return 0; } /* rename */ int32_t changelog_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_ENTRY); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(rename, frame, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); return 0; } int32_t changelog_rename_resume(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { changelog_priv_t *priv = NULL; priv = this->private; gf_msg_debug(this->name, 0, "Dequeue rename"); changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; } int32_t changelog_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { size_t xtra_len = 0; changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; call_stub_t *stub = NULL; struct list_head queue = { 0, }; gf_boolean_t barrier_enabled = _gf_false; dht_changelog_rename_info_t *info = NULL; int ret = 0; INIT_LIST_HEAD(&queue); priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); ret = dict_get_bin(xdata, DHT_CHANGELOG_RENAME_OP_KEY, (void **)&info); if (ret && oldloc->inode->ia_type != IA_IFDIR) { /* xdata "NOT" set for a non-directory, * Special rename => avoid logging */ goto wind; } /* 3 == fop + oldloc + newloc */ CHANGELOG_INIT_NOCHECK(this, frame->local, NULL, oldloc->inode->gfid, 3); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY(co, oldloc->pargfid, oldloc->name, entry_fn, entry_free_fn, xtra_len, wind); co++; CHANGELOG_FILL_ENTRY(co, newloc->pargfid, newloc->name, entry_fn, entry_free_fn, xtra_len, wind); changelog_set_usable_record_and_length(frame->local, xtra_len, 3); /* changelog barrier */ LOCK(&priv->lock); { if ((barrier_enabled = priv->barrier_enabled)) { stub = fop_rename_stub(frame, changelog_rename_resume, oldloc, newloc, xdata); if (!stub) __chlog_barrier_disable(this, &queue); else __chlog_barrier_enqueue(this, stub); } else { ((changelog_local_t *)frame->local)->color = priv->current_color; changelog_inc_fop_cnt(this, priv, frame->local); } } UNLOCK(&priv->lock); if (barrier_enabled && stub) { gf_msg_debug(this->name, 0, "Enqueue rename"); goto out; } if (barrier_enabled && !stub) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, CHANGELOG_MSG_BARRIER_FOP_FAILED, "fop=rename", NULL); chlog_barrier_dequeue_all(this, &queue); } /* changelog barrier */ wind: STACK_WIND(frame, changelog_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); out: return 0; } /* link */ int32_t changelog_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_ENTRY); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(link, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int32_t changelog_link_resume(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { changelog_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("changelog", this, out); GF_VALIDATE_OR_GOTO("changelog", this->fops, out); GF_VALIDATE_OR_GOTO("changelog", frame, out); priv = this->private; gf_msg_debug(this->name, 0, "Dequeuing link"); changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; out: return -1; } int32_t changelog_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { size_t xtra_len = 0; changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; call_stub_t *stub = NULL; struct list_head queue = { 0, }; gf_boolean_t barrier_enabled = _gf_false; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, wind); CHANGELOG_INIT_NOCHECK(this, frame->local, NULL, oldloc->gfid, 2); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY(co, newloc->pargfid, newloc->name, entry_fn, entry_free_fn, xtra_len, wind); changelog_set_usable_record_and_length(frame->local, xtra_len, 2); LOCK(&priv->lock); { if ((barrier_enabled = priv->barrier_enabled)) { stub = fop_link_stub(frame, changelog_link_resume, oldloc, newloc, xdata); if (!stub) __chlog_barrier_disable(this, &queue); else __chlog_barrier_enqueue(this, stub); } else { ((changelog_local_t *)frame->local)->color = priv->current_color; changelog_inc_fop_cnt(this, priv, frame->local); } } UNLOCK(&priv->lock); if (barrier_enabled && stub) { gf_msg_debug(this->name, 0, "Enqueued link"); goto out; } if (barrier_enabled && !stub) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_BARRIER_FOP_FAILED, "fop=link", NULL); chlog_barrier_dequeue_all(this, &queue); } wind: STACK_WIND(frame, changelog_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); out: return 0; } /* mkdir */ int32_t changelog_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_ENTRY); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(mkdir, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int32_t changelog_mkdir_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { changelog_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("changelog", this, out); GF_VALIDATE_OR_GOTO("changelog", this->fops, out); GF_VALIDATE_OR_GOTO("changelog", frame, out); priv = this->private; gf_msg_debug(this->name, 0, "Dequeuing mkdir"); changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; out: return -1; } int32_t changelog_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { int ret = -1; uuid_t gfid = { 0, }; size_t xtra_len = 0; changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; call_stub_t *stub = NULL; struct list_head queue = { 0, }; gf_boolean_t barrier_enabled = _gf_false; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); ret = dict_get_gfuuid(xdata, "gfid-req", &gfid); if (ret) { gf_msg_debug(this->name, 0, "failed to get gfid from dict"); goto wind; } CHANGELOG_INIT_NOCHECK(this, frame->local, NULL, gfid, 5); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, S_IFDIR | mode, number_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, frame->root->uid, number_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, frame->root->gid, number_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY(co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, wind); changelog_set_usable_record_and_length(frame->local, xtra_len, 5); LOCK(&priv->lock); { if ((barrier_enabled = priv->barrier_enabled)) { stub = fop_mkdir_stub(frame, changelog_mkdir_resume, loc, mode, umask, xdata); if (!stub) __chlog_barrier_disable(this, &queue); else __chlog_barrier_enqueue(this, stub); } else { ((changelog_local_t *)frame->local)->color = priv->current_color; changelog_inc_fop_cnt(this, priv, frame->local); } } UNLOCK(&priv->lock); if (barrier_enabled && stub) { gf_msg_debug(this->name, 0, "Enqueued mkdir"); goto out; } if (barrier_enabled && !stub) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, CHANGELOG_MSG_BARRIER_FOP_FAILED, "fop=mkdir", NULL); chlog_barrier_dequeue_all(this, &queue); } wind: STACK_WIND(frame, changelog_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); out: return 0; } /* symlink */ int32_t changelog_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_ENTRY); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(symlink, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int32_t changelog_symlink_resume(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { changelog_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("changelog", this, out); GF_VALIDATE_OR_GOTO("changelog", this->fops, out); GF_VALIDATE_OR_GOTO("changelog", frame, out); priv = this->private; gf_msg_debug(this->name, 0, "Dequeuing symlink"); changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkname, loc, umask, xdata); return 0; out: return -1; } int32_t changelog_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { int ret = -1; size_t xtra_len = 0; uuid_t gfid = { 0, }; changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; call_stub_t *stub = NULL; struct list_head queue = { 0, }; gf_boolean_t barrier_enabled = _gf_false; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); ret = dict_get_gfuuid(xdata, "gfid-req", &gfid); if (ret) { gf_msg_debug(this->name, 0, "failed to get gfid from dict"); goto wind; } CHANGELOG_INIT_NOCHECK(this, frame->local, NULL, gfid, 2); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY(co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, wind); changelog_set_usable_record_and_length(frame->local, xtra_len, 2); LOCK(&priv->lock); { if ((barrier_enabled = priv->barrier_enabled)) { stub = fop_symlink_stub(frame, changelog_symlink_resume, linkname, loc, umask, xdata); if (!stub) __chlog_barrier_disable(this, &queue); else __chlog_barrier_enqueue(this, stub); } else { ((changelog_local_t *)frame->local)->color = priv->current_color; changelog_inc_fop_cnt(this, priv, frame->local); } } UNLOCK(&priv->lock); if (barrier_enabled && stub) { gf_msg_debug(this->name, 0, "Enqueued symlink"); goto out; } if (barrier_enabled && !stub) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, CHANGELOG_MSG_BARRIER_FOP_FAILED, "fop=symlink", NULL); chlog_barrier_dequeue_all(this, &queue); } wind: STACK_WIND(frame, changelog_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkname, loc, umask, xdata); out: return 0; } /* mknod */ int32_t changelog_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_ENTRY); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int32_t changelog_mknod_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { changelog_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("changelog", this, out); GF_VALIDATE_OR_GOTO("changelog", this->fops, out); GF_VALIDATE_OR_GOTO("changelog", frame, out); priv = this->private; gf_msg_debug(this->name, 0, "Dequeuing mknod"); changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; out: return -1; } int32_t changelog_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata) { int ret = -1; uuid_t gfid = { 0, }; size_t xtra_len = 0; changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; call_stub_t *stub = NULL; struct list_head queue = { 0, }; gf_boolean_t barrier_enabled = _gf_false; priv = this->private; /* Check whether changelog active */ if (!(priv->active)) goto wind; /* Check whether rebalance activity */ if (frame->root->pid == GF_CLIENT_PID_DEFRAG) goto wind; /* If tier-dht linkto is SET, ignore about verifiying : * 1. Whether internal fop AND * 2. Whether tier rebalance process activity (this will help in * recording mknod if tier rebalance process calls this mknod) */ if (!(dict_get(xdata, "trusted.tier.tier-dht.linkto"))) { CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, wind); if (frame->root->pid == GF_CLIENT_PID_TIER_DEFRAG) goto wind; } ret = dict_get_gfuuid(xdata, "gfid-req", &gfid); if (ret) { gf_msg_debug(this->name, 0, "failed to get gfid from dict"); goto wind; } CHANGELOG_INIT_NOCHECK(this, frame->local, NULL, gfid, 5); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, mode, number_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, frame->root->uid, number_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, frame->root->gid, number_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY(co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, wind); changelog_set_usable_record_and_length(frame->local, xtra_len, 5); LOCK(&priv->lock); { if ((barrier_enabled = priv->barrier_enabled)) { stub = fop_mknod_stub(frame, changelog_mknod_resume, loc, mode, dev, umask, xdata); if (!stub) __chlog_barrier_disable(this, &queue); else __chlog_barrier_enqueue(this, stub); } else { ((changelog_local_t *)frame->local)->color = priv->current_color; changelog_inc_fop_cnt(this, priv, frame->local); } } UNLOCK(&priv->lock); if (barrier_enabled && stub) { gf_msg_debug(this->name, 0, "Enqueued mknod"); goto out; } if (barrier_enabled && !stub) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, CHANGELOG_MSG_BARRIER_FOP_FAILED, "fop=mknod", NULL); chlog_barrier_dequeue_all(this, &queue); } wind: STACK_WIND(frame, changelog_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, dev, umask, xdata); out: return 0; } /* create */ int32_t changelog_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int32_t ret = 0; changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; changelog_event_t ev = { 0, }; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); /* fill the event structure.. similar to open() */ ev.ev_type = CHANGELOG_OP_TYPE_CREATE; gf_uuid_copy(ev.u.create.gfid, buf->ia_gfid); ev.u.create.flags = fd->flags; changelog_dispatch_event(this, priv, &ev); if (changelog_ev_selected(this, &priv->ev_selection, CHANGELOG_OP_TYPE_RELEASE)) { ret = fd_ctx_set(fd, this, (uint64_t)(long)0x1); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, CHANGELOG_MSG_SET_FD_CONTEXT, NULL); } changelog_update(this, priv, local, CHANGELOG_TYPE_ENTRY); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent, xdata); return 0; } int32_t changelog_create_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { changelog_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("changelog", this, out); GF_VALIDATE_OR_GOTO("changelog", this->fops, out); GF_VALIDATE_OR_GOTO("changelog", frame, out); priv = this->private; gf_msg_debug(this->name, 0, "Dequeuing create"); changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; out: return -1; } int32_t changelog_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { int ret = -1; uuid_t gfid = { 0, }; changelog_opt_t *co = NULL; changelog_priv_t *priv = NULL; size_t xtra_len = 0; call_stub_t *stub = NULL; struct list_head queue = { 0, }; gf_boolean_t barrier_enabled = _gf_false; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); ret = dict_get_gfuuid(xdata, "gfid-req", &gfid); if (ret) { gf_msg_debug(this->name, 0, "failed to get gfid from dict"); goto wind; } /* init with two extra records */ CHANGELOG_INIT_NOCHECK(this, frame->local, NULL, gfid, 5); if (!frame->local) goto wind; co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, mode, number_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, frame->root->uid, number_fn, xtra_len); co++; CHANGELOG_FILL_UINT32(co, frame->root->gid, number_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY(co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, wind); changelog_set_usable_record_and_length(frame->local, xtra_len, 5); LOCK(&priv->lock); { if ((barrier_enabled = priv->barrier_enabled)) { stub = fop_create_stub(frame, changelog_create_resume, loc, flags, mode, umask, fd, xdata); if (!stub) __chlog_barrier_disable(this, &queue); else __chlog_barrier_enqueue(this, stub); } else { ((changelog_local_t *)frame->local)->color = priv->current_color; changelog_inc_fop_cnt(this, priv, frame->local); } } UNLOCK(&priv->lock); if (barrier_enabled && stub) { gf_msg_debug(this->name, 0, "Enqueued create"); goto out; } if (barrier_enabled && !stub) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, CHANGELOG_MSG_BARRIER_FOP_FAILED, "fop=create", NULL); chlog_barrier_dequeue_all(this, &queue); } wind: STACK_WIND(frame, changelog_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); out: return 0; } /* }}} */ /* Metadata modification fops - TYPE II */ /* {{{ */ /* {f}setattr */ int32_t changelog_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preop_stbuf, struct iatt *postop_stbuf, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_METADATA); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(fsetattr, frame, op_ret, op_errno, preop_stbuf, postop_stbuf, xdata); return 0; } int32_t changelog_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_OP_BOUNDARY_CHECK(frame, wind); CHANGELOG_INIT(this, frame->local, fd->inode, fd->inode->gfid, 1); if (!frame->local) goto wind; co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); changelog_set_usable_record_and_length(frame->local, xtra_len, 1); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } int32_t changelog_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preop_stbuf, struct iatt *postop_stbuf, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_METADATA); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(setattr, frame, op_ret, op_errno, preop_stbuf, postop_stbuf, xdata); return 0; } int32_t changelog_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; size_t xtra_len = 0; uuid_t shard_root_gfid = { 0, }; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, wind); /* Do not record META on .shard */ gf_uuid_parse(SHARD_ROOT_GFID, shard_root_gfid); if (gf_uuid_compare(loc->gfid, shard_root_gfid) == 0) { goto wind; } CHANGELOG_OP_BOUNDARY_CHECK(frame, wind); CHANGELOG_INIT(this, frame->local, loc->inode, loc->inode->gfid, 1); if (!frame->local) goto wind; co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); changelog_set_usable_record_and_length(frame->local, xtra_len, 1); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } /* {f}removexattr */ int32_t changelog_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_METADATA_XATTR); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, xdata); return 0; } int32_t changelog_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_OP_BOUNDARY_CHECK(frame, wind); CHANGELOG_INIT(this, frame->local, fd->inode, fd->inode->gfid, 1); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); changelog_set_usable_record_and_length(frame->local, xtra_len, 1); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_fremovexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; } int32_t changelog_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_METADATA_XATTR); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(removexattr, frame, op_ret, op_errno, xdata); return 0; } int32_t changelog_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_OP_BOUNDARY_CHECK(frame, wind); CHANGELOG_INIT(this, frame->local, loc->inode, loc->inode->gfid, 1); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); changelog_set_usable_record_and_length(frame->local, xtra_len, 1); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; } /* {f}setxattr */ int32_t changelog_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_METADATA_XATTR); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); return 0; } /* changelog_handle_virtual_xattr: * Handles virtual setxattr 'glusterfs.geo-rep.trigger-sync' on files. * Following is the behaviour based on the value of xattr. * 1: Captures only DATA entry in changelog. * 2: Tries to captures both ENTRY and DATA entry in * changelog. If failed to get pargfid, only DATA * entry is captured. * any other value: ENOTSUP is returned. */ static void changelog_handle_virtual_xattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; int32_t value = 0; int ret = 0; int dict_ret = 0; gf_boolean_t valid = _gf_false; priv = this->private; GF_ASSERT(priv); dict_ret = dict_get_int32(dict, GF_XATTR_TRIGGER_SYNC, &value); if ((dict_ret == 0 && value == 1) && ((loc->inode->ia_type == IA_IFDIR) || (loc->inode->ia_type == IA_IFREG))) valid = _gf_true; if (valid) { ret = changelog_fill_entry_buf(frame, this, loc, &local); if (ret) { gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_ENTRY_BUF_INFO, "gfid=%s", uuid_utoa(loc->inode->gfid), NULL); goto unwind; } changelog_update(this, priv, local, CHANGELOG_TYPE_ENTRY); unwind: /* Capture DATA only if it's a file. */ if (loc->inode->ia_type != IA_IFDIR) changelog_update(this, priv, frame->local, CHANGELOG_TYPE_DATA); /* Assign local to prev_entry, so unwind will take * care of cleanup. */ ((changelog_local_t *)(frame->local))->prev_entry = local; CHANGELOG_STACK_UNWIND(setxattr, frame, 0, 0, NULL); return; } else { CHANGELOG_STACK_UNWIND(setxattr, frame, -1, ENOTSUP, NULL); return; } } int32_t changelog_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_OP_BOUNDARY_CHECK(frame, wind); CHANGELOG_INIT(this, frame->local, loc->inode, loc->inode->gfid, 1); /* On setting this virtual xattr on a file, an explicit data * sync is triggered from geo-rep as CREATE|DATA entry is * recorded in changelog based on xattr value. */ if (dict_get(dict, GF_XATTR_TRIGGER_SYNC)) { changelog_handle_virtual_xattr(frame, this, loc, dict); return 0; } co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); changelog_set_usable_record_and_length(frame->local, xtra_len, 1); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; } int32_t changelog_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_METADATA_XATTR); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, xdata); return 0; } int32_t changelog_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO(frame, xdata, wind); CHANGELOG_OP_BOUNDARY_CHECK(frame, wind); CHANGELOG_INIT(this, frame->local, fd->inode, fd->inode->gfid, 1); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); changelog_set_usable_record_and_length(frame->local, xtra_len, 1); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; } int32_t changelog_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_METADATA); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(xattrop, frame, op_ret, op_errno, xattr, xdata); return 0; } int32_t changelog_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; size_t xtra_len = 0; int ret = 0; void *size_attr = NULL; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); ret = dict_get_ptr(xattr, GF_XATTR_SHARD_FILE_SIZE, &size_attr); if (ret) goto wind; CHANGELOG_OP_BOUNDARY_CHECK(frame, wind); CHANGELOG_INIT(this, frame->local, loc->inode, loc->inode->gfid, 1); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); changelog_set_usable_record_and_length(frame->local, xtra_len, 1); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, optype, xattr, xdata); return 0; } int32_t changelog_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_METADATA_XATTR); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(fxattrop, frame, op_ret, op_errno, xattr, xdata); return 0; } int32_t changelog_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_opt_t *co = NULL; size_t xtra_len = 0; void *size_attr = NULL; int ret = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); ret = dict_get_ptr(xattr, GF_XATTR_SHARD_FILE_SIZE, &size_attr); if (ret) goto wind; CHANGELOG_OP_BOUNDARY_CHECK(frame, wind); CHANGELOG_INIT(this, frame->local, fd->inode, fd->inode->gfid, 1); co = changelog_get_usable_buffer(frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER(co, frame->root->op, fop_fn, xtra_len); changelog_set_usable_record_and_length(frame->local, xtra_len, 1); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_fxattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, optype, xattr, xdata); return 0; } /* }}} */ /* Data modification fops - TYPE I */ /* {{{ */ /* {f}truncate() */ int32_t changelog_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_DATA); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t changelog_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { changelog_priv_t *priv = NULL; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_INIT(this, frame->local, loc->inode, loc->inode->gfid, 0); LOCK(&priv->c_snap_lock); { if (priv->c_snap_fd != -1 && priv->barrier_enabled == _gf_true) { changelog_snap_handle_ascii_change( this, &(((changelog_local_t *)(frame->local))->cld)); } } UNLOCK(&priv->c_snap_lock); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } int32_t changelog_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_DATA); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t changelog_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { changelog_priv_t *priv = NULL; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_INIT(this, frame->local, fd->inode, fd->inode->gfid, 0); LOCK(&priv->c_snap_lock); { if (priv->c_snap_fd != -1 && priv->barrier_enabled == _gf_true) { changelog_snap_handle_ascii_change( this, &(((changelog_local_t *)(frame->local))->cld)); } } UNLOCK(&priv->c_snap_lock); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } /* writev() */ int32_t changelog_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { changelog_priv_t *priv = NULL; changelog_local_t *local = NULL; priv = this->private; local = frame->local; CHANGELOG_COND_GOTO(priv, ((op_ret <= 0) || !local), unwind); changelog_update(this, priv, local, CHANGELOG_TYPE_DATA); unwind: changelog_dec_fop_cnt(this, priv, local); CHANGELOG_STACK_UNWIND(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t changelog_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { changelog_priv_t *priv = NULL; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); CHANGELOG_INIT(this, frame->local, fd->inode, fd->inode->gfid, 0); LOCK(&priv->c_snap_lock); { if (priv->c_snap_fd != -1 && priv->barrier_enabled == _gf_true) { changelog_snap_handle_ascii_change( this, &(((changelog_local_t *)(frame->local))->cld)); } } UNLOCK(&priv->c_snap_lock); wind: changelog_color_fop_and_inc_cnt(this, priv, frame->local); STACK_WIND(frame, changelog_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; } /* }}} */ /* open, release and other beasts */ /* {{{ */ int changelog_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, dict_t *xdata) { int ret = 0; changelog_priv_t *priv = NULL; changelog_event_t ev = { 0, }; gf_boolean_t logopen = _gf_false; priv = this->private; if (frame->local) { frame->local = NULL; logopen = _gf_true; } CHANGELOG_COND_GOTO(priv, ((op_ret < 0) || !logopen), unwind); /* fill the event structure */ ev.ev_type = CHANGELOG_OP_TYPE_OPEN; gf_uuid_copy(ev.u.open.gfid, fd->inode->gfid); ev.u.open.flags = fd->flags; changelog_dispatch_event(this, priv, &ev); if (changelog_ev_selected(this, &priv->ev_selection, CHANGELOG_OP_TYPE_RELEASE)) { ret = fd_ctx_set(fd, this, (uint64_t)(long)0x1); if (ret) gf_smsg(this->name, GF_LOG_WARNING, 0, CHANGELOG_MSG_SET_FD_CONTEXT, NULL); } unwind: CHANGELOG_STACK_UNWIND(open, frame, op_ret, op_errno, fd, xdata); return 0; } int changelog_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, fd_t *fd, dict_t *xdata) { changelog_priv_t *priv = NULL; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, wind); frame->local = (void *)0x1; /* do not dereference in ->cbk */ wind: STACK_WIND(frame, changelog_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; } /* }}} */ /* {{{ */ /* }}} */ int32_t _changelog_generic_dispatcher(dict_t *dict, char *key, data_t *value, void *data) { xlator_t *this = NULL; changelog_priv_t *priv = NULL; this = data; priv = this->private; changelog_dispatch_event(this, priv, (changelog_event_t *)value->data); return 0; } /** * changelog ipc dispatches events, pointers of which are passed in * @xdata. Dispatching is orderless (whatever order dict_foreach() * traverses the dictionary). */ int32_t changelog_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) { if (op != GF_IPC_TARGET_CHANGELOG) goto wind; /* it's for us, do the job */ if (xdata) (void)dict_foreach(xdata, _changelog_generic_dispatcher, this); STACK_UNWIND_STRICT(ipc, frame, 0, 0, NULL); return 0; wind: STACK_WIND(frame, default_ipc_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc, op, xdata); return 0; } /* {{{ */ int32_t changelog_release(xlator_t *this, fd_t *fd) { changelog_event_t ev = { 0, }; changelog_priv_t *priv = NULL; priv = this->private; ev.ev_type = CHANGELOG_OP_TYPE_RELEASE; gf_uuid_copy(ev.u.release.gfid, fd->inode->gfid); changelog_dispatch_event(this, priv, &ev); (void)fd_ctx_del(fd, this); return 0; } /* }}} */ /** * The * - @init () * - @fini () * - @reconfigure () * ... and helper routines */ /** * needed if there are more operation modes in the future. */ static void changelog_assign_opmode(changelog_priv_t *priv, char *mode) { if (strncmp(mode, "realtime", 8) == 0) { priv->op_mode = CHANGELOG_MODE_RT; } } static void changelog_assign_encoding(changelog_priv_t *priv, char *enc) { if (strncmp(enc, "binary", 6) == 0) { priv->encode_mode = CHANGELOG_ENCODE_BINARY; } else if (strncmp(enc, "ascii", 5) == 0) { priv->encode_mode = CHANGELOG_ENCODE_ASCII; } } static void changelog_assign_barrier_timeout(changelog_priv_t *priv, time_t timeout) { LOCK(&priv->lock); { priv->timeout.tv_sec = timeout; } UNLOCK(&priv->lock); } /* cleanup any helper threads that are running */ static void changelog_cleanup_helper_threads(xlator_t *this, changelog_priv_t *priv) { if (priv->cr.rollover_th) { (void)changelog_thread_cleanup(this, priv->cr.rollover_th); priv->cr.rollover_th = 0; } if (priv->cf.fsync_th) { (void)changelog_thread_cleanup(this, priv->cf.fsync_th); priv->cf.fsync_th = 0; } } /* spawn helper thread; cleaning up in case of errors */ static int changelog_spawn_helper_threads(xlator_t *this, changelog_priv_t *priv) { int ret = 0; /* Geo-Rep snapshot dependency: * * To implement explicit rollover of changlog journal on barrier * notification, a pipe is created to communicate between * 'changelog_rollover' thread and changelog main thread. The select * call used to wait till roll-over time in changelog_rollover thread * is modified to wait on read end of the pipe. When barrier * notification comes (i.e, in 'reconfigure'), select in * changelog_rollover thread is woken up explicitly by writing into * the write end of the pipe in 'reconfigure'. */ priv->cr.notify = _gf_false; priv->cr.this = this; ret = gf_thread_create(&priv->cr.rollover_th, NULL, changelog_rollover, priv, "clogro"); if (ret) goto out; if (priv->fsync_interval) { priv->cf.this = this; ret = gf_thread_create(&priv->cf.fsync_th, NULL, changelog_fsync_thread, priv, "clogfsyn"); } if (ret) changelog_cleanup_helper_threads(this, priv); out: return ret; } int notify(xlator_t *this, int event, void *data, ...) { changelog_priv_t *priv = NULL; dict_t *dict = NULL; char buf[1] = {1}; int barrier = DICT_DEFAULT; gf_boolean_t bclean_req = _gf_false; int ret = 0; int ret1 = 0; struct list_head queue = { 0, }; uint64_t xprtcnt = 0; uint64_t clntcnt = 0; changelog_clnt_t *conn = NULL; gf_boolean_t cleanup_notify = _gf_false; char sockfile[UNIX_PATH_MAX] = { 0, }; rpcsvc_listener_t *listener = NULL; rpcsvc_listener_t *next = NULL; INIT_LIST_HEAD(&queue); priv = this->private; if (!priv) goto out; if (event == GF_EVENT_PARENT_DOWN) { priv->victim = data; gf_log(this->name, GF_LOG_INFO, "cleanup changelog rpc connection of brick %s", priv->victim->name); if (priv->rpc_active) { this->cleanup_starting = 1; changelog_destroy_rpc_listner(this, priv); conn = &priv->connections; if (conn) changelog_ev_cleanup_connections(this, conn); xprtcnt = GF_ATOMIC_GET(priv->xprtcnt); clntcnt = GF_ATOMIC_GET(priv->clntcnt); if (!xprtcnt && !clntcnt) { LOCK(&priv->lock); { cleanup_notify = priv->notify_down; priv->notify_down = _gf_true; } UNLOCK(&priv->lock); if (priv->rpc) { list_for_each_entry_safe(listener, next, &priv->rpc->listeners, list) { if (listener->trans) { rpc_transport_unref(listener->trans); } } rpcsvc_destroy(priv->rpc); priv->rpc = NULL; } CHANGELOG_MAKE_SOCKET_PATH(priv->changelog_brick, sockfile, UNIX_PATH_MAX); sys_unlink(sockfile); if (!cleanup_notify) default_notify(this, GF_EVENT_PARENT_DOWN, data); } } else { default_notify(this, GF_EVENT_PARENT_DOWN, data); } goto out; } if (event == GF_EVENT_TRANSLATOR_OP) { dict = data; barrier = dict_get_str_boolean(dict, "barrier", DICT_DEFAULT); switch (barrier) { case DICT_ERROR: gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_DICT_GET_FAILED, "dict_get_str_boolean", NULL); ret = -1; goto out; case BARRIER_OFF: gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_BARRIER_STATE_NOTIFY, "off", NULL); CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, out); LOCK(&priv->c_snap_lock); { changelog_snap_logging_stop(this, priv); } UNLOCK(&priv->c_snap_lock); LOCK(&priv->bflags.lock); { if (priv->bflags.barrier_ext == _gf_false) ret = -1; } UNLOCK(&priv->bflags.lock); if (ret == -1) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_BARRIER_ERROR, NULL); goto out; } /* Stop changelog barrier and dequeue all fops */ LOCK(&priv->lock); { if (priv->barrier_enabled == _gf_true) __chlog_barrier_disable(this, &queue); else ret = -1; } UNLOCK(&priv->lock); /* If ret = -1, then changelog barrier is already * disabled because of error or timeout. */ if (ret == 0) { chlog_barrier_dequeue_all(this, &queue); gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_BARRIER_DISABLED, NULL); } else { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_BARRIER_ALREADY_DISABLED, NULL); } LOCK(&priv->bflags.lock); { priv->bflags.barrier_ext = _gf_false; } UNLOCK(&priv->bflags.lock); goto out; case BARRIER_ON: gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_BARRIER_STATE_NOTIFY, "on", NULL); CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, out); LOCK(&priv->c_snap_lock); { changelog_snap_logging_start(this, priv); } UNLOCK(&priv->c_snap_lock); LOCK(&priv->bflags.lock); { if (priv->bflags.barrier_ext == _gf_true) ret = -1; else priv->bflags.barrier_ext = _gf_true; } UNLOCK(&priv->bflags.lock); if (ret == -1) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_BARRIER_ON_ERROR, NULL); goto out; } ret = pthread_mutex_lock(&priv->bn.bnotify_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_1(ret, out, bclean_req); { priv->bn.bnotify = _gf_true; } ret = pthread_mutex_unlock(&priv->bn.bnotify_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_1(ret, out, bclean_req); /* Start changelog barrier */ LOCK(&priv->lock); { ret = __chlog_barrier_enable(this, priv); } UNLOCK(&priv->lock); if (ret == -1) { changelog_barrier_cleanup(this, priv, &queue); goto out; } gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_BARRIER_ENABLE, NULL); ret = changelog_barrier_notify(priv, buf); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_WRITE_FAILED, "Explicit roll over", NULL); changelog_barrier_cleanup(this, priv, &queue); ret = -1; goto out; } ret = pthread_mutex_lock(&priv->bn.bnotify_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_1(ret, out, bclean_req); { /* The while condition check is required here to * handle spurious wakeup of cond wait that can * happen with pthreads. See man page */ while (priv->bn.bnotify == _gf_true) { ret = pthread_cond_wait(&priv->bn.bnotify_cond, &priv->bn.bnotify_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_1(ret, out, bclean_req); } if (priv->bn.bnotify_error == _gf_true) { ret = -1; priv->bn.bnotify_error = _gf_false; } } ret1 = pthread_mutex_unlock(&priv->bn.bnotify_mutex); CHANGELOG_PTHREAD_ERROR_HANDLE_1(ret1, out, bclean_req); gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_BNOTIFY_COND_INFO, NULL); goto out; case DICT_DEFAULT: gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_BARRIER_KEY_NOT_FOUND, NULL); ret = -1; goto out; default: gf_smsg(this->name, GF_LOG_ERROR, EINVAL, CHANGELOG_MSG_ERROR_IN_DICT_GET, NULL); ret = -1; goto out; } } else { ret = default_notify(this, event, data); } out: if (bclean_req) changelog_barrier_cleanup(this, priv, &queue); return ret; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_changelog_mt_end); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, CHANGELOG_MSG_MEMORY_INIT_FAILED, NULL); return ret; } return ret; } static int changelog_init(xlator_t *this, changelog_priv_t *priv) { int i = 0; int ret = 0; changelog_log_data_t cld = { 0, }; priv->maps[CHANGELOG_TYPE_DATA] = "D "; priv->maps[CHANGELOG_TYPE_METADATA] = "M "; priv->maps[CHANGELOG_TYPE_METADATA_XATTR] = "M "; priv->maps[CHANGELOG_TYPE_ENTRY] = "E "; for (; i < CHANGELOG_MAX_TYPE; i++) { /* start with version 1 */ priv->slice.changelog_version[i] = 1; } if (!priv->active) return ret; /** * start with a fresh changelog file every time. this is done * in case there was an encoding change. so... things are kept * simple here. */ changelog_fill_rollover_data(&cld, _gf_false); ret = htime_open(this, priv, cld.cld_roll_time); /* call htime open with cld's rollover_time */ if (ret) goto out; LOCK(&priv->lock); { ret = changelog_inject_single_event(this, priv, &cld); } UNLOCK(&priv->lock); /* ... and finally spawn the helpers threads */ ret = changelog_spawn_helper_threads(this, priv); out: return ret; } /** * Init barrier related condition variables and locks */ static int changelog_barrier_pthread_init(xlator_t *this, changelog_priv_t *priv) { gf_boolean_t bn_mutex_init = _gf_false; gf_boolean_t bn_cond_init = _gf_false; gf_boolean_t dm_mutex_black_init = _gf_false; gf_boolean_t dm_cond_black_init = _gf_false; gf_boolean_t dm_mutex_white_init = _gf_false; gf_boolean_t dm_cond_white_init = _gf_false; gf_boolean_t cr_mutex_init = _gf_false; gf_boolean_t cr_cond_init = _gf_false; int ret = 0; if ((ret = pthread_mutex_init(&priv->bn.bnotify_mutex, NULL)) != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_MUTEX_INIT_FAILED, "name=bnotify", "ret=%d", ret, NULL); ret = -1; goto out; } bn_mutex_init = _gf_true; if ((ret = pthread_cond_init(&priv->bn.bnotify_cond, NULL)) != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_COND_INIT_FAILED, "name=bnotify", "ret=%d", ret, NULL); ret = -1; goto out; } bn_cond_init = _gf_true; if ((ret = pthread_mutex_init(&priv->dm.drain_black_mutex, NULL)) != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_MUTEX_INIT_FAILED, "name=drain_black", "ret=%d", ret, NULL); ret = -1; goto out; } dm_mutex_black_init = _gf_true; if ((ret = pthread_cond_init(&priv->dm.drain_black_cond, NULL)) != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_COND_INIT_FAILED, "name=drain_black", "ret=%d", ret, NULL); ret = -1; goto out; } dm_cond_black_init = _gf_true; if ((ret = pthread_mutex_init(&priv->dm.drain_white_mutex, NULL)) != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_MUTEX_INIT_FAILED, "name=drain_white", "ret=%d", ret, NULL); ret = -1; goto out; } dm_mutex_white_init = _gf_true; if ((ret = pthread_cond_init(&priv->dm.drain_white_cond, NULL)) != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_COND_INIT_FAILED, "name=drain_white", "ret=%d", ret, NULL); ret = -1; goto out; } dm_cond_white_init = _gf_true; if ((pthread_mutex_init(&priv->cr.lock, NULL)) != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_MUTEX_INIT_FAILED, "name=changelog_rollover", "ret=%d", ret, NULL); ret = -1; goto out; } cr_mutex_init = _gf_true; if ((pthread_cond_init(&priv->cr.cond, NULL)) != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_MSG_PTHREAD_COND_INIT_FAILED, "changelog_rollover cond init failed", "ret=%d", ret, NULL); ret = -1; goto out; } cr_cond_init = _gf_true; out: if (ret) { if (bn_mutex_init) pthread_mutex_destroy(&priv->bn.bnotify_mutex); if (bn_cond_init) pthread_cond_destroy(&priv->bn.bnotify_cond); if (dm_mutex_black_init) pthread_mutex_destroy(&priv->dm.drain_black_mutex); if (dm_cond_black_init) pthread_cond_destroy(&priv->dm.drain_black_cond); if (dm_mutex_white_init) pthread_mutex_destroy(&priv->dm.drain_white_mutex); if (dm_cond_white_init) pthread_cond_destroy(&priv->dm.drain_white_cond); if (cr_mutex_init) pthread_mutex_destroy(&priv->cr.lock); if (cr_cond_init) pthread_cond_destroy(&priv->cr.cond); } return ret; } /* Destroy barrier related condition variables and locks */ static void changelog_barrier_pthread_destroy(changelog_priv_t *priv) { pthread_mutex_destroy(&priv->bn.bnotify_mutex); pthread_cond_destroy(&priv->bn.bnotify_cond); pthread_mutex_destroy(&priv->dm.drain_black_mutex); pthread_cond_destroy(&priv->dm.drain_black_cond); pthread_mutex_destroy(&priv->dm.drain_white_mutex); pthread_cond_destroy(&priv->dm.drain_white_cond); pthread_mutex_destroy(&priv->cr.lock); pthread_cond_destroy(&priv->cr.cond); LOCK_DESTROY(&priv->bflags.lock); } static void changelog_cleanup_rpc(xlator_t *this, changelog_priv_t *priv) { /* terminate rpc server */ if (!this->cleanup_starting) changelog_destroy_rpc_listner(this, priv); (void)changelog_cleanup_rpc_threads(this, priv); /* cleanup rot buffs */ rbuf_dtor(priv->rbuf); /* cleanup poller thread */ if (priv->poller) (void)changelog_thread_cleanup(this, priv->poller); } int reconfigure(xlator_t *this, dict_t *options) { int ret = 0; char *tmp = NULL; changelog_priv_t *priv = NULL; gf_boolean_t active_earlier = _gf_true; gf_boolean_t active_now = _gf_true; gf_boolean_t rpc_active_earlier = _gf_true; gf_boolean_t rpc_active_now = _gf_true; gf_boolean_t iniate_rpc = _gf_false; changelog_time_slice_t *slice = NULL; changelog_log_data_t cld = { 0, }; char htime_dir[PATH_MAX] = { 0, }; char csnap_dir[PATH_MAX] = { 0, }; time_t timeout = 0; priv = this->private; if (!priv) goto out; ret = -1; active_earlier = priv->active; rpc_active_earlier = priv->rpc_active; /* first stop the rollover and the fsync thread */ changelog_cleanup_helper_threads(this, priv); GF_OPTION_RECONF("changelog-dir", tmp, options, str, out); if (!tmp) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_DIR_OPTIONS_NOT_SET, NULL); goto out; } GF_FREE(priv->changelog_dir); priv->changelog_dir = gf_strdup(tmp); if (!priv->changelog_dir) goto out; ret = mkdir_p(priv->changelog_dir, 0600, _gf_true); if (ret) goto out; CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, htime_dir); ret = mkdir_p(htime_dir, 0600, _gf_true); if (ret) goto out; CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir); ret = mkdir_p(csnap_dir, 0600, _gf_true); if (ret) goto out; GF_OPTION_RECONF("changelog", active_now, options, bool, out); GF_OPTION_RECONF("changelog-notification", rpc_active_now, options, bool, out); /* If journalling is enabled, enable rpc notifications */ if (active_now && !active_earlier) { if (!rpc_active_earlier) iniate_rpc = _gf_true; } if (rpc_active_now && !rpc_active_earlier) { iniate_rpc = _gf_true; } /* TODO: Disable of changelog-notifications is not supported for now * as there is no clean way of cleaning up of rpc resources */ if (iniate_rpc) { ret = changelog_init_rpc(this, priv); if (ret) goto out; priv->rpc_active = _gf_true; } /** * changelog_handle_change() handles changes that could possibly * have been submit changes before changelog deactivation. */ if (!active_now) priv->active = _gf_false; GF_OPTION_RECONF("op-mode", tmp, options, str, out); changelog_assign_opmode(priv, tmp); tmp = NULL; GF_OPTION_RECONF("encoding", tmp, options, str, out); changelog_assign_encoding(priv, tmp); GF_OPTION_RECONF("rollover-time", priv->rollover_time, options, time, out); GF_OPTION_RECONF("fsync-interval", priv->fsync_interval, options, time, out); GF_OPTION_RECONF("changelog-barrier-timeout", timeout, options, time, out); changelog_assign_barrier_timeout(priv, timeout); GF_OPTION_RECONF("capture-del-path", priv->capture_del_path, options, bool, out); if (active_now || active_earlier) { changelog_fill_rollover_data(&cld, !active_now); slice = &priv->slice; LOCK(&priv->lock); { ret = changelog_inject_single_event(this, priv, &cld); if (!ret && active_now) SLICE_VERSION_UPDATE(slice); } UNLOCK(&priv->lock); if (ret) goto out; if (active_now) { if (!active_earlier) { gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_RECONFIGURE, NULL); htime_create(this, priv, gf_time()); } ret = changelog_spawn_helper_threads(this, priv); } } out: if (ret) { /* TODO */ } else { gf_msg_debug(this->name, 0, "changelog reconfigured"); if (active_now && priv) priv->active = _gf_true; } return ret; } static void changelog_freeup_options(xlator_t *this, changelog_priv_t *priv) { int ret = 0; ret = priv->cb->dtor(this, &priv->cd); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_FREEUP_FAILED, NULL); GF_FREE(priv->changelog_brick); GF_FREE(priv->changelog_dir); } static int changelog_init_options(xlator_t *this, changelog_priv_t *priv) { int ret = 0; char *tmp = NULL; time_t timeout = 0; char htime_dir[PATH_MAX] = { 0, }; char csnap_dir[PATH_MAX] = { 0, }; GF_OPTION_INIT("changelog-brick", tmp, str, error_return); priv->changelog_brick = gf_strdup(tmp); if (!priv->changelog_brick) goto error_return; tmp = NULL; GF_OPTION_INIT("changelog-dir", tmp, str, dealloc_1); priv->changelog_dir = gf_strdup(tmp); if (!priv->changelog_dir) goto dealloc_1; tmp = NULL; /** * create the directory even if change-logging would be inactive * so that consumers can _look_ into it (finding nothing...) */ ret = mkdir_p(priv->changelog_dir, 0600, _gf_true); if (ret) goto dealloc_2; CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, htime_dir); ret = mkdir_p(htime_dir, 0600, _gf_true); if (ret) goto dealloc_2; CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir); ret = mkdir_p(csnap_dir, 0600, _gf_true); if (ret) goto dealloc_2; GF_OPTION_INIT("changelog", priv->active, bool, dealloc_2); GF_OPTION_INIT("changelog-notification", priv->rpc_active, bool, dealloc_2); GF_OPTION_INIT("capture-del-path", priv->capture_del_path, bool, dealloc_2); GF_OPTION_INIT("op-mode", tmp, str, dealloc_2); changelog_assign_opmode(priv, tmp); tmp = NULL; GF_OPTION_INIT("encoding", tmp, str, dealloc_2); changelog_assign_encoding(priv, tmp); changelog_encode_change(priv); GF_OPTION_INIT("rollover-time", priv->rollover_time, time, dealloc_2); GF_OPTION_INIT("fsync-interval", priv->fsync_interval, time, dealloc_2); GF_OPTION_INIT("changelog-barrier-timeout", timeout, time, dealloc_2); changelog_assign_barrier_timeout(priv, timeout); GF_ASSERT(cb_bootstrap[priv->op_mode].mode == priv->op_mode); priv->cb = &cb_bootstrap[priv->op_mode]; /* ... now bootstrap the logger */ ret = priv->cb->ctor(this, &priv->cd); if (ret) goto dealloc_2; priv->changelog_fd = -1; return 0; dealloc_2: GF_FREE(priv->changelog_dir); dealloc_1: GF_FREE(priv->changelog_brick); error_return: return -1; } static int changelog_init_rpc(xlator_t *this, changelog_priv_t *priv) { rpcsvc_t *rpc = NULL; changelog_ev_selector_t *selection = NULL; selection = &priv->ev_selection; /* initialize event selection */ changelog_init_event_selection(this, selection); priv->rbuf = rbuf_init(NR_ROTT_BUFFS); if (!priv->rbuf) goto cleanup_thread; rpc = changelog_init_rpc_listener(this, priv, priv->rbuf, NR_DISPATCHERS); if (!rpc) goto cleanup_rbuf; priv->rpc = rpc; return 0; cleanup_rbuf: rbuf_dtor(priv->rbuf); cleanup_thread: if (priv->poller) (void)changelog_thread_cleanup(this, priv->poller); return -1; } int32_t init(xlator_t *this) { int ret = -1; changelog_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("changelog", this, error_return); if (!this->children || this->children->next) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_CHILD_MISCONFIGURED, NULL); goto error_return; } if (!this->parents) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_VOL_MISCONFIGURED, NULL); goto error_return; } priv = GF_CALLOC(1, sizeof(*priv), gf_changelog_mt_priv_t); if (!priv) goto error_return; this->local_pool = mem_pool_new(changelog_local_t, 64); if (!this->local_pool) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, CHANGELOG_MSG_NO_MEMORY, NULL); goto cleanup_priv; } LOCK_INIT(&priv->lock); LOCK_INIT(&priv->c_snap_lock); GF_ATOMIC_INIT(priv->listnercnt, 0); GF_ATOMIC_INIT(priv->clntcnt, 0); GF_ATOMIC_INIT(priv->xprtcnt, 0); INIT_LIST_HEAD(&priv->xprt_list); priv->htime_fd = -1; ret = changelog_init_options(this, priv); if (ret) goto cleanup_mempool; /* snap dependency changes */ priv->dm.black_fop_cnt = 0; priv->dm.white_fop_cnt = 0; priv->dm.drain_wait_black = _gf_false; priv->dm.drain_wait_white = _gf_false; priv->current_color = FOP_COLOR_BLACK; priv->explicit_rollover = _gf_false; priv->cr.notify = _gf_false; /* Mutex is not needed as threads are not spawned yet */ priv->bn.bnotify = _gf_false; priv->bn.bnotify_error = _gf_false; ret = changelog_barrier_pthread_init(this, priv); if (ret) goto cleanup_options; LOCK_INIT(&priv->bflags.lock); priv->bflags.barrier_ext = _gf_false; /* Changelog barrier init */ INIT_LIST_HEAD(&priv->queue); priv->barrier_enabled = _gf_false; if (priv->rpc_active || priv->active) { /* RPC ball rolling.. */ ret = changelog_init_rpc(this, priv); if (ret) goto cleanup_barrier; priv->rpc_active = _gf_true; } ret = changelog_init(this, priv); if (ret) goto cleanup_rpc; gf_msg_debug(this->name, 0, "changelog translator loaded"); this->private = priv; return 0; cleanup_rpc: if (priv->rpc_active) { changelog_cleanup_rpc(this, priv); } cleanup_barrier: changelog_barrier_pthread_destroy(priv); cleanup_options: changelog_freeup_options(this, priv); cleanup_mempool: mem_pool_destroy(this->local_pool); this->local_pool = NULL; cleanup_priv: GF_FREE(priv); error_return: this->private = NULL; return -1; } void fini(xlator_t *this) { changelog_priv_t *priv = NULL; struct list_head queue = { 0, }; priv = this->private; if (priv) { if (priv->active || priv->rpc_active) { /* terminate RPC server/threads */ changelog_cleanup_rpc(this, priv); GF_FREE(priv->ev_dispatcher); } /* call barrier_disable to cancel timer */ if (priv->barrier_enabled) __chlog_barrier_disable(this, &queue); /* cleanup barrier related objects */ changelog_barrier_pthread_destroy(priv); /* cleanup helper threads */ changelog_cleanup_helper_threads(this, priv); /* cleanup allocated options */ changelog_freeup_options(this, priv); /* deallocate mempool */ mem_pool_destroy(this->local_pool); if (priv->htime_fd != -1) { sys_close(priv->htime_fd); } /* finally, dealloac private variable */ GF_FREE(priv); } this->private = NULL; this->local_pool = NULL; return; } struct xlator_fops fops = { .open = changelog_open, .mknod = changelog_mknod, .mkdir = changelog_mkdir, .create = changelog_create, .symlink = changelog_symlink, .writev = changelog_writev, .truncate = changelog_truncate, .ftruncate = changelog_ftruncate, .link = changelog_link, .rename = changelog_rename, .unlink = changelog_unlink, .rmdir = changelog_rmdir, .setattr = changelog_setattr, .fsetattr = changelog_fsetattr, .setxattr = changelog_setxattr, .fsetxattr = changelog_fsetxattr, .removexattr = changelog_removexattr, .fremovexattr = changelog_fremovexattr, .ipc = changelog_ipc, .xattrop = changelog_xattrop, .fxattrop = changelog_fxattrop, }; struct xlator_cbks cbks = { .forget = changelog_forget, .release = changelog_release, }; struct volume_options options[] = { {.key = {"changelog"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "enable/disable change-logging", .op_version = {3}, .flags = OPT_FLAG_SETTABLE, .level = OPT_STATUS_BASIC, .tags = {"journal", "georep", "glusterfind"}}, {.key = {"changelog-notification"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "enable/disable changelog live notification", .op_version = {3}, .level = OPT_STATUS_BASIC, .tags = {"bitrot", "georep"}}, {.key = {"changelog-brick"}, .type = GF_OPTION_TYPE_PATH, .description = "brick path to generate unique socket file name." " should be the export directory of the volume strictly.", .default_value = "{{ brick.path }}", .op_version = {3}, .tags = {"journal"}}, {.key = {"changelog-dir"}, .type = GF_OPTION_TYPE_PATH, .description = "directory for the changelog files", .default_value = "{{ brick.path }}/.glusterfs/changelogs", .op_version = {3}, .flags = OPT_FLAG_SETTABLE, .level = OPT_STATUS_ADVANCED, .tags = {"journal", "georep", "glusterfind"}}, {.key = {"op-mode"}, .type = GF_OPTION_TYPE_STR, .default_value = "realtime", .value = {"realtime"}, .description = "operation mode - futuristic operation modes", .op_version = {3}, .tags = {"journal"}}, {.key = {"encoding"}, .type = GF_OPTION_TYPE_STR, .default_value = "ascii", .value = {"binary", "ascii"}, .description = "encoding type for changelogs", .op_version = {3}, .flags = OPT_FLAG_SETTABLE, .level = OPT_STATUS_ADVANCED, .tags = {"journal"}}, {.key = {"rollover-time"}, .default_value = "15", .type = GF_OPTION_TYPE_TIME, .description = "time to switch to a new changelog file (in seconds)", .op_version = {3}, .flags = OPT_FLAG_SETTABLE, .level = OPT_STATUS_ADVANCED, .tags = {"journal", "georep", "glusterfind"}}, {.key = {"fsync-interval"}, .type = GF_OPTION_TYPE_TIME, .default_value = "5", .description = "do not open CHANGELOG file with O_SYNC mode." " instead perform fsync() at specified intervals", .op_version = {3}, .flags = OPT_FLAG_SETTABLE, .level = OPT_STATUS_ADVANCED, .tags = {"journal"}}, {.key = {"changelog-barrier-timeout"}, .type = GF_OPTION_TYPE_TIME, .default_value = TOSTRING(BARRIER_TIMEOUT), .description = "After 'timeout' seconds since the time 'barrier' " "option was set to \"on\", unlink/rmdir/rename " "operations are no longer blocked and previously " "blocked fops are allowed to go through", .op_version = {3}, .flags = OPT_FLAG_SETTABLE, .level = OPT_STATUS_ADVANCED, .tags = {"journal"}}, {.key = {"capture-del-path"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .description = "enable/disable capturing paths of deleted entries", .op_version = {3}, .flags = OPT_FLAG_SETTABLE, .level = OPT_STATUS_BASIC, .tags = {"journal", "glusterfind"}}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "changelog", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-ev-handle.h0000644000000000000000000000013214522202451026351 xustar000000000000000030 mtime=1699284265.659027408 30 atime=1699284265.659027408 30 ctime=1699284304.328143878 glusterfs-11.1/xlators/features/changelog/src/changelog-ev-handle.h0000664000175100017510000000604214522202451026632 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __CHANGELOG_EV_HANDLE_H #define __CHANGELOG_EV_HANDLE_H #include #include "rpc-clnt.h" #include struct changelog_clnt; typedef struct changelog_rpc_clnt { xlator_t *this; gf_lock_t lock; gf_atomic_t ref; gf_boolean_t disconnected; unsigned int filter; char sock[UNIX_PATH_MAX]; struct changelog_clnt *c_clnt; /* back pointer to list holder */ struct rpc_clnt *rpc; /* RPC client endpoint */ struct list_head list; /* ->pending, ->waitq, ->active */ void (*cleanup)(struct changelog_rpc_clnt *); /* cleanup handler */ } changelog_rpc_clnt_t; static inline void changelog_rpc_clnt_ref(changelog_rpc_clnt_t *crpc) { GF_ATOMIC_INC(crpc->ref); } static inline void changelog_set_disconnect_flag(changelog_rpc_clnt_t *crpc, gf_boolean_t flag) { crpc->disconnected = flag; } static inline int changelog_rpc_clnt_is_disconnected(changelog_rpc_clnt_t *crpc) { return (crpc->disconnected == _gf_true); } static inline void changelog_rpc_clnt_unref(changelog_rpc_clnt_t *crpc) { gf_boolean_t gone = _gf_false; uint64_t ref = 0; ref = GF_ATOMIC_DEC(crpc->ref); if (!ref && changelog_rpc_clnt_is_disconnected(crpc)) { list_del(&crpc->list); gone = _gf_true; } if (gone) crpc->cleanup(crpc); } /** * This structure holds pending and active clients. On probe RPC all * an instance of the above structure (@changelog_rpc_clnt) is placed * in ->pending and gets moved to ->active on a successful connect. * * locking rules: * * Manipulating ->pending * ->pending_lock * ->pending * * Manipulating ->active * ->active_lock * ->active * * Moving object from ->pending to ->active * ->pending_lock * ->active_lock * * Objects are _never_ moved from ->active to ->pending, i.e., during * disconnection, the object is destroyed. Well, we could have tried * to reconnect, but that's pure waste.. let the other end reconnect. */ typedef struct changelog_clnt { xlator_t *this; /* pending connections */ pthread_mutex_t pending_lock; pthread_cond_t pending_cond; struct list_head pending; /* current active connections */ gf_lock_t active_lock; struct list_head active; gf_lock_t wait_lock; struct list_head waitq; /* consumer part of rot-buffs */ rbuf_t *rbuf; unsigned long sequence; } changelog_clnt_t; void * changelog_ev_connector(void *); void * changelog_ev_dispatch(void *); /* APIs */ void changelog_ev_queue_connection(changelog_clnt_t *, changelog_rpc_clnt_t *); void changelog_ev_cleanup_connections(xlator_t *, changelog_clnt_t *); void changelog_process_cleanup_event(xlator_t *); #endif glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-encoders.c0000644000000000000000000000013214522202451026303 xustar000000000000000030 mtime=1699284265.659027408 30 atime=1699284265.659027408 30 ctime=1699284304.337143905 glusterfs-11.1/xlators/features/changelog/src/changelog-encoders.c0000664000175100017510000001316214522202451026565 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "changelog-encoders.h" size_t entry_fn(void *data, char *buffer, gf_boolean_t encode) { char *tmpbuf = NULL; size_t bufsz = 0; struct changelog_entry_fields *ce = NULL; ce = (struct changelog_entry_fields *)data; if (encode) { tmpbuf = uuid_utoa(ce->cef_uuid); CHANGELOG_FILL_BUFFER(buffer, bufsz, tmpbuf, strlen(tmpbuf)); } else { CHANGELOG_FILL_BUFFER(buffer, bufsz, ce->cef_uuid, sizeof(uuid_t)); } CHANGELOG_FILL_BUFFER(buffer, bufsz, "/", 1); CHANGELOG_FILL_BUFFER(buffer, bufsz, ce->cef_bname, strlen(ce->cef_bname)); return bufsz; } size_t del_entry_fn(void *data, char *buffer, gf_boolean_t encode) { char *tmpbuf = NULL; size_t bufsz = 0; struct changelog_entry_fields *ce = NULL; ce = (struct changelog_entry_fields *)data; if (encode) { tmpbuf = uuid_utoa(ce->cef_uuid); CHANGELOG_FILL_BUFFER(buffer, bufsz, tmpbuf, strlen(tmpbuf)); } else { CHANGELOG_FILL_BUFFER(buffer, bufsz, ce->cef_uuid, sizeof(uuid_t)); } CHANGELOG_FILL_BUFFER(buffer, bufsz, "/", 1); CHANGELOG_FILL_BUFFER(buffer, bufsz, ce->cef_bname, strlen(ce->cef_bname)); CHANGELOG_FILL_BUFFER(buffer, bufsz, "\0", 1); if (ce->cef_path[0] == '\0') { CHANGELOG_FILL_BUFFER(buffer, bufsz, "\0", 1); } else { CHANGELOG_FILL_BUFFER(buffer, bufsz, ce->cef_path, strlen(ce->cef_path)); } return bufsz; } size_t fop_fn(void *data, char *buffer, gf_boolean_t encode) { char buf[10] = { 0, }; size_t bufsz = 0; glusterfs_fop_t fop = 0; fop = *(glusterfs_fop_t *)data; if (encode) { (void)snprintf(buf, sizeof(buf), "%d", fop); CHANGELOG_FILL_BUFFER(buffer, bufsz, buf, strlen(buf)); } else CHANGELOG_FILL_BUFFER(buffer, bufsz, &fop, sizeof(fop)); return bufsz; } size_t number_fn(void *data, char *buffer, gf_boolean_t encode) { size_t bufsz = 0; unsigned int nr = 0; char buf[20] = { 0, }; nr = *(unsigned int *)data; if (encode) { (void)snprintf(buf, sizeof(buf), "%u", nr); CHANGELOG_FILL_BUFFER(buffer, bufsz, buf, strlen(buf)); } else CHANGELOG_FILL_BUFFER(buffer, bufsz, &nr, sizeof(unsigned int)); return bufsz; } void entry_free_fn(void *data) { changelog_opt_t *co = data; if (!co) return; GF_FREE(co->co_entry.cef_bname); } void del_entry_free_fn(void *data) { changelog_opt_t *co = data; if (!co) return; GF_FREE(co->co_entry.cef_bname); GF_FREE(co->co_entry.cef_path); } /** * try to write all data in one shot */ static void changelog_encode_write_xtra(changelog_log_data_t *cld, char *buffer, size_t *off, gf_boolean_t encode) { int i = 0; size_t offset = 0; void *data = NULL; changelog_opt_t *co = NULL; offset = *off; co = (changelog_opt_t *)cld->cld_ptr; for (; i < cld->cld_xtra_records; i++, co++) { CHANGELOG_FILL_BUFFER(buffer, offset, "\0", 1); switch (co->co_type) { case CHANGELOG_OPT_REC_FOP: data = &co->co_fop; break; case CHANGELOG_OPT_REC_ENTRY: data = &co->co_entry; break; case CHANGELOG_OPT_REC_UINT32: data = &co->co_uint32; break; } if (co->co_convert) offset += co->co_convert(data, buffer + offset, encode); else /* no coversion: write it out as it is */ CHANGELOG_FILL_BUFFER(buffer, offset, data, co->co_len); } *off = offset; } int changelog_encode_ascii(xlator_t *this, changelog_log_data_t *cld) { size_t off = 0; size_t gfid_len = 0; char *gfid_str = NULL; char *buffer = NULL; changelog_priv_t *priv = NULL; priv = this->private; gfid_str = uuid_utoa(cld->cld_gfid); gfid_len = strlen(gfid_str); /* extra bytes for decorations */ buffer = alloca(gfid_len + cld->cld_ptr_len + 10); CHANGELOG_STORE_ASCII(priv, buffer, off, gfid_str, gfid_len, cld); if (cld->cld_xtra_records) changelog_encode_write_xtra(cld, buffer, &off, _gf_true); CHANGELOG_FILL_BUFFER(buffer, off, "\0", 1); return changelog_write_change(priv, buffer, off); } int changelog_encode_binary(xlator_t *this, changelog_log_data_t *cld) { size_t off = 0; char *buffer = NULL; changelog_priv_t *priv = NULL; priv = this->private; /* extra bytes for decorations */ buffer = alloca(sizeof(uuid_t) + cld->cld_ptr_len + 10); CHANGELOG_STORE_BINARY(priv, buffer, off, cld->cld_gfid, cld); if (cld->cld_xtra_records) changelog_encode_write_xtra(cld, buffer, &off, _gf_false); CHANGELOG_FILL_BUFFER(buffer, off, "\0", 1); return changelog_write_change(priv, buffer, off); } static struct changelog_encoder cb_encoder[] = { [CHANGELOG_ENCODE_BINARY] = { .encoder = CHANGELOG_ENCODE_BINARY, .encode = changelog_encode_binary, }, [CHANGELOG_ENCODE_ASCII] = { .encoder = CHANGELOG_ENCODE_ASCII, .encode = changelog_encode_ascii, }, }; void changelog_encode_change(changelog_priv_t *priv) { priv->ce = &cb_encoder[priv->encode_mode]; } glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-misc.h0000644000000000000000000000013214522202451025441 xustar000000000000000030 mtime=1699284265.661027414 30 atime=1699284265.661027414 30 ctime=1699284304.323143863 glusterfs-11.1/xlators/features/changelog/src/changelog-misc.h0000664000175100017510000001365114522202451025726 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CHANGELOG_MISC_H #define _CHANGELOG_MISC_H #define CHANGELOG_MAX_TYPE 4 #define CHANGELOG_FILE_NAME "CHANGELOG" #define HTIME_FILE_NAME "HTIME" #define CSNAP_FILE_NAME "CHANGELOG.SNAP" #define HTIME_KEY "trusted.glusterfs.htime" #define HTIME_CURRENT "trusted.glusterfs.current_htime" #define HTIME_INITIAL_VALUE "0:0" #define CHANGELOG_VERSION_MAJOR 1 #define CHANGELOG_VERSION_MINOR 2 #define CHANGELOG_UNIX_SOCK DEFAULT_VAR_RUN_DIRECTORY "/changelog-%s.sock" #define CHANGELOG_TMP_UNIX_SOCK DEFAULT_VAR_RUN_DIRECTORY "/.%s%lu.sock" /** * header starts with the version and the format of the changelog. * 'version' not much of a use now. */ #define CHANGELOG_HEADER \ "GlusterFS Changelog | version: v%d.%d | encoding : %d\n" #define CHANGELOG_MAKE_SOCKET_PATH(brick_path, sockpath, len) \ do { \ char xxh64[GF_XXH64_DIGEST_LENGTH * 2 + 1] = { \ 0, \ }; \ gf_xxh64_wrapper((unsigned char *)brick_path, strlen(brick_path), \ GF_XXHSUM64_DEFAULT_SEED, xxh64); \ (void)snprintf(sockpath, len, CHANGELOG_UNIX_SOCK, xxh64); \ } while (0) #define CHANGELOG_MAKE_TMP_SOCKET_PATH(brick_path, sockpath, len) \ do { \ unsigned long pid = 0; \ char xxh64[GF_XXH64_DIGEST_LENGTH * 2 + 1] = { \ 0, \ }; \ pid = (unsigned long)getpid(); \ gf_xxh64_wrapper((unsigned char *)brick_path, strlen(brick_path), \ GF_XXHSUM64_DEFAULT_SEED, xxh64); \ (void)snprintf(sockpath, len, CHANGELOG_TMP_UNIX_SOCK, xxh64, pid); \ } while (0) /** * ... used by libgfchangelog. */ #define CHANGELOG_GET_HEADER_INFO(fd, buffer, len, enc, maj, min, elen) \ do { \ FILE *fp; \ int fd_dup; \ \ enc = -1; \ maj = -1; \ min = -1; \ fd_dup = dup(fd); \ \ if (fd_dup != -1) { \ fp = fdopen(fd_dup, "r"); \ if (fp) { \ if (fgets(buffer, len, fp)) { \ elen = strlen(buffer); \ sscanf(buffer, CHANGELOG_HEADER, &maj, &min, &enc); \ } \ fclose(fp); \ } else { \ sys_close(fd_dup); \ } \ } \ } while (0) #define CHANGELOG_FILL_HTIME_DIR(changelog_dir, path) \ do { \ snprintf(path, sizeof(path), "%s/htime", changelog_dir); \ } while (0) #define CHANGELOG_FILL_CSNAP_DIR(changelog_dir, path) \ do { \ snprintf(path, sizeof(path), "%s/csnap", changelog_dir); \ } while (0) /** * everything after 'CHANGELOG_TYPE_METADATA_XATTR' are internal types * (ie. none of the fops trigger this type of event), hence * CHANGELOG_MAX_TYPE = 4 */ typedef enum { CHANGELOG_TYPE_DATA = 0, CHANGELOG_TYPE_METADATA, CHANGELOG_TYPE_ENTRY, CHANGELOG_TYPE_METADATA_XATTR, CHANGELOG_TYPE_ROLLOVER, CHANGELOG_TYPE_FSYNC, } changelog_log_type; /* operation modes - RT for now */ typedef enum { CHANGELOG_MODE_RT = 0, } changelog_mode_t; /* encoder types */ typedef enum { CHANGELOG_ENCODE_MIN = 0, CHANGELOG_ENCODE_BINARY, CHANGELOG_ENCODE_ASCII, CHANGELOG_ENCODE_MAX, } changelog_encoder_t; #define CHANGELOG_VALID_ENCODING(enc) \ (enc > CHANGELOG_ENCODE_MIN && enc < CHANGELOG_ENCODE_MAX) #define CHANGELOG_TYPE_IS_ENTRY(type) (type == CHANGELOG_TYPE_ENTRY) #define CHANGELOG_TYPE_IS_ROLLOVER(type) (type == CHANGELOG_TYPE_ROLLOVER) #define CHANGELOG_TYPE_IS_FSYNC(type) (type == CHANGELOG_TYPE_FSYNC) #endif /* _CHANGELOG_MISC_H */ glusterfs-11.1/xlators/features/changelog/src/PaxHeaders.9031/changelog-helpers.h0000644000000000000000000000013214522202451026150 xustar000000000000000030 mtime=1699284265.660027411 30 atime=1699284265.660027411 30 ctime=1699284304.315143839 glusterfs-11.1/xlators/features/changelog/src/changelog-helpers.h0000664000175100017510000006346314522202451026443 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CHANGELOG_HELPERS_H #define _CHANGELOG_HELPERS_H #include #include #include "pthread.h" #include #include #include "changelog-misc.h" #include #include "rpcsvc.h" #include "changelog-ev-handle.h" #include "changelog.h" #include "changelog-messages.h" /** * the changelog entry */ typedef struct changelog_log_data { /* rollover related */ time_t cld_roll_time; /* reopen changelog? */ gf_boolean_t cld_finale; changelog_log_type cld_type; /** * sincd gfid is _always_ a necessity, it's not a part * of the iobuf. by doing this we do not add any overhead * for data and metadata related fops. */ uuid_t cld_gfid; /** * iobufs are used for optionals records: pargfid, path, * write offsets etc.. It's the fop implementers job * to allocate (iobuf_get() in the fop) and get unref'ed * in the callback (CHANGELOG_STACK_UNWIND). */ struct iobuf *cld_iobuf; #define cld_ptr cld_iobuf->ptr /** * after allocation you can point this to the length of * usable data, but make sure it does not exceed the * the size of the requested iobuf. */ size_t cld_iobuf_len; #define cld_ptr_len cld_iobuf_len /** * number of optional records */ int cld_xtra_records; } changelog_log_data_t; /** * holder for dispatch function and private data */ typedef struct changelog_priv changelog_priv_t; typedef struct changelog_dispatcher { void *cd_data; int (*dispatchfn)(xlator_t *, changelog_priv_t *, void *, changelog_log_data_t *, changelog_log_data_t *); } changelog_dispatcher_t; struct changelog_bootstrap { changelog_mode_t mode; int (*ctor)(xlator_t *, changelog_dispatcher_t *); int (*dtor)(xlator_t *, changelog_dispatcher_t *); }; struct changelog_encoder { changelog_encoder_t encoder; int (*encode)(xlator_t *, changelog_log_data_t *); }; /* xlator private */ typedef struct changelog_time_slice { /** * version of changelog file, incremented each time changes * rollover. */ unsigned long changelog_version[CHANGELOG_MAX_TYPE]; } changelog_time_slice_t; typedef struct changelog_rollover { /* rollover thread */ pthread_t rollover_th; xlator_t *this; pthread_mutex_t lock; pthread_cond_t cond; gf_boolean_t notify; } changelog_rollover_t; typedef struct changelog_fsync { /* fsync() thread */ pthread_t fsync_th; xlator_t *this; } changelog_fsync_t; /* Draining during changelog rollover (for geo-rep snapshot dependency): * -------------------------------------------------------------------- * The introduction of draining of in-transit fops during changelog rollover * (both explicit/timeout triggered) requires coloring of fops. Basically the * implementation requires two counters, one counter which keeps the count of * current intransit fops which should end up in current changelog and the other * counter to keep track of incoming fops which should be drained as part of * next changelog rollover event. The fops are colored w.r.t these counters. * The fops that are to be drained as part of current changelog rollover is * given one color and the fops which keep incoming during this and not * necessarily should end up in current changelog and should be drained as part * of next changelog rollover are given other color. The color switching * continues with each changelog rollover. Two colors(black and white) are * chosen here and initially black is chosen is default. */ typedef enum chlog_fop_color { FOP_COLOR_BLACK, FOP_COLOR_WHITE } chlog_fop_color_t; /* Barrier notify variable */ typedef struct barrier_notify { pthread_mutex_t bnotify_mutex; pthread_cond_t bnotify_cond; gf_boolean_t bnotify; gf_boolean_t bnotify_error; } barrier_notify_t; /* Two separate mutex and conditional variable set is used * to drain white and black fops. */ typedef struct drain_mgmt { pthread_mutex_t drain_black_mutex; pthread_cond_t drain_black_cond; pthread_mutex_t drain_white_mutex; pthread_cond_t drain_white_cond; /* Represents black fops count in-transit */ unsigned long black_fop_cnt; /* Represents white fops count in-transit */ unsigned long white_fop_cnt; gf_boolean_t drain_wait_black; gf_boolean_t drain_wait_white; } drain_mgmt_t; /* External barrier as a result of snap on/off indicating flag*/ typedef struct barrier_flags { gf_lock_t lock; gf_boolean_t barrier_ext; } barrier_flags_t; /* Event selection */ typedef struct changelog_ev_selector { gf_lock_t reflock; /** * Array of references for each selection bit. */ unsigned int ref[CHANGELOG_EV_SELECTION_RANGE]; } changelog_ev_selector_t; /* changelog's private structure */ struct changelog_priv { /* changelog journalling */ gf_boolean_t active; /* changelog live notifications */ gf_boolean_t rpc_active; /* to generate unique socket file per brick */ char *changelog_brick; /* logging directory */ char *changelog_dir; /* htime directory */ char *htime_dir; /* one file for all changelog types */ int changelog_fd; /* htime fd for current changelog session */ int htime_fd; /* c_snap_fd is fd for call-path changelog */ int c_snap_fd; /* rollover_count used by htime */ int rollover_count; gf_lock_t lock; /* lock to synchronize CSNAP updation */ gf_lock_t c_snap_lock; /* written end of the pipe */ int wfd; /* rollover time */ time_t rollover_time; /* fsync() interval */ time_t fsync_interval; /* changelog type maps */ const char *maps[CHANGELOG_MAX_TYPE]; /* time slicer */ changelog_time_slice_t slice; /* context of the updater */ changelog_dispatcher_t cd; /* context of the rollover thread */ changelog_rollover_t cr; /* context of fsync thread */ changelog_fsync_t cf; /* operation mode */ changelog_mode_t op_mode; /* bootstrap routine for 'current' logger */ struct changelog_bootstrap *cb; /* encoder mode */ changelog_encoder_t encode_mode; /* encoder */ struct changelog_encoder *ce; /** * snapshot dependency changes */ /* Draining of fops*/ drain_mgmt_t dm; /* Represents the active color. Initially by default black */ chlog_fop_color_t current_color; /* flag to determine explicit rollover is triggered */ gf_boolean_t explicit_rollover; /* barrier notification variable protected by mutex */ barrier_notify_t bn; /* barrier on/off indicating flags */ barrier_flags_t bflags; /* changelog barrier on/off indicating flag */ gf_boolean_t barrier_enabled; struct list_head queue; uint32_t queue_size; gf_timer_t *timer; struct timespec timeout; /** * buffers, RPC, event selection, notifications and other * beasts. */ /* epoll pthread */ pthread_t poller; /* rotational buffer */ rbuf_t *rbuf; /* changelog RPC server */ rpcsvc_t *rpc; /* event selection */ changelog_ev_selector_t ev_selection; /* client handling (reverse connection) */ pthread_t connector; int nr_dispatchers; pthread_t *ev_dispatcher; changelog_clnt_t connections; /* glusterfind dependency to capture paths on deleted entries*/ gf_boolean_t capture_del_path; /* Save total no. of listners */ gf_atomic_t listnercnt; /* Save total no. of xprt are associated with listner */ gf_atomic_t xprtcnt; /* Save xprt list */ struct list_head xprt_list; /* Save total no. of client connection */ gf_atomic_t clntcnt; /* Save cleanup brick in victim */ xlator_t *victim; /* Status to save cleanup notify status */ gf_boolean_t notify_down; }; struct changelog_local { inode_t *inode; gf_boolean_t update_no_check; changelog_log_data_t cld; /** * ->prev_entry is used in cases when there needs to be * additional changelog entry for the parent (eg. rename) * It's analogous to ->next in single linked list world, * but we call it as ->prev_entry... ha ha ha */ struct changelog_local *prev_entry; /* snap dependency changes */ chlog_fop_color_t color; }; typedef struct changelog_local changelog_local_t; /* inode version is stored in inode ctx */ typedef struct changelog_inode_ctx { unsigned long iversion[CHANGELOG_MAX_TYPE]; } changelog_inode_ctx_t; #define CHANGELOG_INODE_VERSION_TYPE(ctx, type) &(ctx->iversion[type]) /** * Optional Records: * fops that need to save additional information request a array of * @changelog_opt_t struct. The array is allocated via @iobufs. */ typedef enum { CHANGELOG_OPT_REC_FOP, CHANGELOG_OPT_REC_ENTRY, CHANGELOG_OPT_REC_UINT32, } changelog_optional_rec_type_t; struct changelog_entry_fields { uuid_t cef_uuid; char *cef_bname; char *cef_path; }; typedef struct { /** * @co_covert can be used to do post-processing of the record before * it's persisted to the CHANGELOG. If this is NULL, then the record * is persisted as per it's in memory format. */ size_t (*co_convert)(void *data, char *buffer, gf_boolean_t encode); /* release routines */ void (*co_free)(void *data); /* type of the field */ changelog_optional_rec_type_t co_type; /** * sizeof of the 'valid' field in the union. This field is not used if * @co_convert is specified. */ size_t co_len; union { unsigned int co_uint32; glusterfs_fop_t co_fop; struct changelog_entry_fields co_entry; }; } changelog_opt_t; #define CHANGELOG_OPT_RECORD_LEN sizeof(changelog_opt_t) /** * helpers routines */ int changelog_thread_cleanup(xlator_t *this, pthread_t thr_id); void * changelog_get_usable_buffer(changelog_local_t *local); void changelog_set_usable_record_and_length(changelog_local_t *local, size_t len, int xr); void changelog_local_cleanup(xlator_t *xl, changelog_local_t *local); changelog_local_t * changelog_local_init(xlator_t *this, inode_t *inode, uuid_t gfid, int xtra_records, gf_boolean_t update_flag); int changelog_start_next_change(xlator_t *this, changelog_priv_t *priv, time_t ts, gf_boolean_t finale); int changelog_open_journal(xlator_t *this, changelog_priv_t *priv); void changelog_fill_rollover_data(changelog_log_data_t *cld, gf_boolean_t is_last); int changelog_inject_single_event(xlator_t *this, changelog_priv_t *priv, changelog_log_data_t *cld); size_t changelog_entry_length(void); int changelog_write(int fd, char *buffer, size_t len); int changelog_write_change(changelog_priv_t *priv, char *buffer, size_t len); int changelog_handle_change(xlator_t *this, changelog_priv_t *priv, changelog_log_data_t *cld); void changelog_update(xlator_t *this, changelog_priv_t *priv, changelog_local_t *local, changelog_log_type type); void * changelog_rollover(void *data); void * changelog_fsync_thread(void *data); int changelog_forget(xlator_t *this, inode_t *inode); int htime_update(xlator_t *this, changelog_priv_t *priv, time_t ts, char *buffer); int htime_open(xlator_t *this, changelog_priv_t *priv, time_t ts); int htime_create(xlator_t *this, changelog_priv_t *priv, time_t ts); /* Geo-Rep snapshot dependency changes */ void changelog_color_fop_and_inc_cnt(xlator_t *this, changelog_priv_t *priv, changelog_local_t *local); void changelog_inc_fop_cnt(xlator_t *this, changelog_priv_t *priv, changelog_local_t *local); void changelog_dec_fop_cnt(xlator_t *this, changelog_priv_t *priv, changelog_local_t *local); int changelog_barrier_notify(changelog_priv_t *priv, char *buf); void changelog_barrier_cleanup(xlator_t *this, changelog_priv_t *priv, struct list_head *queue); void changelog_drain_white_fops(xlator_t *this, changelog_priv_t *priv); void changelog_drain_black_fops(xlator_t *this, changelog_priv_t *priv); /* Crash consistency of changelog wrt snapshot */ int changelog_snap_logging_stop(xlator_t *this, changelog_priv_t *priv); int changelog_snap_logging_start(xlator_t *this, changelog_priv_t *priv); int changelog_snap_open(xlator_t *this, changelog_priv_t *priv); int changelog_snap_handle_ascii_change(xlator_t *this, changelog_log_data_t *cld); int changelog_snap_write_change(changelog_priv_t *priv, char *buffer, size_t len); /* Changelog barrier routines */ void __chlog_barrier_enqueue(xlator_t *this, call_stub_t *stub); void __chlog_barrier_disable(xlator_t *this, struct list_head *queue); void chlog_barrier_dequeue_all(xlator_t *this, struct list_head *queue); call_stub_t * __chlog_barrier_dequeue(xlator_t *this, struct list_head *queue); int __chlog_barrier_enable(xlator_t *this, changelog_priv_t *priv); int32_t changelog_fill_entry_buf(call_frame_t *frame, xlator_t *this, loc_t *loc, changelog_local_t **local); /* event selection routines */ void changelog_select_event(xlator_t *, changelog_ev_selector_t *, unsigned int); void changelog_deselect_event(xlator_t *, changelog_ev_selector_t *, unsigned int); int changelog_init_event_selection(xlator_t *, changelog_ev_selector_t *); int changelog_ev_selected(xlator_t *, changelog_ev_selector_t *, unsigned int); void changelog_dispatch_event(xlator_t *, changelog_priv_t *, changelog_event_t *); changelog_inode_ctx_t * __changelog_inode_ctx_get(xlator_t *, inode_t *, unsigned long **, unsigned long *, changelog_log_type); int resolve_pargfid_to_path(xlator_t *this, const uuid_t gfid, char **path, char *bname); /* macros */ #define CHANGELOG_STACK_UNWIND(fop, frame, params...) \ do { \ changelog_local_t *__local = NULL; \ xlator_t *__xl = NULL; \ if (frame) { \ __local = frame->local; \ __xl = frame->this; \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ if (__local && __local->prev_entry) \ changelog_local_cleanup(__xl, __local->prev_entry); \ changelog_local_cleanup(__xl, __local); \ } while (0) #define CHANGELOG_IOBUF_REF(iobuf) \ do { \ if (iobuf) \ iobuf_ref(iobuf); \ } while (0) #define CHANGELOG_IOBUF_UNREF(iobuf) \ do { \ if (iobuf) \ iobuf_unref(iobuf); \ } while (0) #define CHANGELOG_FILL_BUFFER(buffer, off, val, len) \ do { \ memcpy(buffer + off, val, len); \ off += len; \ } while (0) #define SLICE_VERSION_UPDATE(slice) \ do { \ int i = 0; \ for (; i < CHANGELOG_MAX_TYPE; i++) { \ slice->changelog_version[i]++; \ } \ } while (0) #define CHANGELOG_FILL_UINT32(co, number, converter, xlen) \ do { \ co->co_convert = converter; \ co->co_free = NULL; \ co->co_type = CHANGELOG_OPT_REC_UINT32; \ co->co_uint32 = number; \ xlen += sizeof(unsigned int); \ } while (0) #define CHANGLOG_FILL_FOP_NUMBER(co, fop, converter, xlen) \ do { \ co->co_convert = converter; \ co->co_free = NULL; \ co->co_type = CHANGELOG_OPT_REC_FOP; \ co->co_fop = fop; \ xlen += sizeof(fop); \ } while (0) #define CHANGELOG_FILL_ENTRY(co, pargfid, bname, converter, freefn, xlen, \ label) \ do { \ co->co_convert = converter; \ co->co_free = freefn; \ co->co_type = CHANGELOG_OPT_REC_ENTRY; \ gf_uuid_copy(co->co_entry.cef_uuid, pargfid); \ co->co_entry.cef_bname = gf_strdup(bname); \ if (!co->co_entry.cef_bname) \ goto label; \ xlen += (UUID_CANONICAL_FORM_LEN + strlen(bname)); \ } while (0) #define CHANGELOG_FILL_ENTRY_DIR_PATH(co, pargfid, bname, converter, \ del_freefn, xlen, label, capture_del) \ do { \ co->co_convert = converter; \ co->co_free = del_freefn; \ co->co_type = CHANGELOG_OPT_REC_ENTRY; \ gf_uuid_copy(co->co_entry.cef_uuid, pargfid); \ co->co_entry.cef_bname = gf_strdup(bname); \ if (!co->co_entry.cef_bname) \ goto label; \ xlen += (UUID_CANONICAL_FORM_LEN + strlen(bname)); \ if (!capture_del || \ resolve_pargfid_to_path(this, pargfid, &(co->co_entry.cef_path), \ co->co_entry.cef_bname)) { \ co->co_entry.cef_path = gf_strdup("\0"); \ xlen += 1; \ } else { \ xlen += (strlen(co->co_entry.cef_path)); \ } \ } while (0) #define CHANGELOG_INIT(this, local, inode, gfid, xrec) \ local = changelog_local_init(this, inode, gfid, xrec, _gf_false) #define CHANGELOG_INIT_NOCHECK(this, local, inode, gfid, xrec) \ local = changelog_local_init(this, inode, gfid, xrec, _gf_true) #define CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, label) \ do { \ if (!priv->active) \ goto label; \ /* ignore rebalance process's activity. */ \ if ((frame->root->pid == GF_CLIENT_PID_DEFRAG) || \ (frame->root->pid == GF_CLIENT_PID_TIER_DEFRAG)) \ goto label; \ } while (0) /* If it is a METADATA entry and fop num being GF_FOP_NULL, don't * log in the changelog as it is of no use. And also if it is * logged, since slicing version checking is done for metadata * entries, the subsequent entries with valid fop num which falls * to same changelog will be missed. Hence check for boundary * condition. */ #define CHANGELOG_OP_BOUNDARY_CHECK(frame, label) \ do { \ if (frame->root->op <= GF_FOP_NULL || \ frame->root->op >= GF_FOP_MAXVALUE) \ goto label; \ } while (0) /** * ignore internal fops for all clients except AFR self-heal daemon */ #define CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO(frame, dict, label) \ do { \ if ((frame->root->pid != GF_CLIENT_PID_SELF_HEALD) && dict && \ dict_get(dict, GLUSTERFS_INTERNAL_FOP_KEY)) \ goto label; \ } while (0) #define CHANGELOG_COND_GOTO(priv, cond, label) \ do { \ if (!priv->active || cond) \ goto label; \ } while (0) /* Begin: Geo-Rep snapshot dependency changes */ #define DICT_ERROR -1 #define BARRIER_OFF 0 #define BARRIER_ON 1 #define DICT_DEFAULT 2 #define CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, label) \ do { \ if (!priv->active) { \ gf_smsg(this->name, GF_LOG_WARNING, 0, \ CHANGELOG_MSG_CHANGELOG_NOT_ACTIVE, NULL); \ ret = 0; \ goto label; \ } \ } while (0) /* Log pthread error and goto label */ #define CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, label) \ do { \ if (ret) { \ gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_PTHREAD_ERROR, \ "error=%d", ret, NULL); \ ret = -1; \ goto label; \ } \ } while (0); /* Log pthread error, set flag and goto label */ #define CHANGELOG_PTHREAD_ERROR_HANDLE_1(ret, label, flag) \ do { \ if (ret) { \ gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_PTHREAD_ERROR, \ "error=%d", ret, NULL); \ ret = -1; \ flag = _gf_true; \ goto label; \ } \ } while (0) /* Log pthread error, unlock mutex and goto label */ #define CHANGELOG_PTHREAD_ERROR_HANDLE_2(ret, label, mutex) \ do { \ if (ret) { \ gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_PTHREAD_ERROR, \ "error=%d", ret, NULL); \ ret = -1; \ pthread_mutex_unlock(&mutex); \ goto label; \ } \ } while (0) /* End: Geo-Rep snapshot dependency changes */ #endif /* _CHANGELOG_HELPERS_H */ glusterfs-11.1/xlators/features/changelog/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463023671 xustar000000000000000030 mtime=1699284275.484057001 30 atime=1699284290.151101178 30 ctime=1699284304.264143685 glusterfs-11.1/xlators/features/changelog/Makefile.in0000664000175100017510000005274114522202463024161 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/changelog DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src lib CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/changelog/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/changelog/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/changelog/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023655 xustar000000000000000030 mtime=1699284265.655027396 30 atime=1699284275.460056929 30 ctime=1699284304.265143688 glusterfs-11.1/xlators/features/changelog/Makefile.am0000664000175100017510000000004014522202451024126 0ustar00jenkinsjenkins00000000000000SUBDIRS = src lib CLEANFILES = glusterfs-11.1/xlators/features/changelog/PaxHeaders.9031/lib0000644000000000000000000000013214522202520022307 xustar000000000000000030 mtime=1699284304.388144059 30 atime=1699284309.687160019 30 ctime=1699284304.388144059 glusterfs-11.1/xlators/features/changelog/lib/0002775000175100017510000000000014522202520022645 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/changelog/lib/PaxHeaders.9031/src0000644000000000000000000000013214522202520023076 xustar000000000000000030 mtime=1699284304.452144251 30 atime=1699284309.687160019 30 ctime=1699284304.452144251 glusterfs-11.1/xlators/features/changelog/lib/src/0002775000175100017510000000000014522202520023434 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-changelog-helpers.c0000644000000000000000000000013214522202451027303 xustar000000000000000030 mtime=1699284265.657027402 30 atime=1699284265.657027402 30 ctime=1699284304.445144231 glusterfs-11.1/xlators/features/changelog/lib/src/gf-changelog-helpers.c0000664000175100017510000000753614522202451027575 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "changelog-mem-types.h" #include "gf-changelog-helpers.h" #include "changelog-lib-messages.h" #include size_t gf_changelog_write(int fd, char *buffer, size_t len) { ssize_t size = 0; size_t written = 0; while (written < len) { size = sys_write(fd, buffer + written, len - written); if (size <= 0) break; written += size; } return written; } void gf_rfc3986_encode_space_newline(unsigned char *s, char *enc, char *estr) { for (; *s; s++) { if (estr[*s]) sprintf(enc, "%c", estr[*s]); else sprintf(enc, "%%%02X", *s); while (*++enc) ; } } /** * thread safe version of readline with buffering * (taken from Unix Network Programming Volume I, W.R. Stevens) * * This is favoured over fgets() as we'd need to ftruncate() * (see gf_changelog_scan() API) to record new changelog files. * stream open functions does have a truncate like api (although * that can be done via @fflush(fp), @ftruncate(fd) and @fseek(fp), * but this involves mixing POSIX file descriptors and stream FILE *). * * NOTE: This implementation still does work with more than one fd's * used to perform gf_readline(). For this very reason it's not * made a part of libglusterfs. */ static __thread read_line_t thread_tsd = {}; static ssize_t my_read(read_line_t *tsd, int fd, char *ptr) { if (tsd->rl_cnt <= 0) { tsd->rl_cnt = sys_read(fd, tsd->rl_buf, MAXLINE); if (tsd->rl_cnt < 0) return -1; else if (tsd->rl_cnt == 0) return 0; tsd->rl_bufptr = tsd->rl_buf; } tsd->rl_cnt--; *ptr = *tsd->rl_bufptr++; return 1; } ssize_t gf_readline(int fd, void *vptr, size_t maxlen) { size_t n = 0; size_t rc = 0; char c = ' '; char *ptr = NULL; read_line_t *tsd = &thread_tsd; ptr = vptr; for (n = 1; n < maxlen; n++) { if ((rc = my_read(tsd, fd, &c)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { *ptr = '\0'; return (n - 1); } else return -1; } *ptr = '\0'; return n; } off_t gf_lseek(int fd, off_t offset, int whence) { off_t off = 0; read_line_t *tsd = &thread_tsd; off = sys_lseek(fd, offset, whence); if (off == -1) return -1; tsd->rl_cnt = 0; tsd->rl_bufptr = tsd->rl_buf; return off; } int gf_ftruncate(int fd, off_t length) { read_line_t *tsd = &thread_tsd; if (sys_ftruncate(fd, 0)) return -1; tsd->rl_cnt = 0; tsd->rl_bufptr = tsd->rl_buf; return 0; } int gf_thread_cleanup(xlator_t *this, pthread_t thread) { int ret = 0; void *res = NULL; ret = pthread_cancel(thread); if (ret != 0) { gf_msg(this->name, GF_LOG_WARNING, 0, CHANGELOG_LIB_MSG_THREAD_CLEANUP_WARNING, "Failed to send cancellation to thread"); goto error_return; } ret = pthread_join(thread, &res); if (ret != 0) { gf_msg(this->name, GF_LOG_WARNING, 0, CHANGELOG_LIB_MSG_THREAD_CLEANUP_WARNING, "failed to join thread"); goto error_return; } if (res != PTHREAD_CANCELED) { gf_msg(this->name, GF_LOG_WARNING, 0, CHANGELOG_LIB_MSG_THREAD_CLEANUP_WARNING, "Thread could not be cleaned up"); goto error_return; } return 0; error_return: return -1; } glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-changelog.c0000644000000000000000000000013214522202451025643 xustar000000000000000030 mtime=1699284265.658027405 30 atime=1699284265.658027405 30 ctime=1699284304.441144218 glusterfs-11.1/xlators/features/changelog/lib/src/gf-changelog.c0000664000175100017510000003561714522202451026136 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include "gf-changelog-rpc.h" #include "gf-changelog-helpers.h" /* from the changelog translator */ #include "changelog-misc.h" #include "changelog-mem-types.h" #include "changelog-lib-messages.h" /** * Global singleton xlator pointer for the library, initialized * during library load. This should probably be hidden inside * an initialized object which is an handle for the consumer. * * TODO: do away with the global.. */ xlator_t *primary = NULL; static inline gf_private_t * gf_changelog_alloc_priv(void) { int ret = 0; gf_private_t *priv = NULL; priv = GF_CALLOC(1, sizeof(*priv), gf_changelog_mt_priv_t); if (!priv) goto error_return; INIT_LIST_HEAD(&priv->connections); INIT_LIST_HEAD(&priv->cleanups); ret = pthread_mutex_init(&priv->lock, NULL); if (ret != 0) goto free_priv; ret = pthread_cond_init(&priv->cond, NULL); if (ret != 0) goto cleanup_mutex; priv->api = NULL; return priv; cleanup_mutex: (void)pthread_mutex_destroy(&priv->lock); free_priv: GF_FREE(priv); error_return: return NULL; } #define GF_CHANGELOG_EVENT_POOL_SIZE 16384 #define GF_CHANGELOG_EVENT_THREAD_COUNT 4 static int gf_changelog_ctx_defaults_init(glusterfs_ctx_t *ctx) { cmd_args_t *cmd_args = NULL; struct rlimit lim = { 0, }; call_pool_t *pool = NULL; int ret = -1; ret = xlator_mem_acct_init(THIS, gf_changelog_mt_end); if (ret != 0) return -1; ctx->process_uuid = generate_glusterfs_ctx_id(); if (!ctx->process_uuid) return -1; ctx->page_size = 128 * GF_UNIT_KB; ctx->iobuf_pool = iobuf_pool_new(); if (!ctx->iobuf_pool) goto free_pool; ctx->event_pool = gf_event_pool_new(GF_CHANGELOG_EVENT_POOL_SIZE, GF_CHANGELOG_EVENT_THREAD_COUNT); if (!ctx->event_pool) goto free_pool; pool = GF_CALLOC(1, sizeof(call_pool_t), gf_changelog_mt_libgfchangelog_call_pool_t); if (!pool) goto free_pool; /* frame_mem_pool size 112 * 64 */ pool->frame_mem_pool = mem_pool_new(call_frame_t, 32); if (!pool->frame_mem_pool) goto free_pool; /* stack_mem_pool size 256 * 128 */ pool->stack_mem_pool = mem_pool_new(call_stack_t, 16); if (!pool->stack_mem_pool) goto free_pool; ctx->dict_pool = mem_pool_new(dict_t, 32); if (!ctx->dict_pool) goto free_pool; ctx->dict_data_pool = mem_pool_new(data_t, 512); if (!ctx->dict_data_pool) goto free_pool; ctx->logbuf_pool = mem_pool_new(log_buf_t, 256); if (!ctx->logbuf_pool) goto free_pool; INIT_LIST_HEAD(&pool->all_frames); LOCK_INIT(&pool->lock); ctx->pool = pool; LOCK_INIT(&ctx->lock); cmd_args = &ctx->cmd_args; INIT_LIST_HEAD(&cmd_args->xlator_options); lim.rlim_cur = RLIM_INFINITY; lim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &lim); return 0; free_pool: if (pool) { GF_FREE(pool->frame_mem_pool); GF_FREE(pool->stack_mem_pool); GF_FREE(pool); } GF_FREE(ctx->dict_pool); GF_FREE(ctx->dict_data_pool); GF_FREE(ctx->logbuf_pool); GF_FREE(ctx->iobuf_pool); GF_FREE(ctx->event_pool); return -1; } /* TODO: cleanup ctx defaults */ void gf_changelog_cleanup_this(xlator_t *this) { glusterfs_ctx_t *ctx = NULL; if (!this) return; ctx = this->ctx; syncenv_destroy(ctx->env); free(ctx); this->private = NULL; this->ctx = NULL; mem_pools_fini(); } static int gf_changelog_init_context(void) { glusterfs_ctx_t *ctx = NULL; ctx = glusterfs_ctx_new(); if (!ctx) goto error_return; if (glusterfs_globals_init(ctx)) goto free_ctx; THIS->ctx = ctx; if (gf_changelog_ctx_defaults_init(ctx)) goto free_ctx; ctx->env = syncenv_new(0, 0, 0); if (!ctx->env) goto free_ctx; return 0; free_ctx: free(ctx); THIS->ctx = NULL; error_return: return -1; } static int gf_changelog_init_primary(void) { int ret = 0; ret = gf_changelog_init_context(); mem_pools_init(); return ret; } /* TODO: cleanup clnt/svc on failure */ int gf_changelog_setup_rpc(xlator_t *this, gf_changelog_t *entry, int proc) { int ret = 0; rpcsvc_t *svc = NULL; struct rpc_clnt *rpc = NULL; /** * Initialize a connect back socket. A probe() RPC call to the server * triggers a reverse connect. */ svc = gf_changelog_reborp_init_rpc_listner(this, entry->brick, RPC_SOCK(entry), entry); if (!svc) goto error_return; RPC_REBORP(entry) = svc; /* Initialize an RPC client */ rpc = gf_changelog_rpc_init(this, entry); if (!rpc) goto error_return; RPC_PROBER(entry) = rpc; /** * @FIXME * till we have connection state machine, let's delay the RPC call * for now.. */ sleep(2); /** * Probe changelog translator for reverse connection. After a successful * call, there's less use of the client and can be disconnected, but * let's leave the connection active for any future RPC calls. */ ret = gf_changelog_invoke_rpc(this, entry, proc); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_INVOKE_RPC_FAILED, "Could not initiate probe RPC, bailing out!!!"); goto error_return; } return 0; error_return: return -1; } int gf_cleanup_event(xlator_t *this, struct gf_event_list *ev) { int ret = 0; ret = gf_thread_cleanup(this, ev->invoker); if (ret) { gf_msg(this->name, GF_LOG_WARNING, -ret, CHANGELOG_LIB_MSG_CLEANUP_ERROR, "cannot cleanup callback invoker thread." " Not freeing resources"); return -1; } ev->entry = NULL; return 0; } static int gf_init_event(gf_changelog_t *entry) { int ret = 0; struct gf_event_list *ev = NULL; ev = &entry->event; ev->entry = entry; ret = pthread_mutex_init(&ev->lock, NULL); if (ret != 0) goto error_return; ret = pthread_cond_init(&ev->cond, NULL); if (ret != 0) goto cleanup_mutex; INIT_LIST_HEAD(&ev->events); ev->next_seq = 0; /* bootstrap sequencing */ if (GF_NEED_ORDERED_EVENTS(entry)) { entry->pickevent = pick_event_ordered; entry->queueevent = queue_ordered_event; } else { entry->pickevent = pick_event_unordered; entry->queueevent = queue_unordered_event; } ret = gf_thread_create(&ev->invoker, NULL, gf_changelog_callback_invoker, ev, "clogcbki"); if (ret != 0) { entry->pickevent = NULL; entry->queueevent = NULL; goto cleanup_cond; } return 0; cleanup_cond: (void)pthread_cond_destroy(&ev->cond); cleanup_mutex: (void)pthread_mutex_destroy(&ev->lock); error_return: return -1; } /** * TODO: * - cleanup invoker thread * - cleanup event list * - destroy rpc{-clnt, svc} */ int gf_cleanup_brick_connection(xlator_t *this, gf_changelog_t *entry) { return 0; } int gf_cleanup_connections(xlator_t *this) { return 0; } static int gf_setup_brick_connection(xlator_t *this, struct gf_brick_spec *brick, gf_boolean_t ordered, void *xl) { int ret = 0; gf_private_t *priv = NULL; gf_changelog_t *entry = NULL; priv = this->private; if (!brick->callback || !brick->init || !brick->fini) goto error_return; entry = GF_CALLOC(1, sizeof(*entry), gf_changelog_mt_libgfchangelog_t); if (!entry) goto error_return; INIT_LIST_HEAD(&entry->list); LOCK_INIT(&entry->statelock); entry->connstate = GF_CHANGELOG_CONN_STATE_PENDING; entry->notify = brick->filter; if (snprintf(entry->brick, PATH_MAX, "%s", brick->brick_path) >= PATH_MAX) goto free_entry; entry->this = this; entry->invokerxl = xl; entry->ordered = ordered; ret = gf_init_event(entry); if (ret) goto free_entry; entry->fini = brick->fini; entry->callback = brick->callback; entry->connected = brick->connected; entry->disconnected = brick->disconnected; entry->ptr = brick->init(this, brick); if (!entry->ptr) goto cleanup_event; priv->api = entry->ptr; /* pointer to API, if required */ pthread_mutex_lock(&priv->lock); { list_add_tail(&entry->list, &priv->connections); } pthread_mutex_unlock(&priv->lock); ret = gf_changelog_setup_rpc(this, entry, CHANGELOG_RPC_PROBE_FILTER); if (ret) goto cleanup_event; return 0; cleanup_event: (void)gf_cleanup_event(this, &entry->event); free_entry: gf_msg_debug(this->name, 0, "freeing entry %p", entry); list_del(&entry->list); /* FIXME: kludge for now */ GF_FREE(entry); error_return: return -1; } int gf_changelog_register_brick(xlator_t *this, struct gf_brick_spec *brick, gf_boolean_t ordered, void *xl) { return gf_setup_brick_connection(this, brick, ordered, xl); } static int gf_changelog_setup_logging(xlator_t *this, char *logfile, int loglevel) { /* passing ident as NULL means to use default ident for syslog */ if (gf_log_init(this->ctx, logfile, NULL)) return -1; gf_log_set_loglevel(this->ctx, (loglevel == -1) ? GF_LOG_INFO : loglevel); return 0; } static int gf_changelog_set_primary(xlator_t *primary, void *xl) { int32_t ret = 0; xlator_t *this = NULL; xlator_t *old_this = NULL; gf_private_t *priv = NULL; this = xl; if (!this || !this->ctx) { ret = gf_changelog_init_primary(); if (ret) return -1; this = THIS; } primary->ctx = this->ctx; INIT_LIST_HEAD(&primary->volume_options); SAVE_THIS(THIS); ret = xlator_mem_acct_init(THIS, gf_changelog_mt_end); if (ret != 0) goto restore_this; priv = gf_changelog_alloc_priv(); if (!priv) { ret = -1; goto restore_this; } if (!xl) { /* poller thread */ ret = gf_thread_create(&priv->poller, NULL, changelog_rpc_poller, THIS, "clogpoll"); if (ret != 0) { GF_FREE(priv); gf_msg(primary->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_THREAD_CREATION_FAILED, "failed to spawn poller thread"); goto restore_this; } } primary->private = priv; restore_this: RESTORE_THIS(); return ret; } int gf_changelog_init(void *xl) { int ret = 0; gf_private_t *priv = NULL; if (primary) return 0; primary = calloc(1, sizeof(*primary)); if (!primary) goto error_return; primary->name = strdup("gfchangelog"); if (!primary->name) goto dealloc_primary; ret = gf_changelog_set_primary(primary, xl); if (ret) goto dealloc_name; priv = primary->private; ret = gf_thread_create(&priv->connectionjanitor, NULL, gf_changelog_connection_janitor, primary, "clogjan"); if (ret != 0) { /* TODO: cleanup priv, mutex (poller thread for !xl) */ goto dealloc_name; } return 0; dealloc_name: free(primary->name); dealloc_primary: free(primary); primary = NULL; error_return: return -1; } int gf_changelog_register_generic(struct gf_brick_spec *bricks, int count, int ordered, char *logfile, int lvl, void *xl) { int ret = 0; xlator_t *this = NULL; xlator_t *old_this = NULL; struct gf_brick_spec *brick = NULL; gf_boolean_t need_order = _gf_false; SAVE_THIS(xl); this = THIS; if (!this) goto error_return; ret = gf_changelog_setup_logging(this, logfile, lvl); if (ret) goto error_return; need_order = (ordered) ? _gf_true : _gf_false; brick = bricks; while (count--) { gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_LIB_MSG_NOTIFY_REGISTER_INFO, "brick=%s", brick->brick_path, "notify_filter=%d", brick->filter, NULL); ret = gf_changelog_register_brick(this, brick, need_order, xl); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_NOTIFY_REGISTER_FAILED, "Error registering with changelog xlator"); break; } brick++; } if (ret != 0) goto cleanup_inited_bricks; RESTORE_THIS(); return 0; cleanup_inited_bricks: gf_cleanup_connections(this); error_return: RESTORE_THIS(); return -1; } /** * @API * gf_changelog_register() * * This is _NOT_ a generic register API. It's a special API to handle * updates at a journal granulality. This is used by consumers wanting * to process persistent journal such as geo-replication via a set of * APIs. All of this is required to maintain backward compatibility. * Owner specific private data is stored in ->api (in gf_private_t), * which is used by APIs to access it's private data. This limits * the library access to a single brick, but that's how it used to * be anyway. Furthermore, this API solely _owns_ "this", therefore * callers already having a notion of "this" are expected to use the * newer API. * * Newer applications wanting to use this library need not face this * limitation and reply of the much more feature rich generic register * API, which is purely callback based. * * NOTE: @max_reconnects is not used but required for backward compat. * * For generic API, refer gf_changelog_register_generic(). */ int gf_changelog_register(char *brick_path, char *scratch_dir, char *log_file, int log_level, int max_reconnects) { struct gf_brick_spec brick = { 0, }; if (primary) THIS = primary; else return -1; brick.brick_path = brick_path; brick.filter = CHANGELOG_OP_TYPE_JOURNAL; brick.init = gf_changelog_journal_init; brick.fini = gf_changelog_journal_fini; brick.callback = gf_changelog_handle_journal; brick.connected = gf_changelog_journal_connect; brick.disconnected = gf_changelog_journal_disconnect; brick.ptr = scratch_dir; return gf_changelog_register_generic(&brick, 1, 1, log_file, log_level, NULL); } glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-changelog-reborp.c0000644000000000000000000000013214522202451027132 xustar000000000000000030 mtime=1699284265.658027405 30 atime=1699284265.657027402 30 ctime=1699284304.452144251 glusterfs-11.1/xlators/features/changelog/lib/src/gf-changelog-reborp.c0000664000175100017510000002724614522202451027424 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "changelog-misc.h" #include "changelog-mem-types.h" #include "gf-changelog-helpers.h" #include "changelog-rpc-common.h" #include "changelog-lib-messages.h" #include /** * Reverse socket: actual data transfer handler. Connection * initiator is PROBER, data transfer is REBORP. */ static struct rpcsvc_program *gf_changelog_reborp_programs[]; void * gf_changelog_connection_janitor(void *arg) { int32_t ret = 0; xlator_t *this = NULL; gf_private_t *priv = NULL; gf_changelog_t *entry = NULL; struct gf_event *event = NULL; struct gf_event_list *ev = NULL; unsigned long drained = 0; this = arg; THIS = this; priv = this->private; while (1) { pthread_mutex_lock(&priv->lock); { while (list_empty(&priv->cleanups)) pthread_cond_wait(&priv->cond, &priv->lock); entry = list_first_entry(&priv->cleanups, gf_changelog_t, list); list_del_init(&entry->list); } pthread_mutex_unlock(&priv->lock); drained = 0; ev = &entry->event; gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_LIB_MSG_CLEANING_BRICK_ENTRY_INFO, "brick=%s", entry->brick, NULL); /* 0x0: disable rpc-clnt */ rpc_clnt_disable(RPC_PROBER(entry)); /* 0x1: cleanup callback invoker thread */ ret = gf_cleanup_event(this, ev); if (ret) continue; /* 0x2: drain pending events */ while (!list_empty(&ev->events)) { event = list_first_entry(&ev->events, struct gf_event, list); gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_LIB_MSG_DRAINING_EVENT_INFO, "seq=%lu", event->seq, "payload=%d", event->count, NULL); GF_FREE(event); drained++; } gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_LIB_MSG_DRAINED_EVENT_INFO, "num=%lu", drained, NULL); /* 0x3: freeup brick entry */ gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_LIB_MSG_FREEING_ENTRY_INFO, "entry=%p", entry, NULL); LOCK_DESTROY(&entry->statelock); GF_FREE(entry); } return NULL; } int gf_changelog_reborp_rpcsvc_notify(rpcsvc_t *rpc, void *mydata, rpcsvc_event_t event, void *data) { int ret = 0; xlator_t *this = NULL; gf_changelog_t *entry = NULL; if (!(event == RPCSVC_EVENT_ACCEPT || event == RPCSVC_EVENT_DISCONNECT)) return 0; entry = mydata; this = entry->this; switch (event) { case RPCSVC_EVENT_ACCEPT: ret = sys_unlink(RPC_SOCK(entry)); if (ret != 0) gf_smsg(this->name, GF_LOG_WARNING, errno, CHANGELOG_LIB_MSG_UNLINK_FAILED, "name=reverse socket", "path=%s", RPC_SOCK(entry), NULL); if (entry->connected) GF_CHANGELOG_INVOKE_CBK(this, entry->connected, entry->brick, entry->ptr); break; case RPCSVC_EVENT_DISCONNECT: if (entry->disconnected) GF_CHANGELOG_INVOKE_CBK(this, entry->disconnected, entry->brick, entry->ptr); /* passthrough */ default: break; } return 0; } rpcsvc_t * gf_changelog_reborp_init_rpc_listner(xlator_t *this, char *path, char *sock, void *cbkdata) { CHANGELOG_MAKE_TMP_SOCKET_PATH(path, sock, UNIX_PATH_MAX); return changelog_rpc_server_init(this, sock, cbkdata, gf_changelog_reborp_rpcsvc_notify, gf_changelog_reborp_programs); } /** * This is dirty and painful as of now until there is event filtering in the * server. The entire event buffer is scanned and interested events are picked, * whereas we _should_ be notified with the events we were interested in * (selected at the time of probe). As of now this is complete BS and needs * fixture ASAP. I just made it work, it needs to be better. * * @FIXME: cleanup this bugger once server filters events. */ void gf_changelog_invoke_callback(gf_changelog_t *entry, struct iovec **vec, int payloadcnt) { int i = 0; int evsize = 0; xlator_t *this = NULL; changelog_event_t *event = NULL; this = entry->this; for (; i < payloadcnt; i++) { event = (changelog_event_t *)vec[i]->iov_base; evsize = vec[i]->iov_len / CHANGELOG_EV_SIZE; for (; evsize > 0; evsize--, event++) { if (gf_changelog_filter_check(entry, event)) { GF_CHANGELOG_INVOKE_CBK(this, entry->callback, entry->brick, entry->ptr, event); } } } } /** * Ordered event handler is self-adaptive.. if the event sequence number * is what's expected (->next_seq) there is no ordering list that's * maintained. On out-of-order event notifications, event buffers are * dynamically allocated and ordered. */ int __is_expected_sequence(struct gf_event_list *ev, struct gf_event *event) { return (ev->next_seq == event->seq); } int __can_process_event(struct gf_event_list *ev, struct gf_event **event) { *event = list_first_entry(&ev->events, struct gf_event, list); if (__is_expected_sequence(ev, *event)) { list_del(&(*event)->list); ev->next_seq++; return 1; } return 0; } void pick_event_ordered(struct gf_event_list *ev, struct gf_event **event) { pthread_mutex_lock(&ev->lock); { while (list_empty(&ev->events) || !__can_process_event(ev, event)) pthread_cond_wait(&ev->cond, &ev->lock); } pthread_mutex_unlock(&ev->lock); } void pick_event_unordered(struct gf_event_list *ev, struct gf_event **event) { pthread_mutex_lock(&ev->lock); { while (list_empty(&ev->events)) pthread_cond_wait(&ev->cond, &ev->lock); *event = list_first_entry(&ev->events, struct gf_event, list); list_del(&(*event)->list); } pthread_mutex_unlock(&ev->lock); } void * gf_changelog_callback_invoker(void *arg) { xlator_t *this = NULL; gf_changelog_t *entry = NULL; struct iovec *vec = NULL; struct gf_event *event = NULL; struct gf_event_list *ev = NULL; ev = arg; entry = ev->entry; THIS = this = entry->this; while (1) { entry->pickevent(ev, &event); vec = (struct iovec *)&event->iov; gf_changelog_invoke_callback(entry, &vec, event->count); GF_FREE(event); } return NULL; } static int orderfn(struct list_head *pos1, struct list_head *pos2) { struct gf_event *event1 = NULL; struct gf_event *event2 = NULL; event1 = list_entry(pos1, struct gf_event, list); event2 = list_entry(pos2, struct gf_event, list); if (event1->seq > event2->seq) return 1; return -1; } void queue_ordered_event(struct gf_event_list *ev, struct gf_event *event) { /* add event to the ordered event list and wake up listener(s) */ pthread_mutex_lock(&ev->lock); { list_add_order(&event->list, &ev->events, orderfn); if (!ev->next_seq) ev->next_seq = event->seq; if (ev->next_seq == event->seq) pthread_cond_signal(&ev->cond); } pthread_mutex_unlock(&ev->lock); } void queue_unordered_event(struct gf_event_list *ev, struct gf_event *event) { /* add event to the tail of the queue and wake up listener(s) */ pthread_mutex_lock(&ev->lock); { list_add_tail(&event->list, &ev->events); pthread_cond_signal(&ev->cond); } pthread_mutex_unlock(&ev->lock); } int gf_changelog_event_handler(rpcsvc_request_t *req, xlator_t *this, gf_changelog_t *entry) { int i = 0; size_t payloadlen = 0; ssize_t len = 0; int payloadcnt = 0; changelog_event_req rpc_req = { 0, }; changelog_event_rsp rpc_rsp = { 0, }; struct iovec *vec = NULL; struct gf_event *event = NULL; struct gf_event_list *ev = NULL; ev = &entry->event; len = xdr_to_generic(req->msg[0], &rpc_req, (xdrproc_t)xdr_changelog_event_req); if (len < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_XDR_DECODING_FAILED, "xdr decoding failed"); req->rpc_err = GARBAGE_ARGS; goto handle_xdr_error; } if (len < req->msg[0].iov_len) { payloadcnt = 1; payloadlen = (req->msg[0].iov_len - len); } for (i = 1; i < req->count; i++) { payloadcnt++; payloadlen += req->msg[i].iov_len; } event = GF_CALLOC(1, GF_EVENT_CALLOC_SIZE(payloadcnt, payloadlen), gf_changelog_mt_libgfchangelog_event_t); if (!event) goto handle_xdr_error; INIT_LIST_HEAD(&event->list); payloadlen = 0; event->seq = rpc_req.seq; event->count = payloadcnt; /* deep copy IO vectors */ vec = &event->iov[0]; GF_EVENT_ASSIGN_IOVEC(vec, event, (req->msg[0].iov_len - len), payloadlen); (void)memcpy(vec->iov_base, req->msg[0].iov_base + len, vec->iov_len); for (i = 1; i < req->count; i++) { vec = &event->iov[i]; GF_EVENT_ASSIGN_IOVEC(vec, event, req->msg[i].iov_len, payloadlen); (void)memcpy(event->iov[i].iov_base, req->msg[i].iov_base, req->msg[i].iov_len); } gf_msg_debug(this->name, 0, "seq: %" PRIu64 " [%s] (time: %" PRIu64 ".%" PRIu64 "), " "(vec: %d, len: %zd)", rpc_req.seq, entry->brick, rpc_req.tv_sec, rpc_req.tv_usec, payloadcnt, payloadlen); /* dispatch event */ entry->queueevent(ev, event); /* ack sequence number */ rpc_rsp.op_ret = 0; rpc_rsp.seq = rpc_req.seq; goto submit_rpc; handle_xdr_error: rpc_rsp.op_ret = -1; rpc_rsp.seq = 0; /* invalid */ submit_rpc: return changelog_rpc_sumbit_reply(req, &rpc_rsp, NULL, 0, NULL, (xdrproc_t)xdr_changelog_event_rsp); } int gf_changelog_reborp_handle_event(rpcsvc_request_t *req) { xlator_t *this = NULL; rpcsvc_t *svc = NULL; gf_changelog_t *entry = NULL; svc = rpcsvc_request_service(req); entry = svc->mydata; this = THIS = entry->this; return gf_changelog_event_handler(req, this, entry); } static rpcsvc_actor_t gf_changelog_reborp_actors[CHANGELOG_REV_PROC_MAX] = { [CHANGELOG_REV_PROC_EVENT] = {"CHANGELOG EVENT HANDLER", gf_changelog_reborp_handle_event, NULL, CHANGELOG_REV_PROC_EVENT, DRC_NA, 0}, }; /** * Do not use synctask as the RPC layer dereferences ->mydata as THIS. * In gf_changelog_setup_rpc(), @cbkdata is of type @gf_changelog_t, * and that's required to invoke the callback with the appropriate * brick path and it's private data. */ static struct rpcsvc_program gf_changelog_reborp_prog = { .progname = "LIBGFCHANGELOG REBORP", .prognum = CHANGELOG_REV_RPC_PROCNUM, .progver = CHANGELOG_REV_RPC_PROCVER, .numactors = CHANGELOG_REV_PROC_MAX, .actors = gf_changelog_reborp_actors, .synctask = _gf_false, }; static struct rpcsvc_program *gf_changelog_reborp_programs[] = { &gf_changelog_reborp_prog, NULL, }; glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-history-changelog.c0000644000000000000000000000013214522202451027342 xustar000000000000000030 mtime=1699284265.658027405 30 atime=1699284265.658027405 30 ctime=1699284304.448144239 glusterfs-11.1/xlators/features/changelog/lib/src/gf-history-changelog.c0000664000175100017510000006547614522202451027643 0ustar00jenkinsjenkins00000000000000#include #include #include #include #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include "gf-changelog-helpers.h" #include "gf-changelog-journal.h" /* from the changelog translator */ #include "changelog-misc.h" #include "changelog-lib-messages.h" #include "changelog-mem-types.h" /** * @API * gf_history_changelog_done: * Move processed history changelog file from .processing * to .processed * * ARGUMENTS: * file(IN): path to processed history changelog file in * .processing directory. * * RETURN VALUE: * 0: On success. * -1: On error. */ int gf_history_changelog_done(char *file) { int ret = -1; char *buffer = NULL; xlator_t *this = NULL; gf_changelog_journal_t *jnl = NULL; gf_changelog_journal_t *hist_jnl = NULL; char to_path[PATH_MAX] = { 0, }; errno = EINVAL; this = THIS; if (!this) goto out; jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) goto out; hist_jnl = jnl->hist_jnl; if (!hist_jnl) goto out; if (!file || !strlen(file)) goto out; /* make sure 'file' is inside ->jnl_working_dir */ buffer = realpath(file, NULL); if (!buffer) goto out; if (strncmp(hist_jnl->jnl_working_dir, buffer, strlen(hist_jnl->jnl_working_dir))) goto out; (void)snprintf(to_path, PATH_MAX, "%s%s", hist_jnl->jnl_processed_dir, basename(buffer)); gf_msg_debug(this->name, 0, "moving %s to processed directory", file); ret = sys_rename(buffer, to_path); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_RENAME_FAILED, "from=%s", file, "to=%s", to_path, NULL); goto out; } ret = 0; out: if (buffer) free(buffer); /* allocated by realpath() */ return ret; } /** * @API * gf_history_changelog_start_fresh: * For a set of changelogs, start from the beginning. * It will truncates the history tracker fd. * * RETURN VALUES: * 0: On success. * -1: On error. */ int gf_history_changelog_start_fresh(void) { xlator_t *this = NULL; gf_changelog_journal_t *jnl = NULL; gf_changelog_journal_t *hist_jnl = NULL; this = THIS; if (!this) goto out; errno = EINVAL; jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) goto out; hist_jnl = jnl->hist_jnl; if (!hist_jnl) goto out; if (gf_ftruncate(hist_jnl->jnl_fd, 0)) goto out; return 0; out: return -1; } /** * @API * gf_history_changelog_next_change: * Return the next history changelog file entry. Zero means all * history chanelogs are consumed. * * ARGUMENTS: * bufptr(OUT): Path to unprocessed history changelog file * from tracker file. * maxlen(IN): Usually PATH_MAX. * * RETURN VALUES: * size: On success. * -1 : On error. */ ssize_t gf_history_changelog_next_change(char *bufptr, size_t maxlen) { ssize_t size = -1; int tracker_fd = 0; xlator_t *this = NULL; gf_changelog_journal_t *jnl = NULL; gf_changelog_journal_t *hist_jnl = NULL; char buffer[PATH_MAX] = { 0, }; if (maxlen > PATH_MAX) { errno = ENAMETOOLONG; goto out; } errno = EINVAL; this = THIS; if (!this) goto out; jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) goto out; hist_jnl = jnl->hist_jnl; if (!hist_jnl) goto out; tracker_fd = hist_jnl->jnl_fd; size = gf_readline(tracker_fd, buffer, maxlen); if (size < 0) { size = -1; goto out; } if (size == 0) goto out; memcpy(bufptr, buffer, size - 1); bufptr[size - 1] = '\0'; out: return size; } /** * @API * gf_history_changelog_scan: * Scan and generate a list of change entries. * Calling this api multiple times (without calling gf_changlog_done()) * would result new changelogs(s) being refreshed in the tracker file. * This call also acts as a cancellation point for the consumer. * * RETURN VALUES: * +ve integer : success and keep scanning.(count of changelogs) * 0 : success and done scanning. * -1 : error. * * NOTE: After first 0 return call_get_next change for once more time * to empty the tracker * */ ssize_t gf_history_changelog_scan(void) { int tracker_fd = 0; size_t off = 0; xlator_t *this = NULL; size_t nr_entries = 0; gf_changelog_journal_t *jnl = NULL; gf_changelog_journal_t *hist_jnl = NULL; struct dirent *entry = NULL; struct dirent scratch[2] = { { 0, }, }; char buffer[PATH_MAX] = { 0, }; static int is_last_scan; this = THIS; if (!this) goto out; jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) goto out; if (JNL_IS_API_DISCONNECTED(jnl)) { errno = ENOTCONN; goto out; } hist_jnl = jnl->hist_jnl; if (!hist_jnl) goto out; retry: if (is_last_scan == 1) return 0; if (hist_jnl->hist_done == 0) is_last_scan = 1; errno = EINVAL; if (hist_jnl->hist_done == -1) goto out; tracker_fd = hist_jnl->jnl_fd; if (gf_ftruncate(tracker_fd, 0)) goto out; rewinddir(hist_jnl->jnl_dir); for (;;) { errno = 0; entry = sys_readdir(hist_jnl->jnl_dir, scratch); if (!entry || errno != 0) break; if (strcmp(basename(entry->d_name), ".") == 0 || strcmp(basename(entry->d_name), "..") == 0) continue; nr_entries++; GF_CHANGELOG_FILL_BUFFER(hist_jnl->jnl_processing_dir, buffer, off, strlen(hist_jnl->jnl_processing_dir)); GF_CHANGELOG_FILL_BUFFER(entry->d_name, buffer, off, strlen(entry->d_name)); GF_CHANGELOG_FILL_BUFFER("\n", buffer, off, 1); if (gf_changelog_write(tracker_fd, buffer, off) != off) { gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_WRITE_FAILED, "error writing changelog filename" " to tracker file"); break; } off = 0; } gf_msg_debug(this->name, 0, "hist_done %d, is_last_scan: %d", hist_jnl->hist_done, is_last_scan); if (!entry) { if (gf_lseek(tracker_fd, 0, SEEK_SET) != -1) { if (nr_entries > 0) return nr_entries; else { sleep(1); goto retry; } } } out: return -1; } /* * Gets timestamp value at the changelog path at index. * Returns 0 on success(updates given time-stamp), -1 on failure. */ int gf_history_get_timestamp(int fd, int index, int len, unsigned long *ts) { xlator_t *this = NULL; int n_read = -1; char path_buf[PATH_MAX] = { 0, }; char *iter = path_buf; size_t offset = index * (len + 1); unsigned long value = 0; int ret = 0; this = THIS; if (!this) { return -1; } n_read = sys_pread(fd, path_buf, len, offset); if (n_read < 0) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_READ_ERROR, "could not read from htime file"); goto out; } iter += len - TIMESTAMP_LENGTH; sscanf(iter, "%lu", &value); out: if (ret == 0) *ts = value; return ret; } /* * Function to ensure correctness of search * Checks whether @value is there next to @target_index or not */ int gf_history_check(int fd, int target_index, unsigned long value, int len) { int ret = 0; unsigned long ts1 = 0; unsigned long ts2 = 0; if (target_index == 0) { ret = gf_history_get_timestamp(fd, target_index, len, &ts1); if (ret == -1) goto out; if (value <= ts1) goto out; else { ret = -1; goto out; } } ret = gf_history_get_timestamp(fd, target_index, len, &ts1); if (ret == -1) goto out; ret = gf_history_get_timestamp(fd, target_index - 1, len, &ts2); if (ret == -1) goto out; if ((value <= ts1) && (value > ts2)) { goto out; } else ret = -1; out: return ret; } /* * This is a "binary search" based search function which checks neighbours * for in-range availability of the value to be searched and provides the * index at which the changelog file nearest to the requested timestamp(value) * can be read from. * * Actual offset can be calculated as (index* (len+1) ). * "1" is because the changelog paths are null terminated. * * @path : Htime file to search in * @value : time stamp to search * @from : start index to search * @to : end index to search * @len : length of fixes length strings separated by null */ int gf_history_b_search(int fd, unsigned long value, unsigned long from, unsigned long to, int len) { int m_index = -1; unsigned long cur_value = 0; unsigned long ts1 = 0; int ret = 0; m_index = (from + to) / 2; if ((to - from) <= 1) { /* either one or 2 changelogs left */ if (to != from) { /* check if value is less or greater than to * return accordingly */ ret = gf_history_get_timestamp(fd, from, len, &ts1); if (ret == -1) goto out; if (ts1 >= value) { /* actually compatision should be * exactly == but considering * * case of only 2 changelogs in htime file */ return from; } else return to; } else return to; } ret = gf_history_get_timestamp(fd, m_index, len, &cur_value); if (ret == -1) goto out; if (cur_value == value) { return m_index; } else if (cur_value == 0) { // 0 is returned if the timestamp isn't found in the htime file // In this case we need to search backward return gf_history_b_search(fd, value, from, m_index - 1, len); } else if (value > cur_value) { ret = gf_history_get_timestamp(fd, m_index + 1, len, &cur_value); if (ret == -1) goto out; if (value < cur_value) return m_index + 1; else return gf_history_b_search(fd, value, m_index + 1, to, len); } else { if (m_index == 0) { /* we are sure that values exists * in this htime file */ return 0; } else { ret = gf_history_get_timestamp(fd, m_index - 1, len, &cur_value); if (ret == -1) goto out; if (value > cur_value) { return m_index; } else return gf_history_b_search(fd, value, from, m_index - 1, len); } } out: return -1; } /* * Description: Checks if the changelog path is usable or not, * which is differentiated by checking for "changelog" * in the path and not "CHANGELOG". * * Returns: * 1 : Yes, usable ( contains "CHANGELOG" ) * 0 : No, Not usable ( contains, "changelog") */ int gf_is_changelog_usable(char *cl_path) { int ret = -1; const char low_c[] = "changelog"; char *str_ret = NULL; char *bname = NULL; bname = basename(cl_path); str_ret = strstr(bname, low_c); if (str_ret != NULL) ret = 0; else ret = 1; return ret; } void * gf_changelog_consume_wrap(void *data) { int ret = -1; ssize_t nread = 0; xlator_t *this = NULL; gf_changelog_consume_data_t *ccd = NULL; ccd = (gf_changelog_consume_data_t *)data; this = ccd->this; ccd->retval = -1; nread = sys_pread(ccd->fd, ccd->changelog, PATH_MAX - 1, ccd->offset); if (nread < 0) { gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_READ_ERROR, "cannot read from history metadata file"); goto out; } /* TODO: handle short reads and EOF. */ if (gf_is_changelog_usable(ccd->changelog) == 1) { ret = gf_changelog_consume(ccd->this, ccd->jnl, ccd->changelog, _gf_true); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_PARSE_ERROR, "name=%s", ccd->changelog, NULL); goto out; } } ccd->retval = 0; out: return NULL; } /** * "gf_history_consume" is a worker function for history. * parses and moves changelogs files from index "from" * to index "to" in open htime file whose fd is "fd". */ #define MAX_PARALLELS 10 void * gf_history_consume(void *data) { xlator_t *this = NULL; gf_changelog_journal_t *jnl = NULL; gf_changelog_journal_t *hist_jnl = NULL; int ret = 0; int iter = 0; int fd = -1; int from = -1; int to = -1; int len = -1; int n_parallel = 0; int n_envoked = 0; gf_boolean_t publish = _gf_true; pthread_t th_id[MAX_PARALLELS] = { 0, }; gf_changelog_history_data_t *hist_data = NULL; gf_changelog_consume_data_t ccd[MAX_PARALLELS] = { {0}, }; gf_changelog_consume_data_t *curr = NULL; hist_data = (gf_changelog_history_data_t *)data; if (hist_data == NULL) { ret = -1; goto out; } fd = hist_data->htime_fd; from = hist_data->from; to = hist_data->to; len = hist_data->len; n_parallel = hist_data->n_parallel; THIS = hist_data->this; this = hist_data->this; if (!this) { ret = -1; goto out; } jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) { ret = -1; goto out; } hist_jnl = jnl->hist_jnl; if (!hist_jnl) { ret = -1; goto out; } while (from <= to) { n_envoked = 0; for (iter = 0; (iter < n_parallel) && (from <= to); iter++) { curr = &ccd[iter]; curr->this = this; curr->jnl = hist_jnl; curr->fd = fd; curr->offset = from * (len + 1); curr->retval = 0; memset(curr->changelog, '\0', PATH_MAX); ret = gf_thread_create(&th_id[iter], NULL, gf_changelog_consume_wrap, curr, "clogc%03hx", (iter + 1) & 0x3ff); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ret, CHANGELOG_LIB_MSG_THREAD_CREATION_FAILED, "could not create consume-thread"); goto sync; } else n_envoked++; from++; } sync: for (iter = 0; iter < n_envoked; iter++) { ret = pthread_join(th_id[iter], NULL); if (ret) { publish = _gf_false; gf_msg(this->name, GF_LOG_ERROR, ret, CHANGELOG_LIB_MSG_PTHREAD_JOIN_FAILED, "pthread_join() error"); /* try to join the rest */ continue; } if (publish == _gf_false) continue; curr = &ccd[iter]; if (ccd->retval) { publish = _gf_false; gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_PARSE_ERROR_CEASED, NULL); continue; } ret = gf_changelog_publish(curr->this, curr->jnl, curr->changelog); if (ret) { publish = _gf_false; gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_PUBLISH_ERROR, "publish error, ceased publishing..."); } } } /* informing "parsing done". */ hist_jnl->hist_done = (publish == _gf_true) ? 0 : -1; out: if (fd != -1) (void)sys_close(fd); GF_FREE(hist_data); return NULL; } /** * @API * gf_history_changelog() : Get/parse historical changelogs and get them ready * for consumption. * * Arguments: * @changelog_dir : Directory location from where history changelogs are * supposed to be consumed. * @start: Unix timestamp FROM where changelogs should be consumed. * @end: Unix timestamp TO where changelogsshould be consumed. * @n_parallel : degree of parallelism while changelog parsing. * @actual_end : the end time till where changelogs are available. * * Return: * Returns on success, the last time till where changelogs are * available. * Returns -1 on failure(error). */ /** * Extract timestamp range from a historical metadata file * Returns: * 0 : Success ({min,max}_ts with the appropriate values) * -1 : Failure * -2 : Ignore this metadata file and process next */ int gf_changelog_extract_min_max(const char *dname, const char *htime_dir, int *fd, unsigned long *total, unsigned long *min_ts, unsigned long *max_ts) { int ret = -1; xlator_t *this = NULL; char htime_file[PATH_MAX] = { 0, }; struct stat stbuf = { 0, }; char *iter = NULL; char x_value[30] = { 0, }; this = THIS; snprintf(htime_file, PATH_MAX, "%s/%s", htime_dir, dname); iter = (htime_file + strlen(htime_file) - TIMESTAMP_LENGTH); sscanf(iter, "%lu", min_ts); ret = sys_stat(htime_file, &stbuf); if (ret) { ret = -1; gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_HTIME_ERROR, "op=stat", "path=%s", htime_file, NULL); goto out; } /* ignore everything except regular files */ if (!S_ISREG(stbuf.st_mode)) { ret = -2; goto out; } *fd = open(htime_file, O_RDONLY); if (*fd < 0) { ret = -1; gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_HTIME_ERROR, "op=open", "path=%s", htime_file, NULL); goto out; } /* Looks good, extract max timestamp */ ret = sys_fgetxattr(*fd, HTIME_KEY, x_value, sizeof(x_value)); if (ret < 0) { ret = -1; gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_GET_XATTR_FAILED, "path=%s", htime_file, NULL); goto out; } sscanf(x_value, "%lu:%lu", max_ts, total); gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_LIB_MSG_MIN_MAX_INFO, "min=%lu", *min_ts, "max=%lu", *max_ts, "total_changelogs=%lu", *total, NULL); ret = 0; out: return ret; } /* gf_history_changelog returns actual_end and spawns threads to * parse historical changelogs. The return values are as follows. * 0 : On success * 1 : Successful, but partial historical changelogs available, * end time falls into different htime file or future time * -2 : Error, requested historical changelog not available, not * even partial * -1 : On any error */ int gf_history_changelog(char *changelog_dir, unsigned long start, unsigned long end, int n_parallel, unsigned long *actual_end) { int ret = 0; int len = -1; int fd = -1; int n_read = -1; unsigned long min_ts = 0; unsigned long max_ts = 0; unsigned long end2 = 0; unsigned long ts1 = 0; unsigned long ts2 = 0; unsigned long to = 0; unsigned long from = 0; unsigned long total_changelog = 0; xlator_t *this = NULL; gf_changelog_journal_t *jnl = NULL; gf_changelog_journal_t *hist_jnl = NULL; gf_changelog_history_data_t *hist_data = NULL; DIR *dirp = NULL; struct dirent *entry = NULL; struct dirent scratch[2] = { { 0, }, }; pthread_t consume_th = 0; char htime_dir[PATH_MAX] = { 0, }; char buffer[PATH_MAX] = { 0, }; gf_boolean_t partial_history = _gf_false; pthread_attr_t attr; this = THIS; if (!this) { ret = -1; goto out; } ret = pthread_attr_init(&attr); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_PTHREAD_ERROR, "Pthread init failed"); return -1; } jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) { ret = -1; goto out; } hist_jnl = (gf_changelog_journal_t *)jnl->hist_jnl; if (!hist_jnl) { ret = -1; goto out; } gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_LIB_MSG_REQUESTING_INFO, "start=%lu", start, "end=%lu", end, NULL); /* basic sanity check */ if (start > end || n_parallel <= 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_HIST_FAILED, "start=%lu", start, "end=%lu", end, "thread_count=%d", n_parallel, NULL); ret = -1; goto out; } /* cap parallelism count */ if (n_parallel > MAX_PARALLELS) n_parallel = MAX_PARALLELS; CHANGELOG_FILL_HTIME_DIR(changelog_dir, htime_dir); dirp = sys_opendir(htime_dir); if (dirp == NULL) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_HTIME_ERROR, "op=opendir", "path=%s", htime_dir, NULL); ret = -1; goto out; } for (;;) { errno = 0; entry = sys_readdir(dirp, scratch); if (!entry || errno != 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_HIST_FAILED, "start=%lu", start, "end=%lu", end, NULL); ret = -2; break; } ret = gf_changelog_extract_min_max(entry->d_name, htime_dir, &fd, &total_changelog, &min_ts, &max_ts); if (ret) { if (-2 == ret) continue; goto out; } if (start >= min_ts && start < max_ts) { /** * TODO: handle short reads later... */ n_read = sys_read(fd, buffer, PATH_MAX - 1); if (n_read < 0) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_READ_ERROR, "unable to read htime file"); goto out; } buffer[n_read] = '\0'; len = strlen(buffer); /** * search @start in the htime file returning it's index * (@from) */ from = gf_history_b_search(fd, start, 0, total_changelog - 1, len); /* ensuring correctness of gf_b_search */ if (gf_history_check(fd, from, start, len) != 0) { ret = -1; gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_GET_TIME_ERROR, "for=start", "start=%lu", start, "idx=%lu", from, NULL); goto out; } end2 = (end <= max_ts) ? end : max_ts; /* Check if end falls out of same HTIME file. The end * falling to a different htime file or changelog * disable-enable is detected only after 20 seconds. * This is required because, applications generally * asks historical changelogs till current time and * it is possible changelog is not rolled over yet. * So, buffer time of default rollover time plus 5 * seconds is subtracted. If the application requests * the end time with in half a minute of changelog * disable, it's not detected as changelog disable and * it's application's responsibility to retry after * 20 seconds before confirming it as partial history. */ if ((end - 20) > max_ts) { partial_history = _gf_true; } /** * search @end2 in htime file returning it's index (@to) */ to = gf_history_b_search(fd, end2, 0, total_changelog - 1, len); if (gf_history_check(fd, to, end2, len) != 0) { ret = -1; gf_smsg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_GET_TIME_ERROR, "for=end", "start=%lu", end2, "idx=%lu", to, NULL); goto out; } ret = gf_history_get_timestamp(fd, from, len, &ts1); if (ret == -1) goto out; ret = gf_history_get_timestamp(fd, to, len, &ts2); if (ret == -1) goto out; gf_smsg(this->name, GF_LOG_INFO, 0, CHANGELOG_LIB_MSG_FINAL_INFO, "from=%lu", ts1, "to=%lu", ts2, "changes=%lu", (to - from + 1), NULL); hist_data = GF_CALLOC(1, sizeof(gf_changelog_history_data_t), gf_changelog_mt_history_data_t); hist_data->htime_fd = fd; hist_data->from = from; hist_data->to = to; hist_data->len = len; hist_data->n_parallel = n_parallel; hist_data->this = this; ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, ret, CHANGELOG_LIB_MSG_PTHREAD_ERROR, "unable to sets the detach" " state attribute"); ret = -1; goto out; } /* spawn a thread for background parsing & publishing */ ret = gf_thread_create(&consume_th, &attr, gf_history_consume, hist_data, "cloghcon"); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ret, CHANGELOG_LIB_MSG_THREAD_CREATION_FAILED, "creation of consume parent-thread" " failed."); ret = -1; goto out; } goto out; } else { /* end of range check */ gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_HIST_FAILED, "start=%lu", start, "end=%lu", end, "chlog_min=%lu", min_ts, "chlog_max=%lu", max_ts, NULL); } } /* end of readdir() */ out: if (dirp != NULL) (void)sys_closedir(dirp); if (ret < 0) { if (fd != -1) (void)sys_close(fd); GF_FREE(hist_data); (void)pthread_attr_destroy(&attr); return ret; } hist_jnl->hist_done = 1; *actual_end = ts2; if (partial_history) { ret = 1; } return ret; } glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-changelog-rpc.h0000644000000000000000000000013014522202451026430 xustar000000000000000030 mtime=1699284265.658027405 30 atime=1699284265.658027405 28 ctime=1699284304.4351442 glusterfs-11.1/xlators/features/changelog/lib/src/gf-changelog-rpc.h0000664000175100017510000000132514522202451026712 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __GF_CHANGELOG_RPC_H #define __GF_CHANGELOG_RPC_H #include "gf-changelog-helpers.h" #include "changelog-rpc-common.h" struct rpc_clnt * gf_changelog_rpc_init(xlator_t *, gf_changelog_t *); int gf_changelog_invoke_rpc(xlator_t *, gf_changelog_t *, int); rpcsvc_t * gf_changelog_reborp_init_rpc_listner(xlator_t *, char *, char *, void *); #endif glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-changelog-journal-handler.c0000644000000000000000000000013214522202451030726 xustar000000000000000030 mtime=1699284265.657027402 30 atime=1699284265.657027402 30 ctime=1699284304.443144224 glusterfs-11.1/xlators/features/changelog/lib/src/gf-changelog-journal-handler.c0000664000175100017510000007357714522202451031230 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include "gf-changelog-helpers.h" /* from the changelog translator */ #include "changelog-misc.h" #include "changelog-mem-types.h" #include "gf-changelog-journal.h" #include "changelog-lib-messages.h" extern int byebye; enum changelog_versions { VERSION_1_1 = 0, VERSION_1_2 = 1 }; /** * number of gfid records after fop number */ int nr_gfids[2][GF_FOP_MAXVALUE] = {{ [GF_FOP_MKNOD] = 1, [GF_FOP_MKDIR] = 1, [GF_FOP_UNLINK] = 1, [GF_FOP_RMDIR] = 1, [GF_FOP_SYMLINK] = 1, [GF_FOP_RENAME] = 2, [GF_FOP_LINK] = 1, [GF_FOP_CREATE] = 1, }, { [GF_FOP_MKNOD] = 1, [GF_FOP_MKDIR] = 1, [GF_FOP_UNLINK] = 2, [GF_FOP_RMDIR] = 2, [GF_FOP_SYMLINK] = 1, [GF_FOP_RENAME] = 2, [GF_FOP_LINK] = 1, [GF_FOP_CREATE] = 1, }}; int nr_extra_recs[2][GF_FOP_MAXVALUE] = {{ [GF_FOP_MKNOD] = 3, [GF_FOP_MKDIR] = 3, [GF_FOP_UNLINK] = 0, [GF_FOP_RMDIR] = 0, [GF_FOP_SYMLINK] = 0, [GF_FOP_RENAME] = 0, [GF_FOP_LINK] = 0, [GF_FOP_CREATE] = 3, }, { [GF_FOP_MKNOD] = 3, [GF_FOP_MKDIR] = 3, [GF_FOP_UNLINK] = 0, [GF_FOP_RMDIR] = 0, [GF_FOP_SYMLINK] = 0, [GF_FOP_RENAME] = 0, [GF_FOP_LINK] = 0, [GF_FOP_CREATE] = 3, }}; static char * binary_to_ascii(uuid_t uuid) { return uuid_utoa(uuid); } static char * conv_noop(char *ptr) { return ptr; } #define VERIFY_SEPARATOR(ptr, plen, perr) \ { \ if (*(ptr + plen) != '\0') { \ perr = 1; \ break; \ } \ } #define MOVER_MOVE(mover, nleft, bytes) \ { \ mover += bytes; \ nleft -= bytes; \ } #define PARSE_GFID(mov, ptr, le, fn, perr) \ { \ VERIFY_SEPARATOR(mov, le, perr); \ ptr = fn(mov); \ if (!ptr) { \ perr = 1; \ break; \ } \ } #define FILL_AND_MOVE(pt, buf, of, mo, nl, le) \ { \ GF_CHANGELOG_FILL_BUFFER(pt, buf, of, strlen(pt)); \ MOVER_MOVE(mo, nl, le); \ } #define PARSE_GFID_MOVE(ptr, uuid, mover, nleft, perr) \ { \ memcpy(uuid, mover, sizeof(uuid_t)); \ ptr = binary_to_ascii(uuid); \ if (!ptr) { \ perr = 1; \ break; \ } \ MOVER_MOVE(mover, nleft, sizeof(uuid_t)); \ } #define LINE_BUFSIZE (3 * PATH_MAX) /* enough buffer for extra chars too */ /** * using mmap() makes parsing easy. fgets() cannot be used here as * the binary gfid could contain a line-feed (0x0A), in that case fgets() * would read an incomplete line and parsing would fail. using POSIX fds * would result is additional code to maintain state in case of partial * reads of data (where multiple entries do not fit extirely in the buffer). * * mmap() gives the flexibility of pointing to an offset in the file * without us worrying about reading it in memory (VM does that for us for * free). */ static int gf_changelog_parse_binary(xlator_t *this, gf_changelog_journal_t *jnl, int from_fd, int to_fd, size_t start_offset, struct stat *stbuf, int version_idx) { int ret = -1; off_t off = 0; off_t nleft = 0; uuid_t uuid = { 0, }; char *ptr = NULL; char *bname_start = NULL; char *bname_end = NULL; char *mover = NULL; void *start = NULL; char current_mover = ' '; size_t blen = 0; int parse_err = 0; char *ascii = NULL; ascii = GF_CALLOC(LINE_BUFSIZE, sizeof(char), gf_common_mt_char); nleft = stbuf->st_size; start = mmap(NULL, nleft, PROT_READ, MAP_PRIVATE, from_fd, 0); if (start == MAP_FAILED) { gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_MMAP_FAILED, "mmap() error"); goto out; } mover = start; MOVER_MOVE(mover, nleft, start_offset); while (nleft > 0) { off = blen = 0; ptr = bname_start = bname_end = NULL; current_mover = *mover; switch (current_mover) { case 'D': case 'M': MOVER_MOVE(mover, nleft, 1); PARSE_GFID_MOVE(ptr, uuid, mover, nleft, parse_err); break; case 'E': MOVER_MOVE(mover, nleft, 1); PARSE_GFID_MOVE(ptr, uuid, mover, nleft, parse_err); bname_start = mover; bname_end = strchr(mover, '\n'); if (bname_end == NULL) { parse_err = 1; break; } blen = bname_end - bname_start; MOVER_MOVE(mover, nleft, blen); break; default: parse_err = 1; } if (parse_err) break; GF_CHANGELOG_FILL_BUFFER(¤t_mover, ascii, off, 1); GF_CHANGELOG_FILL_BUFFER(" ", ascii, off, 1); GF_CHANGELOG_FILL_BUFFER(ptr, ascii, off, strlen(ptr)); if (blen) GF_CHANGELOG_FILL_BUFFER(bname_start, ascii, off, blen); GF_CHANGELOG_FILL_BUFFER("\n", ascii, off, 1); if (gf_changelog_write(to_fd, ascii, off) != off) { gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_ASCII_ERROR, "processing binary changelog failed due to " " error in writing ascii change"); break; } MOVER_MOVE(mover, nleft, 1); } if ((nleft == 0) && (!parse_err)) ret = 0; if (munmap(start, stbuf->st_size)) gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_MUNMAP_FAILED, "munmap() error"); out: if (ascii) GF_FREE(ascii); return ret; } /** * ascii decoder: * - separate out one entry from another * - use fop name rather than fop number */ static int gf_changelog_parse_ascii(xlator_t *this, gf_changelog_journal_t *jnl, int from_fd, int to_fd, size_t start_offset, struct stat *stbuf, int version_idx) { int ng = 0; int ret = -1; int fop = 0; int len = 0; off_t off = 0; off_t nleft = 0; char *ptr = NULL; char *eptr = NULL; void *start = NULL; char *mover = NULL; int parse_err = 0; char current_mover = ' '; char *ascii = NULL; const char *fopname = NULL; ascii = GF_CALLOC(LINE_BUFSIZE, sizeof(char), gf_common_mt_char); nleft = stbuf->st_size; start = mmap(NULL, nleft, PROT_READ, MAP_PRIVATE, from_fd, 0); if (start == MAP_FAILED) { gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_MMAP_FAILED, "mmap() error"); goto out; } mover = start; MOVER_MOVE(mover, nleft, start_offset); while (nleft > 0) { off = 0; current_mover = *mover; GF_CHANGELOG_FILL_BUFFER(¤t_mover, ascii, off, 1); GF_CHANGELOG_FILL_BUFFER(" ", ascii, off, 1); switch (current_mover) { case 'D': MOVER_MOVE(mover, nleft, 1); /* target gfid */ PARSE_GFID(mover, ptr, UUID_CANONICAL_FORM_LEN, conv_noop, parse_err); FILL_AND_MOVE(ptr, ascii, off, mover, nleft, UUID_CANONICAL_FORM_LEN); break; case 'M': MOVER_MOVE(mover, nleft, 1); /* target gfid */ PARSE_GFID(mover, ptr, UUID_CANONICAL_FORM_LEN, conv_noop, parse_err); FILL_AND_MOVE(ptr, ascii, off, mover, nleft, UUID_CANONICAL_FORM_LEN); FILL_AND_MOVE(" ", ascii, off, mover, nleft, 1); /* fop */ len = strlen(mover); VERIFY_SEPARATOR(mover, len, parse_err); fop = atoi(mover); fopname = gf_fop_list[fop]; if (fopname == NULL) { parse_err = 1; break; } MOVER_MOVE(mover, nleft, len); len = strlen(fopname); GF_CHANGELOG_FILL_BUFFER(fopname, ascii, off, len); break; case 'E': MOVER_MOVE(mover, nleft, 1); /* target gfid */ PARSE_GFID(mover, ptr, UUID_CANONICAL_FORM_LEN, conv_noop, parse_err); FILL_AND_MOVE(ptr, ascii, off, mover, nleft, UUID_CANONICAL_FORM_LEN); FILL_AND_MOVE(" ", ascii, off, mover, nleft, 1); /* fop */ len = strlen(mover); VERIFY_SEPARATOR(mover, len, parse_err); fop = atoi(mover); fopname = gf_fop_list[fop]; if (fopname == NULL) { parse_err = 1; break; } MOVER_MOVE(mover, nleft, len); len = strlen(fopname); GF_CHANGELOG_FILL_BUFFER(fopname, ascii, off, len); ng = nr_extra_recs[version_idx][fop]; for (; ng > 0; ng--) { MOVER_MOVE(mover, nleft, 1); len = strlen(mover); VERIFY_SEPARATOR(mover, len, parse_err); GF_CHANGELOG_FILL_BUFFER(" ", ascii, off, 1); FILL_AND_MOVE(mover, ascii, off, mover, nleft, len); } /* pargfid + bname */ ng = nr_gfids[version_idx][fop]; while (ng-- > 0) { MOVER_MOVE(mover, nleft, 1); len = strlen(mover); if (!len) { MOVER_MOVE(mover, nleft, 1); continue; } GF_CHANGELOG_FILL_BUFFER(" ", ascii, off, 1); PARSE_GFID(mover, ptr, len, conv_noop, parse_err); eptr = calloc(3, strlen(ptr)); if (!eptr) { parse_err = 1; break; } gf_rfc3986_encode_space_newline((unsigned char *)ptr, eptr, jnl->rfc3986_space_newline); FILL_AND_MOVE(eptr, ascii, off, mover, nleft, len); free(eptr); } break; default: parse_err = 1; } if (parse_err) break; GF_CHANGELOG_FILL_BUFFER("\n", ascii, off, 1); if (gf_changelog_write(to_fd, ascii, off) != off) { gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_ASCII_ERROR, "processing ascii changelog failed due to " " error in writing change"); break; } MOVER_MOVE(mover, nleft, 1); } if ((nleft == 0) && (!parse_err)) ret = 0; if (munmap(start, stbuf->st_size)) gf_msg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_MUNMAP_FAILED, "munmap() error"); out: if (ascii) GF_FREE(ascii); return ret; } static int gf_changelog_decode(xlator_t *this, gf_changelog_journal_t *jnl, int from_fd, int to_fd, struct stat *stbuf, int *zerob) { int ret = -1; int encoding = -1; int major_version = -1; int minor_version = -1; int version_idx = -1; size_t elen = 0; char buffer[1024] = { 0, }; CHANGELOG_GET_HEADER_INFO(from_fd, buffer, sizeof(buffer), encoding, major_version, minor_version, elen); if (encoding == -1) /* unknown encoding */ goto out; if (major_version == -1) /* unknown major version */ goto out; if (minor_version == -1) /* unknown minor version */ goto out; if (!CHANGELOG_VALID_ENCODING(encoding)) goto out; if (elen == stbuf->st_size) { *zerob = 1; goto out; } if (major_version == 1 && minor_version == 1) { version_idx = VERSION_1_1; } else if (major_version == 1 && minor_version == 2) { version_idx = VERSION_1_2; } if (version_idx == -1) /* unknown version number */ goto out; /** * start processing after the header */ if (sys_lseek(from_fd, elen, SEEK_SET) < 0) { goto out; } switch (encoding) { case CHANGELOG_ENCODE_BINARY: /** * this ideally should have been a part of changelog-encoders.c * (ie. part of the changelog translator). */ ret = gf_changelog_parse_binary(this, jnl, from_fd, to_fd, elen, stbuf, version_idx); break; case CHANGELOG_ENCODE_ASCII: ret = gf_changelog_parse_ascii(this, jnl, from_fd, to_fd, elen, stbuf, version_idx); break; } out: return ret; } int gf_changelog_publish(xlator_t *this, gf_changelog_journal_t *jnl, char *from_path) { int ret = 0; char dest[PATH_MAX] = { 0, }; char to_path[PATH_MAX] = { 0, }; struct stat stbuf = { 0, }; if (snprintf(to_path, PATH_MAX, "%s%s", jnl->jnl_current_dir, basename(from_path)) >= PATH_MAX) return -1; /* handle zerob file that won't exist in current */ ret = sys_stat(to_path, &stbuf); if (ret) { if (errno == ENOENT) ret = 0; goto out; } if (snprintf(dest, PATH_MAX, "%s%s", jnl->jnl_processing_dir, basename(from_path)) >= PATH_MAX) return -1; ret = sys_rename(to_path, dest); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_RENAME_FAILED, "from=%s", to_path, "to=%s", dest, NULL); } out: return ret; } int gf_changelog_consume(xlator_t *this, gf_changelog_journal_t *jnl, char *from_path, gf_boolean_t no_publish) { int ret = -1; int fd1 = 0; int fd2 = 0; int zerob = 0; struct stat stbuf = { 0, }; char dest[PATH_MAX] = { 0, }; char to_path[PATH_MAX] = { 0, }; if (snprintf(to_path, PATH_MAX, "%s%s", jnl->jnl_current_dir, basename(from_path)) >= PATH_MAX) goto out; if (snprintf(dest, PATH_MAX, "%s%s", jnl->jnl_processing_dir, basename(from_path)) >= PATH_MAX) goto out; ret = sys_stat(from_path, &stbuf); if (ret || !S_ISREG(stbuf.st_mode)) { ret = -1; gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_STAT_FAILED, "path=%s", from_path, NULL); goto out; } fd1 = open(from_path, O_RDONLY); if (fd1 < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_OPEN_FAILED, "path=%s", from_path, NULL); goto out; } fd2 = open(to_path, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd2 < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_OPEN_FAILED, "path=%s", to_path, NULL); goto close_fd; } else { ret = gf_changelog_decode(this, jnl, fd1, fd2, &stbuf, &zerob); sys_close(fd2); if (!ret) { /* move it to processing on a successful decode */ if (no_publish == _gf_true) goto close_fd; ret = sys_rename(to_path, dest); if (ret) gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_RENAME_FAILED, "from=%s", to_path, "to=%s", dest, NULL); } /* remove it from .current if it's an empty file */ if (zerob) { /* zerob changelogs must be unlinked */ ret = sys_unlink(to_path); if (ret) gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_UNLINK_FAILED, "name=empty changelog", "path=%s", to_path, NULL); } } close_fd: sys_close(fd1); out: return ret; } void * gf_changelog_process(void *data) { xlator_t *this = NULL; gf_changelog_journal_t *jnl = NULL; gf_changelog_entry_t *entry = NULL; gf_changelog_processor_t *jnl_proc = NULL; jnl = data; jnl_proc = jnl->jnl_proc; THIS = jnl->this; this = jnl->this; while (1) { pthread_mutex_lock(&jnl_proc->lock); { while (list_empty(&jnl_proc->entries)) { jnl_proc->waiting = _gf_true; pthread_cond_wait(&jnl_proc->cond, &jnl_proc->lock); } entry = list_first_entry(&jnl_proc->entries, gf_changelog_entry_t, list); if (entry) list_del(&entry->list); jnl_proc->waiting = _gf_false; } pthread_mutex_unlock(&jnl_proc->lock); if (entry) { (void)gf_changelog_consume(this, jnl, entry->path, _gf_false); GF_FREE(entry); } } return NULL; } void gf_changelog_queue_journal(gf_changelog_processor_t *jnl_proc, changelog_event_t *event) { size_t len = 0; gf_changelog_entry_t *entry = NULL; entry = GF_CALLOC(1, sizeof(gf_changelog_entry_t), gf_changelog_mt_libgfchangelog_entry_t); if (!entry) return; INIT_LIST_HEAD(&entry->list); len = strlen(event->u.journal.path); (void)memcpy(entry->path, event->u.journal.path, len + 1); entry->path[len] = '\0'; pthread_mutex_lock(&jnl_proc->lock); { list_add_tail(&entry->list, &jnl_proc->entries); if (jnl_proc->waiting) pthread_cond_signal(&jnl_proc->cond); } pthread_mutex_unlock(&jnl_proc->lock); return; } void gf_changelog_handle_journal(void *xl, char *brick, void *cbkdata, changelog_event_t *event) { gf_changelog_journal_t *jnl = NULL; gf_changelog_processor_t *jnl_proc = NULL; jnl = cbkdata; jnl_proc = jnl->jnl_proc; gf_changelog_queue_journal(jnl_proc, event); } void gf_changelog_journal_disconnect(void *xl, char *brick, void *data) { gf_changelog_journal_t *jnl = NULL; jnl = data; pthread_spin_lock(&jnl->lock); { JNL_SET_API_STATE(jnl, JNL_API_DISCONNECTED); }; pthread_spin_unlock(&jnl->lock); } void gf_changelog_journal_connect(void *xl, char *brick, void *data) { gf_changelog_journal_t *jnl = NULL; jnl = data; pthread_spin_lock(&jnl->lock); { JNL_SET_API_STATE(jnl, JNL_API_CONNECTED); }; pthread_spin_unlock(&jnl->lock); return; } void gf_changelog_cleanup_processor(gf_changelog_journal_t *jnl) { int ret = 0; xlator_t *this = NULL; gf_changelog_processor_t *jnl_proc = NULL; this = THIS; if (!this || !jnl || !jnl->jnl_proc) goto error_return; jnl_proc = jnl->jnl_proc; ret = gf_thread_cleanup(this, jnl_proc->processor); if (ret != 0) { gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_CLEANUP_ERROR, "failed to cleanup processor thread"); goto error_return; } (void)pthread_mutex_destroy(&jnl_proc->lock); (void)pthread_cond_destroy(&jnl_proc->cond); GF_FREE(jnl_proc); error_return: return; } int gf_changelog_init_processor(gf_changelog_journal_t *jnl) { int ret = -1; gf_changelog_processor_t *jnl_proc = NULL; jnl_proc = GF_CALLOC(1, sizeof(gf_changelog_processor_t), gf_changelog_mt_libgfchangelog_t); if (!jnl_proc) goto error_return; ret = pthread_mutex_init(&jnl_proc->lock, NULL); if (ret != 0) goto free_jnl_proc; ret = pthread_cond_init(&jnl_proc->cond, NULL); if (ret != 0) goto cleanup_mutex; INIT_LIST_HEAD(&jnl_proc->entries); jnl_proc->waiting = _gf_false; jnl->jnl_proc = jnl_proc; ret = gf_thread_create(&jnl_proc->processor, NULL, gf_changelog_process, jnl, "clogproc"); if (ret != 0) { jnl->jnl_proc = NULL; goto cleanup_cond; } return 0; cleanup_cond: (void)pthread_cond_destroy(&jnl_proc->cond); cleanup_mutex: (void)pthread_mutex_destroy(&jnl_proc->lock); free_jnl_proc: GF_FREE(jnl_proc); error_return: return -1; } static void gf_changelog_cleanup_fds(gf_changelog_journal_t *jnl) { /* tracker fd */ if (jnl->jnl_fd != -1) sys_close(jnl->jnl_fd); /* processing dir */ if (jnl->jnl_dir) sys_closedir(jnl->jnl_dir); if (jnl->jnl_working_dir) free(jnl->jnl_working_dir); /* allocated by realpath */ } static int gf_changelog_open_dirs(xlator_t *this, gf_changelog_journal_t *jnl) { int ret = -1; DIR *dir = NULL; int tracker_fd = 0; char tracker_path[PATH_MAX] = { 0, }; /* .current */ (void)snprintf(jnl->jnl_current_dir, PATH_MAX, "%s/" GF_CHANGELOG_CURRENT_DIR "/", jnl->jnl_working_dir); ret = recursive_rmdir(jnl->jnl_current_dir); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_FAILED_TO_RMDIR, "path=%s", jnl->jnl_current_dir, NULL); goto out; } ret = mkdir_p(jnl->jnl_current_dir, 0600, _gf_false); if (ret) goto out; /* .processed */ (void)snprintf(jnl->jnl_processed_dir, PATH_MAX, "%s/" GF_CHANGELOG_PROCESSED_DIR "/", jnl->jnl_working_dir); ret = mkdir_p(jnl->jnl_processed_dir, 0600, _gf_false); if (ret) goto out; /* .processing */ (void)snprintf(jnl->jnl_processing_dir, PATH_MAX, "%s/" GF_CHANGELOG_PROCESSING_DIR "/", jnl->jnl_working_dir); ret = recursive_rmdir(jnl->jnl_processing_dir); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_FAILED_TO_RMDIR, "path=%s", jnl->jnl_processing_dir, NULL); goto out; } ret = mkdir_p(jnl->jnl_processing_dir, 0600, _gf_false); if (ret) goto out; dir = sys_opendir(jnl->jnl_processing_dir); if (!dir) { gf_msg("", GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_OPENDIR_ERROR, "opendir() error"); goto out; } jnl->jnl_dir = dir; (void)snprintf(tracker_path, PATH_MAX, "%s/" GF_CHANGELOG_TRACKER, jnl->jnl_working_dir); tracker_fd = open(tracker_path, O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (tracker_fd < 0) { sys_closedir(jnl->jnl_dir); ret = -1; goto out; } jnl->jnl_fd = tracker_fd; ret = 0; out: return ret; } int gf_changelog_init_history(xlator_t *this, gf_changelog_journal_t *jnl, char *brick_path) { int i = 0; int ret = 0; char hist_scratch_dir[PATH_MAX] = { 0, }; jnl->hist_jnl = GF_CALLOC(1, sizeof(*jnl), gf_changelog_mt_libgfchangelog_t); if (!jnl->hist_jnl) goto error_return; jnl->hist_jnl->jnl_dir = NULL; jnl->hist_jnl->jnl_fd = -1; (void)snprintf(hist_scratch_dir, PATH_MAX, "%s/" GF_CHANGELOG_HISTORY_DIR "/", jnl->jnl_working_dir); ret = mkdir_p(hist_scratch_dir, 0600, _gf_false); if (ret) goto dealloc_hist; jnl->hist_jnl->jnl_working_dir = realpath(hist_scratch_dir, NULL); if (!jnl->hist_jnl->jnl_working_dir) goto dealloc_hist; ret = gf_changelog_open_dirs(this, jnl->hist_jnl); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_OPENDIR_ERROR, "could not create entries in history scratch dir"); goto dealloc_hist; } if (snprintf(jnl->hist_jnl->jnl_brickpath, PATH_MAX, "%s", brick_path) >= PATH_MAX) goto dealloc_hist; for (i = 0; i < 256; i++) { jnl->hist_jnl->rfc3986_space_newline[i] = (i == ' ' || i == '\n' || i == '%') ? 0 : i; } return 0; dealloc_hist: GF_FREE(jnl->hist_jnl); jnl->hist_jnl = NULL; error_return: return -1; } void gf_changelog_journal_fini(void *xl, char *brick, void *data) { gf_changelog_journal_t *jnl = NULL; jnl = data; gf_changelog_cleanup_processor(jnl); gf_changelog_cleanup_fds(jnl); if (jnl->hist_jnl) gf_changelog_cleanup_fds(jnl->hist_jnl); GF_FREE(jnl); } void * gf_changelog_journal_init(void *xl, struct gf_brick_spec *brick) { int i = 0; int ret = 0; xlator_t *this = NULL; struct stat buf = { 0, }; char *scratch_dir = NULL; gf_changelog_journal_t *jnl = NULL; this = xl; scratch_dir = (char *)brick->ptr; jnl = GF_CALLOC(1, sizeof(gf_changelog_journal_t), gf_changelog_mt_libgfchangelog_t); if (!jnl) goto error_return; if (snprintf(jnl->jnl_brickpath, PATH_MAX, "%s", brick->brick_path) >= PATH_MAX) goto dealloc_private; if (sys_stat(scratch_dir, &buf) && errno == ENOENT) { ret = mkdir_p(scratch_dir, 0600, _gf_true); if (ret) goto dealloc_private; } jnl->jnl_working_dir = realpath(scratch_dir, NULL); if (!jnl->jnl_working_dir) goto dealloc_private; ret = gf_changelog_open_dirs(this, jnl); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_OPENDIR_ERROR, "could not create entries in scratch dir"); goto dealloc_private; } /* RFC 3986 {de,en}coding */ for (i = 0; i < 256; i++) { jnl->rfc3986_space_newline[i] = (i == ' ' || i == '\n' || i == '%') ? 0 : i; } ret = gf_changelog_init_history(this, jnl, brick->brick_path); if (ret) goto cleanup_fds; /* initialize journal processor */ jnl->this = this; ret = gf_changelog_init_processor(jnl); if (ret) goto cleanup_fds; JNL_SET_API_STATE(jnl, JNL_API_CONN_INPROGESS); ret = pthread_spin_init(&jnl->lock, 0); if (ret != 0) goto cleanup_processor; return jnl; cleanup_processor: gf_changelog_cleanup_processor(jnl); cleanup_fds: gf_changelog_cleanup_fds(jnl); if (jnl->hist_jnl) gf_changelog_cleanup_fds(jnl->hist_jnl); dealloc_private: GF_FREE(jnl); error_return: return NULL; } glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/changelog-lib-messages.h0000644000000000000000000000013214522202451027627 xustar000000000000000030 mtime=1699284265.656027399 30 atime=1699284265.656027399 30 ctime=1699284304.439144212 glusterfs-11.1/xlators/features/changelog/lib/src/changelog-lib-messages.h0000664000175100017510000000727314522202451030117 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CHANGELOG_LIB_MESSAGES_H_ #define _CHANGELOG_LIB_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID( CHANGELOG_LIB, CHANGELOG_LIB_MSG_OPEN_FAILED, CHANGELOG_LIB_MSG_FAILED_TO_RMDIR, CHANGELOG_LIB_MSG_SCRATCH_DIR_ENTRIES_CREATION_ERROR, CHANGELOG_LIB_MSG_THREAD_CREATION_FAILED, CHANGELOG_LIB_MSG_OPENDIR_ERROR, CHANGELOG_LIB_MSG_RENAME_FAILED, CHANGELOG_LIB_MSG_READ_ERROR, CHANGELOG_LIB_MSG_HTIME_ERROR, CHANGELOG_LIB_MSG_GET_TIME_ERROR, CHANGELOG_LIB_MSG_WRITE_FAILED, CHANGELOG_LIB_MSG_PTHREAD_ERROR, CHANGELOG_LIB_MSG_MMAP_FAILED, CHANGELOG_LIB_MSG_MUNMAP_FAILED, CHANGELOG_LIB_MSG_ASCII_ERROR, CHANGELOG_LIB_MSG_STAT_FAILED, CHANGELOG_LIB_MSG_GET_XATTR_FAILED, CHANGELOG_LIB_MSG_PUBLISH_ERROR, CHANGELOG_LIB_MSG_PARSE_ERROR, CHANGELOG_LIB_MSG_MIN_MAX_INFO, CHANGELOG_LIB_MSG_CLEANUP_ERROR, CHANGELOG_LIB_MSG_UNLINK_FAILED, CHANGELOG_LIB_MSG_NOTIFY_REGISTER_FAILED, CHANGELOG_LIB_MSG_INVOKE_RPC_FAILED, CHANGELOG_LIB_MSG_DRAINING_EVENT_INFO, CHANGELOG_LIB_MSG_CLEANING_BRICK_ENTRY_INFO, CHANGELOG_LIB_MSG_FREEING_ENTRY_INFO, CHANGELOG_LIB_MSG_XDR_DECODING_FAILED, CHANGELOG_LIB_MSG_NOTIFY_REGISTER_INFO, CHANGELOG_LIB_MSG_THREAD_CLEANUP_WARNING, CHANGELOG_LIB_MSG_COPY_FROM_BUFFER_FAILED, CHANGELOG_LIB_MSG_PTHREAD_JOIN_FAILED, CHANGELOG_LIB_MSG_HIST_FAILED, CHANGELOG_LIB_MSG_DRAINED_EVENT_INFO, CHANGELOG_LIB_MSG_PARSE_ERROR_CEASED, CHANGELOG_LIB_MSG_REQUESTING_INFO, CHANGELOG_LIB_MSG_FINAL_INFO); #define CHANGELOG_LIB_MSG_NOTIFY_REGISTER_INFO_STR "Registering brick" #define CHANGELOG_LIB_MSG_RENAME_FAILED_STR "error moving changelog file" #define CHANGELOG_LIB_MSG_OPEN_FAILED_STR "cannot open changelog file" #define CHANGELOG_LIB_MSG_UNLINK_FAILED_STR "failed to unlink" #define CHANGELOG_LIB_MSG_FAILED_TO_RMDIR_STR "failed to rmdir" #define CHANGELOG_LIB_MSG_STAT_FAILED_STR "stat failed on changelog file" #define CHANGELOG_LIB_MSG_PARSE_ERROR_STR "could not parse changelog" #define CHANGELOG_LIB_MSG_PARSE_ERROR_CEASED_STR \ "parsing error, ceased publishing..." #define CHANGELOG_LIB_MSG_HTIME_ERROR_STR "fop failed on htime file" #define CHANGELOG_LIB_MSG_GET_XATTR_FAILED_STR \ "error extracting max timstamp from htime file" #define CHANGELOG_LIB_MSG_MIN_MAX_INFO_STR "changelogs min max" #define CHANGELOG_LIB_MSG_REQUESTING_INFO_STR "Requesting historical changelogs" #define CHANGELOG_LIB_MSG_FINAL_INFO_STR "FINAL" #define CHANGELOG_LIB_MSG_HIST_FAILED_STR \ "Requested changelog range is not available" #define CHANGELOG_LIB_MSG_GET_TIME_ERROR_STR "wrong result" #define CHANGELOG_LIB_MSG_CLEANING_BRICK_ENTRY_INFO_STR \ "Cleaning brick entry for brick" #define CHANGELOG_LIB_MSG_DRAINING_EVENT_INFO_STR "Draining event" #define CHANGELOG_LIB_MSG_DRAINED_EVENT_INFO_STR "Drained event" #define CHANGELOG_LIB_MSG_FREEING_ENTRY_INFO_STR "freeing entry" #endif /* !_CHANGELOG_MESSAGES_H_ */ glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463025226 xustar000000000000000030 mtime=1699284275.579057287 30 atime=1699284290.214101368 30 ctime=1699284304.430144185 glusterfs-11.1/xlators/features/changelog/lib/src/Makefile.in0000664000175100017510000011020214522202463025501 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/changelog/lib/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgfchangelog_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la am_libgfchangelog_la_OBJECTS = libgfchangelog_la-gf-changelog.lo \ libgfchangelog_la-gf-changelog-journal-handler.lo \ libgfchangelog_la-gf-changelog-helpers.lo \ libgfchangelog_la-gf-changelog-api.lo \ libgfchangelog_la-gf-history-changelog.lo \ libgfchangelog_la-gf-changelog-rpc.lo \ libgfchangelog_la-gf-changelog-reborp.lo \ libgfchangelog_la-changelog-rpc-common.lo libgfchangelog_la_OBJECTS = $(am_libgfchangelog_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgfchangelog_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libgfchangelog_la_CFLAGS) $(CFLAGS) \ $(libgfchangelog_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgfchangelog_la_SOURCES) DIST_SOURCES = $(libgfchangelog_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ libgfchangelog_la_CFLAGS = -Wall $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \ -DDATADIR=\"$(localstatedir)\" libgfchangelog_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 -D__USE_LARGEFILE64 -fpic \ -I../../../src/ -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/features/changelog/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/rpc-transport/socket/src \ -DDATADIR=\"$(localstatedir)\" libgfchangelog_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la libgfchangelog_la_LDFLAGS = $(GF_LDFLAGS) \ -version-info $(LIBGFCHANGELOG_LT_VERSION) \ $(GF_NO_UNDEFINED) lib_LTLIBRARIES = libgfchangelog.la CONTRIB_BUILDDIR = $(top_builddir)/contrib libgfchangelog_la_SOURCES = gf-changelog.c gf-changelog-journal-handler.c \ gf-changelog-helpers.c gf-changelog-api.c gf-history-changelog.c \ gf-changelog-rpc.c gf-changelog-reborp.c \ $(top_srcdir)/xlators/features/changelog/src/changelog-rpc-common.c noinst_HEADERS = gf-changelog-helpers.h gf-changelog-rpc.h \ gf-changelog-journal.h changelog-lib-messages.h CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/changelog/lib/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/changelog/lib/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgfchangelog.la: $(libgfchangelog_la_OBJECTS) $(libgfchangelog_la_DEPENDENCIES) $(EXTRA_libgfchangelog_la_DEPENDENCIES) $(AM_V_CCLD)$(libgfchangelog_la_LINK) -rpath $(libdir) $(libgfchangelog_la_OBJECTS) $(libgfchangelog_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgfchangelog_la-changelog-rpc-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgfchangelog_la-gf-changelog-api.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgfchangelog_la-gf-changelog-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgfchangelog_la-gf-changelog-journal-handler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgfchangelog_la-gf-changelog-reborp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgfchangelog_la-gf-changelog-rpc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgfchangelog_la-gf-changelog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgfchangelog_la-gf-history-changelog.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libgfchangelog_la-gf-changelog.lo: gf-changelog.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -MT libgfchangelog_la-gf-changelog.lo -MD -MP -MF $(DEPDIR)/libgfchangelog_la-gf-changelog.Tpo -c -o libgfchangelog_la-gf-changelog.lo `test -f 'gf-changelog.c' || echo '$(srcdir)/'`gf-changelog.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgfchangelog_la-gf-changelog.Tpo $(DEPDIR)/libgfchangelog_la-gf-changelog.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gf-changelog.c' object='libgfchangelog_la-gf-changelog.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -c -o libgfchangelog_la-gf-changelog.lo `test -f 'gf-changelog.c' || echo '$(srcdir)/'`gf-changelog.c libgfchangelog_la-gf-changelog-journal-handler.lo: gf-changelog-journal-handler.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -MT libgfchangelog_la-gf-changelog-journal-handler.lo -MD -MP -MF $(DEPDIR)/libgfchangelog_la-gf-changelog-journal-handler.Tpo -c -o libgfchangelog_la-gf-changelog-journal-handler.lo `test -f 'gf-changelog-journal-handler.c' || echo '$(srcdir)/'`gf-changelog-journal-handler.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgfchangelog_la-gf-changelog-journal-handler.Tpo $(DEPDIR)/libgfchangelog_la-gf-changelog-journal-handler.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gf-changelog-journal-handler.c' object='libgfchangelog_la-gf-changelog-journal-handler.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -c -o libgfchangelog_la-gf-changelog-journal-handler.lo `test -f 'gf-changelog-journal-handler.c' || echo '$(srcdir)/'`gf-changelog-journal-handler.c libgfchangelog_la-gf-changelog-helpers.lo: gf-changelog-helpers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -MT libgfchangelog_la-gf-changelog-helpers.lo -MD -MP -MF $(DEPDIR)/libgfchangelog_la-gf-changelog-helpers.Tpo -c -o libgfchangelog_la-gf-changelog-helpers.lo `test -f 'gf-changelog-helpers.c' || echo '$(srcdir)/'`gf-changelog-helpers.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgfchangelog_la-gf-changelog-helpers.Tpo $(DEPDIR)/libgfchangelog_la-gf-changelog-helpers.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gf-changelog-helpers.c' object='libgfchangelog_la-gf-changelog-helpers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -c -o libgfchangelog_la-gf-changelog-helpers.lo `test -f 'gf-changelog-helpers.c' || echo '$(srcdir)/'`gf-changelog-helpers.c libgfchangelog_la-gf-changelog-api.lo: gf-changelog-api.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -MT libgfchangelog_la-gf-changelog-api.lo -MD -MP -MF $(DEPDIR)/libgfchangelog_la-gf-changelog-api.Tpo -c -o libgfchangelog_la-gf-changelog-api.lo `test -f 'gf-changelog-api.c' || echo '$(srcdir)/'`gf-changelog-api.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgfchangelog_la-gf-changelog-api.Tpo $(DEPDIR)/libgfchangelog_la-gf-changelog-api.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gf-changelog-api.c' object='libgfchangelog_la-gf-changelog-api.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -c -o libgfchangelog_la-gf-changelog-api.lo `test -f 'gf-changelog-api.c' || echo '$(srcdir)/'`gf-changelog-api.c libgfchangelog_la-gf-history-changelog.lo: gf-history-changelog.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -MT libgfchangelog_la-gf-history-changelog.lo -MD -MP -MF $(DEPDIR)/libgfchangelog_la-gf-history-changelog.Tpo -c -o libgfchangelog_la-gf-history-changelog.lo `test -f 'gf-history-changelog.c' || echo '$(srcdir)/'`gf-history-changelog.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgfchangelog_la-gf-history-changelog.Tpo $(DEPDIR)/libgfchangelog_la-gf-history-changelog.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gf-history-changelog.c' object='libgfchangelog_la-gf-history-changelog.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -c -o libgfchangelog_la-gf-history-changelog.lo `test -f 'gf-history-changelog.c' || echo '$(srcdir)/'`gf-history-changelog.c libgfchangelog_la-gf-changelog-rpc.lo: gf-changelog-rpc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -MT libgfchangelog_la-gf-changelog-rpc.lo -MD -MP -MF $(DEPDIR)/libgfchangelog_la-gf-changelog-rpc.Tpo -c -o libgfchangelog_la-gf-changelog-rpc.lo `test -f 'gf-changelog-rpc.c' || echo '$(srcdir)/'`gf-changelog-rpc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgfchangelog_la-gf-changelog-rpc.Tpo $(DEPDIR)/libgfchangelog_la-gf-changelog-rpc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gf-changelog-rpc.c' object='libgfchangelog_la-gf-changelog-rpc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -c -o libgfchangelog_la-gf-changelog-rpc.lo `test -f 'gf-changelog-rpc.c' || echo '$(srcdir)/'`gf-changelog-rpc.c libgfchangelog_la-gf-changelog-reborp.lo: gf-changelog-reborp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -MT libgfchangelog_la-gf-changelog-reborp.lo -MD -MP -MF $(DEPDIR)/libgfchangelog_la-gf-changelog-reborp.Tpo -c -o libgfchangelog_la-gf-changelog-reborp.lo `test -f 'gf-changelog-reborp.c' || echo '$(srcdir)/'`gf-changelog-reborp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgfchangelog_la-gf-changelog-reborp.Tpo $(DEPDIR)/libgfchangelog_la-gf-changelog-reborp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gf-changelog-reborp.c' object='libgfchangelog_la-gf-changelog-reborp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -c -o libgfchangelog_la-gf-changelog-reborp.lo `test -f 'gf-changelog-reborp.c' || echo '$(srcdir)/'`gf-changelog-reborp.c libgfchangelog_la-changelog-rpc-common.lo: $(top_srcdir)/xlators/features/changelog/src/changelog-rpc-common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -MT libgfchangelog_la-changelog-rpc-common.lo -MD -MP -MF $(DEPDIR)/libgfchangelog_la-changelog-rpc-common.Tpo -c -o libgfchangelog_la-changelog-rpc-common.lo `test -f '$(top_srcdir)/xlators/features/changelog/src/changelog-rpc-common.c' || echo '$(srcdir)/'`$(top_srcdir)/xlators/features/changelog/src/changelog-rpc-common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgfchangelog_la-changelog-rpc-common.Tpo $(DEPDIR)/libgfchangelog_la-changelog-rpc-common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/xlators/features/changelog/src/changelog-rpc-common.c' object='libgfchangelog_la-changelog-rpc-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgfchangelog_la_CPPFLAGS) $(CPPFLAGS) $(libgfchangelog_la_CFLAGS) $(CFLAGS) -c -o libgfchangelog_la-changelog-rpc-common.lo `test -f '$(top_srcdir)/xlators/features/changelog/src/changelog-rpc-common.c' || echo '$(srcdir)/'`$(top_srcdir)/xlators/features/changelog/src/changelog-rpc-common.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES $(top_builddir)/libglusterfs/src/libglusterfs.la: $(MAKE) -C $(top_builddir)/libglusterfs/src/ all # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451025212 xustar000000000000000030 mtime=1699284265.656027399 30 atime=1699284275.529057137 30 ctime=1699284304.432144191 glusterfs-11.1/xlators/features/changelog/lib/src/Makefile.am0000664000175100017510000000247714522202451025503 0ustar00jenkinsjenkins00000000000000libgfchangelog_la_CFLAGS = -Wall $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \ -DDATADIR=\"$(localstatedir)\" libgfchangelog_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 -D__USE_LARGEFILE64 -fpic \ -I../../../src/ -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/features/changelog/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src \ -I$(top_srcdir)/rpc/rpc-transport/socket/src \ -DDATADIR=\"$(localstatedir)\" libgfchangelog_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la libgfchangelog_la_LDFLAGS = $(GF_LDFLAGS) \ -version-info $(LIBGFCHANGELOG_LT_VERSION) \ $(GF_NO_UNDEFINED) lib_LTLIBRARIES = libgfchangelog.la CONTRIB_BUILDDIR = $(top_builddir)/contrib libgfchangelog_la_SOURCES = gf-changelog.c gf-changelog-journal-handler.c \ gf-changelog-helpers.c gf-changelog-api.c gf-history-changelog.c \ gf-changelog-rpc.c gf-changelog-reborp.c \ $(top_srcdir)/xlators/features/changelog/src/changelog-rpc-common.c noinst_HEADERS = gf-changelog-helpers.h gf-changelog-rpc.h \ gf-changelog-journal.h changelog-lib-messages.h CLEANFILES = $(top_builddir)/libglusterfs/src/libglusterfs.la: $(MAKE) -C $(top_builddir)/libglusterfs/src/ all glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-changelog-journal.h0000644000000000000000000000013214522202451027320 xustar000000000000000030 mtime=1699284265.657027402 30 atime=1699284265.657027402 30 ctime=1699284304.437144206 glusterfs-11.1/xlators/features/changelog/lib/src/gf-changelog-journal.h0000664000175100017510000000527614522202451027611 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __GF_CHANGELOG_JOURNAL_H #define __GF_CHANGELOG_JOURNAL_H #include #include enum api_conn { JNL_API_CONNECTED, JNL_API_CONN_INPROGESS, JNL_API_DISCONNECTED, }; typedef struct gf_changelog_entry { char path[PATH_MAX]; struct list_head list; } gf_changelog_entry_t; typedef struct gf_changelog_processor { pthread_mutex_t lock; /* protects ->entries */ pthread_cond_t cond; /* waiter during empty list */ gf_boolean_t waiting; pthread_t processor; /* thread-id of journal processing thread */ struct list_head entries; } gf_changelog_processor_t; typedef struct gf_changelog_journal { DIR *jnl_dir; /* 'processing' directory stream */ int jnl_fd; /* fd to the tracker file */ char jnl_brickpath[PATH_MAX]; /* brick path for this end-point */ gf_changelog_processor_t *jnl_proc; char *jnl_working_dir; /* scratch directory */ char jnl_current_dir[PATH_MAX]; char jnl_processed_dir[PATH_MAX]; char jnl_processing_dir[PATH_MAX]; char rfc3986_space_newline[256]; /* RFC 3986 string encoding */ struct gf_changelog_journal *hist_jnl; int hist_done; /* holds 0 done scanning, 1 keep scanning and -1 error */ pthread_spinlock_t lock; int connected; xlator_t *this; } gf_changelog_journal_t; #define JNL_SET_API_STATE(jnl, state) (jnl->connected = state) #define JNL_IS_API_DISCONNECTED(jnl) (jnl->connected == JNL_API_DISCONNECTED) /* History API */ typedef struct gf_changelog_history_data { int len; int htime_fd; /* parallelism count */ int n_parallel; /* history from, to indexes */ unsigned long from; unsigned long to; xlator_t *this; } gf_changelog_history_data_t; typedef struct gf_changelog_consume_data { /** set of inputs */ /* fd to read from */ int fd; /* from @offset */ off_t offset; xlator_t *this; gf_changelog_journal_t *jnl; /** set of outputs */ /* return value */ int retval; /* journal processed */ char changelog[PATH_MAX]; } gf_changelog_consume_data_t; /* event handler */ CALLBACK gf_changelog_handle_journal; /* init, connect & disconnect handler */ INIT gf_changelog_journal_init; FINI gf_changelog_journal_fini; CONNECT gf_changelog_journal_connect; DISCONNECT gf_changelog_journal_disconnect; #endif glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-changelog-helpers.h0000644000000000000000000000013214522202451027310 xustar000000000000000030 mtime=1699284265.657027402 30 atime=1699284265.657027402 30 ctime=1699284304.434144197 glusterfs-11.1/xlators/features/changelog/lib/src/gf-changelog-helpers.h0000664000175100017510000002015714522202451027574 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GF_CHANGELOG_HELPERS_H #define _GF_CHANGELOG_HELPERS_H #include #include #include #include #include "changelog.h" #include "changelog-rpc-common.h" #include "gf-changelog-journal.h" #define GF_CHANGELOG_TRACKER "tracker" #define GF_CHANGELOG_CURRENT_DIR ".current" #define GF_CHANGELOG_PROCESSED_DIR ".processed" #define GF_CHANGELOG_PROCESSING_DIR ".processing" #define GF_CHANGELOG_HISTORY_DIR ".history" #define TIMESTAMP_LENGTH 10 #ifndef MAXLINE #define MAXLINE 4096 #endif #define GF_CHANGELOG_FILL_BUFFER(ptr, ascii, off, len) \ do { \ memcpy(ascii + off, ptr, len); \ off += len; \ } while (0) typedef struct read_line { int rl_cnt; char *rl_bufptr; char rl_buf[MAXLINE]; } read_line_t; struct gf_changelog; struct gf_event; /** * Event list for ordered event notification * * ->next_seq holds the next _expected_ sequence number. */ struct gf_event_list { pthread_mutex_t lock; /* protects this structure */ pthread_cond_t cond; pthread_t invoker; unsigned long next_seq; /* next sequence number expected: zero during bootstrap */ struct gf_changelog *entry; /* backpointer to it's brick encapsulator (entry) */ struct list_head events; /* list of events */ }; /** * include a refcount if it's of use by additional layers */ struct gf_event { int count; unsigned long seq; struct list_head list; struct iovec iov[]; }; #define GF_EVENT_CALLOC_SIZE(cnt, len) \ (sizeof(struct gf_event) + (cnt * sizeof(struct iovec)) + len) /** * assign the base address of the IO vector to the correct memory o * area and set it's addressable length. */ #define GF_EVENT_ASSIGN_IOVEC(vec, event, len, pos) \ do { \ vec->iov_base = ((char *)event) + sizeof(struct gf_event) + \ (event->count * sizeof(struct iovec)) + pos; \ vec->iov_len = len; \ pos += len; \ } while (0) typedef enum gf_changelog_conn_state { GF_CHANGELOG_CONN_STATE_PENDING = 0, GF_CHANGELOG_CONN_STATE_ACCEPTED, GF_CHANGELOG_CONN_STATE_DISCONNECTED, } gf_changelog_conn_state_t; /** * An instance of this structure is allocated for each brick for which * notifications are streamed. */ typedef struct gf_changelog { gf_lock_t statelock; gf_changelog_conn_state_t connstate; xlator_t *this; struct list_head list; /* list of instances */ char brick[PATH_MAX]; /* brick path for this end-point */ changelog_rpc_t grpc; /* rpc{-clnt,svc} for this brick */ #define RPC_PROBER(ent) ent->grpc.rpc #define RPC_REBORP(ent) ent->grpc.svc #define RPC_SOCK(ent) ent->grpc.sock unsigned int notify; /* notification flag(s) */ FINI *fini; /* destructor callback */ CALLBACK *callback; /* event callback dispatcher */ CONNECT *connected; /* connect callback */ DISCONNECT *disconnected; /* disconnection callback */ void *ptr; /* owner specific private data */ xlator_t *invokerxl; /* consumers _this_, if valid, assigned to THIS before cbk is invoked */ gf_boolean_t ordered; void (*queueevent)(struct gf_event_list *, struct gf_event *); void (*pickevent)(struct gf_event_list *, struct gf_event **); struct gf_event_list event; } gf_changelog_t; static inline int gf_changelog_filter_check(gf_changelog_t *entry, changelog_event_t *event) { if (event->ev_type & entry->notify) return 1; return 0; } #define GF_NEED_ORDERED_EVENTS(ent) (ent->ordered == _gf_true) /** private structure */ typedef struct gf_private { pthread_mutex_t lock; /* protects ->connections, cleanups */ pthread_cond_t cond; void *api; /* pointer for API access */ pthread_t poller; /* event poller thread */ pthread_t connectionjanitor; /* connection cleaner */ struct list_head connections; /* list of connections */ struct list_head cleanups; /* list of connection to be cleaned up */ } gf_private_t; #define GF_CHANGELOG_GET_API_PTR(this) (((gf_private_t *)this->private)->api) /** * upcall: invoke callback with _correct_ THIS */ #define GF_CHANGELOG_INVOKE_CBK(this, cbk, brick, args...) \ do { \ xlator_t *old_this = NULL; \ xlator_t *invokerxl = NULL; \ \ invokerxl = entry->invokerxl; \ old_this = this; \ \ if (invokerxl) { \ THIS = invokerxl; \ } \ \ cbk(invokerxl, brick, args); \ THIS = old_this; \ \ } while (0) #define SAVE_THIS(xl) \ do { \ old_this = xl; \ THIS = primary; \ } while (0) #define RESTORE_THIS() \ do { \ if (old_this) \ THIS = old_this; \ } while (0) /** APIs and the rest */ void * gf_changelog_process(void *data); void gf_rfc3986_encode_space_newline(unsigned char *s, char *enc, char *estr); size_t gf_changelog_write(int fd, char *buffer, size_t len); ssize_t gf_readline(int fd, void *vptr, size_t maxlen); int gf_ftruncate(int fd, off_t length); off_t gf_lseek(int fd, off_t offset, int whence); int gf_changelog_consume(xlator_t *this, gf_changelog_journal_t *jnl, char *from_path, gf_boolean_t no_publish); int gf_changelog_publish(xlator_t *this, gf_changelog_journal_t *jnl, char *from_path); int gf_thread_cleanup(xlator_t *this, pthread_t thread); void * gf_changelog_callback_invoker(void *arg); int gf_cleanup_event(xlator_t *, struct gf_event_list *); /* (un)ordered event queueing */ void queue_ordered_event(struct gf_event_list *, struct gf_event *); void queue_unordered_event(struct gf_event_list *, struct gf_event *); /* (un)ordered event picking */ void pick_event_ordered(struct gf_event_list *, struct gf_event **); void pick_event_unordered(struct gf_event_list *, struct gf_event **); /* connection janitor thread */ void * gf_changelog_connection_janitor(void *); #endif glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-changelog-rpc.c0000644000000000000000000000013214522202451026425 xustar000000000000000030 mtime=1699284265.658027405 30 atime=1699284265.658027405 30 ctime=1699284304.450144246 glusterfs-11.1/xlators/features/changelog/lib/src/gf-changelog-rpc.c0000664000175100017510000000514214522202451026706 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "gf-changelog-rpc.h" #include "changelog-misc.h" #include "changelog-mem-types.h" struct rpc_clnt_program gf_changelog_clnt; /* TODO: piggyback reconnect to called (upcall) */ int gf_changelog_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, void *data) { switch (event) { case RPC_CLNT_CONNECT: break; case RPC_CLNT_DISCONNECT: case RPC_CLNT_MSG: case RPC_CLNT_DESTROY: case RPC_CLNT_PING: break; } return 0; } struct rpc_clnt * gf_changelog_rpc_init(xlator_t *this, gf_changelog_t *entry) { char sockfile[UNIX_PATH_MAX] = { 0, }; CHANGELOG_MAKE_SOCKET_PATH(entry->brick, sockfile, UNIX_PATH_MAX); return changelog_rpc_client_init(this, entry, sockfile, gf_changelog_rpc_notify); } /** * remote procedure calls declarations. */ int gf_probe_changelog_cbk(struct rpc_req *req, struct iovec *iovec, int count, void *myframe) { return 0; } int gf_probe_changelog_filter(call_frame_t *frame, xlator_t *this, void *data) { char *sock = NULL; gf_changelog_t *entry = NULL; changelog_probe_req req = { 0, }; entry = data; sock = RPC_SOCK(entry); (void)memcpy(&req.sock, sock, strlen(sock)); req.filter = entry->notify; /* invoke RPC */ return changelog_rpc_sumbit_req( RPC_PROBER(entry), (void *)&req, frame, &gf_changelog_clnt, CHANGELOG_RPC_PROBE_FILTER, NULL, 0, NULL, this, gf_probe_changelog_cbk, (xdrproc_t)xdr_changelog_probe_req); } int gf_changelog_invoke_rpc(xlator_t *this, gf_changelog_t *entry, int procidx) { return changelog_invoke_rpc(this, RPC_PROBER(entry), &gf_changelog_clnt, procidx, entry); } struct rpc_clnt_procedure gf_changelog_procs[CHANGELOG_RPC_PROC_MAX] = { [CHANGELOG_RPC_PROC_NULL] = {"NULL", NULL}, [CHANGELOG_RPC_PROBE_FILTER] = {"PROBE FILTER", gf_probe_changelog_filter}, }; struct rpc_clnt_program gf_changelog_clnt = { .progname = "LIBGFCHANGELOG", .prognum = CHANGELOG_RPC_PROGNUM, .progver = CHANGELOG_RPC_PROGVER, .numproc = CHANGELOG_RPC_PROC_MAX, .proctable = gf_changelog_procs, }; glusterfs-11.1/xlators/features/changelog/lib/src/PaxHeaders.9031/gf-changelog-api.c0000644000000000000000000000013214522202451026412 xustar000000000000000030 mtime=1699284265.656027399 30 atime=1699284265.656027399 30 ctime=1699284304.447144236 glusterfs-11.1/xlators/features/changelog/lib/src/gf-changelog-api.c0000664000175100017510000001167214522202451026700 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include "gf-changelog-helpers.h" #include "gf-changelog-journal.h" #include "changelog-mem-types.h" #include "changelog-lib-messages.h" int gf_changelog_done(char *file) { int ret = -1; char *buffer = NULL; xlator_t *this = NULL; gf_changelog_journal_t *jnl = NULL; char to_path[PATH_MAX] = { 0, }; errno = EINVAL; this = THIS; if (!this) goto out; jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) goto out; if (!file || !strlen(file)) goto out; /* make sure 'file' is inside ->jnl_working_dir */ buffer = realpath(file, NULL); if (!buffer) goto out; if (strncmp(jnl->jnl_working_dir, buffer, strlen(jnl->jnl_working_dir))) goto out; (void)snprintf(to_path, PATH_MAX, "%s%s", jnl->jnl_processed_dir, basename(buffer)); gf_msg_debug(this->name, 0, "moving %s to processed directory", file); ret = sys_rename(buffer, to_path); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, CHANGELOG_LIB_MSG_RENAME_FAILED, "from=%s", file, "to=%s", to_path, NULL); goto out; } ret = 0; out: if (buffer) free(buffer); /* allocated by realpath() */ return ret; } /** * @API * for a set of changelogs, start from the beginning */ int gf_changelog_start_fresh(void) { xlator_t *this = NULL; gf_changelog_journal_t *jnl = NULL; this = THIS; if (!this) goto out; errno = EINVAL; jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) goto out; if (gf_ftruncate(jnl->jnl_fd, 0)) goto out; return 0; out: return -1; } /** * @API * return the next changelog file entry. zero means all chanelogs * consumed. */ ssize_t gf_changelog_next_change(char *bufptr, size_t maxlen) { ssize_t size = -1; int tracker_fd = 0; xlator_t *this = NULL; gf_changelog_journal_t *jnl = NULL; char buffer[PATH_MAX] = { 0, }; errno = EINVAL; this = THIS; if (!this) goto out; jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) goto out; tracker_fd = jnl->jnl_fd; size = gf_readline(tracker_fd, buffer, maxlen); if (size < 0) { size = -1; goto out; } if (size == 0) goto out; memcpy(bufptr, buffer, size - 1); bufptr[size - 1] = '\0'; out: return size; } /** * @API * gf_changelog_scan() - scan and generate a list of change entries * * calling this api multiple times (without calling gf_changlog_done()) * would result new changelogs(s) being refreshed in the tracker file. * This call also acts as a cancellation point for the consumer. */ ssize_t gf_changelog_scan(void) { int tracker_fd = 0; size_t off = 0; xlator_t *this = NULL; size_t nr_entries = 0; gf_changelog_journal_t *jnl = NULL; struct dirent *entry = NULL; struct dirent scratch[2] = { { 0, }, }; char buffer[PATH_MAX] = { 0, }; this = THIS; if (!this) goto out; jnl = (gf_changelog_journal_t *)GF_CHANGELOG_GET_API_PTR(this); if (!jnl) goto out; if (JNL_IS_API_DISCONNECTED(jnl)) { errno = ENOTCONN; goto out; } errno = EINVAL; tracker_fd = jnl->jnl_fd; if (gf_ftruncate(tracker_fd, 0)) goto out; rewinddir(jnl->jnl_dir); for (;;) { errno = 0; entry = sys_readdir(jnl->jnl_dir, scratch); if (!entry || errno != 0) break; if (!strcmp(basename(entry->d_name), ".") || !strcmp(basename(entry->d_name), "..")) continue; nr_entries++; GF_CHANGELOG_FILL_BUFFER(jnl->jnl_processing_dir, buffer, off, strlen(jnl->jnl_processing_dir)); GF_CHANGELOG_FILL_BUFFER(entry->d_name, buffer, off, strlen(entry->d_name)); GF_CHANGELOG_FILL_BUFFER("\n", buffer, off, 1); if (gf_changelog_write(tracker_fd, buffer, off) != off) { gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_WRITE_FAILED, "error writing changelog filename" " to tracker file"); break; } off = 0; } if (!entry) { if (gf_lseek(tracker_fd, 0, SEEK_SET) != -1) return nr_entries; } out: return -1; } glusterfs-11.1/xlators/features/changelog/lib/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463024437 xustar000000000000000030 mtime=1699284275.518057104 30 atime=1699284290.194101308 30 ctime=1699284304.381144038 glusterfs-11.1/xlators/features/changelog/lib/Makefile.in0000664000175100017510000005275114522202463024730 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/changelog/lib DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/changelog/lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/changelog/lib/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/changelog/lib/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024423 xustar000000000000000030 mtime=1699284265.655027396 30 atime=1699284275.494057031 30 ctime=1699284304.383144044 glusterfs-11.1/xlators/features/changelog/lib/Makefile.am0000664000175100017510000000003414522202451024677 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/compress0000644000000000000000000000013214522202520021445 xustar000000000000000030 mtime=1699284304.175143417 30 atime=1699284309.687160019 30 ctime=1699284304.175143417 glusterfs-11.1/xlators/features/compress/0002775000175100017510000000000014522202520022003 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/compress/PaxHeaders.9031/src0000644000000000000000000000013214522202520022234 xustar000000000000000030 mtime=1699284304.225143568 30 atime=1699284309.687160019 30 ctime=1699284304.225143568 glusterfs-11.1/xlators/features/compress/src/0002775000175100017510000000000014522202520022572 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/compress/src/PaxHeaders.9031/cdc-mem-types.h0000644000000000000000000000013214522202451025134 xustar000000000000000030 mtime=1699284265.667027432 30 atime=1699284265.667027432 30 ctime=1699284304.221143556 glusterfs-11.1/xlators/features/compress/src/cdc-mem-types.h0000664000175100017510000000124114522202451025411 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __CDC_MEM_TYPES_H #define __CDC_MEM_TYPES_H #include enum gf_cdc_mem_types { gf_cdc_mt_priv_t = gf_common_mt_end + 1, gf_cdc_mt_vec_t = gf_common_mt_end + 2, gf_cdc_mt_gzip_trailer_t = gf_common_mt_end + 3, gf_cdc_mt_end = gf_common_mt_end + 4, }; #endif glusterfs-11.1/xlators/features/compress/src/PaxHeaders.9031/cdc.h0000644000000000000000000000013214522202451023216 xustar000000000000000030 mtime=1699284265.667027432 30 atime=1699284265.667027432 30 ctime=1699284304.220143553 glusterfs-11.1/xlators/features/compress/src/cdc.h0000664000175100017510000000413114522202451023474 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __CDC_H #define __CDC_H #include #include typedef struct cdc_priv { int window_size; int mem_level; int cdc_level; int min_file_size; int op_mode; gf_boolean_t debug; } cdc_priv_t; typedef struct cdc_info { /* input bits */ int count; int32_t ibytes; struct iovec *vector; struct iatt *buf; /* output bits */ int ncount; int nbytes; int buffer_size; struct iovec vec[MAX_IOVEC]; struct iobref *iobref; /* zlib bits */ z_stream stream; unsigned long crc; } cdc_info_t; #define CURR_VEC(ci) ci->vec[ci->ncount - 1] #define THIS_VEC(ci, i) ci->vector[i] /* Gzip defaults */ #define GF_CDC_DEF_WINDOWSIZE -15 /* default value */ #define GF_CDC_MAX_WINDOWSIZE -8 /* max value */ #define GF_CDC_DEF_MEMLEVEL 8 #define GF_CDC_DEF_BUFFERSIZE \ 1024 * 128 // 128K - default compression buffer size /* Operation mode * If xlator is loaded on client, readv decompresses and writev compresses * If xlator is loaded on server, readv compresses and writev decompresses */ #define GF_CDC_MODE_CLIENT 0 #define GF_CDC_MODE_SERVER 1 /* min size of data to do cmpression * 0 == compress even 1byte */ #define GF_CDC_MIN_CHUNK_SIZE 0 #define GF_CDC_VALIDATION_SIZE 8 #define GF_CDC_OS_ID 0xFF #define GF_CDC_DEFLATE_CANARY_VAL "deflate" #define GF_CDC_DEBUG_DUMP_FILE "/tmp/cdcdump.gz" #define GF_CDC_MODE_IS_CLIENT(m) (strcmp(m, "client") == 0) #define GF_CDC_MODE_IS_SERVER(m) (strcmp(m, "server") == 0) int32_t cdc_compress(xlator_t *this, cdc_priv_t *priv, cdc_info_t *ci, dict_t **xdata); int32_t cdc_decompress(xlator_t *this, cdc_priv_t *priv, cdc_info_t *ci, dict_t *xdata); #endif glusterfs-11.1/xlators/features/compress/src/PaxHeaders.9031/cdc.c0000644000000000000000000000013214522202451023211 xustar000000000000000030 mtime=1699284265.667027432 30 atime=1699284265.667027432 30 ctime=1699284304.223143562 glusterfs-11.1/xlators/features/compress/src/cdc.c0000664000175100017510000002254714522202451023502 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "cdc.h" #include "cdc-mem-types.h" static void cdc_cleanup_iobref(cdc_info_t *ci) { assert(ci->iobref != NULL); iobref_clear(ci->iobref); } static int32_t cdc_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { int ret = -1; cdc_priv_t *priv = NULL; cdc_info_t ci = { 0, }; GF_VALIDATE_OR_GOTO("cdc", this, default_out); GF_VALIDATE_OR_GOTO(this->name, frame, default_out); if (op_ret <= 0) goto default_out; priv = this->private; if ((priv->min_file_size != 0) && (op_ret < priv->min_file_size)) goto default_out; ci.count = count; ci.ibytes = op_ret; ci.vector = vector; ci.buf = NULL; ci.iobref = NULL; ci.ncount = 0; ci.crc = 0; ci.buffer_size = GF_CDC_DEF_BUFFERSIZE; /* A readv compresses on the server side and decompresses on the client side */ if (priv->op_mode == GF_CDC_MODE_SERVER) { ret = cdc_compress(this, priv, &ci, &xdata); } else if (priv->op_mode == GF_CDC_MODE_CLIENT) { ret = cdc_decompress(this, priv, &ci, xdata); } else { gf_log(this->name, GF_LOG_ERROR, "Invalid operation mode (%d)", priv->op_mode); } if (ret) goto default_out; STACK_UNWIND_STRICT(readv, frame, ci.nbytes, op_errno, ci.vec, ci.ncount, stbuf, iobref, xdata); cdc_cleanup_iobref(&ci); return 0; default_out: STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, stbuf, iobref, xdata); return 0; } int32_t cdc_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { STACK_WIND(frame, cdc_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; } static int32_t cdc_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t cdc_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { int ret = -1; cdc_priv_t *priv = NULL; cdc_info_t ci = { 0, }; size_t isize = 0; GF_VALIDATE_OR_GOTO("cdc", this, err); GF_VALIDATE_OR_GOTO(this->name, frame, err); isize = iov_length(vector, count); if (isize <= 0) goto default_out; priv = this->private; if ((priv->min_file_size != 0) && (isize < priv->min_file_size)) goto default_out; ci.count = count; ci.ibytes = isize; ci.vector = vector; ci.buf = NULL; ci.iobref = NULL; ci.ncount = 0; ci.crc = 0; ci.buffer_size = GF_CDC_DEF_BUFFERSIZE; /* A writev compresses on the client side and decompresses on the server * side */ if (priv->op_mode == GF_CDC_MODE_CLIENT) { ret = cdc_compress(this, priv, &ci, &xdata); } else if (priv->op_mode == GF_CDC_MODE_SERVER) { ret = cdc_decompress(this, priv, &ci, xdata); } else { gf_log(this->name, GF_LOG_ERROR, "Invalid operation mode (%d) ", priv->op_mode); } if (ret) goto default_out; STACK_WIND(frame, cdc_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, ci.vec, ci.ncount, offset, flags, iobref, xdata); cdc_cleanup_iobref(&ci); return 0; default_out: STACK_WIND(frame, cdc_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; err: STACK_UNWIND_STRICT(writev, frame, -1, EINVAL, NULL, NULL, NULL); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_cdc_mt_end); if (ret != 0) { gf_log(this->name, GF_LOG_ERROR, "Memory accounting init" "failed"); return ret; } return ret; } int32_t init(xlator_t *this) { int ret = -1; char *temp_str = NULL; cdc_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("cdc", this, err); if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "Need subvolume == 1"); goto err; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "Dangling volume. Check volfile"); } priv = GF_CALLOC(1, sizeof(*priv), gf_cdc_mt_priv_t); if (!priv) { goto err; } /* Check if debug mode is turned on */ GF_OPTION_INIT("debug", priv->debug, bool, err); if (priv->debug) { gf_log(this->name, GF_LOG_DEBUG, "CDC debug option turned on"); } /* Set Gzip Window Size */ GF_OPTION_INIT("window-size", priv->window_size, int32, err); if ((priv->window_size > GF_CDC_MAX_WINDOWSIZE) || (priv->window_size < GF_CDC_DEF_WINDOWSIZE)) { gf_log(this->name, GF_LOG_WARNING, "Invalid gzip window size (%d), using default", priv->window_size); priv->window_size = GF_CDC_DEF_WINDOWSIZE; } /* Set Gzip (De)Compression Level */ GF_OPTION_INIT("compression-level", priv->cdc_level, int32, err); if (((priv->cdc_level < 1) || (priv->cdc_level > 9)) && (priv->cdc_level != Z_DEFAULT_COMPRESSION)) { gf_log(this->name, GF_LOG_WARNING, "Invalid gzip (de)compression level (%d)," " using default", priv->cdc_level); priv->cdc_level = Z_DEFAULT_COMPRESSION; } /* Set Gzip Memory Level */ GF_OPTION_INIT("mem-level", priv->mem_level, int32, err); if ((priv->mem_level < 1) || (priv->mem_level > 9)) { gf_log(this->name, GF_LOG_WARNING, "Invalid gzip memory level, using the default"); priv->mem_level = GF_CDC_DEF_MEMLEVEL; } /* Set min file size to enable compression */ GF_OPTION_INIT("min-size", priv->min_file_size, int32, err); /* Mode of operation - Server/Client */ ret = dict_get_str(this->options, "mode", &temp_str); if (ret) { gf_log(this->name, GF_LOG_CRITICAL, "Operation mode not specified !!"); goto err; } if (GF_CDC_MODE_IS_CLIENT(temp_str)) { priv->op_mode = GF_CDC_MODE_CLIENT; } else if (GF_CDC_MODE_IS_SERVER(temp_str)) { priv->op_mode = GF_CDC_MODE_SERVER; } else { gf_log(this->name, GF_LOG_CRITICAL, "Bogus operation mode (%s) specified", temp_str); goto err; } this->private = priv; gf_log(this->name, GF_LOG_DEBUG, "CDC xlator loaded in (%s) mode", temp_str); return 0; err: if (priv) GF_FREE(priv); return -1; } void fini(xlator_t *this) { cdc_priv_t *priv = this->private; if (priv) GF_FREE(priv); this->private = NULL; return; } struct xlator_fops fops = { .readv = cdc_readv, .writev = cdc_writev, }; struct xlator_cbks cbks = {}; struct volume_options options[] = { {.key = {"window-size"}, .default_value = "-15", .type = GF_OPTION_TYPE_INT, .description = "Size of the zlib history buffer."}, {.key = {"mem-level"}, .default_value = "8", .type = GF_OPTION_TYPE_INT, .description = "Memory allocated for internal compression state. " "1 uses minimum memory but is slow and reduces " "compression ratio; memLevel=9 uses maximum memory " "for optimal speed. The default value is 8."}, {.key = {"compression-level"}, .default_value = "1", .type = GF_OPTION_TYPE_INT, .description = "Compression levels \n" "0 : no compression, 1 : best speed, \n" "9 : best compression, -1 : default compression "}, {.key = {"min-size"}, .default_value = "1024", .type = GF_OPTION_TYPE_INT, .description = "Data is compressed only when its size exceeds this."}, {.key = {"mode"}, .value = {"server", "client"}, .type = GF_OPTION_TYPE_STR, .description = "Set on the basis of where the xlator is loaded. " "This option should NOT be configured by user."}, {.key = {"debug"}, .default_value = "false", .type = GF_OPTION_TYPE_BOOL, .description = "This is used in testing. Will dump compressed data " "to disk as a gzip file."}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .mem_acct_init = mem_acct_init, .op_version = {GD_OP_VERSION_3_9_0}, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "cdc", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/features/compress/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464024365 xustar000000000000000030 mtime=1699284276.041058679 30 atime=1699284290.565102425 30 ctime=1699284304.216143541 glusterfs-11.1/xlators/features/compress/src/Makefile.in0000664000175100017510000005747314522202464024664 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/compress/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) am__DEPENDENCIES_1 = cdc_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(am__DEPENDENCIES_1) am_cdc_la_OBJECTS = cdc.lo cdc-helper.lo cdc_la_OBJECTS = $(am_cdc_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = cdc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(cdc_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(cdc_la_SOURCES) DIST_SOURCES = $(cdc_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = cdc.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features noinst_HEADERS = cdc.h cdc-mem-types.h cdc_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) cdc_la_SOURCES = cdc.c cdc-helper.c cdc_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(ZLIB_LIBS) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(ZLIB_CFLAGS) AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/compress/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/compress/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } cdc.la: $(cdc_la_OBJECTS) $(cdc_la_DEPENDENCIES) $(EXTRA_cdc_la_DEPENDENCIES) $(AM_V_CCLD)$(cdc_la_LINK) -rpath $(xlatordir) $(cdc_la_OBJECTS) $(cdc_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdc-helper.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdc.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/compress/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024350 xustar000000000000000030 mtime=1699284265.667027432 30 atime=1699284276.004058567 30 ctime=1699284304.218143547 glusterfs-11.1/xlators/features/compress/src/Makefile.am0000664000175100017510000000103114522202451024622 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = cdc.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features noinst_HEADERS = cdc.h cdc-mem-types.h cdc_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) cdc_la_SOURCES = cdc.c cdc-helper.c cdc_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(ZLIB_LIBS) AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(ZLIB_CFLAGS) AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/compress/src/PaxHeaders.9031/cdc-helper.c0000644000000000000000000000013214522202451024466 xustar000000000000000030 mtime=1699284265.667027432 30 atime=1699284265.667027432 30 ctime=1699284304.225143568 glusterfs-11.1/xlators/features/compress/src/cdc-helper.c0000664000175100017510000003250114522202451024746 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include "cdc.h" #include "cdc-mem-types.h" /* gzip header looks something like this * (RFC 1950) * * +---+---+---+---+---+---+---+---+---+---+ * |ID1|ID2|CM |FLG| MTIME |XFL|OS | * +---+---+---+---+---+---+---+---+---+---+ * * Data is usually sent without this header i.e * Data sent = + trailer(8) * The trailer contains the checksum. * * gzip_header is added only during debugging. * Refer to the function cdc_dump_iovec_to_disk */ static const char gzip_header[10] = {'\037', '\213', Z_DEFLATED, 0, 0, 0, 0, 0, 0, GF_CDC_OS_ID}; static int32_t cdc_next_iovec(cdc_info_t *ci) { int ret = -1; ci->ncount++; /* check for iovec overflow -- should not happen */ if (caa_unlikely(ci->ncount == MAX_IOVEC)) { gf_log(THIS->name, GF_LOG_ERROR, "Zlib output buffer overflow" " ->ncount (%d) | ->MAX_IOVEC (%d)", ci->ncount, MAX_IOVEC); goto out; } ret = 0; out: return ret; } static void cdc_put_long(unsigned char *string, unsigned long x) { string[0] = (unsigned char)(x & 0xff); string[1] = (unsigned char)((x & 0xff00) >> 8); string[2] = (unsigned char)((x & 0xff0000) >> 16); string[3] = (unsigned char)((x & 0xff000000) >> 24); } static unsigned long cdc_get_long(unsigned char *buf) { return ((unsigned long)buf[0]) | (((unsigned long)buf[1]) << 8) | (((unsigned long)buf[2]) << 16) | (((unsigned long)buf[3]) << 24); } static int32_t cdc_init_gzip_trailer(cdc_info_t *ci) { int ret = -1; char *buf = NULL; ret = cdc_next_iovec(ci); if (ret) goto out; buf = CURR_VEC(ci).iov_base = (char *)GF_CALLOC(1, GF_CDC_VALIDATION_SIZE, gf_cdc_mt_gzip_trailer_t); if (!CURR_VEC(ci).iov_base) goto out; CURR_VEC(ci).iov_len = GF_CDC_VALIDATION_SIZE; cdc_put_long((unsigned char *)&buf[0], ci->crc); cdc_put_long((unsigned char *)&buf[4], ci->stream.total_in); ret = 0; out: return ret; } static int32_t cdc_alloc_iobuf_and_init_vec(xlator_t *this, cdc_info_t *ci, int size) { int ret = -1; int alloc_len = 0; struct iobuf *iobuf = NULL; ret = cdc_next_iovec(ci); if (caa_unlikely(ret)) goto out; alloc_len = size ? size : ci->buffer_size; iobuf = iobuf_get2(this->ctx->iobuf_pool, alloc_len); if (caa_unlikely(!iobuf)) goto out; ret = iobref_add(ci->iobref, iobuf); if (caa_unlikely(ret)) goto out; /* Initialize this iovec */ CURR_VEC(ci).iov_base = iobuf->ptr; CURR_VEC(ci).iov_len = alloc_len; ret = 0; out: return ret; } static void cdc_init_zlib_output_stream(cdc_info_t *ci, int size) { ci->stream.next_out = (unsigned char *)CURR_VEC(ci).iov_base; ci->stream.avail_out = size ? size : ci->buffer_size; } /* This routine is for testing and debugging only. * Data written = header(10) + + trailer(8) * So each gzip dump file is at least 18 bytes in size. */ static void cdc_dump_iovec_to_disk(xlator_t *this, cdc_info_t *ci, const char *file) { int i = 0; int fd = 0; size_t written = 0; size_t total_written = 0; fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { gf_log(this->name, GF_LOG_ERROR, "Cannot open file: %s", file); return; } written = sys_write(fd, (char *)gzip_header, 10); total_written += written; for (i = 0; i < ci->ncount; i++) { written = sys_write(fd, (char *)ci->vec[i].iov_base, ci->vec[i].iov_len); total_written += written; } gf_log(this->name, GF_LOG_DEBUG, "dump'd %zu bytes to %s", total_written, GF_CDC_DEBUG_DUMP_FILE); sys_close(fd); } static int32_t cdc_flush_libz_buffer(xlator_t *this, cdc_info_t *ci, int (*libz_func)(z_streamp, int), int flush) { int32_t ret = Z_OK; int done = 0; unsigned int deflate_len = 0; for (;;) { deflate_len = ci->buffer_size - ci->stream.avail_out; if (deflate_len != 0) { CURR_VEC(ci).iov_len = deflate_len; ret = cdc_alloc_iobuf_and_init_vec(this, ci, 0); if (ret) { ret = Z_MEM_ERROR; break; } /* Re-position Zlib output buffer */ cdc_init_zlib_output_stream(ci, 0); } if (done) { ci->ncount--; break; } ret = libz_func(&ci->stream, flush); if (ret == Z_BUF_ERROR) { ret = Z_OK; ci->ncount--; break; } done = (ci->stream.avail_out != 0 || ret == Z_STREAM_END); if (ret != Z_OK && ret != Z_STREAM_END) break; } return ret; } static int32_t do_cdc_compress(struct iovec *vec, xlator_t *this, cdc_info_t *ci) { int ret = -1; ret = cdc_alloc_iobuf_and_init_vec(this, ci, 0); if (ret) goto out; /* setup output buffer */ cdc_init_zlib_output_stream(ci, 0); /* setup input buffer */ ci->stream.next_in = (unsigned char *)vec->iov_base; ci->stream.avail_in = vec->iov_len; ci->crc = crc32(ci->crc, (const Bytef *)vec->iov_base, vec->iov_len); gf_log(this->name, GF_LOG_DEBUG, "crc=%lu len=%d buffer_size=%d", ci->crc, ci->stream.avail_in, ci->buffer_size); /* compress !! */ while (ci->stream.avail_in != 0) { if (ci->stream.avail_out == 0) { CURR_VEC(ci).iov_len = ci->buffer_size; ret = cdc_alloc_iobuf_and_init_vec(this, ci, 0); if (ret) break; /* Re-position Zlib output buffer */ cdc_init_zlib_output_stream(ci, 0); } ret = deflate(&ci->stream, Z_NO_FLUSH); if (ret != Z_OK) break; } out: return ret; } int32_t cdc_compress(xlator_t *this, cdc_priv_t *priv, cdc_info_t *ci, dict_t **xdata) { int ret = -1; int i = 0; ci->iobref = iobref_new(); if (!ci->iobref) goto out; if (!*xdata) { *xdata = dict_new(); if (!*xdata) { gf_log(this->name, GF_LOG_ERROR, "Cannot allocate xdata" " dict"); goto out; } } /* Initialize defalte */ ret = deflateInit2(&ci->stream, priv->cdc_level, Z_DEFLATED, priv->window_size, priv->mem_level, Z_DEFAULT_STRATEGY); if (ret) { gf_log(this->name, GF_LOG_ERROR, "unable to init Zlib (retval: %d)", ret); goto out; } /* data */ for (i = 0; i < ci->count; i++) { ret = do_cdc_compress(&ci->vector[i], this, ci); if (ret != Z_OK) goto deflate_cleanup_out; } /* flush zlib buffer */ ret = cdc_flush_libz_buffer(this, ci, deflate, Z_FINISH); if (!(ret == Z_OK || ret == Z_STREAM_END)) { gf_log(this->name, GF_LOG_ERROR, "Compression Error: ret (%d)", ret); ret = -1; goto deflate_cleanup_out; } /* trailer */ ret = cdc_init_gzip_trailer(ci); if (ret) goto deflate_cleanup_out; gf_log(this->name, GF_LOG_DEBUG, "Compressed %ld to %ld bytes", ci->stream.total_in, ci->stream.total_out); ci->nbytes = ci->stream.total_out + GF_CDC_VALIDATION_SIZE; /* set deflated canary value for identification */ ret = dict_set_int32(*xdata, GF_CDC_DEFLATE_CANARY_VAL, 1); if (ret) { /* Send uncompressed data if we can't _tell_ the client * that deflated data is on its way. So, we just log * the failure and continue as usual. */ gf_log(this->name, GF_LOG_ERROR, "Data deflated, but could not set canary" " value in dict for identification"); } /* This is to be used in testing */ if (priv->debug) { cdc_dump_iovec_to_disk(this, ci, GF_CDC_DEBUG_DUMP_FILE); } deflate_cleanup_out: (void)deflateEnd(&ci->stream); out: return ret; } /* deflate content is checked by the presence of a canary * value in the dict as the key */ static int32_t cdc_check_content_for_deflate(dict_t *xdata) { return dict_get(xdata, GF_CDC_DEFLATE_CANARY_VAL) ? -1 : 0; } static unsigned long cdc_extract_crc(char *trailer) { return cdc_get_long((unsigned char *)&trailer[0]); } static unsigned long cdc_extract_size(char *trailer) { return cdc_get_long((unsigned char *)&trailer[4]); } static int32_t cdc_validate_inflate(cdc_info_t *ci, unsigned long crc, unsigned long len) { return !((crc == ci->crc) /* inflated length is hidden inside * Zlib stream struct */ && (len == ci->stream.total_out)); } static int32_t do_cdc_decompress(xlator_t *this, cdc_info_t *ci) { int ret = -1; int i = 0; int len = 0; char *inflte = NULL; char *trailer = NULL; struct iovec vec = { 0, }; unsigned long computed_crc = 0; unsigned long computed_len = 0; vec = THIS_VEC(ci, 0); trailer = (char *)(((char *)vec.iov_base) + vec.iov_len - GF_CDC_VALIDATION_SIZE); /* CRC of uncompressed data */ computed_crc = cdc_extract_crc(trailer); /* size of uncomrpessed data */ computed_len = cdc_extract_size(trailer); gf_log(this->name, GF_LOG_DEBUG, "crc=%lu len=%lu buffer_size=%d", computed_crc, computed_len, ci->buffer_size); inflte = vec.iov_base; len = vec.iov_len - GF_CDC_VALIDATION_SIZE; /* allocate buffer of the original length of the data */ ret = cdc_alloc_iobuf_and_init_vec(this, ci, 0); if (ret) goto out; /* setup output buffer */ cdc_init_zlib_output_stream(ci, 0); /* setup input buffer */ ci->stream.next_in = (unsigned char *)inflte; ci->stream.avail_in = len; while (ci->stream.avail_in != 0) { if (ci->stream.avail_out == 0) { CURR_VEC(ci).iov_len = ci->buffer_size; ret = cdc_alloc_iobuf_and_init_vec(this, ci, 0); if (ret) break; /* Re-position Zlib output buffer */ cdc_init_zlib_output_stream(ci, 0); } ret = inflate(&ci->stream, Z_NO_FLUSH); if (ret == Z_STREAM_ERROR) break; } /* flush zlib buffer */ ret = cdc_flush_libz_buffer(this, ci, inflate, Z_SYNC_FLUSH); if (!(ret == Z_OK || ret == Z_STREAM_END)) { gf_log(this->name, GF_LOG_ERROR, "Decompression Error: ret (%d)", ret); ret = -1; goto out; } /* compute CRC of the uncompressed data to check for * correctness */ for (i = 0; i < ci->ncount; i++) { ci->crc = crc32(ci->crc, (const Bytef *)ci->vec[i].iov_base, ci->vec[i].iov_len); } /* validate inflated data */ ret = cdc_validate_inflate(ci, computed_crc, computed_len); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Checksum or length mismatched in inflated data"); } out: return ret; } int32_t cdc_decompress(xlator_t *this, cdc_priv_t *priv, cdc_info_t *ci, dict_t *xdata) { int32_t ret = -1; /* check for deflate content */ if (!cdc_check_content_for_deflate(xdata)) { gf_log(this->name, GF_LOG_DEBUG, "Content not deflated, passing through ..."); goto passthrough_out; } ci->iobref = iobref_new(); if (!ci->iobref) goto passthrough_out; /* do we need to do this? can we assume that one iovec * will hold per request data every time? * * server/client protocol seems to deal with a single * iovec even if op_ret > 1M. So, it looks ok to * assume that a single iovec will contain all the * data (This saves us a lot from finding the trailer * and the data since it could have been split-up onto * two adjacent iovec's. * * But, in case this translator is loaded above quick-read * for some reason, then it's entirely possible that we get * multiple iovec's... * * This case (handled below) is not tested. (by loading the * xlator below quick-read) */ /* @@ I_HOPE_THIS_IS_NEVER_HIT */ if (ci->count > 1) { gf_log(this->name, GF_LOG_WARNING, "unable to handle" " multiple iovecs (%d in number)", ci->count); goto inflate_cleanup_out; /* TODO: coallate all iovecs in one */ } ret = inflateInit2(&ci->stream, priv->window_size); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Zlib: Unable to initialize inflate"); goto inflate_cleanup_out; } ret = do_cdc_decompress(this, ci); if (ret) goto inflate_cleanup_out; ci->nbytes = ci->stream.total_out; gf_log(this->name, GF_LOG_DEBUG, "Inflated %ld to %ld bytes", ci->stream.total_in, ci->stream.total_out); inflate_cleanup_out: (void)inflateEnd(&ci->stream); passthrough_out: return ret; } glusterfs-11.1/xlators/features/compress/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463023575 xustar000000000000000030 mtime=1699284275.993058534 30 atime=1699284290.543102359 30 ctime=1699284304.168143396 glusterfs-11.1/xlators/features/compress/Makefile.in0000664000175100017510000005273214522202463024065 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/compress DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/compress/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/compress/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/compress/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023561 xustar000000000000000030 mtime=1699284265.667027432 30 atime=1699284275.969058462 30 ctime=1699284304.170143402 glusterfs-11.1/xlators/features/compress/Makefile.am0000664000175100017510000000003414522202451024035 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/locks0000644000000000000000000000013214522202517020733 xustar000000000000000030 mtime=1699284303.239140598 30 atime=1699284309.687160019 30 ctime=1699284303.239140598 glusterfs-11.1/xlators/features/locks/0002775000175100017510000000000014522202517021271 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/locks/PaxHeaders.9031/src0000644000000000000000000000013214522202517021522 xustar000000000000000030 mtime=1699284303.301140785 30 atime=1699284309.687160019 30 ctime=1699284303.301140785 glusterfs-11.1/xlators/features/locks/src/0002775000175100017510000000000014522202517022060 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/common.c0000644000000000000000000000013214522202451023230 xustar000000000000000030 mtime=1699284265.672027447 30 atime=1699284265.672027447 30 ctime=1699284303.292140758 glusterfs-11.1/xlators/features/locks/src/common.c0000664000175100017510000012113714522202451023514 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012, 2015-2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include "locks.h" #include "common.h" static int __is_lock_grantable(pl_inode_t *pl_inode, posix_lock_t *lock); static void __insert_and_merge(pl_inode_t *pl_inode, posix_lock_t *lock); static int pl_send_prelock_unlock(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *old_lock); static pl_dom_list_t * __allocate_domain(const char *volume) { pl_dom_list_t *dom = NULL; dom = GF_MALLOC(sizeof(*dom), gf_locks_mt_pl_dom_list_t); if (!dom) goto out; dom->domain = gf_strdup(volume); if (!dom->domain) goto out; gf_log("posix-locks", GF_LOG_TRACE, "New domain allocated: %s", dom->domain); INIT_LIST_HEAD(&dom->inode_list); INIT_LIST_HEAD(&dom->entrylk_list); INIT_LIST_HEAD(&dom->blocked_entrylks); INIT_LIST_HEAD(&dom->inodelk_list); INIT_LIST_HEAD(&dom->blocked_inodelks); out: if (dom && (NULL == dom->domain)) { GF_FREE(dom); dom = NULL; } return dom; } /* Returns domain for the lock. If domain is not present, * allocates a domain and returns it */ pl_dom_list_t * get_domain(pl_inode_t *pl_inode, const char *volume) { pl_dom_list_t *dom = NULL; GF_VALIDATE_OR_GOTO("posix-locks", pl_inode, out); GF_VALIDATE_OR_GOTO("posix-locks", volume, out); pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry(dom, &pl_inode->dom_list, inode_list) { if (strcmp(dom->domain, volume) == 0) goto unlock; } dom = __allocate_domain(volume); if (dom) list_add(&dom->inode_list, &pl_inode->dom_list); } unlock: pthread_mutex_unlock(&pl_inode->mutex); if (dom) { gf_log("posix-locks", GF_LOG_TRACE, "Domain %s found", volume); } else { gf_log("posix-locks", GF_LOG_TRACE, "Domain %s not found", volume); } out: return dom; } unsigned long fd_to_fdnum(fd_t *fd) { return ((unsigned long)fd); } fd_t * fd_from_fdnum(posix_lock_t *lock) { return ((fd_t *)lock->fd_num); } int __pl_inode_is_empty(pl_inode_t *pl_inode) { return (list_empty(&pl_inode->ext_list)); } void pl_print_locker(char *str, int size, xlator_t *this, call_frame_t *frame) { snprintf(str, size, "Pid=%llu, lk-owner=%s, Client=%p, Frame=%llu", (unsigned long long)frame->root->pid, lkowner_utoa(&frame->root->lk_owner), frame->root->client, (unsigned long long)frame->root->unique); } void pl_print_lockee(char *str, int size, fd_t *fd, loc_t *loc) { inode_t *inode = NULL; char *ipath = NULL; int ret = 0; if (fd) inode = fd->inode; if (loc) inode = loc->inode; if (!inode) { snprintf(str, size, ""); return; } if (loc && loc->path) { ipath = gf_strdup(loc->path); } else { ret = inode_path(inode, NULL, &ipath); if (ret <= 0) ipath = NULL; } snprintf(str, size, "gfid=%s, fd=%p, path=%s", uuid_utoa(inode->gfid), fd, ipath ? ipath : ""); GF_FREE(ipath); } void pl_print_lock(char *str, int size, int cmd, struct gf_flock *flock, gf_lkowner_t *owner) { char *cmd_str = NULL; char *type_str = NULL; switch (cmd) { #if F_GETLK != F_GETLK64 case F_GETLK64: #endif case F_GETLK: cmd_str = "GETLK"; break; #if F_SETLK != F_SETLK64 case F_SETLK64: #endif case F_SETLK: cmd_str = "SETLK"; break; #if F_SETLKW != F_SETLKW64 case F_SETLKW64: #endif case F_SETLKW: cmd_str = "SETLKW"; break; default: cmd_str = "UNKNOWN"; break; } switch (flock->l_type) { case F_RDLCK: type_str = "READ"; break; case F_WRLCK: type_str = "WRITE"; break; case F_UNLCK: type_str = "UNLOCK"; break; default: type_str = "UNKNOWN"; break; } snprintf(str, size, "lock=FCNTL, cmd=%s, type=%s, " "start=%llu, len=%llu, pid=%llu, lk-owner=%s", cmd_str, type_str, (unsigned long long)flock->l_start, (unsigned long long)flock->l_len, (unsigned long long)flock->l_pid, lkowner_utoa(owner)); } void pl_trace_in(xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc, int cmd, struct gf_flock *flock, const char *domain) { posix_locks_private_t *priv = this->private; char pl_locker[256]; char pl_lockee[256]; char pl_lock[256]; if (!priv->trace) return; pl_print_locker(pl_locker, 256, this, frame); pl_print_lockee(pl_lockee, 256, fd, loc); if (domain) pl_print_inodelk(pl_lock, 256, cmd, flock, domain); else pl_print_lock(pl_lock, 256, cmd, flock, &frame->root->lk_owner); gf_log(this->name, GF_LOG_INFO, "[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}", pl_locker, pl_lockee, pl_lock); } void pl_print_verdict(char *str, int size, int op_ret, int op_errno) { char *verdict = NULL; if (op_ret == 0) { verdict = "GRANTED"; } else { switch (op_errno) { case EAGAIN: verdict = "TRYAGAIN"; break; default: verdict = strerror(op_errno); } } snprintf(str, size, "%s", verdict); } void pl_trace_out(xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc, int cmd, struct gf_flock *flock, int op_ret, int op_errno, const char *domain) { posix_locks_private_t *priv = NULL; char pl_locker[256]; char pl_lockee[256]; char pl_lock[256]; char verdict[32]; priv = this->private; if (!priv->trace) return; pl_print_locker(pl_locker, 256, this, frame); pl_print_lockee(pl_lockee, 256, fd, loc); if (domain) pl_print_inodelk(pl_lock, 256, cmd, flock, domain); else pl_print_lock(pl_lock, 256, cmd, flock, &frame->root->lk_owner); pl_print_verdict(verdict, 32, op_ret, op_errno); gf_log(this->name, GF_LOG_INFO, "[%s] Locker = {%s} Lockee = {%s} Lock = {%s}", verdict, pl_locker, pl_lockee, pl_lock); } void pl_trace_block(xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc, int cmd, struct gf_flock *flock, const char *domain) { posix_locks_private_t *priv = this->private; char pl_locker[256]; char pl_lockee[256]; char pl_lock[256]; if (!priv->trace) return; pl_print_locker(pl_locker, 256, this, frame); pl_print_lockee(pl_lockee, 256, fd, loc); if (domain) pl_print_inodelk(pl_lock, 256, cmd, flock, domain); else pl_print_lock(pl_lock, 256, cmd, flock, &frame->root->lk_owner); gf_log(this->name, GF_LOG_INFO, "[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}", pl_locker, pl_lockee, pl_lock); } void pl_trace_flush(xlator_t *this, call_frame_t *frame, fd_t *fd) { posix_locks_private_t *priv = NULL; char pl_locker[256]; char pl_lockee[256]; pl_inode_t *pl_inode = NULL; priv = this->private; if (!priv->trace) return; pl_inode = pl_inode_get(this, fd->inode, NULL); if (pl_inode && __pl_inode_is_empty(pl_inode)) return; pl_print_locker(pl_locker, 256, this, frame); pl_print_lockee(pl_lockee, 256, fd, NULL); gf_log(this->name, GF_LOG_INFO, "[FLUSH] Locker = {%s} Lockee = {%s}", pl_locker, pl_lockee); } void pl_trace_release(xlator_t *this, fd_t *fd) { posix_locks_private_t *priv = NULL; char pl_lockee[256]; priv = this->private; if (!priv->trace) return; pl_print_lockee(pl_lockee, 256, fd, NULL); gf_log(this->name, GF_LOG_INFO, "[RELEASE] Lockee = {%s}", pl_lockee); } void pl_update_refkeeper(xlator_t *this, inode_t *inode) { pl_inode_t *pl_inode = NULL; int is_empty = 0; int need_unref = 0; int need_ref = 0; pl_inode = pl_inode_get(this, inode, NULL); if (!pl_inode) return; pthread_mutex_lock(&pl_inode->mutex); { is_empty = __pl_inode_is_empty(pl_inode); if (is_empty && pl_inode->refkeeper) { need_unref = 1; pl_inode->refkeeper = NULL; } if (!is_empty && !pl_inode->refkeeper) { need_ref = 1; pl_inode->refkeeper = inode; } } pthread_mutex_unlock(&pl_inode->mutex); if (need_unref) inode_unref(inode); if (need_ref) inode_ref(inode); } /* Get lock enforcement info from disk */ int pl_fetch_mlock_info_from_disk(xlator_t *this, pl_inode_t *pl_inode, pl_local_t *local) { dict_t *xdata_rsp = NULL; int ret = 0; int op_ret = 0; if (!local) { return -1; } if (local->fd) { op_ret = syncop_fgetxattr(this, local->fd, &xdata_rsp, GF_ENFORCE_MANDATORY_LOCK, NULL, NULL); } else { op_ret = syncop_getxattr(this, &local->loc[0], &xdata_rsp, GF_ENFORCE_MANDATORY_LOCK, NULL, NULL); } pthread_mutex_lock(&pl_inode->mutex); { if (op_ret >= 0) { pl_inode->mlock_enforced = _gf_true; pl_inode->check_mlock_info = _gf_false; } else { gf_msg(this->name, GF_LOG_WARNING, -op_ret, 0, "getxattr failed with %d", op_ret); pl_inode->mlock_enforced = _gf_false; if (-op_ret == ENODATA) { pl_inode->check_mlock_info = _gf_false; } else { pl_inode->check_mlock_info = _gf_true; } } } pthread_mutex_unlock(&pl_inode->mutex); return ret; } pl_inode_t * pl_inode_get(xlator_t *this, inode_t *inode, pl_local_t *local) { uint64_t tmp_pl_inode = 0; pl_inode_t *pl_inode = NULL; int ret = 0; LOCK(&inode->lock); { ret = __inode_ctx_get(inode, this, &tmp_pl_inode); if (ret == 0) { pl_inode = (pl_inode_t *)(long)tmp_pl_inode; goto unlock; } pl_inode = GF_CALLOC(1, sizeof(*pl_inode), gf_locks_mt_pl_inode_t); if (!pl_inode) { goto unlock; } gf_log(this->name, GF_LOG_TRACE, "Allocating new pl inode"); pthread_mutex_init(&pl_inode->mutex, NULL); pthread_cond_init(&pl_inode->check_fop_wind_count, 0); INIT_LIST_HEAD(&pl_inode->dom_list); INIT_LIST_HEAD(&pl_inode->ext_list); INIT_LIST_HEAD(&pl_inode->rw_list); INIT_LIST_HEAD(&pl_inode->reservelk_list); INIT_LIST_HEAD(&pl_inode->blocked_reservelks); INIT_LIST_HEAD(&pl_inode->blocked_calls); INIT_LIST_HEAD(&pl_inode->metalk_list); INIT_LIST_HEAD(&pl_inode->queued_locks); INIT_LIST_HEAD(&pl_inode->waiting); gf_uuid_copy(pl_inode->gfid, inode->gfid); pl_inode->check_mlock_info = _gf_true; pl_inode->mlock_enforced = _gf_false; pl_inode->remove_running = 0; ret = __inode_ctx_put(inode, this, (uint64_t)(long)(pl_inode)); if (ret) { pthread_mutex_destroy(&pl_inode->mutex); GF_FREE(pl_inode); pl_inode = NULL; goto unlock; } } unlock: UNLOCK(&inode->lock); if ((pl_inode != NULL) && pl_is_mandatory_locking_enabled(pl_inode) && pl_inode->check_mlock_info && local) { /* Note: The lock enforcement information per file can be stored in the attribute flag of stat(x) in posix. With that there won't be a need for doing getxattr post a reboot */ pl_fetch_mlock_info_from_disk(this, pl_inode, local); } return pl_inode; } /* Create a new posix_lock_t */ posix_lock_t * new_posix_lock(struct gf_flock *flock, client_t *client, pid_t client_pid, gf_lkowner_t *owner, fd_t *fd, uint32_t lk_flags, int blocking, int32_t *op_errno) { posix_lock_t *lock = NULL; GF_VALIDATE_OR_GOTO("posix-locks", flock, out); GF_VALIDATE_OR_GOTO("posix-locks", client, out); GF_VALIDATE_OR_GOTO("posix-locks", fd, out); if (!pl_is_lk_owner_valid(owner, client)) { *op_errno = EINVAL; goto out; } lock = GF_CALLOC(1, sizeof(posix_lock_t), gf_locks_mt_posix_lock_t); if (!lock) { *op_errno = ENOMEM; goto out; } lock->fl_start = flock->l_start; lock->fl_type = flock->l_type; if (flock->l_len == 0) lock->fl_end = LLONG_MAX; else lock->fl_end = flock->l_start + flock->l_len - 1; lock->client = client; lock->client_uid = gf_strdup(client->client_uid); if (lock->client_uid == NULL) { GF_FREE(lock); lock = NULL; *op_errno = ENOMEM; goto out; } lock->fd_num = fd_to_fdnum(fd); lock->fd = fd; lock->client_pid = client_pid; lk_owner_copy(&lock->owner, owner); lock->lk_flags = lk_flags; lock->blocking = blocking; gf_flock_copy(&lock->user_flock, flock); INIT_LIST_HEAD(&lock->list); out: return lock; } /* Delete a lock from the inode's lock list */ void __delete_lock(posix_lock_t *lock) { list_del_init(&lock->list); } /* Destroy a posix_lock */ void __destroy_lock(posix_lock_t *lock) { GF_FREE(lock->client_uid); GF_FREE(lock); } static posix_lock_t * __copy_lock(posix_lock_t *src) { posix_lock_t *dst; dst = GF_MALLOC(sizeof(posix_lock_t), gf_locks_mt_posix_lock_t); if (dst != NULL) { /* TODO: replace this memcpy with copying individual * variables, and then efficiently copy the owner and * user_owner structures using lk_owner_copy(), gf_flock_copy()*/ memcpy(dst, src, sizeof(posix_lock_t)); dst->client_uid = gf_strdup(src->client_uid); if (dst->client_uid == NULL) { GF_FREE(dst); dst = NULL; } if (dst != NULL) INIT_LIST_HEAD(&dst->list); } return dst; } /* Convert a posix_lock to a struct gf_flock */ void posix_lock_to_flock(posix_lock_t *lock, struct gf_flock *flock) { flock->l_pid = lock->user_flock.l_pid; flock->l_type = lock->fl_type; flock->l_start = lock->fl_start; lk_owner_copy(&flock->l_owner, &lock->owner); if (lock->fl_end == LLONG_MAX) flock->l_len = 0; else flock->l_len = lock->fl_end - lock->fl_start + 1; } /* Insert the lock into the inode's lock list */ static void __insert_lock(pl_inode_t *pl_inode, posix_lock_t *lock) { if (lock->blocked) lock->blkd_time = gf_time(); else lock->granted_time = gf_time(); list_add_tail(&lock->list, &pl_inode->ext_list); } /* Return true if the locks overlap, false otherwise */ int locks_overlap(posix_lock_t *l1, posix_lock_t *l2) { /* Note: FUSE always gives us absolute offsets, so no need to worry about SEEK_CUR or SEEK_END */ return ((l1->fl_end >= l2->fl_start) && (l2->fl_end >= l1->fl_start)); } /* Return true if the locks have the same owner */ int same_owner(posix_lock_t *l1, posix_lock_t *l2) { return (is_same_lkowner(&l1->owner, &l2->owner) && (l1->client == l2->client)); } /* Delete all F_UNLCK locks */ void __delete_unlck_locks(pl_inode_t *pl_inode) { posix_lock_t *l = NULL; posix_lock_t *tmp = NULL; list_for_each_entry_safe(l, tmp, &pl_inode->ext_list, list) { if (l->fl_type == F_UNLCK) { __delete_lock(l); __destroy_lock(l); } } } /* Add two locks */ static posix_lock_t * add_locks(posix_lock_t *l1, posix_lock_t *l2, posix_lock_t *dst) { posix_lock_t *sum = NULL; sum = __copy_lock(dst); if (!sum) return NULL; sum->fl_start = min(l1->fl_start, l2->fl_start); sum->fl_end = max(l1->fl_end, l2->fl_end); posix_lock_to_flock(sum, &sum->user_flock); return sum; } /* Subtract two locks */ struct _values { posix_lock_t *locks[3]; }; /* {big} must always be contained inside {small} */ static struct _values subtract_locks(posix_lock_t *big, posix_lock_t *small) { struct _values v = {.locks = {0, 0, 0}}; if ((big->fl_start == small->fl_start) && (big->fl_end == small->fl_end)) { /* both edges coincide with big */ v.locks[0] = __copy_lock(big); if (!v.locks[0]) { goto out; } v.locks[0]->fl_type = small->fl_type; v.locks[0]->user_flock.l_type = small->fl_type; goto done; } if ((small->fl_start > big->fl_start) && (small->fl_end < big->fl_end)) { /* both edges lie inside big */ v.locks[0] = __copy_lock(big); v.locks[1] = __copy_lock(small); v.locks[2] = __copy_lock(big); if ((v.locks[0] == NULL) || (v.locks[1] == NULL) || (v.locks[2] == NULL)) { goto out; } v.locks[0]->fl_end = small->fl_start - 1; v.locks[2]->fl_start = small->fl_end + 1; posix_lock_to_flock(v.locks[0], &v.locks[0]->user_flock); posix_lock_to_flock(v.locks[2], &v.locks[2]->user_flock); goto done; } /* one edge coincides with big */ if (small->fl_start == big->fl_start) { v.locks[0] = __copy_lock(big); v.locks[1] = __copy_lock(small); if ((v.locks[0] == NULL) || (v.locks[1] == NULL)) { goto out; } v.locks[0]->fl_start = small->fl_end + 1; posix_lock_to_flock(v.locks[0], &v.locks[0]->user_flock); goto done; } if (small->fl_end == big->fl_end) { v.locks[0] = __copy_lock(big); v.locks[1] = __copy_lock(small); if ((v.locks[0] == NULL) || (v.locks[1] == NULL)) { goto out; } v.locks[0]->fl_end = small->fl_start - 1; posix_lock_to_flock(v.locks[0], &v.locks[0]->user_flock); goto done; } GF_ASSERT(0); gf_log("posix-locks", GF_LOG_ERROR, "Unexpected case in subtract_locks"); out: if (v.locks[0]) { __destroy_lock(v.locks[0]); v.locks[0] = NULL; } if (v.locks[1]) { __destroy_lock(v.locks[1]); v.locks[1] = NULL; } if (v.locks[2]) { __destroy_lock(v.locks[2]); v.locks[2] = NULL; } done: return v; } static posix_lock_t * first_conflicting_overlap(pl_inode_t *pl_inode, posix_lock_t *lock) { posix_lock_t *l = NULL; posix_lock_t *conf = NULL; pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry(l, &pl_inode->ext_list, list) { if (l->blocked) continue; if (locks_overlap(l, lock)) { if (same_owner(l, lock)) continue; if ((l->fl_type == F_WRLCK) || (lock->fl_type == F_WRLCK)) { conf = l; goto unlock; } } } } unlock: pthread_mutex_unlock(&pl_inode->mutex); return conf; } /* Start searching from {begin}, and return the first lock that conflicts, NULL if no conflict If {begin} is NULL, then start from the beginning of the list */ static posix_lock_t * first_overlap(pl_inode_t *pl_inode, posix_lock_t *lock) { posix_lock_t *l = NULL; list_for_each_entry(l, &pl_inode->ext_list, list) { if (l->blocked) continue; if (locks_overlap(l, lock)) return l; } return NULL; } /* Return true if lock is grantable */ static int __is_lock_grantable(pl_inode_t *pl_inode, posix_lock_t *lock) { posix_lock_t *l = NULL; int ret = 1; list_for_each_entry(l, &pl_inode->ext_list, list) { if (!l->blocked && locks_overlap(lock, l)) { if (((l->fl_type == F_WRLCK) || (lock->fl_type == F_WRLCK)) && (lock->fl_type != F_UNLCK) && !same_owner(l, lock)) { ret = 0; break; } } } return ret; } extern void do_blocked_rw(pl_inode_t *); static void __insert_and_merge(pl_inode_t *pl_inode, posix_lock_t *lock) { posix_lock_t *conf = NULL; posix_lock_t *t = NULL; posix_lock_t *sum = NULL; int i = 0; struct _values v = {.locks = {0, 0, 0}}; list_for_each_entry_safe(conf, t, &pl_inode->ext_list, list) { if (conf->blocked) continue; if (!locks_overlap(conf, lock)) continue; if (same_owner(conf, lock)) { if (conf->fl_type == lock->fl_type && conf->lk_flags == lock->lk_flags) { sum = add_locks(lock, conf, lock); __delete_lock(conf); __destroy_lock(conf); __destroy_lock(lock); __insert_and_merge(pl_inode, sum); return; } else { sum = add_locks(lock, conf, conf); v = subtract_locks(sum, lock); __delete_lock(conf); __destroy_lock(conf); __delete_lock(lock); __destroy_lock(lock); __destroy_lock(sum); for (i = 0; i < 3; i++) { if (!v.locks[i]) continue; __insert_and_merge(pl_inode, v.locks[i]); } __delete_unlck_locks(pl_inode); return; } } if (lock->fl_type == F_UNLCK) { continue; } if ((conf->fl_type == F_RDLCK) && (lock->fl_type == F_RDLCK)) { __insert_lock(pl_inode, lock); return; } } /* no conflicts, so just insert */ if (lock->fl_type != F_UNLCK) { __insert_lock(pl_inode, lock); } else { __destroy_lock(lock); } } void __grant_blocked_locks(xlator_t *this, pl_inode_t *pl_inode, struct list_head *granted) { struct list_head tmp_list; posix_lock_t *l = NULL; posix_lock_t *tmp = NULL; posix_lock_t *conf = NULL; INIT_LIST_HEAD(&tmp_list); list_for_each_entry_safe(l, tmp, &pl_inode->ext_list, list) { if (l->blocked) { conf = first_overlap(pl_inode, l); if (conf) continue; l->blocked = 0; list_move_tail(&l->list, &tmp_list); } } list_for_each_entry_safe(l, tmp, &tmp_list, list) { list_del_init(&l->list); if (__is_lock_grantable(pl_inode, l)) { conf = GF_CALLOC(1, sizeof(*conf), gf_locks_mt_posix_lock_t); if (!conf) { l->blocked = 1; __insert_lock(pl_inode, l); continue; } conf->frame = l->frame; l->frame = NULL; posix_lock_to_flock(l, &conf->user_flock); gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) lk-owner:%s %" PRId64 " - %" PRId64 " => Granted", l->fl_type == F_UNLCK ? "Unlock" : "Lock", l->client_pid, lkowner_utoa(&l->owner), l->user_flock.l_start, l->user_flock.l_len); __insert_and_merge(pl_inode, l); list_add(&conf->list, granted); } else { l->blocked = 1; __insert_lock(pl_inode, l); } } } void grant_blocked_locks(xlator_t *this, pl_inode_t *pl_inode) { struct list_head granted_list; posix_lock_t *tmp = NULL; posix_lock_t *lock = NULL; pl_local_t *local = NULL; INIT_LIST_HEAD(&granted_list); pthread_mutex_lock(&pl_inode->mutex); { __grant_blocked_locks(this, pl_inode, &granted_list); } pthread_mutex_unlock(&pl_inode->mutex); list_for_each_entry_safe(lock, tmp, &granted_list, list) { list_del_init(&lock->list); pl_trace_out(this, lock->frame, NULL, NULL, F_SETLKW, &lock->user_flock, 0, 0, NULL); local = lock->frame->local; PL_STACK_UNWIND_AND_FREE(local, lk, lock->frame, 0, 0, &lock->user_flock, NULL); __destroy_lock(lock); } return; } static int pl_send_prelock_unlock(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *old_lock) { struct gf_flock flock = { 0, }; posix_lock_t *unlock_lock = NULL; int32_t op_errno = 0; struct list_head granted_list; posix_lock_t *tmp = NULL; posix_lock_t *lock = NULL; pl_local_t *local = NULL; int ret = -1; INIT_LIST_HEAD(&granted_list); flock.l_type = F_UNLCK; flock.l_whence = old_lock->user_flock.l_whence; flock.l_start = old_lock->user_flock.l_start; flock.l_len = old_lock->user_flock.l_len; flock.l_pid = old_lock->user_flock.l_pid; unlock_lock = new_posix_lock(&flock, old_lock->client, old_lock->client_pid, &old_lock->owner, old_lock->fd, old_lock->lk_flags, 0, &op_errno); GF_VALIDATE_OR_GOTO(this->name, unlock_lock, out); ret = 0; __insert_and_merge(pl_inode, unlock_lock); __grant_blocked_locks(this, pl_inode, &granted_list); list_for_each_entry_safe(lock, tmp, &granted_list, list) { list_del_init(&lock->list); pl_trace_out(this, lock->frame, NULL, NULL, F_SETLKW, &lock->user_flock, 0, 0, NULL); local = lock->frame->local; PL_STACK_UNWIND_AND_FREE(local, lk, lock->frame, 0, 0, &lock->user_flock, NULL); __destroy_lock(lock); } out: return ret; } int pl_setlk(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, int can_block) { int ret; pthread_mutex_lock(&pl_inode->mutex); { if (GF_ATOMIC_GET(((client_t *)lock->client)->bind) == 0) { /* The client that sent the lock request has disconnected. Unless * this is an unlock request or it's non-blocking, we forbid it. */ if (can_block && (lock->fl_type != F_UNLCK)) { pthread_mutex_unlock(&pl_inode->mutex); ret = -ENOTCONN; goto out; } } /* Send unlock before the actual lock to prevent lock upgrade / downgrade problems only if: - it is a blocking call - it has other conflicting locks */ if (can_block && !(__is_lock_grantable(pl_inode, lock))) { ret = pl_send_prelock_unlock(this, pl_inode, lock); if (ret) { gf_log(this->name, GF_LOG_DEBUG, "Could not send pre-lock " "unlock"); } } ret = PL_LOCK_GRANTED; if (__is_lock_grantable(pl_inode, lock)) { if (pl_metalock_is_active(pl_inode)) { __pl_queue_lock(pl_inode, lock); pthread_mutex_unlock(&pl_inode->mutex); ret = PL_LOCK_QUEUED; goto out; } gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) lk-owner:%s %" PRId64 " - %" PRId64 " => OK", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); __insert_and_merge(pl_inode, lock); } else if (can_block) { if (pl_metalock_is_active(pl_inode)) { __pl_queue_lock(pl_inode, lock); pthread_mutex_unlock(&pl_inode->mutex); ret = PL_LOCK_QUEUED; goto out; } gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) lk-owner:%s %" PRId64 " - %" PRId64 " => Blocked", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); pl_trace_block(this, lock->frame, NULL, NULL, F_SETLKW, &lock->user_flock, NULL); lock->blocked = 1; __insert_lock(pl_inode, lock); ret = PL_LOCK_WOULD_BLOCK; } else { gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) lk-owner:%s %" PRId64 " - %" PRId64 " => NOK", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); ret = PL_LOCK_WOULD_BLOCK; } } pthread_mutex_unlock(&pl_inode->mutex); grant_blocked_locks(this, pl_inode); do_blocked_rw(pl_inode); out: return ret; } posix_lock_t * pl_getlk(pl_inode_t *pl_inode, posix_lock_t *lock) { posix_lock_t *conf = first_conflicting_overlap(pl_inode, lock); if (conf == NULL) { lock->fl_type = F_UNLCK; return lock; } return conf; } gf_boolean_t pl_does_monkey_want_stuck_lock(void) { long int monkey_unlock_rand = 0; long int monkey_unlock_rand_rem = 0; /* coverity[DC.WEAK_CRYPTO] */ monkey_unlock_rand = random(); monkey_unlock_rand_rem = monkey_unlock_rand % 100; if (monkey_unlock_rand_rem == 0) return _gf_true; return _gf_false; } int pl_lock_preempt(pl_inode_t *pl_inode, posix_lock_t *reqlock) { posix_lock_t *lock = NULL; posix_lock_t *i = NULL; pl_rw_req_t *rw = NULL; pl_rw_req_t *itr = NULL; pl_local_t *local; struct list_head unwind_blist = { 0, }; struct list_head unwind_rw_list = { 0, }; int ret = 0; INIT_LIST_HEAD(&unwind_blist); INIT_LIST_HEAD(&unwind_rw_list); pthread_mutex_lock(&pl_inode->mutex); { /* - go through the lock list - remove all locks from different owners - same owner locks will be added or substracted based on the new request - add the new lock */ list_for_each_entry_safe(lock, i, &pl_inode->ext_list, list) { if (lock->blocked) { list_del_init(&lock->list); list_add(&lock->list, &unwind_blist); continue; } if (locks_overlap(lock, reqlock)) { if (same_owner(lock, reqlock)) continue; /* remove conflicting locks */ list_del_init(&lock->list); __delete_lock(lock); __destroy_lock(lock); } } __insert_and_merge(pl_inode, reqlock); list_for_each_entry_safe(rw, itr, &pl_inode->rw_list, list) { list_del_init(&rw->list); list_add(&rw->list, &unwind_rw_list); } } pthread_mutex_unlock(&pl_inode->mutex); /* unwind blocked locks */ list_for_each_entry_safe(lock, i, &unwind_blist, list) { local = lock->frame->local; PL_STACK_UNWIND_AND_FREE(local, lk, lock->frame, -1, EBUSY, &lock->user_flock, NULL); __destroy_lock(lock); } /* unwind blocked IOs */ list_for_each_entry_safe(rw, itr, &unwind_rw_list, list) { pl_clean_local(rw->stub->frame->local); call_unwind_error(rw->stub, -1, EBUSY); } return ret; } /* Return true in case we need to ensure mandatory-locking * semantics under different modes. */ gf_boolean_t pl_is_mandatory_locking_enabled(pl_inode_t *pl_inode) { posix_locks_private_t *priv = THIS->private; if (priv->mandatory_mode == MLK_FILE_BASED && pl_inode->mandatory) return _gf_true; else if (priv->mandatory_mode == MLK_FORCED || priv->mandatory_mode == MLK_OPTIMAL) return _gf_true; return _gf_false; } void pl_clean_local(pl_local_t *local) { if (!local) return; if (local->inodelk_dom_count_req) data_unref(local->inodelk_dom_count_req); loc_wipe(&local->loc[0]); loc_wipe(&local->loc[1]); if (local->fd) fd_unref(local->fd); if (local->inode) inode_unref(local->inode); mem_put(local); } /* TODO: detach local initialization from PL_LOCAL_GET_REQUESTS and add it here */ int pl_local_init(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) { pl_local_t *local = NULL; if (!loc && !fd) { return -1; } if (!frame->local) { local = mem_get0(this->local_pool); if (!local) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, 0, "mem allocation failed"); return -1; } local->inode = (loc ? inode_ref(loc->inode) : inode_ref(fd->inode)); frame->local = local; } return 0; } gf_boolean_t pl_is_lk_owner_valid(gf_lkowner_t *owner, client_t *client) { if (client && (client->opversion < GD_OP_VERSION_7_0)) { return _gf_true; } if (is_lk_owner_null(owner)) { return _gf_false; } return _gf_true; } static int32_t pl_inode_from_loc(loc_t *loc, inode_t **pinode) { inode_t *inode = NULL; int32_t error = 0; if (loc->inode != NULL) { inode = inode_ref(loc->inode); goto done; } if (loc->parent == NULL) { error = EINVAL; goto done; } if (!gf_uuid_is_null(loc->gfid)) { inode = inode_find(loc->parent->table, loc->gfid); if (inode != NULL) { goto done; } } if (loc->name == NULL) { error = EINVAL; goto done; } inode = inode_grep(loc->parent->table, loc->parent, loc->name); if (inode == NULL) { /* We haven't found any inode. This means that the file doesn't exist * or that even if it exists, we don't have any knowledge about it, so * we don't have locks on it either, which is fine for our purposes. */ goto done; } done: *pinode = inode; return error; } static gf_boolean_t pl_inode_has_owners(xlator_t *xl, client_t *client, pl_inode_t *pl_inode, struct timespec *now, struct list_head *contend) { pl_dom_list_t *dom; pl_inode_lock_t *lock; gf_boolean_t has_owners = _gf_false; list_for_each_entry(dom, &pl_inode->dom_list, inode_list) { list_for_each_entry(lock, &dom->inodelk_list, list) { /* If the lock belongs to the same client, we assume it's related * to the same operation, so we allow the removal to continue. */ if (lock->client == client) { continue; } /* If the lock belongs to an internal process, we don't block the * removal. */ if (lock->client_pid < 0) { continue; } if (contend == NULL) { return _gf_true; } has_owners = _gf_true; inodelk_contention_notify_check(xl, lock, now, contend); } } return has_owners; } int32_t pl_inode_remove_prepare(xlator_t *xl, call_frame_t *frame, loc_t *loc, pl_inode_t **ppl_inode, struct list_head *contend) { struct timespec now; inode_t *inode; pl_inode_t *pl_inode; int32_t error; pl_inode = NULL; error = pl_inode_from_loc(loc, &inode); if ((error != 0) || (inode == NULL)) { goto done; } pl_inode = pl_inode_get(xl, inode, NULL); if (pl_inode == NULL) { inode_unref(inode); error = ENOMEM; goto done; } /* pl_inode_from_loc() already increments ref count for inode, so * we only assign here our reference. */ pl_inode->inode = inode; timespec_now(&now); pthread_mutex_lock(&pl_inode->mutex); if (pl_inode_has_owners(xl, frame->root->client, pl_inode, &now, contend)) { error = -1; /* We skip the unlock here because the caller must create a stub when * we return -1 and do a call to pl_inode_remove_complete(), which * assumes the lock is still acquired and will release it once * everything else is prepared. */ goto done; } pl_inode->is_locked = _gf_true; pl_inode->remove_running++; pthread_mutex_unlock(&pl_inode->mutex); done: *ppl_inode = pl_inode; return error; } int32_t pl_inode_remove_complete(xlator_t *xl, pl_inode_t *pl_inode, call_stub_t *stub, struct list_head *contend) { pl_inode_lock_t *lock; int32_t error = -1; if (stub != NULL) { list_add_tail(&stub->list, &pl_inode->waiting); pl_inode->is_locked = _gf_true; } else { error = ENOMEM; while (!list_empty(contend)) { lock = list_first_entry(contend, pl_inode_lock_t, list); list_del_init(&lock->list); __pl_inodelk_unref(lock); } } pthread_mutex_unlock(&pl_inode->mutex); if (error < 0) { inodelk_contention_notify(xl, contend); } inode_unref(pl_inode->inode); return error; } void pl_inode_remove_wake(struct list_head *list) { call_stub_t *stub; while (!list_empty(list)) { stub = list_first_entry(list, call_stub_t, list); list_del_init(&stub->list); call_resume(stub); } } void pl_inode_remove_cbk(xlator_t *xl, pl_inode_t *pl_inode, int32_t error) { struct list_head contend, granted; struct timespec now; pl_dom_list_t *dom; if (pl_inode == NULL) { return; } INIT_LIST_HEAD(&contend); INIT_LIST_HEAD(&granted); timespec_now(&now); pthread_mutex_lock(&pl_inode->mutex); pl_inode->remove_running--; if ((pl_inode->remove_running == 0) && list_empty(&pl_inode->waiting)) { pl_inode->is_locked = _gf_false; /* At this point it's possible that the inode has been deleted, but * there could be open fd's still referencing it, so we can't prevent * pending locks from being granted. If the file has really been * deleted, whatever the client does once the lock is granted will * fail with the appropriate error, so we don't need to worry about * it here. */ list_for_each_entry(dom, &pl_inode->dom_list, inode_list) { __grant_blocked_inode_locks(xl, pl_inode, &granted, dom, &now, &contend); } } pthread_mutex_unlock(&pl_inode->mutex); unwind_granted_inodes(xl, pl_inode, &granted); inodelk_contention_notify(xl, &contend); inode_unref(pl_inode->inode); } void pl_inode_remove_unlocked(xlator_t *xl, pl_inode_t *pl_inode, struct list_head *list) { call_stub_t *stub, *tmp; if (!pl_inode->is_locked) { return; } list_for_each_entry_safe(stub, tmp, &pl_inode->waiting, list) { if (!pl_inode_has_owners(xl, stub->frame->root->client, pl_inode, NULL, NULL)) { list_move_tail(&stub->list, list); } } } /* This function determines if an inodelk attempt can be done now or it needs * to wait. * * Possible return values: * < 0: An error occurred. Currently only -ESTALE can be returned if the * inode has been deleted previously by unlink/rmdir/rename * = 0: The lock can be attempted. * > 0: The lock needs to wait because a conflicting remove operation is * ongoing. */ int32_t pl_inode_remove_inodelk(pl_inode_t *pl_inode, pl_inode_lock_t *lock) { pl_dom_list_t *dom; pl_inode_lock_t *ilock; /* We only synchronize with locks made for regular operations coming from * the user. Locks done for internal purposes are hard to control and could * lead to long delays or deadlocks quite easily. */ if (lock->client_pid < 0) { return 0; } if (!pl_inode->is_locked) { return 0; } if (pl_inode->remove_running > 0) { return 1; } list_for_each_entry(dom, &pl_inode->dom_list, inode_list) { list_for_each_entry(ilock, &dom->inodelk_list, list) { /* If a lock from the same client is already granted, we allow this * one to continue. This is necessary to prevent deadlocks when * multiple locks are taken for the same operation. * * On the other side it's unlikely that the same client sends * completely unrelated locks for the same inode. */ if (ilock->client == lock->client) { return 0; } } } return 1; } glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/pl-messages.h0000644000000000000000000000013014522202451024163 xustar000000000000000029 mtime=1699284265.67302745 29 atime=1699284265.67302745 30 ctime=1699284303.291140755 glusterfs-11.1/xlators/features/locks/src/pl-messages.h0000664000175100017510000000166214522202451024451 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _PL_MESSAGES_H_ #define _PL_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(PL, PL_MSG_LOCK_NUMBER, PL_MSG_INODELK_CONTENTION_FAILED, PL_MSG_ENTRYLK_CONTENTION_FAILED); #endif /* !_PL_MESSAGES_H_ */ glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/common.h0000644000000000000000000000013214522202451023235 xustar000000000000000030 mtime=1699284265.672027447 30 atime=1699284265.672027447 30 ctime=1699284303.285140737 glusterfs-11.1/xlators/features/locks/src/common.h0000664000175100017510000002213014522202451023512 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012, 2015-2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __COMMON_H__ #define __COMMON_H__ /*dump locks format strings */ #define RANGE_FMT "type=%s, whence=%hd, start=%llu, len=%llu" #define ENTRY_FMT "type=%s on basename=%s" #define DUMP_GEN_FMT "pid = %llu, owner=%s, client=%p" #define GRNTD_AT "granted at %s" #define BLKD_AT "blocked at %s" #define CONN_ID "connection-id=%s" #define DUMP_BLKD_FMT DUMP_GEN_FMT ", " CONN_ID ", " BLKD_AT #define DUMP_GRNTD_FMT DUMP_GEN_FMT ", " CONN_ID ", " GRNTD_AT #define DUMP_BLKD_GRNTD_FMT DUMP_GEN_FMT ", " CONN_ID ", " BLKD_AT ", " GRNTD_AT #define ENTRY_BLKD_FMT ENTRY_FMT ", " DUMP_BLKD_FMT #define ENTRY_GRNTD_FMT ENTRY_FMT ", " DUMP_GRNTD_FMT #define ENTRY_BLKD_GRNTD_FMT ENTRY_FMT ", " DUMP_BLKD_GRNTD_FMT #define RANGE_BLKD_FMT RANGE_FMT ", " DUMP_BLKD_FMT #define RANGE_GRNTD_FMT RANGE_FMT ", " DUMP_GRNTD_FMT #define RANGE_BLKD_GRNTD_FMT RANGE_FMT ", " DUMP_BLKD_GRNTD_FMT #define SET_FLOCK_PID(flock, lock) ((flock)->l_pid = lock->client_pid) #define PL_STACK_UNWIND_AND_FREE(__local, fop, frame, op_ret, params...) \ do { \ frame->local = NULL; \ STACK_UNWIND_STRICT(fop, frame, op_ret, params); \ if (__local) { \ if (__local->inodelk_dom_count_req) { \ data_unref(__local->inodelk_dom_count_req); \ __local->inodelk_dom_count_req = NULL; \ } \ loc_wipe(&__local->loc[0]); \ loc_wipe(&__local->loc[1]); \ if (__local->fd) { \ fd_unref(__local->fd); \ __local->fd = NULL; \ } \ if (__local->inode) { \ inode_unref(__local->inode); \ __local->inode = NULL; \ } \ if (__local->xdata) { \ dict_unref(__local->xdata); \ __local->xdata = NULL; \ } \ mem_put(__local); \ } \ } while (0) enum { PL_LOCK_GRANTED = 0, PL_LOCK_WOULD_BLOCK, PL_LOCK_QUEUED }; posix_lock_t * new_posix_lock(struct gf_flock *flock, client_t *client, pid_t client_pid, gf_lkowner_t *owner, fd_t *fd, uint32_t lk_flags, int blocking, int32_t *op_errno); pl_inode_t * pl_inode_get(xlator_t *this, inode_t *inode, pl_local_t *local); posix_lock_t * pl_getlk(pl_inode_t *inode, posix_lock_t *lock); int pl_setlk(xlator_t *this, pl_inode_t *inode, posix_lock_t *lock, int can_block); int pl_lock_preempt(pl_inode_t *pl_inode, posix_lock_t *reqlock); void grant_blocked_locks(xlator_t *this, pl_inode_t *inode); void posix_lock_to_flock(posix_lock_t *lock, struct gf_flock *flock); int locks_overlap(posix_lock_t *l1, posix_lock_t *l2); int same_owner(posix_lock_t *l1, posix_lock_t *l2); void __delete_lock(posix_lock_t *); void __destroy_lock(posix_lock_t *); pl_dom_list_t * get_domain(pl_inode_t *pl_inode, const char *volume); void grant_blocked_inode_locks(xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, struct timespec *now, struct list_head *contend); void inodelk_contention_notify(xlator_t *this, struct list_head *contend); void __delete_inode_lock(pl_inode_lock_t *lock); void __pl_inodelk_unref(pl_inode_lock_t *lock); void __grant_blocked_inode_locks(xlator_t *this, pl_inode_t *pl_inode, struct list_head *granted, pl_dom_list_t *dom, struct timespec *now, struct list_head *contend); void unwind_granted_inodes(xlator_t *this, pl_inode_t *pl_inode, struct list_head *granted); void grant_blocked_entry_locks(xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, struct timespec *now, struct list_head *contend); void entrylk_contention_notify(xlator_t *this, struct list_head *contend); void pl_update_refkeeper(xlator_t *this, inode_t *inode); int32_t __get_inodelk_count(xlator_t *this, pl_inode_t *pl_inode, char *domname); int32_t get_inodelk_count(xlator_t *this, inode_t *inode, char *domname); int32_t __get_entrylk_count(xlator_t *this, pl_inode_t *pl_inode); int32_t get_entrylk_count(xlator_t *this, inode_t *inode); void pl_trace_in(xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc, int cmd, struct gf_flock *flock, const char *domain); void pl_trace_out(xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc, int cmd, struct gf_flock *flock, int op_ret, int op_errno, const char *domain); void pl_trace_block(xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc, int cmd, struct gf_flock *flock, const char *domain); void pl_trace_flush(xlator_t *this, call_frame_t *frame, fd_t *fd); void entrylk_trace_in(xlator_t *this, call_frame_t *frame, const char *volume, fd_t *fd, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type); void entrylk_trace_out(xlator_t *this, call_frame_t *frame, const char *volume, fd_t *fd, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, int op_ret, int op_errno); void entrylk_trace_block(xlator_t *this, call_frame_t *frame, const char *volume, fd_t *fd, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type); void pl_print_verdict(char *str, int size, int op_ret, int op_errno); void pl_print_lockee(char *str, int size, fd_t *fd, loc_t *loc); void pl_print_locker(char *str, int size, xlator_t *this, call_frame_t *frame); void pl_print_inodelk(char *str, int size, int cmd, struct gf_flock *flock, const char *domain); void pl_trace_release(xlator_t *this, fd_t *fd); unsigned long fd_to_fdnum(fd_t *fd); fd_t * fd_from_fdnum(posix_lock_t *lock); int pl_reserve_setlk(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, int can_block); int reservelks_equal(posix_lock_t *l1, posix_lock_t *l2); int pl_verify_reservelk(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, int can_block); int pl_reserve_unlock(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *reqlock); int32_t check_entrylk_on_basename(xlator_t *this, inode_t *parent, char *basename); void __pl_inodelk_unref(pl_inode_lock_t *lock); void __pl_entrylk_unref(pl_entry_lock_t *lock); int pl_metalock_is_active(pl_inode_t *pl_inode); void __pl_queue_lock(pl_inode_t *pl_inode, posix_lock_t *reqlock); void inodelk_contention_notify_check(xlator_t *xl, pl_inode_lock_t *lock, struct timespec *now, struct list_head *contend); void entrylk_contention_notify_check(xlator_t *xl, pl_entry_lock_t *lock, struct timespec *now, struct list_head *contend); gf_boolean_t pl_does_monkey_want_stuck_lock(void); gf_boolean_t pl_is_mandatory_locking_enabled(pl_inode_t *pl_inode); void pl_clean_local(pl_local_t *local); int pl_local_init(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd); gf_boolean_t pl_is_lk_owner_valid(gf_lkowner_t *owner, client_t *client); int32_t pl_inode_remove_prepare(xlator_t *xl, call_frame_t *frame, loc_t *loc, pl_inode_t **ppl_inode, struct list_head *contend); int32_t pl_inode_remove_complete(xlator_t *xl, pl_inode_t *pl_inode, call_stub_t *stub, struct list_head *contend); void pl_inode_remove_wake(struct list_head *list); void pl_inode_remove_cbk(xlator_t *xl, pl_inode_t *pl_inode, int32_t error); void pl_inode_remove_unlocked(xlator_t *xl, pl_inode_t *pl_inode, struct list_head *list); int32_t pl_inode_remove_inodelk(pl_inode_t *pl_inode, pl_inode_lock_t *lock); #endif /* __COMMON_H__ */ glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/posix.c0000644000000000000000000000013114522202451023101 xustar000000000000000030 mtime=1699284265.674027453 29 atime=1699284265.67302745 30 ctime=1699284303.294140764 glusterfs-11.1/xlators/features/locks/src/posix.c0000664000175100017510000044147114522202451023374 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012, 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include "locks.h" #include "common.h" #include #include "clear.h" #include #ifndef LLONG_MAX #define LLONG_MAX LONG_LONG_MAX /* compat with old gcc */ #endif /* LLONG_MAX */ /* Forward declarations */ void do_blocked_rw(pl_inode_t *); static int __rw_allowable(pl_inode_t *, posix_lock_t *, glusterfs_fop_t); static int format_brickname(char *); int pl_lockinfo_get_brickname(xlator_t *, inode_t *, int32_t *); static int fetch_pathinfo(xlator_t *, inode_t *, int32_t *, char **); static void set_bit(uint32_t *byte, uint32_t bit_number); /* * The client is always requesting data, but older * servers were not returning it. Newer ones are, so * the client is receiving a mix of NULL and non-NULL * xdata in the answers when bricks are of different * versions. This triggers a bug in older clients. * To prevent that, we avoid returning extra xdata to * older clients (making the newer brick to behave as * an old brick). */ #define PL_STACK_UNWIND_FOR_CLIENT(fop, xdata, frame, op_ret, params...) \ do { \ pl_local_t *__local = NULL; \ if (frame->root->client && \ (frame->root->client->opversion < GD_OP_VERSION_3_10_0)) { \ __local = frame->local; \ PL_STACK_UNWIND_AND_FREE(__local, fop, frame, op_ret, params); \ } else { \ PL_STACK_UNWIND(fop, xdata, frame, op_ret, params); \ } \ } while (0) #define PL_STACK_UNWIND(fop, xdata, frame, op_ret, params...) \ do { \ pl_local_t *__local = NULL; \ inode_t *__parent = NULL; \ inode_t *__inode = NULL; \ char *__name = NULL; \ dict_t *__unref = NULL; \ int __i = 0; \ __local = frame->local; \ if (op_ret >= 0 && pl_needs_xdata_response(frame->local)) { \ if (xdata) \ dict_ref(xdata); \ else \ xdata = dict_new(); \ if (xdata) { \ __unref = xdata; \ while (__local->fd || __local->loc[__i].inode) { \ pl_get_xdata_rsp_args(__local, #fop, &__parent, &__inode, \ &__name, __i); \ pl_set_xdata_response(frame->this, __local, __parent, \ __inode, __name, xdata, __i > 0); \ if (__local->fd || __i == 1) \ break; \ __i++; \ } \ } \ } \ PL_STACK_UNWIND_AND_FREE(__local, fop, frame, op_ret, params); \ if (__unref) \ dict_unref(__unref); \ } while (0) #define IS_BIT_SET(byte, bit_number) (byte & (1 << bit_number)) #define PL_LOCAL_GET_REQUESTS(frame, this, xdata, __fd, __loc, __newloc) \ do { \ uint32_t bitfield = pl_has_xdata_requests(xdata); \ if (bitfield > 0) { \ if (!frame->local) \ frame->local = mem_get0(this->local_pool); \ pl_local_t *__local = frame->local; \ if (__local) { \ if (__fd) { \ __local->fd = fd_ref(__fd); \ __local->inode = inode_ref(__fd->inode); \ } else { \ if (__loc) \ loc_copy(&__local->loc[0], __loc); \ if (__newloc) \ loc_copy(&__local->loc[1], __newloc); \ __local->inode = inode_ref(__local->loc[0].inode); \ } \ __local->bitfield = bitfield; \ pl_get_xdata_requests(__local, xdata); \ } \ } \ } while (0) #define PL_CHECK_LOCK_ENFORCE_KEY(frame, dict, name, this, loc, fd, priv) \ do { \ if ((dict && (dict_get(dict, GF_ENFORCE_MANDATORY_LOCK))) || \ (name && (strcmp(name, GF_ENFORCE_MANDATORY_LOCK) == 0))) { \ inode_t *__inode = (loc ? loc->inode : fd->inode); \ pl_inode_t *__pl_inode = pl_inode_get(this, __inode, NULL); \ if (__pl_inode == NULL) { \ op_ret = -1; \ op_errno = ENOMEM; \ goto unwind; \ } \ if (!pl_is_mandatory_locking_enabled(__pl_inode) || \ !priv->mlock_enforced) { \ op_ret = -1; \ gf_msg(this->name, GF_LOG_DEBUG, EINVAL, 0, \ "option %s would need mandatory lock to be enabled " \ "and feature.enforce-mandatory-lock option to be set " \ "to on", \ GF_ENFORCE_MANDATORY_LOCK); \ op_errno = EINVAL; \ goto unwind; \ } \ \ op_ret = pl_local_init(frame, this, loc, fd); \ if (op_ret) { \ op_errno = ENOMEM; \ goto unwind; \ } \ \ ((pl_local_t *)(frame->local))->update_mlock_enforced_flag = 1; \ } \ } while (0) #define PL_INODE_REMOVE(_fop, _frame, _xl, _loc1, _loc2, _cont, _cbk, \ _args...) \ ({ \ struct list_head contend; \ pl_inode_t *__pl_inode; \ call_stub_t *__stub; \ int32_t __error; \ INIT_LIST_HEAD(&contend); \ __error = pl_inode_remove_prepare(_xl, _frame, _loc2 ? _loc2 : _loc1, \ &__pl_inode, &contend); \ if (__error < 0) { \ __stub = fop_##_fop##_stub(_frame, _cont, ##_args); \ __error = pl_inode_remove_complete(_xl, __pl_inode, __stub, \ &contend); \ } else if (__error == 0) { \ PL_LOCAL_GET_REQUESTS(_frame, _xl, xdata, ((fd_t *)NULL), _loc1, \ _loc2); \ STACK_WIND_COOKIE(_frame, _cbk, __pl_inode, FIRST_CHILD(_xl), \ FIRST_CHILD(_xl)->fops->_fop, ##_args); \ } \ __error; \ }) static void set_bit(uint32_t *byte, uint32_t bit_number) { *byte = (*byte | (1 << bit_number)); } static uint32_t pl_has_xdata_requests(dict_t *xdata) { uint32_t bitfield = 0; if (!xdata) return _gf_false; if (dict_del_sizen(xdata, GLUSTERFS_ENTRYLK_COUNT)) set_bit(&bitfield, GLUSTERFS_ENTRYLK_COUNT_BIT); if (dict_del_sizen(xdata, GLUSTERFS_INODELK_COUNT)) set_bit(&bitfield, GLUSTERFS_INODELK_COUNT_BIT); if (dict_del_sizen(xdata, GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS)) set_bit(&bitfield, GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS_BIT); if (dict_getn(xdata, GLUSTERFS_INODELK_DOM_COUNT, SLEN(GLUSTERFS_INODELK_DOM_COUNT))) set_bit(&bitfield, GLUSTERFS_INODELK_DOM_COUNT_BIT); if (dict_del_sizen(xdata, GLUSTERFS_POSIXLK_COUNT)) set_bit(&bitfield, GLUSTERFS_POSIXLK_COUNT_BIT); if (dict_del_sizen(xdata, GLUSTERFS_PARENT_ENTRYLK)) set_bit(&bitfield, GLUSTERFS_PARENT_ENTRYLK_BIT); return bitfield; } static int dict_delete_domain_key(dict_t *dict, char *key, data_t *value, void *data) { dict_del(dict, key); return 0; } static void pl_get_xdata_requests(pl_local_t *local, dict_t *xdata) { if (!local || !xdata) return; GF_ASSERT(local->xdata == NULL); local->xdata = dict_copy_with_ref(xdata, NULL); if (IS_BIT_SET(local->bitfield, GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS_BIT)) { dict_foreach_fnmatch(xdata, GLUSTERFS_INODELK_DOM_PREFIX "*", dict_delete_domain_key, NULL); } local->inodelk_dom_count_req = dict_get_sizen(xdata, GLUSTERFS_INODELK_DOM_COUNT); if (local->inodelk_dom_count_req) { data_ref(local->inodelk_dom_count_req); dict_del_sizen(xdata, GLUSTERFS_INODELK_DOM_COUNT); } } gf_boolean_t pl_needs_xdata_response(pl_local_t *local) { if (!local) return _gf_false; if (local->bitfield) return _gf_true; return _gf_false; } void pl_get_xdata_rsp_args(pl_local_t *local, char *fop, inode_t **parent, inode_t **inode, char **name, int i) { if (strcmp(fop, "lookup") == 0) { *parent = local->loc[0].parent; *inode = local->loc[0].inode; *name = (char *)local->loc[0].name; } else { if (local->fd) { *inode = local->fd->inode; } else { *inode = local->loc[i].parent; } } } static inline int pl_track_io_fop_count(pl_local_t *local, xlator_t *this, pl_count_op_t op) { pl_inode_t *pl_inode = NULL; if (!local) return -1; pl_inode = pl_inode_get(this, local->inode, NULL); if (!pl_inode) return -1; if (pl_inode->mlock_enforced && pl_inode->track_fop_wind_count) { pthread_mutex_lock(&pl_inode->mutex); { if (op == DECREMENT) { pl_inode->fop_wind_count--; /* fop_wind_count can go negative when lock enforcement is * enabled on unwind path of an IO. Hence the "<" comparision. */ if (pl_inode->fop_wind_count <= 0) { pthread_cond_broadcast(&pl_inode->check_fop_wind_count); pl_inode->track_fop_wind_count = _gf_false; pl_inode->fop_wind_count = 0; } } else { pl_inode->fop_wind_count++; } } pthread_mutex_unlock(&pl_inode->mutex); } return 0; } static int32_t __get_posixlk_count(pl_inode_t *pl_inode) { posix_lock_t *lock = NULL; int32_t count = 0; list_for_each_entry(lock, &pl_inode->ext_list, list) { count++; } return count; } int32_t get_posixlk_count(xlator_t *this, inode_t *inode) { pl_inode_t *pl_inode = NULL; uint64_t tmp_pl_inode = 0; int32_t count = 0; int ret = inode_ctx_get(inode, this, &tmp_pl_inode); if (ret != 0) { goto out; } pl_inode = (pl_inode_t *)(long)tmp_pl_inode; pthread_mutex_lock(&pl_inode->mutex); { count = __get_posixlk_count(pl_inode); } pthread_mutex_unlock(&pl_inode->mutex); out: return count; } void pl_parent_entrylk_xattr_fill(xlator_t *this, inode_t *parent, char *basename, dict_t *dict, gf_boolean_t keep_max) { int32_t entrylk = 0; int32_t maxcount = -1; int ret = -1; if (!parent || !basename) goto out; if (keep_max) { ret = dict_get_int32_sizen(dict, GLUSTERFS_PARENT_ENTRYLK, &maxcount); if (ret < 0) gf_msg_debug(this->name, 0, " Failed to fetch the value for key %s", GLUSTERFS_PARENT_ENTRYLK); } entrylk = check_entrylk_on_basename(this, parent, basename); if (maxcount >= entrylk) return; out: ret = dict_set_int32_sizen(dict, GLUSTERFS_PARENT_ENTRYLK, entrylk); if (ret < 0) { gf_msg_debug(this->name, 0, " dict_set failed on key %s", GLUSTERFS_PARENT_ENTRYLK); } } void pl_entrylk_xattr_fill(xlator_t *this, inode_t *inode, dict_t *dict, gf_boolean_t keep_max) { int32_t count = 0; int32_t maxcount = -1; int ret = -1; if (keep_max) { ret = dict_get_int32_sizen(dict, GLUSTERFS_ENTRYLK_COUNT, &maxcount); if (ret < 0) gf_msg_debug(this->name, 0, " Failed to fetch the value for key %s", GLUSTERFS_ENTRYLK_COUNT); } count = get_entrylk_count(this, inode); if (maxcount >= count) return; ret = dict_set_int32_sizen(dict, GLUSTERFS_ENTRYLK_COUNT, count); if (ret < 0) { gf_msg_debug(this->name, 0, " dict_set failed on key %s", GLUSTERFS_ENTRYLK_COUNT); } } void pl_inodelk_xattr_fill(xlator_t *this, inode_t *inode, dict_t *dict, char *domname, gf_boolean_t keep_max) { int32_t count = 0; int32_t maxcount = -1; int ret = -1; if (keep_max) { ret = dict_get_int32_sizen(dict, GLUSTERFS_INODELK_COUNT, &maxcount); if (ret < 0) gf_msg_debug(this->name, 0, " Failed to fetch the value for key %s", GLUSTERFS_INODELK_COUNT); } count = get_inodelk_count(this, inode, domname); if (maxcount >= count) return; ret = dict_set_int32_sizen(dict, GLUSTERFS_INODELK_COUNT, count); if (ret < 0) { gf_msg_debug(this->name, 0, "Failed to set count for " "key %s", GLUSTERFS_INODELK_COUNT); } return; } void pl_posixlk_xattr_fill(xlator_t *this, inode_t *inode, dict_t *dict, gf_boolean_t keep_max) { int32_t count = 0; int32_t maxcount = -1; int ret = -1; if (keep_max) { ret = dict_get_int32_sizen(dict, GLUSTERFS_POSIXLK_COUNT, &maxcount); if (ret < 0) gf_msg_debug(this->name, 0, " Failed to fetch the value for key %s", GLUSTERFS_POSIXLK_COUNT); } count = get_posixlk_count(this, inode); if (maxcount >= count) return; ret = dict_set_int32_sizen(dict, GLUSTERFS_POSIXLK_COUNT, count); if (ret < 0) { gf_msg_debug(this->name, 0, " dict_set failed on key %s", GLUSTERFS_POSIXLK_COUNT); } } void pl_inodelk_xattr_fill_each(xlator_t *this, inode_t *inode, dict_t *dict, char *domname, gf_boolean_t keep_max, char *key) { int32_t count = 0; int32_t maxcount = -1; int ret = -1; if (keep_max) { ret = dict_get_int32(dict, key, &maxcount); if (ret < 0) gf_msg_debug(this->name, 0, " Failed to fetch the value for key %s", GLUSTERFS_INODELK_COUNT); } count = get_inodelk_count(this, inode, domname); if (maxcount >= count) return; ret = dict_set_int32(dict, key, count); if (ret < 0) { gf_msg_debug(this->name, 0, "Failed to set count for " "key %s", key); } return; } static int pl_inodelk_xattr_fill_multiple(dict_t *this, char *key, data_t *value, void *data) { multi_dom_lk_data *d = data; char *tmp_key = NULL; char *save_ptr = NULL; tmp_key = gf_strdup(key); if (!tmp_key) return -1; strtok_r(tmp_key, ":", &save_ptr); if (!*save_ptr) { if (tmp_key) GF_FREE(tmp_key); gf_msg(THIS->name, GF_LOG_ERROR, 0, EINVAL, "Could not tokenize domain string from key %s", key); return -1; } pl_inodelk_xattr_fill_each(d->this, d->inode, d->xdata_rsp, save_ptr, d->keep_max, key); if (tmp_key) GF_FREE(tmp_key); return 0; } void pl_fill_multiple_dom_lk_requests(xlator_t *this, pl_local_t *local, inode_t *inode, dict_t *dict, gf_boolean_t keep_max) { multi_dom_lk_data data; data.this = this; data.inode = inode; data.xdata_rsp = dict; data.keep_max = keep_max; dict_foreach_fnmatch(local->xdata, GLUSTERFS_INODELK_DOM_PREFIX "*", pl_inodelk_xattr_fill_multiple, &data); } void pl_set_xdata_response(xlator_t *this, pl_local_t *local, inode_t *parent, inode_t *inode, char *name, dict_t *xdata, gf_boolean_t max_lock) { if (!xdata || !local) return; if (IS_BIT_SET(local->bitfield, GLUSTERFS_PARENT_ENTRYLK_BIT) && parent && name && name[0] != '\0') pl_parent_entrylk_xattr_fill(this, parent, name, xdata, max_lock); if (!inode) return; if (IS_BIT_SET(local->bitfield, GLUSTERFS_ENTRYLK_COUNT_BIT)) pl_entrylk_xattr_fill(this, inode, xdata, max_lock); if (local->inodelk_dom_count_req) pl_inodelk_xattr_fill(this, inode, xdata, data_to_str(local->inodelk_dom_count_req), max_lock); if (IS_BIT_SET(local->bitfield, GLUSTERFS_INODELK_COUNT_BIT)) pl_inodelk_xattr_fill(this, inode, xdata, NULL, max_lock); if (IS_BIT_SET(local->bitfield, GLUSTERFS_POSIXLK_COUNT_BIT)) pl_posixlk_xattr_fill(this, inode, xdata, max_lock); if (IS_BIT_SET(local->bitfield, GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS_BIT)) pl_fill_multiple_dom_lk_requests(this, local, inode, xdata, max_lock); } /* Checks whether the region where fop is acting upon conflicts * with existing locks. If there is no conflict function returns * 1 else returns 0 with can_block boolean set accordingly to * indicate block/fail the fop. */ int pl_is_fop_allowed(pl_inode_t *pl_inode, posix_lock_t *region, fd_t *fd, glusterfs_fop_t op, gf_boolean_t *can_block) { int ret = 0; if (!__rw_allowable(pl_inode, region, op)) { if (pl_inode->mlock_enforced) { *can_block = _gf_false; } else if ((!fd) || (fd && (fd->flags & O_NONBLOCK))) { gf_log("locks", GF_LOG_TRACE, "returning EAGAIN" " because fd is O_NONBLOCK"); *can_block = _gf_false; } else { *can_block = _gf_true; } } else { ret = 1; } return ret; } static pl_fdctx_t * pl_new_fdctx(void) { pl_fdctx_t *fdctx = GF_MALLOC(sizeof(*fdctx), gf_locks_mt_pl_fdctx_t); GF_VALIDATE_OR_GOTO("posix-locks", fdctx, out); INIT_LIST_HEAD(&fdctx->locks_list); out: return fdctx; } static pl_fdctx_t * pl_check_n_create_fdctx(xlator_t *this, fd_t *fd) { int ret = 0; pl_fdctx_t *fdctx = NULL; GF_VALIDATE_OR_GOTO("posix-locks", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); LOCK(&fd->lock); { fdctx = __fd_ctx_get_ptr(fd, this); if (fdctx) goto unlock; fdctx = pl_new_fdctx(); if (fdctx == NULL) { goto unlock; } ret = __fd_ctx_set(fd, this, (uint64_t)(long)fdctx); if (ret != 0) { UNLOCK(&fd->lock); GF_FREE(fdctx); fdctx = NULL; gf_log(this->name, GF_LOG_DEBUG, "failed to set fd ctx"); goto out; } } unlock: UNLOCK(&fd->lock); out: return fdctx; } int32_t pl_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, DECREMENT); PL_STACK_UNWIND(discard, xdata, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int pl_discard_cont(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, INCREMENT); STACK_WIND(frame, pl_discard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); return 0; } int32_t pl_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { pl_local_t *local = NULL; pl_inode_t *pl_inode = NULL; pl_rw_req_t *rw = NULL; posix_lock_t region = { .list = { 0, }, }; gf_boolean_t enabled = _gf_false; gf_boolean_t can_block = _gf_true; int op_ret = 0; int op_errno = 0; int allowed = 1; GF_VALIDATE_OR_GOTO("locks", this, unwind); local = mem_get0(this->local_pool); if (!local) { op_ret = -1; op_errno = ENOMEM; goto unwind; } frame->local = local; local->inode = inode_ref(fd->inode); local->fd = fd_ref(fd); pl_inode = pl_inode_get(this, fd->inode, local); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } if (frame->root->pid < 0) enabled = _gf_false; else enabled = pl_is_mandatory_locking_enabled(pl_inode); if (enabled) { region.fl_start = offset; region.fl_end = offset + len - 1; region.client = frame->root->client; region.fd_num = fd_to_fdnum(fd); region.client_pid = frame->root->pid; lk_owner_copy(®ion.owner, &frame->root->lk_owner); pthread_mutex_lock(&pl_inode->mutex); { allowed = pl_is_fop_allowed(pl_inode, ®ion, fd, GF_FOP_DISCARD, &can_block); if (allowed == 1) { if (pl_inode->mlock_enforced && pl_inode->track_fop_wind_count) { pl_inode->fop_wind_count++; } goto unlock; } else if (!can_block) { op_errno = EAGAIN; op_ret = -1; goto unlock; } rw = GF_MALLOC(sizeof(*rw), gf_locks_mt_pl_rw_req_t); if (!rw) { op_errno = ENOMEM; op_ret = -1; goto unlock; } rw->stub = fop_discard_stub(frame, pl_discard_cont, fd, offset, len, xdata); if (!rw->stub) { op_errno = ENOMEM; op_ret = -1; GF_FREE(rw); goto unlock; } rw->region = region; list_add_tail(&rw->list, &pl_inode->rw_list); } unlock: pthread_mutex_unlock(&pl_inode->mutex); } if (allowed == 1) STACK_WIND(frame, pl_discard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); unwind: if (op_ret == -1) PL_STACK_UNWIND(discard, xdata, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } int32_t pl_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, DECREMENT); PL_STACK_UNWIND(zerofill, xdata, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int pl_zerofill_cont(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, INCREMENT); STACK_WIND(frame, pl_zerofill_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata); return 0; } int32_t pl_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { pl_local_t *local = NULL; pl_inode_t *pl_inode = NULL; pl_rw_req_t *rw = NULL; posix_lock_t region = { .list = { 0, }, }; gf_boolean_t enabled = _gf_false; gf_boolean_t can_block = _gf_true; int op_ret = 0; int op_errno = 0; int allowed = 1; GF_VALIDATE_OR_GOTO("locks", this, unwind); local = mem_get0(this->local_pool); if (!local) { op_ret = -1; op_errno = ENOMEM; goto unwind; } frame->local = local; local->inode = inode_ref(fd->inode); local->fd = fd_ref(fd); pl_inode = pl_inode_get(this, fd->inode, local); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } if (frame->root->pid < 0) enabled = _gf_false; else enabled = pl_is_mandatory_locking_enabled(pl_inode); if (enabled) { region.fl_start = offset; region.fl_end = offset + len - 1; region.client = frame->root->client; region.fd_num = fd_to_fdnum(fd); region.client_pid = frame->root->pid; lk_owner_copy(®ion.owner, &frame->root->lk_owner); pthread_mutex_lock(&pl_inode->mutex); { allowed = pl_is_fop_allowed(pl_inode, ®ion, fd, GF_FOP_ZEROFILL, &can_block); if (allowed == 1) { if (pl_inode->mlock_enforced && pl_inode->track_fop_wind_count) { pl_inode->fop_wind_count++; } goto unlock; } else if (!can_block) { op_errno = EAGAIN; op_ret = -1; goto unlock; } rw = GF_MALLOC(sizeof(*rw), gf_locks_mt_pl_rw_req_t); if (!rw) { op_errno = ENOMEM; op_ret = -1; goto unlock; } rw->stub = fop_zerofill_stub(frame, pl_zerofill_cont, fd, offset, len, xdata); if (!rw->stub) { op_errno = ENOMEM; op_ret = -1; GF_FREE(rw); goto unlock; } rw->region = region; list_add_tail(&rw->list, &pl_inode->rw_list); } unlock: pthread_mutex_unlock(&pl_inode->mutex); } if (allowed == 1) STACK_WIND(frame, pl_zerofill_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata); unwind: if (op_ret == -1) PL_STACK_UNWIND(zerofill, xdata, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } int pl_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { pl_local_t *local = frame->local; pl_track_io_fop_count(local, this, DECREMENT); if (local->op == GF_FOP_TRUNCATE) PL_STACK_UNWIND(truncate, xdata, frame, op_ret, op_errno, prebuf, postbuf, xdata); else PL_STACK_UNWIND(ftruncate, xdata, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int pl_ftruncate_cont(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, INCREMENT); STACK_WIND(frame, pl_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } int pl_truncate_cont(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, INCREMENT); STACK_WIND(frame, pl_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } static int truncate_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { pl_local_t *local = frame->local; inode_t *inode = NULL; pl_inode_t *pl_inode = NULL; pl_rw_req_t *rw = NULL; posix_lock_t region = { .list = { 0, }, }; gf_boolean_t enabled = _gf_false; gf_boolean_t can_block = _gf_true; int allowed = 1; GF_VALIDATE_OR_GOTO("locks", this, unwind); if (op_ret != 0) { gf_log(this->name, GF_LOG_ERROR, "got error (errno=%d, stderror=%s) from child", op_errno, strerror(op_errno)); goto unwind; } if (local->op == GF_FOP_TRUNCATE) inode = local->loc[0].inode; else inode = local->fd->inode; local->inode = inode_ref(inode); pl_inode = pl_inode_get(this, inode, local); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } if (frame->root->pid < 0) enabled = _gf_false; else enabled = pl_is_mandatory_locking_enabled(pl_inode); if (enabled) { region.fl_start = local->offset; region.fl_end = LLONG_MAX; region.client = frame->root->client; region.fd_num = fd_to_fdnum(local->fd); region.client_pid = frame->root->pid; lk_owner_copy(®ion.owner, &frame->root->lk_owner); pthread_mutex_lock(&pl_inode->mutex); { allowed = pl_is_fop_allowed(pl_inode, ®ion, local->fd, local->op, &can_block); if (allowed == 1) { if (pl_inode->mlock_enforced && pl_inode->track_fop_wind_count) { pl_inode->fop_wind_count++; } goto unlock; } else if (!can_block) { op_errno = EAGAIN; op_ret = -1; goto unlock; } rw = GF_MALLOC(sizeof(*rw), gf_locks_mt_pl_rw_req_t); if (!rw) { op_errno = ENOMEM; op_ret = -1; goto unlock; } if (local->op == GF_FOP_TRUNCATE) rw->stub = fop_truncate_stub(frame, pl_truncate_cont, &local->loc[0], local->offset, local->xdata); else rw->stub = fop_ftruncate_stub(frame, pl_ftruncate_cont, local->fd, local->offset, local->xdata); if (!rw->stub) { op_errno = ENOMEM; op_ret = -1; GF_FREE(rw); goto unlock; } rw->region = region; list_add_tail(&rw->list, &pl_inode->rw_list); } unlock: pthread_mutex_unlock(&pl_inode->mutex); } if (allowed == 1) { switch (local->op) { case GF_FOP_TRUNCATE: STACK_WIND(frame, pl_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, &local->loc[0], local->offset, local->xdata); break; case GF_FOP_FTRUNCATE: STACK_WIND(frame, pl_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, local->fd, local->offset, local->xdata); break; default: break; } } unwind: if (op_ret == -1) { gf_log(this ? this->name : "locks", GF_LOG_ERROR, "truncate failed with " "ret: %d, error: %s", op_ret, strerror(op_errno)); switch (local->op) { case GF_FOP_TRUNCATE: PL_STACK_UNWIND(truncate, xdata, frame, op_ret, op_errno, buf, NULL, xdata); break; case GF_FOP_FTRUNCATE: PL_STACK_UNWIND(ftruncate, xdata, frame, op_ret, op_errno, buf, NULL, xdata); break; default: break; } } return 0; } int pl_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { pl_local_t *local = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("locks", this, unwind); local = mem_get0(this->local_pool); GF_VALIDATE_OR_GOTO(this->name, local, unwind); local->op = GF_FOP_TRUNCATE; local->offset = offset; loc_copy(&local->loc[0], loc); if (xdata) local->xdata = dict_ref(xdata); frame->local = local; STACK_WIND(frame, truncate_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, NULL); ret = 0; unwind: if (ret == -1) { gf_log(this ? this->name : "locks", GF_LOG_ERROR, "truncate on %s failed with" " ret: %d, error: %s", loc->path, -1, strerror(ENOMEM)); STACK_UNWIND_STRICT(truncate, frame, -1, ENOMEM, NULL, NULL, NULL); } return 0; } int pl_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { pl_local_t *local = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("locks", this, unwind); local = mem_get0(this->local_pool); GF_VALIDATE_OR_GOTO(this->name, local, unwind); local->op = GF_FOP_FTRUNCATE; local->offset = offset; local->fd = fd_ref(fd); if (xdata) local->xdata = dict_ref(xdata); frame->local = local; STACK_WIND(frame, truncate_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); ret = 0; unwind: if (ret == -1) { gf_log(this ? this->name : "locks", GF_LOG_ERROR, "ftruncate failed with" " ret: %d, error: %s", -1, strerror(ENOMEM)); STACK_UNWIND_STRICT(ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL); } return 0; } int pl_locks_by_fd(pl_inode_t *pl_inode, fd_t *fd) { posix_lock_t *l = NULL; int found = 0; pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry(l, &pl_inode->ext_list, list) { if (l->fd_num == fd_to_fdnum(fd)) { found = 1; break; } } } pthread_mutex_unlock(&pl_inode->mutex); return found; } static void delete_locks_of_fd(xlator_t *this, pl_inode_t *pl_inode, fd_t *fd) { posix_lock_t *tmp = NULL; posix_lock_t *l = NULL; pl_local_t *local; struct list_head blocked_list; INIT_LIST_HEAD(&blocked_list); pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry_safe(l, tmp, &pl_inode->ext_list, list) { if (l->fd_num == fd_to_fdnum(fd)) { if (l->blocked) { list_move_tail(&l->list, &blocked_list); continue; } __delete_lock(l); __destroy_lock(l); } } } pthread_mutex_unlock(&pl_inode->mutex); list_for_each_entry_safe(l, tmp, &blocked_list, list) { list_del_init(&l->list); local = l->frame->local; PL_STACK_UNWIND_AND_FREE(local, lk, l->frame, -1, EAGAIN, &l->user_flock, NULL); __destroy_lock(l); } grant_blocked_locks(this, pl_inode); do_blocked_rw(pl_inode); } static void __delete_locks_of_owner(pl_inode_t *pl_inode, client_t *client, gf_lkowner_t *owner) { posix_lock_t *tmp = NULL; posix_lock_t *l = NULL; /* TODO: what if it is a blocked lock with pending l->frame */ list_for_each_entry_safe(l, tmp, &pl_inode->ext_list, list) { if (l->blocked) continue; if ((l->client == client) && is_same_lkowner(&l->owner, owner)) { gf_log("posix-locks", GF_LOG_TRACE, " Flushing lock" "%s (pid=%d) (lk-owner=%s) %" PRId64 " - %" PRId64 " state: %s", l->fl_type == F_UNLCK ? "Unlock" : "Lock", l->client_pid, lkowner_utoa(&l->owner), l->user_flock.l_start, l->user_flock.l_len, l->blocked == 1 ? "Blocked" : "Active"); __delete_lock(l); __destroy_lock(l); } } return; } int32_t pl_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata); return 0; } static int32_t pl_getxattr_clrlk(xlator_t *this, const char *name, inode_t *inode, dict_t **dict, int32_t *op_errno, char *client_uid, pid_t client_pid) { int32_t bcount = 0; int32_t gcount = 0; char *key = NULL; char *lk_summary = NULL; pl_inode_t *pl_inode = NULL; bool setlk_interrupt = false; clrlk_args args = { 0, }; char *brickname = NULL; int32_t op_ret = -1; *op_errno = EINVAL; if (clrlk_parse_args(name, &args)) { *op_errno = EINVAL; goto out; } *dict = dict_new(); if (!*dict) { *op_errno = ENOMEM; goto out; } pl_inode = pl_inode_get(this, inode, NULL); if (!pl_inode) { *op_errno = ENOMEM; goto out; } switch (args.type) { case CLRLK_INODE: case CLRLK_ENTRY: op_ret = clrlk_clear_lks_in_all_domains(this, pl_inode, &args, &bcount, &gcount, op_errno); break; case CLRLK_POSIX: if (!strncmp(name, GF_XATTR_INTRLK_CMD, SLEN(GF_XATTR_INTRLK_CMD))) { setlk_interrupt = true; } op_ret = clrlk_clear_posixlk(this, pl_inode, &args, &bcount, &gcount, op_errno, client_uid, client_pid, setlk_interrupt); break; default: op_ret = -1; *op_errno = EINVAL; } if (op_ret) { if (args.type >= CLRLK_TYPE_MAX) { gf_log(this->name, GF_LOG_ERROR, "clear locks: invalid lock type %d", args.type); } else { gf_log(this->name, GF_LOG_ERROR, "clear locks of type %s failed: %s", clrlk_type_names[args.type], strerror(*op_errno)); } goto out; } op_ret = fetch_pathinfo(this, inode, op_errno, &brickname); if (op_ret) { gf_log(this->name, GF_LOG_WARNING, "Couldn't get brickname"); } else { op_ret = format_brickname(brickname); if (op_ret) { gf_log(this->name, GF_LOG_WARNING, "Couldn't format brickname"); GF_FREE(brickname); brickname = NULL; } } if (!gcount && !bcount) { if (gf_asprintf(&lk_summary, "No locks cleared.") == -1) { op_ret = -1; *op_errno = ENOMEM; goto out; } } else if (gf_asprintf(&lk_summary, "%s: %s blocked locks=%d " "granted locks=%d", (brickname == NULL) ? this->name : brickname, clrlk_type_names[args.type], bcount, gcount) == -1) { op_ret = -1; *op_errno = ENOMEM; goto out; } gf_log(this->name, GF_LOG_DEBUG, "%s", lk_summary); key = gf_strdup(name); if (!key) { op_ret = -1; goto out; } if (dict_set_dynstr(*dict, key, lk_summary)) { op_ret = -1; *op_errno = ENOMEM; goto out; } op_ret = 0; out: GF_FREE(brickname); GF_FREE(args.opts); GF_FREE(key); if (op_ret) { GF_FREE(lk_summary); } return op_ret; } int32_t pl_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int32_t op_errno = EINVAL; int32_t op_ret = -1; dict_t *dict = NULL; char *client_uid = NULL; pid_t client_pid = -1; if (!name) goto usual; if (strncmp(name, GF_XATTR_CLRLK_CMD, SLEN(GF_XATTR_CLRLK_CMD))) goto usual; GF_ASSERT(frame->root); if (frame->root->client) { client_uid = frame->root->client->client_uid; client_pid = frame->root->pid; } if (strncmp(name, GF_XATTR_INTRLK_CMD, SLEN(GF_XATTR_INTRLK_CMD)) == 0) { if (!client_uid || client_pid < 0) goto unwind; } op_ret = pl_getxattr_clrlk(this, name, loc->inode, &dict, &op_errno, client_uid, client_pid); unwind: STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata); if (dict) dict_unref(dict); return 0; usual: STACK_WIND(frame, pl_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); return 0; } static int format_brickname(char *brickname) { int ret = -1; char *hostname = NULL; char *volume = NULL; char *saveptr = NULL; if (!brickname) goto out; strtok_r(brickname, ":", &saveptr); hostname = gf_strdup(strtok_r(NULL, ":", &saveptr)); if (hostname == NULL) goto out; volume = gf_strdup(strtok_r(NULL, ".", &saveptr)); if (volume == NULL) goto out; sprintf(brickname, "%s:%s", hostname, volume); ret = 0; out: GF_FREE(hostname); GF_FREE(volume); return ret; } static int fetch_pathinfo(xlator_t *this, inode_t *inode, int32_t *op_errno, char **brickname) { int ret = -1; loc_t loc = { 0, }; dict_t *dict = NULL; if (!brickname) goto out; if (!op_errno) goto out; gf_uuid_copy(loc.gfid, inode->gfid); loc.inode = inode_ref(inode); ret = syncop_getxattr(FIRST_CHILD(this), &loc, &dict, GF_XATTR_PATHINFO_KEY, NULL, NULL); if (ret < 0) { *op_errno = -ret; ret = -1; goto out; } ret = dict_get_str_sizen(dict, GF_XATTR_PATHINFO_KEY, brickname); if (ret) goto out; *brickname = gf_strdup(*brickname); if (*brickname == NULL) { ret = -1; goto out; } ret = 0; out: if (dict != NULL) { dict_unref(dict); } loc_wipe(&loc); return ret; } int pl_lockinfo_get_brickname(xlator_t *this, inode_t *inode, int32_t *op_errno) { posix_locks_private_t *priv = this->private; char *brickname = NULL; char *end = NULL; char *tmp = NULL; int ret = fetch_pathinfo(this, inode, op_errno, &brickname); if (ret) goto out; end = strrchr(brickname, ':'); if (!end) { GF_FREE(brickname); ret = -1; goto out; } tmp = brickname; brickname = gf_strndup(brickname, (end - brickname)); if (brickname == NULL) { ret = -1; goto out; } priv->brickname = brickname; ret = 0; out: GF_FREE(tmp); return ret; } char * pl_lockinfo_key(xlator_t *this, inode_t *inode, int32_t *op_errno) { posix_locks_private_t *priv = this->private; char *key = NULL; int ret = 0; if (priv->brickname == NULL) { ret = pl_lockinfo_get_brickname(this, inode, op_errno); if (ret < 0) { gf_log(this->name, GF_LOG_WARNING, "cannot get brickname"); goto out; } } key = priv->brickname; out: return key; } int32_t pl_fgetxattr_handle_lockinfo(xlator_t *this, fd_t *fd, dict_t *dict, int32_t *op_errno) { char *key = NULL, *buf = NULL; int32_t op_ret = 0; unsigned long fdnum = 0; int32_t len = 0; dict_t *tmp = NULL; pl_inode_t *pl_inode = pl_inode_get(this, fd->inode, NULL); if (!pl_inode) { gf_log(this->name, GF_LOG_DEBUG, "Could not get inode."); *op_errno = EBADFD; op_ret = -1; goto out; } if (!pl_locks_by_fd(pl_inode, fd)) { op_ret = 0; goto out; } fdnum = fd_to_fdnum(fd); key = pl_lockinfo_key(this, fd->inode, op_errno); if (key == NULL) { op_ret = -1; goto out; } tmp = dict_new(); if (tmp == NULL) { op_ret = -1; *op_errno = ENOMEM; goto out; } op_ret = dict_set_uint64(tmp, key, fdnum); if (op_ret < 0) { *op_errno = -op_ret; op_ret = -1; gf_log(this->name, GF_LOG_WARNING, "setting lockinfo value " "(%lu) for fd (ptr:%p inode-gfid:%s) failed (%s)", fdnum, fd, uuid_utoa(fd->inode->gfid), strerror(*op_errno)); goto out; } op_ret = dict_allocate_and_serialize(tmp, (char **)&buf, (unsigned int *)&len); if (op_ret != 0) { *op_errno = -op_ret; op_ret = -1; gf_log(this->name, GF_LOG_WARNING, "dict_serialized_length failed (%s) while handling " "lockinfo for fd (ptr:%p inode-gfid:%s)", strerror(*op_errno), fd, uuid_utoa(fd->inode->gfid)); goto out; } op_ret = dict_set_dynptr(dict, GF_XATTR_LOCKINFO_KEY, buf, len); if (op_ret < 0) { *op_errno = -op_ret; op_ret = -1; gf_log(this->name, GF_LOG_WARNING, "setting lockinfo value " "(%lu) for fd (ptr:%p inode-gfid:%s) failed (%s)", fdnum, fd, uuid_utoa(fd->inode->gfid), strerror(*op_errno)); goto out; } buf = NULL; out: if (tmp != NULL) { dict_unref(tmp); } if (buf != NULL) { GF_FREE(buf); } return op_ret; } int32_t pl_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int32_t op_ret = 0, op_errno = 0; dict_t *dict = NULL; char *client_uid = NULL; pid_t client_pid = -1; if (!name) { goto usual; } GF_ASSERT(frame->root); if (frame->root->client) { client_uid = frame->root->client->client_uid; client_pid = frame->root->pid; } if (strncmp(name, GF_XATTR_INTRLK_CMD, SLEN(GF_XATTR_INTRLK_CMD)) == 0) { if (!client_uid || client_pid < 0) { op_ret = -1; op_errno = EINVAL; goto unwind; } } if (strcmp(name, GF_XATTR_LOCKINFO_KEY) == 0) { dict = dict_new(); if (dict == NULL) { op_ret = -1; op_errno = ENOMEM; goto unwind; } op_ret = pl_fgetxattr_handle_lockinfo(this, fd, dict, &op_errno); if (op_ret < 0) { gf_log(this->name, GF_LOG_WARNING, "getting lockinfo on fd (ptr:%p inode-gfid:%s) " "failed (%s)", fd, uuid_utoa(fd->inode->gfid), strerror(op_errno)); } goto unwind; } else if (strncmp(name, GF_XATTR_CLRLK_CMD, SLEN(GF_XATTR_CLRLK_CMD)) == 0 || strncmp(name, GF_XATTR_INTRLK_CMD, SLEN(GF_XATTR_INTRLK_CMD)) == 0) { op_ret = pl_getxattr_clrlk(this, name, fd->inode, &dict, &op_errno, client_uid, client_pid); goto unwind; } else { goto usual; } unwind: STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, NULL); if (dict != NULL) { dict_unref(dict); } return 0; usual: STACK_WIND(frame, default_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); return 0; } int32_t pl_migrate_locks(call_frame_t *frame, fd_t *newfd, uint64_t oldfd_num, int32_t *op_errno) { posix_lock_t *l = NULL; int32_t op_ret = 0; uint64_t newfd_num = fd_to_fdnum(newfd); pl_inode_t *pl_inode = pl_inode_get(frame->this, newfd->inode, NULL); if (pl_inode == NULL) { op_ret = -1; *op_errno = EBADFD; goto out; } pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry(l, &pl_inode->ext_list, list) { if (l->fd_num == oldfd_num) { l->fd_num = newfd_num; l->client = frame->root->client; } } } pthread_mutex_unlock(&pl_inode->mutex); op_ret = 0; out: return op_ret; } int32_t pl_fsetxattr_handle_lockinfo(call_frame_t *frame, fd_t *fd, char *lockinfo_buf, int len, int32_t *op_errno) { int32_t op_ret = -1; uint64_t oldfd_num = 0; char *key = NULL; dict_t *lockinfo = dict_new(); if (lockinfo == NULL) { op_ret = -1; *op_errno = ENOMEM; goto out; } op_ret = dict_unserialize(lockinfo_buf, len, &lockinfo); if (op_ret < 0) { *op_errno = -op_ret; op_ret = -1; goto out; } key = pl_lockinfo_key(frame->this, fd->inode, op_errno); if (key == NULL) { op_ret = -1; goto out; } op_ret = dict_get_uint64(lockinfo, key, &oldfd_num); if (oldfd_num == 0) { op_ret = 0; goto out; } op_ret = pl_migrate_locks(frame, fd, oldfd_num, op_errno); if (op_ret < 0) { gf_log(frame->this->name, GF_LOG_WARNING, "migration of locks from oldfd (ptr:%p) to newfd " "(ptr:%p) (inode-gfid:%s)", (void *)(uintptr_t)oldfd_num, fd, uuid_utoa(fd->inode->gfid)); goto out; } out: dict_unref(lockinfo); return op_ret; } int32_t pl_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { pl_local_t *local = NULL; pl_inode_t *pl_inode = NULL; local = frame->local; if (local && local->update_mlock_enforced_flag && op_ret != -1) { pl_inode = pl_inode_get(this, local->inode, NULL); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } pthread_mutex_lock(&pl_inode->mutex); { pl_inode->mlock_enforced = _gf_true; pl_inode->check_mlock_info = _gf_false; } pthread_mutex_unlock(&pl_inode->mutex); } unwind: PL_STACK_UNWIND_FOR_CLIENT(fsetxattr, xdata, frame, op_ret, op_errno, xdata); return 0; } int32_t pl_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { int32_t op_errno = 0; void *lockinfo_buf = NULL; int len = 0; char *name = NULL; posix_locks_private_t *priv = this->private; int32_t op_ret = dict_get_ptr_and_len(dict, GF_XATTR_LOCKINFO_KEY, &lockinfo_buf, &len); if (lockinfo_buf == NULL) { goto usual; } op_ret = pl_fsetxattr_handle_lockinfo(frame, fd, lockinfo_buf, len, &op_errno); if (op_ret < 0) { goto unwind; } usual: PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); PL_CHECK_LOCK_ENFORCE_KEY(frame, dict, name, this, ((loc_t *)NULL), fd, priv); STACK_WIND(frame, pl_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; unwind: PL_STACK_UNWIND_FOR_CLIENT(fsetxattr, xdata, frame, op_ret, op_errno, NULL); return 0; } int32_t pl_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { pl_fdctx_t *fdctx = NULL; if (op_ret < 0) goto unwind; fdctx = pl_check_n_create_fdctx(this, fd); if (!fdctx) { op_errno = ENOMEM; op_ret = -1; goto unwind; } unwind: PL_STACK_UNWIND(opendir, xdata, frame, op_ret, op_errno, fd, xdata); return 0; } int32_t pl_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); return 0; } int pl_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(flush, xdata, frame, op_ret, op_errno, xdata); return 0; } int pl_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { pl_inode_t *pl_inode = pl_inode_get(this, fd->inode, NULL); if (!pl_inode) { gf_log(this->name, GF_LOG_DEBUG, "Could not get inode."); STACK_UNWIND_STRICT(flush, frame, -1, EBADFD, NULL); return 0; } pthread_mutex_lock(&pl_inode->mutex); { if (pl_inode->migrated) { pthread_mutex_unlock(&pl_inode->mutex); STACK_UNWIND_STRICT(flush, frame, -1, EREMOTE, NULL); return 0; } } pthread_mutex_unlock(&pl_inode->mutex); pl_trace_flush(this, frame, fd); if (frame->root->lk_owner.len == 0) { /* Handle special case when protocol/server sets lk-owner to zero. * This usually happens due to a client disconnection. Hence, free * all locks opened with this fd. */ gf_log(this->name, GF_LOG_TRACE, "Releasing all locks with fd %p", fd); delete_locks_of_fd(this, pl_inode, fd); goto wind; } pthread_mutex_lock(&pl_inode->mutex); { __delete_locks_of_owner(pl_inode, frame->root->client, &frame->root->lk_owner); } pthread_mutex_unlock(&pl_inode->mutex); grant_blocked_locks(this, pl_inode); do_blocked_rw(pl_inode); wind: PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_flush_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush, fd, xdata); return 0; } int pl_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { pl_fdctx_t *fdctx = NULL; if (op_ret < 0) goto unwind; fdctx = pl_check_n_create_fdctx(this, fd); if (!fdctx) { op_errno = ENOMEM; op_ret = -1; goto unwind; } unwind: STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, xdata); return 0; } int pl_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { int op_ret = -1; int op_errno = EINVAL; pl_inode_t *pl_inode = NULL; posix_lock_t *l = NULL; posix_locks_private_t *priv = this->private; GF_VALIDATE_OR_GOTO("locks", this, unwind); op_ret = 0, op_errno = 0; pl_inode = pl_inode_get(this, fd->inode, NULL); if (!pl_inode) { gf_msg(this->name, GF_LOG_ERROR, 0, ENOMEM, "Could not get inode"); op_ret = -1; op_errno = ENOMEM; goto unwind; } /* As per design, under forced and file-based mandatory locking modes * it doesn't matter whether inodes's lock list contain advisory or * mandatory type locks. So we just check whether inode's lock list is * empty or not to make sure that no locks are being held for the file. * Whereas under optimal mandatory locking mode, we strictly fail open * if and only if lock list contain mandatory locks. */ if (((priv->mandatory_mode == MLK_FILE_BASED) && pl_inode->mandatory) || priv->mandatory_mode == MLK_FORCED) { if (fd->flags & O_TRUNC) { pthread_mutex_lock(&pl_inode->mutex); { if (!list_empty(&pl_inode->ext_list)) { op_ret = -1; op_errno = EAGAIN; } } pthread_mutex_unlock(&pl_inode->mutex); } } else if (priv->mandatory_mode == MLK_OPTIMAL) { if (fd->flags & O_TRUNC) { pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry(l, &pl_inode->ext_list, list) { if ((l->lk_flags & GF_LK_MANDATORY)) { op_ret = -1; op_errno = EAGAIN; break; } } } pthread_mutex_unlock(&pl_inode->mutex); } } unwind: if (op_ret == -1) STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, NULL, NULL); else STACK_WIND(frame, pl_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; } int pl_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { pl_fdctx_t *fdctx = NULL; if (op_ret < 0) goto unwind; fdctx = pl_check_n_create_fdctx(this, fd); if (!fdctx) { op_errno = ENOMEM; op_ret = -1; goto unwind; } unwind: PL_STACK_UNWIND(create, xdata, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent, xdata); return 0; } int pl_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; } int pl_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, DECREMENT); PL_STACK_UNWIND(readv, xdata, frame, op_ret, op_errno, vector, count, stbuf, iobref, xdata); return 0; } int pl_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, DECREMENT); PL_STACK_UNWIND(writev, xdata, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } void do_blocked_rw(pl_inode_t *pl_inode) { struct list_head wind_list; pl_rw_req_t *rw = NULL; pl_rw_req_t *tmp = NULL; INIT_LIST_HEAD(&wind_list); pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry_safe(rw, tmp, &pl_inode->rw_list, list) { if (__rw_allowable(pl_inode, &rw->region, rw->stub->fop)) { list_del_init(&rw->list); list_add_tail(&rw->list, &wind_list); if (pl_inode->mlock_enforced && pl_inode->track_fop_wind_count) { pl_inode->fop_wind_count++; } } } } pthread_mutex_unlock(&pl_inode->mutex); list_for_each_entry_safe(rw, tmp, &wind_list, list) { list_del_init(&rw->list); call_resume(rw->stub); GF_FREE(rw); } return; } /* when mandatory lock is enforced: If an IO request comes on a region which is out of the boundary of the granted mandatory lock, it will be rejected. Note: There is no IO blocking with mandatory lock enforced as it may be a stale data from an old client. */ static gf_boolean_t within_range(posix_lock_t *existing, posix_lock_t *new) { if (existing->fl_start <= new->fl_start && existing->fl_end >= new->fl_end) return _gf_true; return _gf_false; } static int __rw_allowable(pl_inode_t *pl_inode, posix_lock_t *region, glusterfs_fop_t op) { posix_lock_t *l = NULL; posix_locks_private_t *priv = THIS->private; int ret = 1; if (pl_inode->mlock_enforced) { list_for_each_entry(l, &pl_inode->ext_list, list) { /* with lock enforced (fencing) there should not be any blocking lock coexisting. */ if (same_owner(l, region)) { /* Should range check be strict for same owner with fencing? */ if (locks_overlap(l, region)) { if (within_range(l, region)) { return 1; } else { /* Should we allow read fop if it does not fit it in the range? if (op == GF_FOP_READ && l->fl_type != F_WRLCK) { return 1; } */ return 0; } } } else { if (locks_overlap(l, region)) { /* with fencing should a read from a different owner be allowed if the mandatory lock taken is F_RDLCK? if (op == GF_FOP_READ && l->fl_type != F_WRLCK) { return 1; } */ return 0; } } } /* No lock has been taken by this owner */ return 0; } list_for_each_entry(l, &pl_inode->ext_list, list) { if (!l->blocked && locks_overlap(l, region) && !same_owner(l, region)) { if ((op == GF_FOP_READ) && (l->fl_type != F_WRLCK)) continue; /* Check for mandatory lock under optimal * mandatory-locking mode */ if (priv->mandatory_mode == MLK_OPTIMAL && !(l->lk_flags & GF_LK_MANDATORY)) continue; ret = 0; break; } } return ret; } int pl_readv_cont(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, INCREMENT); STACK_WIND(frame, pl_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; } int pl_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { pl_local_t *local = NULL; pl_inode_t *pl_inode = NULL; pl_rw_req_t *rw = NULL; posix_lock_t region = { .list = { 0, }, }; gf_boolean_t enabled = _gf_false; gf_boolean_t can_block = _gf_true; int op_ret = 0; int op_errno = 0; int allowed = 1; GF_VALIDATE_OR_GOTO("locks", this, unwind); PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); if (!frame->local) { frame->local = mem_get0(this->local_pool); local = frame->local; local->inode = inode_ref(fd->inode); local->fd = fd_ref(fd); } pl_inode = pl_inode_get(this, fd->inode, local); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } if (frame->root->pid < 0) enabled = _gf_false; else enabled = pl_is_mandatory_locking_enabled(pl_inode); if (enabled) { region.fl_start = offset; region.fl_end = offset + size - 1; region.client = frame->root->client; region.fd_num = fd_to_fdnum(fd); region.client_pid = frame->root->pid; lk_owner_copy(®ion.owner, &frame->root->lk_owner); pthread_mutex_lock(&pl_inode->mutex); { allowed = pl_is_fop_allowed(pl_inode, ®ion, fd, GF_FOP_READ, &can_block); if (allowed == 1) { if (pl_inode->mlock_enforced && pl_inode->track_fop_wind_count) { pl_inode->fop_wind_count++; } goto unlock; } else if (!can_block) { op_errno = EAGAIN; op_ret = -1; goto unlock; } rw = GF_MALLOC(sizeof(*rw), gf_locks_mt_pl_rw_req_t); if (!rw) { op_errno = ENOMEM; op_ret = -1; goto unlock; } rw->stub = fop_readv_stub(frame, pl_readv_cont, fd, size, offset, flags, xdata); if (!rw->stub) { op_errno = ENOMEM; op_ret = -1; GF_FREE(rw); goto unlock; } rw->region = region; list_add_tail(&rw->list, &pl_inode->rw_list); } unlock: pthread_mutex_unlock(&pl_inode->mutex); } if (allowed == 1) { STACK_WIND(frame, pl_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); } unwind: if (op_ret == -1) PL_STACK_UNWIND(readv, xdata, frame, op_ret, op_errno, NULL, 0, NULL, NULL, NULL); return 0; } int pl_writev_cont(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { pl_track_io_fop_count(frame->local, this, INCREMENT); STACK_WIND(frame, pl_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; } int pl_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { pl_local_t *local = NULL; pl_inode_t *pl_inode = NULL; pl_rw_req_t *rw = NULL; posix_lock_t region = { .list = { 0, }, }; gf_boolean_t enabled = _gf_false; gf_boolean_t can_block = _gf_true; int op_ret = 0; int op_errno = 0; int allowed = 1; GF_VALIDATE_OR_GOTO("locks", this, unwind); PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); if (!frame->local) { frame->local = mem_get0(this->local_pool); local = frame->local; local->inode = inode_ref(fd->inode); local->fd = fd_ref(fd); } pl_inode = pl_inode_get(this, fd->inode, local); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } if (frame->root->pid < 0) enabled = _gf_false; else enabled = pl_is_mandatory_locking_enabled(pl_inode); if (enabled) { region.fl_start = offset; region.fl_end = offset + iov_length(vector, count) - 1; region.client = frame->root->client; region.fd_num = fd_to_fdnum(fd); region.client_pid = frame->root->pid; lk_owner_copy(®ion.owner, &frame->root->lk_owner); pthread_mutex_lock(&pl_inode->mutex); { allowed = pl_is_fop_allowed(pl_inode, ®ion, fd, GF_FOP_WRITE, &can_block); if (allowed == 1) { if (pl_inode->mlock_enforced && pl_inode->track_fop_wind_count) { pl_inode->fop_wind_count++; } goto unlock; } else if (!can_block) { if (pl_inode->mlock_enforced) { op_errno = EBUSY; } else { op_errno = EAGAIN; } op_ret = -1; goto unlock; } rw = GF_MALLOC(sizeof(*rw), gf_locks_mt_pl_rw_req_t); if (!rw) { op_errno = ENOMEM; op_ret = -1; goto unlock; } rw->stub = fop_writev_stub(frame, pl_writev_cont, fd, vector, count, offset, flags, iobref, xdata); if (!rw->stub) { op_errno = ENOMEM; op_ret = -1; GF_FREE(rw); goto unlock; } rw->region = region; list_add_tail(&rw->list, &pl_inode->rw_list); } unlock: pthread_mutex_unlock(&pl_inode->mutex); } if (allowed == 1) { STACK_WIND(frame, pl_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); } unwind: if (op_ret == -1) PL_STACK_UNWIND(writev, xdata, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } static int __fd_has_locks(pl_inode_t *pl_inode, fd_t *fd) { posix_lock_t *l = NULL; list_for_each_entry(l, &pl_inode->ext_list, list) { if (l->fd_num == fd_to_fdnum(fd)) { return 1; } } return 0; } static posix_lock_t * lock_dup(posix_lock_t *lock) { int32_t op_errno = 0; return new_posix_lock(&lock->user_flock, lock->client, lock->client_pid, &lock->owner, (fd_t *)lock->fd_num, lock->lk_flags, lock->blocking, &op_errno); } static int __dup_locks_to_fdctx(pl_inode_t *pl_inode, fd_t *fd, pl_fdctx_t *fdctx) { posix_lock_t *l = NULL; posix_lock_t *duplock = NULL; int ret = 0; list_for_each_entry(l, &pl_inode->ext_list, list) { if (l->fd_num == fd_to_fdnum(fd)) { duplock = lock_dup(l); if (!duplock) { ret = -1; break; } list_add_tail(&duplock->list, &fdctx->locks_list); } } return ret; } static int __copy_locks_to_fdctx(pl_inode_t *pl_inode, fd_t *fd, pl_fdctx_t *fdctx) { return __dup_locks_to_fdctx(pl_inode, fd, fdctx); } static void pl_mark_eol_lock(posix_lock_t *lock) { lock->user_flock.l_type = GF_LK_EOL; return; } static posix_lock_t * __get_next_fdctx_lock(pl_fdctx_t *fdctx) { posix_lock_t *lock = NULL; GF_ASSERT(fdctx); if (list_empty(&fdctx->locks_list)) { gf_log(THIS->name, GF_LOG_DEBUG, "fdctx lock list empty"); goto out; } lock = list_entry(fdctx->locks_list.next, typeof(*lock), list); GF_ASSERT(lock); list_del_init(&lock->list); out: return lock; } static int __set_next_lock_fd(pl_fdctx_t *fdctx, posix_lock_t *reqlock) { posix_lock_t *lock = NULL; int ret = 0; GF_ASSERT(fdctx); lock = __get_next_fdctx_lock(fdctx); if (!lock) { gf_log(THIS->name, GF_LOG_DEBUG, "marking EOL in reqlock"); pl_mark_eol_lock(reqlock); goto out; } gf_flock_copy(&reqlock->user_flock, &lock->user_flock); reqlock->fl_start = lock->fl_start; reqlock->fl_type = lock->fl_type; reqlock->fl_end = lock->fl_end; lk_owner_copy(&reqlock->owner, &lock->owner); out: if (lock) __destroy_lock(lock); return ret; } static int pl_getlk_fd(xlator_t *this, pl_inode_t *pl_inode, fd_t *fd, posix_lock_t *reqlock) { pl_fdctx_t *fdctx = NULL; int ret = 0; pthread_mutex_lock(&pl_inode->mutex); { if (!__fd_has_locks(pl_inode, fd)) { pthread_mutex_unlock(&pl_inode->mutex); gf_log(this->name, GF_LOG_DEBUG, "fd=%p has no active locks", fd); ret = 0; goto out; } gf_log(this->name, GF_LOG_DEBUG, "There are active locks on fd"); fdctx = fd_ctx_get_ptr(fd, this); if (list_empty(&fdctx->locks_list)) { gf_log(this->name, GF_LOG_TRACE, "no fdctx -> copying all locks on fd"); ret = __copy_locks_to_fdctx(pl_inode, fd, fdctx); if (ret) { goto unlock; } ret = __set_next_lock_fd(fdctx, reqlock); } else { gf_log(this->name, GF_LOG_TRACE, "fdctx present -> returning the next lock"); ret = __set_next_lock_fd(fdctx, reqlock); if (ret) { pthread_mutex_unlock(&pl_inode->mutex); gf_log(this->name, GF_LOG_DEBUG, "could not get next lock of fd"); goto out; } } } unlock: pthread_mutex_unlock(&pl_inode->mutex); out: return ret; } int pl_metalock_is_active(pl_inode_t *pl_inode) { if (list_empty(&pl_inode->metalk_list)) return 0; else return 1; } void __pl_queue_lock(pl_inode_t *pl_inode, posix_lock_t *reqlock) { list_add_tail(&reqlock->list, &pl_inode->queued_locks); } int pl_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { pl_inode_t *pl_inode = NULL; int op_ret = 0; int op_errno = 0; int can_block = 0; posix_lock_t *reqlock = NULL; posix_lock_t *conf = NULL; uint32_t lk_flags = 0; posix_locks_private_t *priv = this->private; pl_local_t *local = NULL; short lock_type = 0; int ret = 0; if (xdata) { ret = dict_get_uint32(xdata, GF_LOCK_MODE, &lk_flags); if (ret == 0) { if (priv->mandatory_mode == MLK_NONE) gf_log(this->name, GF_LOG_DEBUG, "Lock flags received " "in a non-mandatory locking environment, " "continuing"); else gf_log(this->name, GF_LOG_DEBUG, "Lock flags received, " "continuing"); } } if ((flock->l_start < 0) || ((flock->l_start + flock->l_len) < 0)) { op_ret = -1; op_errno = EINVAL; goto unwind; } /* As per 'man 3 fcntl', the value of l_len may be * negative. In such cases, lock request should be * considered for the range starting at 'l_start+l_len' * and ending at 'l_start-1'. Update the fields accordingly. */ if (flock->l_len < 0) { flock->l_start += flock->l_len; flock->l_len = labs(flock->l_len); } local = mem_get0(this->local_pool); if (!local) { op_ret = -1; op_errno = ENOMEM; goto unwind; } else { frame->local = local; local->fd = fd_ref(fd); } pl_inode = pl_inode_get(this, fd->inode, local); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } reqlock = new_posix_lock(flock, frame->root->client, frame->root->pid, &frame->root->lk_owner, fd, lk_flags, can_block, &op_errno); if (!reqlock) { op_ret = -1; goto unwind; } pl_trace_in(this, frame, fd, NULL, cmd, flock, NULL); switch (cmd) { case F_RESLK_LCKW: can_block = 1; /* fall through */ case F_RESLK_LCK: reqlock->frame = frame; ret = pl_reserve_setlk(this, pl_inode, reqlock, can_block); if (ret < 0) { if (can_block) goto out; op_ret = -1; op_errno = -ret; __destroy_lock(reqlock); goto unwind; } /* Finally a getlk and return the call */ conf = pl_getlk(pl_inode, reqlock); if (conf) posix_lock_to_flock(conf, flock); break; case F_RESLK_UNLCK: reqlock->frame = frame; ret = pl_reserve_unlock(this, pl_inode, reqlock); if (ret < 0) { op_ret = -1; op_errno = -ret; } __destroy_lock(reqlock); goto unwind; break; case F_GETLK_FD: reqlock->frame = frame; ret = pl_verify_reservelk(this, pl_inode, reqlock, can_block); GF_ASSERT(ret >= 0); ret = pl_getlk_fd(this, pl_inode, fd, reqlock); if (ret < 0) { gf_log(this->name, GF_LOG_DEBUG, "getting locks on fd failed"); op_ret = -1; op_errno = ENOLCK; goto unwind; } gf_log(this->name, GF_LOG_TRACE, "Replying with a lock on fd for healing"); posix_lock_to_flock(reqlock, flock); __destroy_lock(reqlock); break; #if F_GETLK != F_GETLK64 case F_GETLK64: #endif case F_GETLK: conf = pl_getlk(pl_inode, reqlock); posix_lock_to_flock(conf, flock); __destroy_lock(reqlock); break; #if F_SETLKW != F_SETLKW64 case F_SETLKW64: #endif case F_SETLKW: can_block = 1; reqlock->frame = frame; reqlock->blocking = can_block; /* fall through */ #if F_SETLK != F_SETLK64 case F_SETLK64: #endif case F_SETLK: reqlock->frame = frame; lock_type = flock->l_type; pthread_mutex_lock(&pl_inode->mutex); { if (pl_inode->migrated) { op_errno = EREMOTE; pthread_mutex_unlock(&pl_inode->mutex); PL_STACK_UNWIND(lk, xdata, frame, -1, op_errno, flock, xdata); __destroy_lock(reqlock); goto out; } } pthread_mutex_unlock(&pl_inode->mutex); ret = pl_verify_reservelk(this, pl_inode, reqlock, can_block); if (ret < 0) { gf_log(this->name, GF_LOG_TRACE, "Lock blocked due to conflicting reserve lock"); goto out; } if (reqlock->fl_type != F_UNLCK && pl_inode->mlock_enforced) { ret = pl_lock_preempt(pl_inode, reqlock); if (ret == -1) { gf_log(this->name, GF_LOG_ERROR, "lock preempt failed"); op_ret = -1; op_errno = EAGAIN; __destroy_lock(reqlock); goto out; } pl_trace_block(this, frame, fd, NULL, cmd, flock, NULL); goto unwind; } ret = pl_setlk(this, pl_inode, reqlock, can_block); if (ret < 0) { op_ret = -1; op_errno = -ret; __destroy_lock(reqlock); goto out; } if (ret == PL_LOCK_WOULD_BLOCK) { if ((can_block) && (F_UNLCK != lock_type)) { goto out; } gf_log(this->name, GF_LOG_DEBUG, "returning EAGAIN"); op_ret = -1; op_errno = EAGAIN; __destroy_lock(reqlock); } else if (ret == PL_LOCK_QUEUED) { goto out; } else if ((0 == ret) && (F_UNLCK == flock->l_type)) { /* For NLM's last "unlock on fd" detection */ if (pl_locks_by_fd(pl_inode, fd)) flock->l_type = F_RDLCK; else flock->l_type = F_UNLCK; } } unwind: pl_trace_out(this, frame, fd, NULL, cmd, flock, op_ret, op_errno, NULL); pl_update_refkeeper(this, fd->inode); PL_STACK_UNWIND(lk, xdata, frame, op_ret, op_errno, flock, xdata); out: return 0; } /* TODO: this function just logs, no action required?? */ int pl_forget(xlator_t *this, inode_t *inode) { pl_inode_t *pl_inode = NULL; pl_local_t *local; posix_lock_t *ext_tmp = NULL; posix_lock_t *ext_l = NULL; struct list_head posixlks_released; pl_inode_lock_t *ino_tmp = NULL; pl_inode_lock_t *ino_l = NULL; struct list_head inodelks_released; pl_rw_req_t *rw_tmp = NULL; pl_rw_req_t *rw_req = NULL; pl_entry_lock_t *entry_tmp = NULL; pl_entry_lock_t *entry_l = NULL; struct list_head entrylks_released; pl_dom_list_t *dom = NULL; pl_dom_list_t *dom_tmp = NULL; INIT_LIST_HEAD(&posixlks_released); INIT_LIST_HEAD(&inodelks_released); INIT_LIST_HEAD(&entrylks_released); pl_inode = pl_inode_get(this, inode, NULL); if (!pl_inode) return 0; pthread_mutex_lock(&pl_inode->mutex); { if (!list_empty(&pl_inode->rw_list)) { gf_log(this->name, GF_LOG_WARNING, "Pending R/W requests found, releasing."); list_for_each_entry_safe(rw_req, rw_tmp, &pl_inode->rw_list, list) { list_del(&rw_req->list); call_stub_destroy(rw_req->stub); GF_FREE(rw_req); } } if (!list_empty(&pl_inode->ext_list)) { gf_log(this->name, GF_LOG_WARNING, "Pending fcntl locks found, releasing."); list_for_each_entry_safe(ext_l, ext_tmp, &pl_inode->ext_list, list) { __delete_lock(ext_l); if (ext_l->blocked) { list_add_tail(&ext_l->list, &posixlks_released); continue; } __destroy_lock(ext_l); } } list_for_each_entry_safe(dom, dom_tmp, &pl_inode->dom_list, inode_list) { if (!list_empty(&dom->inodelk_list)) { gf_log(this->name, GF_LOG_WARNING, "Pending inode locks found, releasing."); list_for_each_entry_safe(ino_l, ino_tmp, &dom->inodelk_list, list) { __delete_inode_lock(ino_l); __pl_inodelk_unref(ino_l); } list_splice_init(&dom->blocked_inodelks, &inodelks_released); } if (!list_empty(&dom->entrylk_list)) { gf_log(this->name, GF_LOG_WARNING, "Pending entry locks found, releasing."); list_for_each_entry_safe(entry_l, entry_tmp, &dom->entrylk_list, domain_list) { list_del_init(&entry_l->domain_list); GF_FREE((char *)entry_l->basename); GF_FREE(entry_l->connection_id); GF_FREE(entry_l); } list_splice_init(&dom->blocked_entrylks, &entrylks_released); } list_del(&dom->inode_list); gf_log("posix-locks", GF_LOG_TRACE, " Cleaning up domain: %s", dom->domain); GF_FREE((char *)(dom->domain)); GF_FREE(dom); } } pthread_mutex_unlock(&pl_inode->mutex); if (!list_empty(&posixlks_released)) { list_for_each_entry_safe(ext_l, ext_tmp, &posixlks_released, list) { local = ext_l->frame->local; PL_STACK_UNWIND_AND_FREE(local, lk, ext_l->frame, -1, 0, &ext_l->user_flock, NULL); __destroy_lock(ext_l); } } if (!list_empty(&inodelks_released)) { list_for_each_entry_safe(ino_l, ino_tmp, &inodelks_released, blocked_locks) { STACK_UNWIND_STRICT(inodelk, ino_l->frame, -1, 0, NULL); __pl_inodelk_unref(ino_l); } } if (!list_empty(&entrylks_released)) { list_for_each_entry_safe(entry_l, entry_tmp, &entrylks_released, blocked_locks) { STACK_UNWIND_STRICT(entrylk, entry_l->frame, -1, 0, NULL); GF_FREE((char *)entry_l->basename); GF_FREE(entry_l->connection_id); GF_FREE(entry_l); } } pthread_mutex_destroy(&pl_inode->mutex); GF_FREE(pl_inode); return 0; } int pl_release(xlator_t *this, fd_t *fd) { pl_inode_t *pl_inode = NULL; uint64_t tmp_pl_inode = 0; int ret = -1; pl_fdctx_t *fdctx = NULL; if (fd == NULL) { goto out; } ret = inode_ctx_get(fd->inode, this, &tmp_pl_inode); if (ret != 0) goto clean; pl_inode = (pl_inode_t *)(long)tmp_pl_inode; pl_trace_release(this, fd); gf_log(this->name, GF_LOG_TRACE, "Releasing all locks with fd %p", fd); delete_locks_of_fd(this, pl_inode, fd); pl_update_refkeeper(this, fd->inode); clean: fdctx = fd_ctx_del_ptr(fd, this); if (!fdctx) { gf_log(this->name, GF_LOG_DEBUG, "Could not get fdctx"); ret = -1; goto out; } ret = 0; GF_FREE(fdctx); out: return ret; } int pl_releasedir(xlator_t *this, fd_t *fd) { int ret = -1; pl_fdctx_t *fdctx = NULL; if (fd == NULL) { goto out; } fdctx = fd_ctx_del_ptr(fd, this); if (!fdctx) { gf_log(this->name, GF_LOG_DEBUG, "Could not get fdctx"); goto out; } GF_FREE(fdctx); ret = 0; out: return ret; } int32_t pl_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { PL_STACK_UNWIND(lookup, xdata, frame, op_ret, op_errno, inode, buf, xdata, postparent); return 0; } int32_t pl_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); return 0; } int32_t pl_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { PL_STACK_UNWIND(fstat, xdata, frame, op_ret, op_errno, buf, xdata); return 0; } int32_t pl_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; } int pl_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata) { pl_local_t *local = NULL; gf_dirent_t *entry = NULL; if (op_ret <= 0) goto unwind; local = frame->local; if (!local) goto unwind; list_for_each_entry(entry, &entries->list, list) { pl_set_xdata_response(this, local, local->fd->inode, entry->inode, entry->d_name, entry->dict, 0); } unwind: PL_STACK_UNWIND(readdirp, xdata, frame, op_ret, op_errno, entries, xdata); return 0; } int pl_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, xdata); return 0; } lock_migration_info_t * gf_mig_info_for_lock(posix_lock_t *lock) { lock_migration_info_t *new = GF_MALLOC(sizeof(lock_migration_info_t), gf_common_mt_lock_mig); if (new == NULL) { goto out; } INIT_LIST_HEAD(&new->list); posix_lock_to_flock(lock, &new->flock); new->lk_flags = lock->lk_flags; new->client_uid = gf_strdup(lock->client_uid); out: return new; } int pl_fill_active_locks(pl_inode_t *pl_inode, lock_migration_info_t *lmi) { posix_lock_t *temp = NULL; lock_migration_info_t *newlock = NULL; int count = 0; pthread_mutex_lock(&pl_inode->mutex); { if (list_empty(&pl_inode->ext_list)) { count = 0; goto unlock; } list_for_each_entry(temp, &pl_inode->ext_list, list) { if (temp->blocked) continue; newlock = gf_mig_info_for_lock(temp); if (!newlock) { pthread_mutex_unlock(&pl_inode->mutex); gf_msg(THIS->name, GF_LOG_ERROR, 0, 0, "lock_dup failed"); count = -1; goto out; } list_add_tail(&newlock->list, &lmi->list); count++; } } unlock: pthread_mutex_unlock(&pl_inode->mutex); out: return count; } /* This function reads only active locks */ static int pl_getactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { pl_inode_t *pl_inode = NULL; lock_migration_info_t locks; int op_ret = 0; int op_errno = 0; int count = 0; INIT_LIST_HEAD(&locks.list); pl_inode = pl_inode_get(this, loc->inode, NULL); if (!pl_inode) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "pl_inode_get failed"); op_ret = -1; op_errno = ENOMEM; goto out; } count = pl_fill_active_locks(pl_inode, &locks); op_ret = count; out: STACK_UNWIND_STRICT(getactivelk, frame, op_ret, op_errno, &locks, NULL); gf_free_mig_locks(&locks); return 0; } void pl_metalk_unref(pl_meta_lock_t *lock) { lock->ref--; if (!lock->ref) { GF_FREE(lock->client_uid); GF_FREE(lock); } } void __pl_metalk_ref(pl_meta_lock_t *lock) { lock->ref++; } pl_meta_lock_t * new_meta_lock(call_frame_t *frame, xlator_t *this) { pl_meta_lock_t *lock = GF_CALLOC(1, sizeof(*lock), gf_locks_mt_pl_meta_lock_t); if (!lock) { gf_msg(this->name, GF_LOG_ERROR, 0, ENOMEM, "mem allocation" " failed for meta lock"); goto out; } INIT_LIST_HEAD(&lock->list); INIT_LIST_HEAD(&lock->client_list); lock->client_uid = gf_strdup(frame->root->client->client_uid); if (!lock->client_uid) { gf_msg(this->name, GF_LOG_ERROR, 0, ENOMEM, "mem allocation" " failed for client_uid"); GF_FREE(lock); lock = NULL; goto out; } __pl_metalk_ref(lock); out: return lock; } int pl_insert_metalk(pl_inode_t *pl_inode, pl_ctx_t *ctx, pl_meta_lock_t *lock) { int ret = 0; if (!pl_inode || !ctx || !lock) { gf_msg(THIS->name, GF_LOG_INFO, 0, 0, "NULL parameter"); ret = -1; goto out; } lock->pl_inode = pl_inode; /* refer function pl_inode_setlk for more info for this ref. * This should be unrefed on meta-unlock triggered by rebalance or * in cleanup with client disconnect*/ /*TODO: unref this in cleanup code for disconnect and meta-unlock*/ pl_inode->inode = inode_ref(pl_inode->inode); /* NOTE:In case of a client-server disconnect we need to cleanup metalk. * Hence, adding the metalk to pl_ctx_t as well. The mutex lock order * should always be on ctx and then on pl_inode*/ pthread_mutex_lock(&ctx->lock); { pthread_mutex_lock(&pl_inode->mutex); { list_add_tail(&lock->list, &pl_inode->metalk_list); } pthread_mutex_unlock(&pl_inode->mutex); list_add_tail(&lock->client_list, &ctx->metalk_list); } pthread_mutex_unlock(&ctx->lock); out: return ret; } int32_t pl_metalk(call_frame_t *frame, xlator_t *this, inode_t *inode) { pl_inode_t *pl_inode = NULL; int ret = 0; pl_meta_lock_t *reqlk = NULL; pl_ctx_t *ctx = NULL; pl_inode = pl_inode_get(this, inode, NULL); if (!pl_inode) { gf_msg(this->name, GF_LOG_ERROR, 0, ENOMEM, "pl_inode mem allocation failedd"); ret = -1; goto out; } /* Non rebalance process trying to do metalock */ if (frame->root->pid != GF_CLIENT_PID_DEFRAG) { ret = -1; goto out; } /* Note: In the current scheme of glusterfs where lock migration is * experimental, (ideally) the rebalance process which is migrating * the file should request for a metalock. Hence, the metalock count * should not be more than one for an inode. In future, if there is a * need for meta-lock from other clients, the following block can be * removed. * * Since pl_metalk is called as part of setxattr operation, any client * process(non-rebalance) residing outside trusted network can exhaust * memory of the server node by issuing setxattr repetitively on the * metalock key. The following code makes sure that more than * one metalock cannot be granted on an inode*/ pthread_mutex_lock(&pl_inode->mutex); { if (pl_metalock_is_active(pl_inode)) { ret = -1; } } pthread_mutex_unlock(&pl_inode->mutex); if (ret == -1) { gf_msg(this->name, GF_LOG_WARNING, EINVAL, 0, "More than one meta-lock cannot be granted on" " the inode"); goto out; } if (frame->root->client) { ctx = pl_ctx_get(frame->root->client, this); if (!ctx) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "pl_ctx_get failed"); ret = -1; goto out; } } else { gf_msg(this->name, GF_LOG_INFO, 0, 0, "frame-root-client " "is NULL"); ret = -1; goto out; } reqlk = new_meta_lock(frame, this); if (!reqlk) { ret = -1; goto out; } ret = pl_insert_metalk(pl_inode, ctx, reqlk); if (ret < 0) { pl_metalk_unref(reqlk); } out: return ret; } static void __unwind_queued_locks(pl_inode_t *pl_inode, struct list_head *tmp_list) { if (list_empty(&pl_inode->queued_locks)) return; list_splice_init(&pl_inode->queued_locks, tmp_list); } static void __unwind_blocked_locks(pl_inode_t *pl_inode, struct list_head *tmp_list) { posix_lock_t *lock = NULL; posix_lock_t *tmp = NULL; if (list_empty(&pl_inode->ext_list)) return; list_for_each_entry_safe(lock, tmp, &pl_inode->ext_list, list) { if (!lock->blocking) continue; list_del_init(&lock->list); list_add_tail(&lock->list, tmp_list); } } int pl_metaunlock(call_frame_t *frame, xlator_t *this, inode_t *inode, dict_t *dict) { pl_inode_t *pl_inode = NULL; pl_local_t *local; int ret = 0; pl_meta_lock_t *meta_lock = NULL; pl_meta_lock_t *tmp_metalk = NULL; pl_ctx_t *ctx = NULL; posix_lock_t *posix_lock = NULL; posix_lock_t *tmp_posixlk = NULL; struct list_head tmp_posixlk_list; INIT_LIST_HEAD(&tmp_posixlk_list); if (frame->root->client) { ctx = pl_ctx_get(frame->root->client, this); if (!ctx) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "pl_ctx_get failed"); ret = -1; goto out; } } else { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "frame-root-client is " "NULL"); ret = -1; goto out; } pl_inode = pl_inode_get(this, inode, NULL); if (!pl_inode) { ret = -1; goto out; } pthread_mutex_lock(&ctx->lock); { pthread_mutex_lock(&pl_inode->mutex); { /* Unwind queued locks regardless of migration status */ __unwind_queued_locks(pl_inode, &tmp_posixlk_list); /* Unwind blocked locks only for successful migration */ if (dict_get_sizen(dict, "status")) { /* unwind all blocked locks */ __unwind_blocked_locks(pl_inode, &tmp_posixlk_list); } /* unlock metalk */ /* if this list is empty then pl_inode->metalk_list * should be empty too. meta lock should in all cases * be added/removed from both pl_ctx_t and pl_inode */ if (list_empty(&ctx->metalk_list)) goto unlock; list_for_each_entry_safe(meta_lock, tmp_metalk, &ctx->metalk_list, client_list) { list_del_init(&meta_lock->client_list); pl_inode = meta_lock->pl_inode; list_del_init(&meta_lock->list); pl_metalk_unref(meta_lock); /* The corresponding ref is taken in * pl_insert_metalk*/ inode_unref(pl_inode->inode); } if (dict_get_sizen(dict, "status")) pl_inode->migrated = _gf_true; else pl_inode->migrated = _gf_false; } unlock: pthread_mutex_unlock(&pl_inode->mutex); } pthread_mutex_unlock(&ctx->lock); out: list_for_each_entry_safe(posix_lock, tmp_posixlk, &tmp_posixlk_list, list) { list_del_init(&posix_lock->list); local = posix_lock->frame->local; PL_STACK_UNWIND_AND_FREE(local, lk, posix_lock->frame, -1, EREMOTE, &posix_lock->user_flock, NULL); __destroy_lock(posix_lock); } return ret; } int32_t pl_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { pl_local_t *local = NULL; pl_inode_t *pl_inode = NULL; local = frame->local; if (local && local->update_mlock_enforced_flag && op_ret != -1) { pl_inode = pl_inode_get(this, local->inode, NULL); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } pthread_mutex_lock(&pl_inode->mutex); { while (pl_inode->fop_wind_count > 0) { gf_msg(this->name, GF_LOG_INFO, 0, 0, "waiting for existing fops (count %d) to drain for " "gfid %s", pl_inode->fop_wind_count, uuid_utoa(pl_inode->gfid)); pthread_cond_wait(&pl_inode->check_fop_wind_count, &pl_inode->mutex); } pl_inode->mlock_enforced = _gf_true; pl_inode->check_mlock_info = _gf_false; } pthread_mutex_unlock(&pl_inode->mutex); } unwind: PL_STACK_UNWIND_FOR_CLIENT(setxattr, xdata, frame, op_ret, op_errno, xdata); return 0; } int32_t pl_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int flags, dict_t *xdata) { int op_ret = 0; int op_errno = EINVAL; dict_t *xdata_rsp = NULL; char *name = NULL; posix_locks_private_t *priv = this->private; PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); if (dict_get_sizen(dict, GF_META_LOCK_KEY)) { op_ret = pl_metalk(frame, this, loc->inode); } else if (dict_get_sizen(dict, GF_META_UNLOCK_KEY)) { op_ret = pl_metaunlock(frame, this, loc->inode, dict); } else { goto usual; } PL_STACK_UNWIND_FOR_CLIENT(setxattr, xdata_rsp, frame, op_ret, op_errno, xdata_rsp); return 0; usual: PL_CHECK_LOCK_ENFORCE_KEY(frame, dict, name, this, loc, ((fd_t *)NULL), priv); STACK_WIND(frame, pl_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; unwind: PL_STACK_UNWIND_FOR_CLIENT(setxattr, xdata, frame, op_ret, op_errno, xdata); return 0; } void pl_dump_lock(char *str, int size, struct gf_flock *flock, gf_lkowner_t *owner, void *trans, char *conn_id, time_t *granted_time, time_t *blkd_time, gf_boolean_t active) { char *type_str = NULL; char granted[GF_TIMESTR_SIZE] = { 0, }; char blocked[GF_TIMESTR_SIZE] = { 0, }; if (granted_time) gf_time_fmt_FT(granted, sizeof(granted), *granted_time); if (blkd_time) gf_time_fmt_FT(blocked, sizeof(blocked), *blkd_time); switch (flock->l_type) { case F_RDLCK: type_str = "READ"; break; case F_WRLCK: type_str = "WRITE"; break; case F_UNLCK: type_str = "UNLOCK"; break; default: type_str = "UNKNOWN"; break; } if (active) { if (blkd_time && *blkd_time == 0) { snprintf(str, size, RANGE_GRNTD_FMT, type_str, flock->l_whence, (unsigned long long)flock->l_start, (unsigned long long)flock->l_len, (unsigned long long)flock->l_pid, lkowner_utoa(owner), trans, conn_id, granted); } else { snprintf(str, size, RANGE_BLKD_GRNTD_FMT, type_str, flock->l_whence, (unsigned long long)flock->l_start, (unsigned long long)flock->l_len, (unsigned long long)flock->l_pid, lkowner_utoa(owner), trans, conn_id, blocked, granted); } } else { snprintf(str, size, RANGE_BLKD_FMT, type_str, flock->l_whence, (unsigned long long)flock->l_start, (unsigned long long)flock->l_len, (unsigned long long)flock->l_pid, lkowner_utoa(owner), trans, conn_id, blocked); } } void __dump_entrylks(pl_inode_t *pl_inode) { pl_dom_list_t *dom = NULL; pl_entry_lock_t *lock = NULL; char blocked[GF_TIMESTR_SIZE] = { 0, }; char granted[GF_TIMESTR_SIZE] = { 0, }; int count = 0; char key[GF_DUMP_MAX_BUF_LEN] = { 0, }; char *k = "xlator.feature.locks.lock-dump.domain.entrylk"; char tmp[4098]; list_for_each_entry(dom, &pl_inode->dom_list, inode_list) { count = 0; gf_proc_dump_build_key(key, "lock-dump.domain", "domain"); gf_proc_dump_write(key, "%s", dom->domain); list_for_each_entry(lock, &dom->entrylk_list, domain_list) { gf_time_fmt_FT(granted, sizeof(granted), lock->granted_time); gf_proc_dump_build_key(key, k, "entrylk[%d](ACTIVE)", count); if (lock->blkd_time == 0) { snprintf(tmp, sizeof(tmp), ENTRY_GRNTD_FMT, lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" : "ENTRYLK_WRLCK", lock->basename, (unsigned long long)lock->client_pid, lkowner_utoa(&lock->owner), lock->client, lock->connection_id, granted); } else { gf_time_fmt_FT(blocked, sizeof(blocked), lock->blkd_time); snprintf(tmp, sizeof(tmp), ENTRY_BLKD_GRNTD_FMT, lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" : "ENTRYLK_WRLCK", lock->basename, (unsigned long long)lock->client_pid, lkowner_utoa(&lock->owner), lock->client, lock->connection_id, blocked, granted); } gf_proc_dump_write(key, "%s", tmp); count++; } list_for_each_entry(lock, &dom->blocked_entrylks, blocked_locks) { gf_time_fmt_FT(blocked, sizeof(blocked), lock->blkd_time); gf_proc_dump_build_key(key, k, "entrylk[%d](BLOCKED)", count); snprintf( tmp, sizeof(tmp), ENTRY_BLKD_FMT, lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" : "ENTRYLK_WRLCK", lock->basename, (unsigned long long)lock->client_pid, lkowner_utoa(&lock->owner), lock->client, lock->connection_id, blocked); gf_proc_dump_write(key, "%s", tmp); count++; } } } void dump_entrylks(pl_inode_t *pl_inode) { pthread_mutex_lock(&pl_inode->mutex); { __dump_entrylks(pl_inode); } pthread_mutex_unlock(&pl_inode->mutex); } void __dump_inodelks(pl_inode_t *pl_inode) { pl_dom_list_t *dom = NULL; pl_inode_lock_t *lock = NULL; int count = 0; char key[GF_DUMP_MAX_BUF_LEN]; char tmp[4098]; list_for_each_entry(dom, &pl_inode->dom_list, inode_list) { count = 0; gf_proc_dump_build_key(key, "lock-dump.domain", "domain"); gf_proc_dump_write(key, "%s", dom->domain); list_for_each_entry(lock, &dom->inodelk_list, list) { gf_proc_dump_build_key(key, "inodelk", "inodelk[%d](ACTIVE)", count); SET_FLOCK_PID(&lock->user_flock, lock); pl_dump_lock(tmp, sizeof(tmp), &lock->user_flock, &lock->owner, lock->client, lock->connection_id, &lock->granted_time, &lock->blkd_time, _gf_true); gf_proc_dump_write(key, "%s", tmp); count++; } list_for_each_entry(lock, &dom->blocked_inodelks, blocked_locks) { gf_proc_dump_build_key(key, "inodelk", "inodelk[%d](BLOCKED)", count); SET_FLOCK_PID(&lock->user_flock, lock); pl_dump_lock(tmp, sizeof(tmp), &lock->user_flock, &lock->owner, lock->client, lock->connection_id, 0, &lock->blkd_time, _gf_false); gf_proc_dump_write(key, "%s", tmp); count++; } } } void dump_inodelks(pl_inode_t *pl_inode) { pthread_mutex_lock(&pl_inode->mutex); { __dump_inodelks(pl_inode); } pthread_mutex_unlock(&pl_inode->mutex); } void __dump_posixlks(pl_inode_t *pl_inode) { posix_lock_t *lock = NULL; int count = 0; char key[GF_DUMP_MAX_BUF_LEN]; char tmp[4098]; list_for_each_entry(lock, &pl_inode->ext_list, list) { SET_FLOCK_PID(&lock->user_flock, lock); gf_proc_dump_build_key(key, "posixlk", "posixlk[%d](%s)", count, lock->blocked ? "BLOCKED" : "ACTIVE"); pl_dump_lock(tmp, sizeof(tmp), &lock->user_flock, &lock->owner, lock->client, lock->client_uid, &lock->granted_time, &lock->blkd_time, (lock->blocked) ? _gf_false : _gf_true); gf_proc_dump_write(key, "%s", tmp); count++; } } void dump_posixlks(pl_inode_t *pl_inode) { pthread_mutex_lock(&pl_inode->mutex); { __dump_posixlks(pl_inode); } pthread_mutex_unlock(&pl_inode->mutex); } int32_t pl_dump_inode_priv(xlator_t *this, inode_t *inode) { int ret = -1; uint64_t tmp_pl_inode = 0; pl_inode_t *pl_inode = NULL; char *pathname = NULL; gf_boolean_t section_added = _gf_false; int count = 0; if (!inode) { errno = EINVAL; goto out; } ret = TRY_LOCK(&inode->lock); if (ret) goto out; { ret = __inode_ctx_get(inode, this, &tmp_pl_inode); if (ret) goto unlock; } unlock: UNLOCK(&inode->lock); if (ret) goto out; pl_inode = (pl_inode_t *)(long)tmp_pl_inode; if (!pl_inode) { ret = -1; goto out; } gf_proc_dump_add_section("xlator.features.locks.%s.inode", this->name); section_added = _gf_true; /*We are safe to call __inode_path since we have the * inode->table->lock */ __inode_path(inode, NULL, &pathname); if (pathname) gf_proc_dump_write("path", "%s", pathname); gf_proc_dump_write("mandatory", "%d", pl_inode->mandatory); ret = pthread_mutex_trylock(&pl_inode->mutex); if (ret) goto out; { count = __get_entrylk_count(this, pl_inode); if (count) { gf_proc_dump_write("entrylk-count", "%d", count); __dump_entrylks(pl_inode); } count = __get_inodelk_count(this, pl_inode, NULL); if (count) { gf_proc_dump_write("inodelk-count", "%d", count); __dump_inodelks(pl_inode); } count = __get_posixlk_count(pl_inode); if (count) { gf_proc_dump_write("posixlk-count", "%d", count); __dump_posixlks(pl_inode); } gf_proc_dump_write("removes_pending", "%u", pl_inode->remove_running); } pthread_mutex_unlock(&pl_inode->mutex); out: GF_FREE(pathname); if (ret && inode) { if (!section_added) gf_proc_dump_add_section( "xlator.features.locks.%s." "inode", this->name); gf_proc_dump_write("Unable to print lock state", "(Lock " "acquisition failure) %s", uuid_utoa(inode->gfid)); } return ret; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_locks_mt_end); if (ret != 0) { gf_log(this->name, GF_LOG_ERROR, "Memory accounting init" "failed"); return ret; } return ret; } pl_ctx_t * pl_ctx_get(client_t *client, xlator_t *xlator) { void *tmp = NULL; pl_ctx_t *ctx = NULL; pl_ctx_t *setted_ctx = NULL; tmp = client_ctx_get(client, xlator); ctx = tmp; if (ctx != NULL) goto out; ctx = GF_CALLOC(1, sizeof(pl_ctx_t), gf_locks_mt_posix_lock_t); if (ctx == NULL) goto out; pthread_mutex_init(&ctx->lock, NULL); INIT_LIST_HEAD(&ctx->inodelk_lockers); INIT_LIST_HEAD(&ctx->entrylk_lockers); INIT_LIST_HEAD(&ctx->metalk_list); setted_ctx = client_ctx_set(client, xlator, ctx); if (ctx != setted_ctx) { pthread_mutex_destroy(&ctx->lock); GF_FREE(ctx); ctx = setted_ctx; } out: return ctx; } int pl_metalk_client_cleanup(xlator_t *this, pl_ctx_t *ctx) { pl_meta_lock_t *meta_lock = NULL; pl_meta_lock_t *tmp_metalk = NULL; pl_inode_t *pl_inode = NULL; posix_lock_t *posix_lock = NULL; posix_lock_t *tmp_posixlk = NULL; pl_local_t *local; struct list_head tmp_posixlk_list; INIT_LIST_HEAD(&tmp_posixlk_list); pthread_mutex_lock(&ctx->lock); { /* if this list is empty then pl_inode->metalk_list should be * empty too. meta lock should in all cases be added/removed * from both pl_ctx_t and pl_inode */ if (list_empty(&ctx->metalk_list)) goto unlock; list_for_each_entry_safe(meta_lock, tmp_metalk, &ctx->metalk_list, client_list) { list_del_init(&meta_lock->client_list); pl_inode = meta_lock->pl_inode; pthread_mutex_lock(&pl_inode->mutex); { /* Since the migration status is unknown here * unwind all queued and blocked locks to check * migration status and find the correct * destination */ __unwind_queued_locks(pl_inode, &tmp_posixlk_list); __unwind_blocked_locks(pl_inode, &tmp_posixlk_list); list_del_init(&meta_lock->list); pl_metalk_unref(meta_lock); } pthread_mutex_unlock(&pl_inode->mutex); /* The corresponding ref is taken in * pl_insert_metalk*/ inode_unref(pl_inode->inode); } } unlock: pthread_mutex_unlock(&ctx->lock); list_for_each_entry_safe(posix_lock, tmp_posixlk, &tmp_posixlk_list, list) { list_del_init(&posix_lock->list); local = posix_lock->frame->local; PL_STACK_UNWIND_AND_FREE(local, lk, posix_lock->frame, -1, EREMOTE, &posix_lock->user_flock, NULL); __destroy_lock(posix_lock); } return 0; } static int pl_client_disconnect_cbk(xlator_t *this, client_t *client) { pl_ctx_t *pl_ctx = pl_ctx_get(client, this); if (pl_ctx) { pl_inodelk_client_cleanup(this, pl_ctx); pl_entrylk_client_cleanup(this, pl_ctx); pl_metalk_client_cleanup(this, pl_ctx); } return 0; } static int pl_client_destroy_cbk(xlator_t *this, client_t *client) { void *tmp = NULL; pl_ctx_t *pl_ctx = NULL; pl_client_disconnect_cbk(this, client); tmp = client_ctx_del(client, this); if (tmp == NULL) return 0; pl_ctx = tmp; GF_ASSERT(list_empty(&pl_ctx->inodelk_lockers)); GF_ASSERT(list_empty(&pl_ctx->entrylk_lockers)); pthread_mutex_destroy(&pl_ctx->lock); GF_FREE(pl_ctx); return 0; } int reconfigure(xlator_t *this, dict_t *options) { posix_locks_private_t *priv = this->private; int ret = -1; char *tmp_str = NULL; GF_OPTION_RECONF("trace", priv->trace, options, bool, out); GF_OPTION_RECONF("monkey-unlocking", priv->monkey_unlocking, options, bool, out); GF_OPTION_RECONF("revocation-secs", priv->revocation_secs, options, uint32, out); GF_OPTION_RECONF("revocation-clear-all", priv->revocation_clear_all, options, bool, out); GF_OPTION_RECONF("revocation-max-blocked", priv->revocation_max_blocked, options, uint32, out); GF_OPTION_RECONF("notify-contention", priv->notify_contention, options, bool, out); GF_OPTION_RECONF("notify-contention-delay", priv->notify_contention_delay, options, uint32, out); GF_OPTION_RECONF("mandatory-locking", tmp_str, options, str, out); GF_OPTION_RECONF("enforce-mandatory-lock", priv->mlock_enforced, options, bool, out); if (!strcmp(tmp_str, "forced")) priv->mandatory_mode = MLK_FORCED; else if (!strcmp(tmp_str, "file")) priv->mandatory_mode = MLK_FILE_BASED; else if (!strcmp(tmp_str, "optimal")) priv->mandatory_mode = MLK_OPTIMAL; else priv->mandatory_mode = MLK_NONE; ret = 0; out: return ret; } int init(xlator_t *this) { posix_locks_private_t *priv = NULL; xlator_list_t *trav = NULL; char *tmp_str = NULL; int ret = -1; if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_CRITICAL, "FATAL: posix-locks should have exactly one child"); goto out; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "Volume is dangling. Please check the volume file."); } trav = this->children; while (trav->xlator->children) trav = trav->xlator->children; if (strncmp("storage/", trav->xlator->type, 8)) { gf_log(this->name, GF_LOG_CRITICAL, "'locks' translator is not loaded over a storage " "translator"); goto out; } priv = GF_CALLOC(1, sizeof(*priv), gf_locks_mt_posix_locks_private_t); GF_OPTION_INIT("mandatory-locking", tmp_str, str, out); if (!strcmp(tmp_str, "forced")) priv->mandatory_mode = MLK_FORCED; else if (!strcmp(tmp_str, "file")) priv->mandatory_mode = MLK_FILE_BASED; else if (!strcmp(tmp_str, "optimal")) priv->mandatory_mode = MLK_OPTIMAL; else priv->mandatory_mode = MLK_NONE; tmp_str = NULL; GF_OPTION_INIT("trace", priv->trace, bool, out); GF_OPTION_INIT("monkey-unlocking", priv->monkey_unlocking, bool, out); GF_OPTION_INIT("revocation-secs", priv->revocation_secs, uint32, out); GF_OPTION_INIT("revocation-clear-all", priv->revocation_clear_all, bool, out); GF_OPTION_INIT("revocation-max-blocked", priv->revocation_max_blocked, uint32, out); GF_OPTION_INIT("notify-contention", priv->notify_contention, bool, out); GF_OPTION_INIT("notify-contention-delay", priv->notify_contention_delay, uint32, out); GF_OPTION_INIT("enforce-mandatory-lock", priv->mlock_enforced, bool, out); this->local_pool = mem_pool_new(pl_local_t, 32); if (!this->local_pool) { ret = -1; gf_log(this->name, GF_LOG_ERROR, "failed to create local_t's memory pool"); goto out; } this->private = priv; ret = 0; out: if (ret) { GF_FREE(priv); } return ret; } void fini(xlator_t *this) { posix_locks_private_t *priv = this->private; if (!priv) return; this->private = NULL; if (this->local_pool) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; } GF_FREE(priv->brickname); GF_FREE(priv); return; } int pl_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata); int pl_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata); int pl_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata); int pl_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata); int32_t pl_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { pl_inode_remove_cbk(this, cookie, op_ret < 0 ? op_errno : 0); PL_STACK_UNWIND(rename, xdata, frame, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); return 0; } int32_t pl_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int32_t error; error = PL_INODE_REMOVE(rename, frame, this, oldloc, newloc, pl_rename, pl_rename_cbk, oldloc, newloc, xdata); if (error > 0) { STACK_UNWIND_STRICT(rename, frame, -1, error, NULL, NULL, NULL, NULL, NULL, NULL); } return 0; } posix_lock_t * gf_lkmig_info_to_posix_lock(call_frame_t *frame, lock_migration_info_t *lmi) { posix_lock_t *lock = GF_CALLOC(1, sizeof(posix_lock_t), gf_locks_mt_posix_lock_t); if (!lock) goto out; lock->fl_start = lmi->flock.l_start; lock->fl_type = lmi->flock.l_type; if (lmi->flock.l_len == 0) lock->fl_end = LLONG_MAX; else lock->fl_end = lmi->flock.l_start + lmi->flock.l_len - 1; lock->client = frame->root->client; lock->lk_flags = lmi->lk_flags; lock->client_uid = gf_strdup(lmi->client_uid); if (lock->client_uid == NULL) { GF_FREE(lock); lock = NULL; goto out; } lock->client_pid = lmi->flock.l_pid; lk_owner_copy(&lock->owner, &lmi->flock.l_owner); INIT_LIST_HEAD(&lock->list); out: return lock; } /* This function is supposed to write the active locks from the source brick(in * rebalance context) and write here. Hence, will add the locks directly to the * pl_inode->ext_list*/ int pl_write_active_locks(call_frame_t *frame, pl_inode_t *pl_inode, lock_migration_info_t *locklist) { posix_lock_t *newlock = NULL; lock_migration_info_t *temp = NULL; int ret = 0; pthread_mutex_lock(&pl_inode->mutex); { /* Just making sure the activelk list is empty. Should not * happen though*/ if (!list_empty(&pl_inode->ext_list)) { pthread_mutex_unlock(&pl_inode->mutex); gf_msg(THIS->name, GF_LOG_ERROR, 0, 0, "invalid locks found"); ret = -1; goto out; } /* This list also should not be empty */ if (list_empty(&locklist->list)) { pthread_mutex_unlock(&pl_inode->mutex); gf_msg(THIS->name, GF_LOG_ERROR, 0, 0, "empty lock list"); ret = -1; goto out; } list_for_each_entry(temp, &locklist->list, list) { newlock = gf_lkmig_info_to_posix_lock(frame, temp); if (!newlock) { pthread_mutex_unlock(&pl_inode->mutex); gf_msg(THIS->name, GF_LOG_ERROR, 0, 0, "mem allocation failed for newlock"); ret = -1; goto out; } list_add_tail(&newlock->list, &pl_inode->ext_list); } } /*TODO: What if few lock add failed with ENOMEM. Should the already * added locks be clearted */ pthread_mutex_unlock(&pl_inode->mutex); out: return ret; } static int pl_setactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc, lock_migration_info_t *locklist, dict_t *xdata) { int op_ret = 0; int op_errno = 0; int ret = 0; pl_inode_t *pl_inode = pl_inode_get(this, loc->inode, NULL); if (!pl_inode) { gf_msg(this->name, GF_LOG_ERROR, 0, 0, "pl_inode_get failed"); op_ret = -1; op_errno = ENOMEM; goto out; } ret = pl_write_active_locks(frame, pl_inode, locklist); op_ret = ret; out: STACK_UNWIND_STRICT(setactivelk, frame, op_ret, op_errno, NULL); return 0; } int32_t pl_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { pl_inode_remove_cbk(this, cookie, op_ret < 0 ? op_errno : 0); PL_STACK_UNWIND(unlink, xdata, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int32_t pl_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { int32_t error; error = PL_INODE_REMOVE(unlink, frame, this, loc, NULL, pl_unlink, pl_unlink_cbk, loc, xflag, xdata); if (error > 0) { STACK_UNWIND_STRICT(unlink, frame, -1, error, NULL, NULL, NULL); } return 0; } int32_t pl_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(mkdir, xdata, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int pl_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; } int32_t pl_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(stat, xdata, frame, op_ret, op_errno, buf, xdata); return 0; } int pl_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; } int32_t pl_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(mknod, xdata, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int pl_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; } int32_t pl_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { pl_inode_remove_cbk(this, cookie, op_ret < 0 ? op_errno : 0); PL_STACK_UNWIND_FOR_CLIENT(rmdir, xdata, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int pl_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { int32_t error; error = PL_INODE_REMOVE(rmdir, frame, this, loc, NULL, pl_rmdir, pl_rmdir_cbk, loc, xflags, xdata); if (error > 0) { STACK_UNWIND_STRICT(rmdir, frame, -1, error, NULL, NULL, NULL); } return 0; } int32_t pl_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(symlink, xdata, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int pl_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkname, loc, umask, xdata); return 0; } int32_t pl_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(link, xdata, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } int pl_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), oldloc, newloc); STACK_WIND(frame, pl_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; } int32_t pl_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(fsync, xdata, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int pl_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_fsync_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata); return 0; } int32_t pl_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(readdir, xdata, frame, op_ret, op_errno, entries, xdata); return 0; } int pl_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, fd, size, offset, xdata); return 0; } int32_t pl_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(fsyncdir, xdata, frame, op_ret, op_errno, xdata); return 0; } int pl_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_fsyncdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsyncdir, fd, datasync, xdata); return 0; } int32_t pl_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(statfs, xdata, frame, op_ret, op_errno, buf, xdata); return 0; } int pl_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_statfs_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, loc, xdata); return 0; } int32_t pl_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { pl_local_t *local = NULL; pl_inode_t *pl_inode = NULL; local = frame->local; if (local && local->update_mlock_enforced_flag && op_ret != -1) { pl_inode = pl_inode_get(this, local->inode, NULL); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } pthread_mutex_lock(&pl_inode->mutex); { pl_inode->mlock_enforced = _gf_false; pl_inode->check_mlock_info = _gf_false; pl_inode->track_fop_wind_count = _gf_true; } pthread_mutex_unlock(&pl_inode->mutex); } unwind: PL_STACK_UNWIND_FOR_CLIENT(removexattr, xdata, frame, op_ret, op_errno, xdata); return 0; } int pl_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int op_ret = 0; int op_errno = EINVAL; posix_locks_private_t *priv = this->private; PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); PL_CHECK_LOCK_ENFORCE_KEY(frame, ((dict_t *)NULL), name, this, loc, ((fd_t *)NULL), priv); STACK_WIND(frame, pl_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; unwind: PL_STACK_UNWIND_FOR_CLIENT(removexattr, xdata, frame, op_ret, op_errno, NULL); return 0; } int32_t pl_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { pl_local_t *local = NULL; pl_inode_t *pl_inode = NULL; local = frame->local; if (local && local->update_mlock_enforced_flag && op_ret != -1) { pl_inode = pl_inode_get(this, local->inode, NULL); if (!pl_inode) { op_ret = -1; op_errno = ENOMEM; goto unwind; } pthread_mutex_lock(&pl_inode->mutex); { pl_inode->mlock_enforced = _gf_false; pl_inode->check_mlock_info = _gf_false; } pthread_mutex_unlock(&pl_inode->mutex); } unwind: PL_STACK_UNWIND_FOR_CLIENT(fremovexattr, xdata, frame, op_ret, op_errno, xdata); return 0; } int pl_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int op_ret = -1; int op_errno = EINVAL; posix_locks_private_t *priv = this->private; PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); PL_CHECK_LOCK_ENFORCE_KEY(frame, ((dict_t *)NULL), name, this, ((loc_t *)NULL), fd, priv); STACK_WIND(frame, pl_fremovexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; unwind: PL_STACK_UNWIND_FOR_CLIENT(fremovexattr, xdata, frame, op_ret, op_errno, NULL); return 0; } int32_t pl_rchecksum_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, uint32_t weak_cksum, uint8_t *strong_cksum, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(rchecksum, xdata, frame, op_ret, op_errno, weak_cksum, strong_cksum, xdata); return 0; } int pl_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, int32_t len, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_rchecksum_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata); return 0; } int32_t pl_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(xattrop, xdata, frame, op_ret, op_errno, dict, xdata); return 0; } int pl_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, optype, xattr, xdata); return 0; } int32_t pl_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(fxattrop, xdata, frame, op_ret, op_errno, dict, xdata); return 0; } int pl_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_fxattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, optype, xattr, xdata); return 0; } int32_t pl_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(setattr, xdata, frame, op_ret, op_errno, statpre, statpost, xdata); return 0; } int pl_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } int32_t pl_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(fsetattr, xdata, frame, op_ret, op_errno, statpre, statpost, xdata); return 0; } int pl_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } int32_t pl_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(fallocate, xdata, frame, op_ret, op_errno, pre, post, xdata); return 0; } int pl_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_size, off_t offset, size_t len, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_fallocate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset, len, xdata); return 0; } int32_t pl_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, const char *path, struct iatt *buf, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(readlink, xdata, frame, op_ret, op_errno, path, buf, xdata); return 0; } int pl_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_readlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink, loc, size, xdata); return 0; } int32_t pl_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(access, xdata, frame, op_ret, op_errno, xdata); return 0; } int pl_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, ((fd_t *)NULL), loc, NULL); STACK_WIND(frame, pl_access_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->access, loc, mask, xdata); return 0; } int32_t pl_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata) { PL_STACK_UNWIND_FOR_CLIENT(seek, xdata, frame, op_ret, op_errno, offset, xdata); return 0; } int32_t pl_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { PL_LOCAL_GET_REQUESTS(frame, this, xdata, fd, NULL, NULL); STACK_WIND(frame, pl_seek_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->seek, fd, offset, what, xdata); return 0; } struct xlator_fops fops = { .lookup = pl_lookup, .create = pl_create, .fstat = pl_fstat, .truncate = pl_truncate, .ftruncate = pl_ftruncate, .discard = pl_discard, .zerofill = pl_zerofill, .open = pl_open, .readv = pl_readv, .writev = pl_writev, .lk = pl_lk, .inodelk = pl_inodelk, .finodelk = pl_finodelk, .entrylk = pl_entrylk, .fentrylk = pl_fentrylk, .flush = pl_flush, .opendir = pl_opendir, .readdirp = pl_readdirp, .setxattr = pl_setxattr, .fsetxattr = pl_fsetxattr, .getxattr = pl_getxattr, .fgetxattr = pl_fgetxattr, .removexattr = pl_removexattr, .fremovexattr = pl_fremovexattr, .rename = pl_rename, .getactivelk = pl_getactivelk, .setactivelk = pl_setactivelk, .unlink = pl_unlink, .access = pl_access, .readlink = pl_readlink, .fallocate = pl_fallocate, .fsetattr = pl_fsetattr, .setattr = pl_setattr, .fxattrop = pl_fxattrop, .xattrop = pl_xattrop, .rchecksum = pl_rchecksum, .statfs = pl_statfs, .fsyncdir = pl_fsyncdir, .fsync = pl_fsync, .readdir = pl_readdir, .symlink = pl_symlink, .link = pl_link, .rmdir = pl_rmdir, .mknod = pl_mknod, .stat = pl_stat, .seek = pl_seek, }; struct xlator_dumpops dumpops = { .inodectx = pl_dump_inode_priv, }; struct xlator_cbks cbks = { .forget = pl_forget, .release = pl_release, .releasedir = pl_releasedir, .client_destroy = pl_client_destroy_cbk, .client_disconnect = pl_client_disconnect_cbk, }; struct volume_options options[] = { {.key = {"mandatory-locking"}, .type = GF_OPTION_TYPE_STR, .default_value = "off", .op_version = {GD_OP_VERSION_3_8_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"locks"}, .description = "Specifies the mandatory-locking mode. Valid options " "are 'file' to use linux style mandatory locks, " "'forced' to use volume strictly under mandatory lock " "semantics only and 'optimal' to treat advisory and " "mandatory locks separately on their own."}, {.key = {"trace"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .op_version = {GD_OP_VERSION_3_7_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"locks"}, .description = "Trace the different lock requests " "to logs."}, {.key = {"monkey-unlocking"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "false", .op_version = {GD_OP_VERSION_3_9_0}, .flags = OPT_FLAG_SETTABLE, .tags = {"locks"}, .description = "Ignore a random number of unlock requests. Useful " "for testing/creating robust lock recovery mechanisms."}, { .key = {"revocation-secs"}, .type = GF_OPTION_TYPE_INT, .min = 0, .max = INT_MAX, .default_value = "0", .op_version = {GD_OP_VERSION_3_9_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"locks"}, .description = "Maximum time a lock can be taken out, before" "being revoked.", }, { .key = {"revocation-clear-all"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "false", .op_version = {GD_OP_VERSION_3_9_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"locks"}, .description = "If set to true, will revoke BOTH granted and blocked " "(pending) lock requests if a revocation threshold is " "hit.", }, {.key = {"revocation-max-blocked"}, .type = GF_OPTION_TYPE_INT, .min = 0, .max = INT_MAX, .default_value = "0", .op_version = {GD_OP_VERSION_3_9_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .tags = {"locks"}, .description = "A number of blocked lock requests after which a lock " "will be revoked to allow the others to proceed. Can " "be used in conjunction w/ revocation-clear-all."}, {.key = {"notify-contention"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "yes", .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .op_version = {GD_OP_VERSION_4_0_0}, .tags = {"locks", "contention"}, .description = "When this option is enabled and a lock request " "conflicts with a currently granted lock, an upcall " "notification will be sent to the current owner of " "the lock to request it to be released as soon as " "possible."}, {.key = {"notify-contention-delay"}, .type = GF_OPTION_TYPE_INT, .min = 0, /* An upcall notification is sent every time a conflict is * detected. */ .max = 60, .default_value = "5", .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .op_version = {GD_OP_VERSION_4_0_0}, .tags = {"locks", "contention", "timeout"}, .description = "This value determines the minimum amount of time " "(in seconds) between upcall contention notifications " "on the same inode. If multiple lock requests are " "received during this period, only one upcall will " "be sent."}, {.key = {"enforce-mandatory-lock"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .flags = OPT_FLAG_SETTABLE, .op_version = {GD_OP_VERSION_6_0}, .description = "option to enable lock enforcement"}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "locks", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/entrylk.c0000644000000000000000000000013014522202451023426 xustar000000000000000029 mtime=1699284265.67302745 30 atime=1699284265.672027447 29 ctime=1699284303.29614077 glusterfs-11.1/xlators/features/locks/src/entrylk.c0000664000175100017510000010136114522202451023711 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include "locks.h" #include "clear.h" #include "common.h" #include "pl-messages.h" void __pl_entrylk_unref(pl_entry_lock_t *lock) { lock->ref--; if (!lock->ref) { GF_FREE((char *)lock->basename); GF_FREE(lock->connection_id); GF_FREE(lock); } } static void __pl_entrylk_ref(pl_entry_lock_t *lock) { lock->ref++; } static pl_entry_lock_t * new_entrylk_lock(pl_inode_t *pinode, const char *basename, entrylk_type type, const char *domain, call_frame_t *frame, char *conn_id, int32_t *op_errno) { pl_entry_lock_t *newlock = NULL; if (!pl_is_lk_owner_valid(&frame->root->lk_owner, frame->root->client)) { *op_errno = EINVAL; goto out; } newlock = GF_CALLOC(1, sizeof(pl_entry_lock_t), gf_locks_mt_pl_entry_lock_t); if (!newlock) { *op_errno = ENOMEM; goto out; } newlock->basename = basename ? gf_strdup(basename) : NULL; newlock->type = type; newlock->client = frame->root->client; newlock->client_pid = frame->root->pid; newlock->volume = domain; lk_owner_copy(&newlock->owner, &frame->root->lk_owner); newlock->frame = frame; newlock->this = frame->this; if (conn_id) { newlock->connection_id = gf_strdup(conn_id); } INIT_LIST_HEAD(&newlock->domain_list); INIT_LIST_HEAD(&newlock->blocked_locks); INIT_LIST_HEAD(&newlock->client_list); __pl_entrylk_ref(newlock); out: return newlock; } /** * all_names - does a basename represent all names? * @basename: name to check */ #define all_names(basename) ((basename == NULL) ? 1 : 0) /** * names_conflict - do two names conflict? * @n1: name * @n2: name */ static int names_conflict(const char *n1, const char *n2) { return all_names(n1) || all_names(n2) || !strcmp(n1, n2); } static int __same_entrylk_owner(pl_entry_lock_t *l1, pl_entry_lock_t *l2) { return (is_same_lkowner(&l1->owner, &l2->owner) && (l1->client == l2->client)); } /* Just as in inodelk, allow conflicting name locks from same (lk_owner, conn)*/ static int __conflicting_entrylks(pl_entry_lock_t *l1, pl_entry_lock_t *l2) { if (names_conflict(l1->basename, l2->basename) && !__same_entrylk_owner(l1, l2)) return 1; return 0; } /* See comments in inodelk.c for details */ static inline gf_boolean_t __stale_entrylk(xlator_t *this, pl_entry_lock_t *candidate_lock, pl_entry_lock_t *requested_lock, time_t *lock_age_sec) { posix_locks_private_t *priv = NULL; priv = this->private; /* Question: Should we just prune them all given the * chance? Or just the locks we are attempting to acquire? */ if (names_conflict(candidate_lock->basename, requested_lock->basename)) { *lock_age_sec = gf_time() - candidate_lock->granted_time; if (*lock_age_sec > priv->revocation_secs) return _gf_true; } return _gf_false; } /* See comments in inodelk.c for details */ static gf_boolean_t __entrylk_prune_stale(xlator_t *this, pl_inode_t *pinode, pl_dom_list_t *dom, pl_entry_lock_t *lock) { posix_locks_private_t *priv = NULL; pl_entry_lock_t *tmp = NULL; pl_entry_lock_t *lk = NULL; gf_boolean_t revoke_lock = _gf_false; int bcount = 0; int gcount = 0; int op_errno = 0; clrlk_args args; args.opts = NULL; time_t lk_age_sec = 0; uint32_t max_blocked = 0; char *reason_str = NULL; priv = this->private; args.type = CLRLK_ENTRY; if (priv->revocation_clear_all == _gf_true) args.kind = CLRLK_ALL; else args.kind = CLRLK_GRANTED; if (list_empty(&dom->entrylk_list)) goto out; pthread_mutex_lock(&pinode->mutex); lock->pinode = pinode; list_for_each_entry_safe(lk, tmp, &dom->entrylk_list, domain_list) { if (__stale_entrylk(this, lk, lock, &lk_age_sec) == _gf_true) { revoke_lock = _gf_true; reason_str = "age"; break; } } max_blocked = priv->revocation_max_blocked; if (max_blocked != 0 && revoke_lock == _gf_false) { list_for_each_entry_safe(lk, tmp, &dom->blocked_entrylks, blocked_locks) { max_blocked--; if (max_blocked == 0) { revoke_lock = _gf_true; reason_str = "max blocked"; break; } } } pthread_mutex_unlock(&pinode->mutex); out: if (revoke_lock == _gf_true) { clrlk_clear_entrylk(this, pinode, dom, &args, &bcount, &gcount, &op_errno); gf_log(this->name, GF_LOG_WARNING, "Lock revocation [reason: %s; gfid: %s; domain: %s; " "age: %ld sec] - Entry lock revoked: %d granted & %d " "blocked locks cleared", reason_str, uuid_utoa(pinode->gfid), dom->domain, lk_age_sec, gcount, bcount); } return revoke_lock; } void entrylk_contention_notify_check(xlator_t *this, pl_entry_lock_t *lock, struct timespec *now, struct list_head *contend) { posix_locks_private_t *priv; int64_t elapsed; priv = this->private; /* If this lock is in a list, it means that we are about to send a * notification for it, so no need to do anything else. */ if (!list_empty(&lock->contend)) { return; } elapsed = now->tv_sec; elapsed -= lock->contention_time.tv_sec; if (now->tv_nsec < lock->contention_time.tv_nsec) { elapsed--; } if (elapsed < priv->notify_contention_delay) { return; } /* All contention notifications will be sent outside of the locked * region. This means that currently granted locks might have already * been unlocked by that time. To avoid the lock or the inode to be * destroyed before we process them, we take an additional reference * on both. */ inode_ref(lock->pinode->inode); __pl_entrylk_ref(lock); lock->contention_time = *now; list_add_tail(&lock->contend, contend); } void entrylk_contention_notify(xlator_t *this, struct list_head *contend) { struct gf_upcall up; struct gf_upcall_entrylk_contention lc; pl_entry_lock_t *lock; pl_inode_t *pl_inode; client_t *client; gf_boolean_t notify; while (!list_empty(contend)) { lock = list_first_entry(contend, pl_entry_lock_t, contend); pl_inode = lock->pinode; pthread_mutex_lock(&pl_inode->mutex); /* If the lock has already been released, no notification is * sent. We clear the notification time in this case. */ notify = !list_empty(&lock->domain_list); if (!notify) { lock->contention_time.tv_sec = 0; lock->contention_time.tv_nsec = 0; } else { lc.type = lock->type; lc.name = lock->basename; lc.pid = lock->client_pid; lc.domain = lock->volume; lc.xdata = NULL; gf_uuid_copy(up.gfid, lock->pinode->gfid); client = (client_t *)lock->client; if (client == NULL) { /* A NULL client can be found if the entrylk * was issued by a server side xlator. */ up.client_uid = NULL; } else { up.client_uid = client->client_uid; } } pthread_mutex_unlock(&pl_inode->mutex); if (notify) { up.event_type = GF_UPCALL_ENTRYLK_CONTENTION; up.data = &lc; if (this->notify(this, GF_EVENT_UPCALL, &up) < 0) { gf_msg_debug(this->name, 0, "Entrylk contention notification " "failed"); } else { gf_msg_debug(this->name, 0, "Entrylk contention notification " "sent"); } } pthread_mutex_lock(&pl_inode->mutex); list_del_init(&lock->contend); __pl_entrylk_unref(lock); pthread_mutex_unlock(&pl_inode->mutex); inode_unref(pl_inode->inode); } } /** * entrylk_grantable - is this lock grantable? * @inode: inode in which to look * @basename: name we're trying to lock * @type: type of lock */ static pl_entry_lock_t * __entrylk_grantable(xlator_t *this, pl_dom_list_t *dom, pl_entry_lock_t *lock, struct timespec *now, struct list_head *contend) { pl_entry_lock_t *tmp = NULL; pl_entry_lock_t *ret = NULL; list_for_each_entry(tmp, &dom->entrylk_list, domain_list) { if (__conflicting_entrylks(tmp, lock)) { if (ret == NULL) { ret = tmp; if (contend == NULL) { break; } } entrylk_contention_notify_check(this, tmp, now, contend); } } return ret; } static pl_entry_lock_t * __blocked_entrylk_conflict(pl_dom_list_t *dom, pl_entry_lock_t *lock) { pl_entry_lock_t *tmp = NULL; list_for_each_entry(tmp, &dom->blocked_entrylks, blocked_locks) { if (names_conflict(tmp->basename, lock->basename)) return lock; } return NULL; } static int __owner_has_lock(pl_dom_list_t *dom, pl_entry_lock_t *newlock) { pl_entry_lock_t *lock = NULL; list_for_each_entry(lock, &dom->entrylk_list, domain_list) { if (__same_entrylk_owner(lock, newlock)) return 1; } list_for_each_entry(lock, &dom->blocked_entrylks, blocked_locks) { if (__same_entrylk_owner(lock, newlock)) return 1; } return 0; } static int names_equal(const char *n1, const char *n2) { return (n1 == NULL && n2 == NULL) || (n1 && n2 && !strcmp(n1, n2)); } void pl_print_entrylk(char *str, int size, entrylk_cmd cmd, entrylk_type type, const char *basename, const char *domain) { char *cmd_str = NULL; char *type_str = NULL; switch (cmd) { case ENTRYLK_LOCK: cmd_str = "LOCK"; break; case ENTRYLK_LOCK_NB: cmd_str = "LOCK_NB"; break; case ENTRYLK_UNLOCK: cmd_str = "UNLOCK"; break; default: cmd_str = "UNKNOWN"; break; } switch (type) { case ENTRYLK_RDLCK: type_str = "READ"; break; case ENTRYLK_WRLCK: type_str = "WRITE"; break; default: type_str = "UNKNOWN"; break; } snprintf(str, size, "lock=ENTRYLK, cmd=%s, type=%s, basename=%s, domain: %s", cmd_str, type_str, basename, domain); } void entrylk_trace_in(xlator_t *this, call_frame_t *frame, const char *domain, fd_t *fd, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type) { posix_locks_private_t *priv = NULL; char pl_locker[256]; char pl_lockee[256]; char pl_entrylk[256]; priv = this->private; if (!priv->trace) return; pl_print_locker(pl_locker, 256, this, frame); pl_print_lockee(pl_lockee, 256, fd, loc); pl_print_entrylk(pl_entrylk, 256, cmd, type, basename, domain); gf_log(this->name, GF_LOG_INFO, "[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}", pl_locker, pl_lockee, pl_entrylk); } void entrylk_trace_out(xlator_t *this, call_frame_t *frame, const char *domain, fd_t *fd, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, int op_ret, int op_errno) { posix_locks_private_t *priv = NULL; char pl_locker[256]; char pl_lockee[256]; char pl_entrylk[256]; char verdict[32]; priv = this->private; if (!priv->trace) return; pl_print_locker(pl_locker, 256, this, frame); pl_print_lockee(pl_lockee, 256, fd, loc); pl_print_entrylk(pl_entrylk, 256, cmd, type, basename, domain); pl_print_verdict(verdict, 32, op_ret, op_errno); gf_log(this->name, GF_LOG_INFO, "[%s] Locker = {%s} Lockee = {%s} Lock = {%s}", verdict, pl_locker, pl_lockee, pl_entrylk); } void entrylk_trace_block(xlator_t *this, call_frame_t *frame, const char *volume, fd_t *fd, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type) { posix_locks_private_t *priv = NULL; char pl_locker[256]; char pl_lockee[256]; char pl_entrylk[256]; priv = this->private; if (!priv->trace) return; pl_print_locker(pl_locker, 256, this, frame); pl_print_lockee(pl_lockee, 256, fd, loc); pl_print_entrylk(pl_entrylk, 256, cmd, type, basename, volume); gf_log(this->name, GF_LOG_INFO, "[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}", pl_locker, pl_lockee, pl_entrylk); } /** * __find_most_matching_lock - find the lock struct which most matches in order * of: lock on the exact basename || an all_names lock * * * @inode: inode in which to look * @basename: name to search for */ static pl_entry_lock_t * __find_most_matching_lock(pl_dom_list_t *dom, const char *basename) { pl_entry_lock_t *lock; pl_entry_lock_t *all = NULL; pl_entry_lock_t *exact = NULL; if (list_empty(&dom->entrylk_list)) return NULL; list_for_each_entry(lock, &dom->entrylk_list, domain_list) { if (all_names(lock->basename)) all = lock; else if (names_equal(lock->basename, basename)) exact = lock; } return (exact ? exact : all); } static pl_entry_lock_t * __find_matching_lock(pl_dom_list_t *dom, pl_entry_lock_t *lock) { pl_entry_lock_t *tmp = NULL; list_for_each_entry(tmp, &dom->entrylk_list, domain_list) { if (names_equal(lock->basename, tmp->basename) && __same_entrylk_owner(lock, tmp) && (lock->type == tmp->type)) return tmp; } return NULL; } static int __lock_blocked_add(xlator_t *this, pl_inode_t *pinode, pl_dom_list_t *dom, pl_entry_lock_t *lock, int nonblock) { if (nonblock) goto out; lock->blkd_time = gf_time(); list_add_tail(&lock->blocked_locks, &dom->blocked_entrylks); gf_msg_trace(this->name, 0, "Blocking lock: {pinode=%p, basename=%s}", pinode, lock->basename); entrylk_trace_block(this, lock->frame, NULL, NULL, NULL, lock->basename, ENTRYLK_LOCK, lock->type); out: return -EAGAIN; } /** * __lock_entrylk - lock a name in a directory * @inode: inode for the directory in which to lock * @basename: name of the entry to lock * if null, lock the entire directory * * the entire directory being locked is represented as: a single * pl_entry_lock_t present in the entrylk_locks list with its * basename = NULL */ int __lock_entrylk(xlator_t *this, pl_inode_t *pinode, pl_entry_lock_t *lock, int nonblock, pl_dom_list_t *dom, struct timespec *now, struct list_head *contend) { pl_entry_lock_t *conf = NULL; int ret = -EAGAIN; conf = __entrylk_grantable(this, dom, lock, now, contend); if (conf) { ret = __lock_blocked_add(this, pinode, dom, lock, nonblock); goto out; } /* To prevent blocked locks starvation, check if there are any blocked * locks thay may conflict with this lock. If there is then don't grant * the lock. BUT grant the lock if the owner already has lock to allow * nested locks. * Example: SHD from Machine1 takes (gfid, basename=257-length-name) * and is granted. * SHD from machine2 takes (gfid, basename=NULL) and is blocked. * When SHD from Machine1 takes (gfid, basename=NULL) it needs to be * granted, without which self-heal can't progress. * TODO: Find why 'owner_has_lock' is checked even for blocked locks. */ if (__blocked_entrylk_conflict(dom, lock) && !(__owner_has_lock(dom, lock))) { if (nonblock == 0) { gf_log(this->name, GF_LOG_DEBUG, "Lock is grantable, but blocking to prevent " "starvation"); } ret = __lock_blocked_add(this, pinode, dom, lock, nonblock); goto out; } __pl_entrylk_ref(lock); lock->granted_time = gf_time(); list_add(&lock->domain_list, &dom->entrylk_list); ret = 0; out: return ret; } /** * __unlock_entrylk - unlock a name in a directory * @inode: inode for the directory to unlock in * @basename: name of the entry to unlock * if null, unlock the entire directory */ pl_entry_lock_t * __unlock_entrylk(pl_dom_list_t *dom, pl_entry_lock_t *lock) { pl_entry_lock_t *ret_lock = NULL; ret_lock = __find_matching_lock(dom, lock); if (ret_lock) { list_del_init(&ret_lock->domain_list); } else { gf_log("locks", GF_LOG_ERROR, "unlock on %s " "(type=ENTRYLK_WRLCK) attempted but no matching lock " "found", lock->basename); } return ret_lock; } int32_t check_entrylk_on_basename(xlator_t *this, inode_t *parent, char *basename) { int32_t entrylk = 0; pl_dom_list_t *dom = NULL; pl_entry_lock_t *conf = NULL; pl_inode_t *pinode = pl_inode_get(this, parent, NULL); if (!pinode) goto out; pthread_mutex_lock(&pinode->mutex); { list_for_each_entry(dom, &pinode->dom_list, inode_list) { conf = __find_most_matching_lock(dom, basename); if (conf && conf->basename) { entrylk = 1; break; } } } pthread_mutex_unlock(&pinode->mutex); out: return entrylk; } void __grant_blocked_entry_locks(xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, struct list_head *granted, struct timespec *now, struct list_head *contend) { int bl_ret = 0; pl_entry_lock_t *bl = NULL; pl_entry_lock_t *tmp = NULL; struct list_head blocked_list; INIT_LIST_HEAD(&blocked_list); list_splice_init(&dom->blocked_entrylks, &blocked_list); list_for_each_entry_safe(bl, tmp, &blocked_list, blocked_locks) { list_del_init(&bl->blocked_locks); bl_ret = __lock_entrylk(bl->this, pl_inode, bl, 0, dom, now, contend); if (bl_ret == 0) { list_add_tail(&bl->blocked_locks, granted); } } } /* Grants locks if possible which are blocked on a lock */ void grant_blocked_entry_locks(xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, struct timespec *now, struct list_head *contend) { struct list_head granted_list; pl_entry_lock_t *tmp = NULL; pl_entry_lock_t *lock = NULL; INIT_LIST_HEAD(&granted_list); pthread_mutex_lock(&pl_inode->mutex); { __grant_blocked_entry_locks(this, pl_inode, dom, &granted_list, now, contend); } pthread_mutex_unlock(&pl_inode->mutex); list_for_each_entry_safe(lock, tmp, &granted_list, blocked_locks) { entrylk_trace_out(this, lock->frame, NULL, NULL, NULL, lock->basename, ENTRYLK_LOCK, lock->type, 0, 0); STACK_UNWIND_STRICT(entrylk, lock->frame, 0, 0, NULL); lock->frame = NULL; } pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry_safe(lock, tmp, &granted_list, blocked_locks) { list_del_init(&lock->blocked_locks); __pl_entrylk_unref(lock); } } pthread_mutex_unlock(&pl_inode->mutex); } /* Common entrylk code called by pl_entrylk and pl_fentrylk */ int pl_common_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, inode_t *inode, const char *basename, entrylk_cmd cmd, entrylk_type type, loc_t *loc, fd_t *fd, dict_t *xdata) { int32_t op_ret = -1; int32_t op_errno = 0; int ret = -1; char unwind = 1; GF_UNUSED int dict_ret = -1; pl_inode_t *pinode = NULL; pl_entry_lock_t *reqlock = NULL; pl_entry_lock_t *unlocked = NULL; pl_dom_list_t *dom = NULL; char *conn_id = NULL; pl_ctx_t *ctx = NULL; int nonblock = 0; gf_boolean_t need_inode_unref = _gf_false; posix_locks_private_t *priv = NULL; struct list_head *pcontend = NULL; struct list_head contend; struct timespec now = {}; priv = this->private; if (priv->notify_contention) { pcontend = &contend; INIT_LIST_HEAD(pcontend); timespec_now(&now); } if (xdata) dict_ret = dict_get_str(xdata, "connection-id", &conn_id); pinode = pl_inode_get(this, inode, NULL); if (!pinode) { op_errno = ENOMEM; goto out; } if (frame->root->client) { ctx = pl_ctx_get(frame->root->client, this); if (!ctx) { op_errno = ENOMEM; gf_log(this->name, GF_LOG_INFO, "pl_ctx_get() failed"); goto unwind; } } dom = get_domain(pinode, volume); if (!dom) { op_errno = ENOMEM; goto out; } entrylk_trace_in(this, frame, volume, fd, loc, basename, cmd, type); reqlock = new_entrylk_lock(pinode, basename, type, dom->domain, frame, conn_id, &op_errno); if (!reqlock) { op_ret = -1; goto unwind; } /* Ideally, AFTER a successful lock (both blocking and non-blocking) or * an unsuccessful blocking lock operation, the inode needs to be ref'd. * * But doing so might give room to a race where the lock-requesting * client could send a DISCONNECT just before this thread refs the inode * after the locking is done, and the epoll thread could unref the inode * in cleanup which means the inode's refcount would come down to 0, and * the call to pl_forget() at this point destroys @pinode. Now when * the io-thread executing this function tries to access pinode, * it could crash on account of illegal memory access. * * To get around this problem, the inode is ref'd once even before * adding the lock into client_list as a precautionary measure. * This way even if there are DISCONNECTs, there will always be 1 extra * ref on the inode, so @pinode is still alive until after the * current stack unwinds. */ pinode->inode = inode_ref(inode); if (priv->revocation_secs != 0) { if (cmd != ENTRYLK_UNLOCK) { __entrylk_prune_stale(this, pinode, dom, reqlock); } else if (priv->monkey_unlocking == _gf_true) { if (pl_does_monkey_want_stuck_lock()) { gf_log(this->name, GF_LOG_WARNING, "MONKEY LOCKING (forcing stuck lock)!"); op_ret = 0; need_inode_unref = _gf_true; pthread_mutex_lock(&pinode->mutex); { __pl_entrylk_unref(reqlock); } pthread_mutex_unlock(&pinode->mutex); goto out; } } } switch (cmd) { case ENTRYLK_LOCK_NB: nonblock = 1; /* fall through */ case ENTRYLK_LOCK: if (ctx) pthread_mutex_lock(&ctx->lock); pthread_mutex_lock(&pinode->mutex); { reqlock->pinode = pinode; ret = __lock_entrylk(this, pinode, reqlock, nonblock, dom, &now, pcontend); if (ret == 0) { reqlock->frame = NULL; op_ret = 0; } else { op_errno = -ret; } if (ctx && (!ret || !nonblock)) list_add(&reqlock->client_list, &ctx->entrylk_lockers); if (ret == -EAGAIN && !nonblock) { /* blocked */ unwind = 0; } else { __pl_entrylk_unref(reqlock); } /* For all but the case where a non-blocking lock * attempt fails, the extra ref taken before the switch * block must be negated. */ if ((ret == -EAGAIN) && (nonblock)) need_inode_unref = _gf_true; } pthread_mutex_unlock(&pinode->mutex); if (ctx) pthread_mutex_unlock(&ctx->lock); break; case ENTRYLK_UNLOCK: if (ctx) pthread_mutex_lock(&ctx->lock); pthread_mutex_lock(&pinode->mutex); { /* Irrespective of whether unlock succeeds or not, * the extra inode ref that was done before the switch * block must be negated. Towards this, * @need_inode_unref flag is set unconditionally here. */ need_inode_unref = _gf_true; unlocked = __unlock_entrylk(dom, reqlock); if (unlocked) { list_del_init(&unlocked->client_list); __pl_entrylk_unref(unlocked); op_ret = 0; } else { op_errno = EINVAL; } __pl_entrylk_unref(reqlock); } pthread_mutex_unlock(&pinode->mutex); if (ctx) pthread_mutex_unlock(&ctx->lock); grant_blocked_entry_locks(this, pinode, dom, &now, pcontend); break; default: need_inode_unref = _gf_true; gf_log(this->name, GF_LOG_ERROR, "Unexpected case in entrylk (cmd=%d). Please file" "a bug report at http://bugs.gluster.com", cmd); goto out; } /* The following (extra) unref corresponds to the ref that * was done at the time the lock was granted. */ if ((cmd == ENTRYLK_UNLOCK) && (op_ret == 0)) inode_unref(pinode->inode); out: if (need_inode_unref) inode_unref(pinode->inode); if (unwind) { entrylk_trace_out(this, frame, volume, fd, loc, basename, cmd, type, op_ret, op_errno); unwind: STACK_UNWIND_STRICT(entrylk, frame, op_ret, op_errno, NULL); } if (pcontend != NULL) { entrylk_contention_notify(this, pcontend); } return 0; } /** * pl_entrylk: * * Locking on names (directory entries) */ int pl_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { pl_common_entrylk(frame, this, volume, loc->inode, basename, cmd, type, loc, NULL, xdata); return 0; } /** * pl_fentrylk: * * Locking on names (directory entries) */ int pl_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { pl_common_entrylk(frame, this, volume, fd->inode, basename, cmd, type, NULL, fd, xdata); return 0; } static void pl_entrylk_log_cleanup(pl_entry_lock_t *lock) { pl_inode_t *pinode = NULL; pinode = lock->pinode; gf_log(THIS->name, GF_LOG_WARNING, "releasing lock on %s held by " "{client=%p, pid=%" PRId64 " lk-owner=%s}", uuid_utoa(pinode->gfid), lock->client, (uint64_t)lock->client_pid, lkowner_utoa(&lock->owner)); } /* Release all entrylks from this client */ int pl_entrylk_client_cleanup(xlator_t *this, pl_ctx_t *ctx) { posix_locks_private_t *priv; pl_entry_lock_t *tmp = NULL; pl_entry_lock_t *l = NULL; pl_dom_list_t *dom = NULL; pl_inode_t *pinode = NULL; struct list_head *pcontend = NULL; struct list_head released; struct list_head unwind; struct list_head contend; struct timespec now = {}; INIT_LIST_HEAD(&released); INIT_LIST_HEAD(&unwind); priv = this->private; if (priv->notify_contention) { pcontend = &contend; INIT_LIST_HEAD(pcontend); timespec_now(&now); } pthread_mutex_lock(&ctx->lock); { list_for_each_entry_safe(l, tmp, &ctx->entrylk_lockers, client_list) { pl_entrylk_log_cleanup(l); pinode = l->pinode; pthread_mutex_lock(&pinode->mutex); { /* If the entrylk object is part of granted list but not * blocked list, then perform the following actions: * i. delete the object from granted list; * ii. grant other locks (from other clients) that may * have been blocked on this entrylk; and * iii. unref the object. * * If the entrylk object (L1) is part of both granted * and blocked lists, then this means that a parallel * unlock on another entrylk (L2 say) may have 'granted' * L1 and added it to 'granted' list in * __grant_blocked_entry_locks() (although using the * 'blocked_locks' member). In that case, the cleanup * codepath must try and grant other overlapping * blocked entrylks from other clients, now that L1 is * out of their way and then unref L1 in the end, and * leave it to the other thread (the one executing * unlock codepath) to unwind L1's frame, delete it from * blocked_locks list, and perform the last unref on L1. * * If the entrylk object (L1) is part of blocked list * only, the cleanup code path must: * i. delete it from the blocked_locks list inside * this critical section, * ii. unwind its frame with EAGAIN, * iii. try and grant blocked entry locks from other * clients that were otherwise grantable, but were * blocked to avoid leaving L1 to starve forever. * iv. unref the object. */ list_del_init(&l->client_list); if (!list_empty(&l->domain_list)) { list_del_init(&l->domain_list); list_add_tail(&l->client_list, &released); } else { list_del_init(&l->blocked_locks); list_add_tail(&l->client_list, &unwind); } } pthread_mutex_unlock(&pinode->mutex); } } pthread_mutex_unlock(&ctx->lock); if (!list_empty(&unwind)) { list_for_each_entry_safe(l, tmp, &unwind, client_list) { list_del_init(&l->client_list); if (l->frame) STACK_UNWIND_STRICT(entrylk, l->frame, -1, EAGAIN, NULL); list_add_tail(&l->client_list, &released); } } if (!list_empty(&released)) { list_for_each_entry_safe(l, tmp, &released, client_list) { list_del_init(&l->client_list); pinode = l->pinode; dom = get_domain(pinode, l->volume); grant_blocked_entry_locks(this, pinode, dom, &now, pcontend); pthread_mutex_lock(&pinode->mutex); { __pl_entrylk_unref(l); } pthread_mutex_unlock(&pinode->mutex); inode_unref(pinode->inode); } } if (pcontend != NULL) { entrylk_contention_notify(this, pcontend); } return 0; } int32_t __get_entrylk_count(xlator_t *this, pl_inode_t *pl_inode) { int32_t count = 0; pl_entry_lock_t *lock = NULL; pl_dom_list_t *dom = NULL; list_for_each_entry(dom, &pl_inode->dom_list, inode_list) { list_for_each_entry(lock, &dom->entrylk_list, domain_list) { count++; } list_for_each_entry(lock, &dom->blocked_entrylks, blocked_locks) { count++; } } return count; } int32_t get_entrylk_count(xlator_t *this, inode_t *inode) { pl_inode_t *pl_inode = NULL; uint64_t tmp_pl_inode = 0; int ret = 0; int32_t count = 0; ret = inode_ctx_get(inode, this, &tmp_pl_inode); if (ret != 0) { goto out; } pl_inode = (pl_inode_t *)(long)tmp_pl_inode; pthread_mutex_lock(&pl_inode->mutex); { count = __get_entrylk_count(this, pl_inode); } pthread_mutex_unlock(&pl_inode->mutex); out: return count; } glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023645 xustar000000000000000030 mtime=1699284276.372059676 30 atime=1699284290.261101509 30 ctime=1699284303.280140722 glusterfs-11.1/xlators/features/locks/src/Makefile.in0000664000175100017510000006116614522202464024136 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/locks/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) locks_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_locks_la_OBJECTS = common.lo posix.lo entrylk.lo inodelk.lo \ reservelk.lo clear.lo locks_la_OBJECTS = $(am_locks_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = locks_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(locks_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_locks_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(locks_la_SOURCES) DIST_SOURCES = $(locks_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = locks.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features locks_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) locks_la_SOURCES = common.c posix.c entrylk.c inodelk.c reservelk.c \ clear.c locks_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = locks.h common.h locks-mem-types.h clear.h pl-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/locks/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/locks/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } locks.la: $(locks_la_OBJECTS) $(locks_la_DEPENDENCIES) $(EXTRA_locks_la_DEPENDENCIES) $(AM_V_CCLD)$(locks_la_LINK) $(am_locks_la_rpath) $(locks_la_OBJECTS) $(locks_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clear.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/entrylk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inodelk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reservelk.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @WITH_SERVER_FALSE@uninstall-local: @WITH_SERVER_FALSE@install-data-hook: clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-xlatorLTLIBRARIES .MAKE: install-am install-data-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-hook install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-local uninstall-xlatorLTLIBRARIES @WITH_SERVER_TRUE@uninstall-local: @WITH_SERVER_TRUE@ rm -f $(DESTDIR)$(xlatordir)/posix-locks.so @WITH_SERVER_TRUE@install-data-hook: @WITH_SERVER_TRUE@ ln -sf locks.so $(DESTDIR)$(xlatordir)/posix-locks.so # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/clear.h0000644000000000000000000000013214522202451023033 xustar000000000000000030 mtime=1699284265.672027447 30 atime=1699284265.672027447 30 ctime=1699284303.289140749 glusterfs-11.1/xlators/features/locks/src/clear.h0000664000175100017510000000362014522202451023313 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __CLEAR_H__ #define __CLEAR_H__ #include #include "locks.h" typedef enum { CLRLK_INODE, CLRLK_ENTRY, CLRLK_POSIX, CLRLK_TYPE_MAX } clrlk_type; extern const char *clrlk_type_names[]; typedef enum { CLRLK_BLOCKED = 1, CLRLK_GRANTED, CLRLK_ALL, CLRLK_KIND_MAX } clrlk_kind; typedef enum { KW_TYPE, KW_KIND, /*add new keywords here*/ KW_MAX } clrlk_opts; struct _clrlk_args; typedef struct _clrlk_args clrlk_args; struct _clrlk_args { int type; int kind; char *opts; }; int clrlk_get__kind(char *kind); int clrlk_get_type(char *type); int clrlk_get_lock_range(char *range_str, struct gf_flock *ulock, gf_boolean_t *chk_range); int clrlk_parse_args(const char *cmd, clrlk_args *args); int clrlk_clear_posixlk(xlator_t *this, pl_inode_t *pl_inode, clrlk_args *args, int *blkd, int *granted, int *op_errno, char *client_uid, pid_t client_pid, bool setlk_interrupt); int clrlk_clear_inodelk(xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, clrlk_args *args, int *blkd, int *granted, int *op_errno); int clrlk_clear_entrylk(xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, clrlk_args *args, int *blkd, int *granted, int *op_errno); int clrlk_clear_lks_in_all_domains(xlator_t *this, pl_inode_t *pl_inode, clrlk_args *args, int *blkd, int *granted, int *op_errno); #endif /* __CLEAR_H__ */ glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023630 xustar000000000000000030 mtime=1699284265.671027444 30 atime=1699284276.334059561 30 ctime=1699284303.282140728 glusterfs-11.1/xlators/features/locks/src/Makefile.am0000664000175100017510000000135614522202451024114 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = locks.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features locks_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) locks_la_SOURCES = common.c posix.c entrylk.c inodelk.c reservelk.c \ clear.c locks_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = locks.h common.h locks-mem-types.h clear.h pl-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) CLEANFILES = if WITH_SERVER uninstall-local: rm -f $(DESTDIR)$(xlatordir)/posix-locks.so install-data-hook: ln -sf locks.so $(DESTDIR)$(xlatordir)/posix-locks.so endif glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/locks.h0000644000000000000000000000013014522202451023056 xustar000000000000000029 mtime=1699284265.67302745 29 atime=1699284265.67302745 30 ctime=1699284303.284140734 glusterfs-11.1/xlators/features/locks/src/locks.h0000664000175100017510000002075214522202451023345 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012, 2015-2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __POSIX_LOCKS_H__ #define __POSIX_LOCKS_H__ #include #include #include "locks-mem-types.h" typedef enum { MLK_NONE, MLK_FILE_BASED, MLK_FORCED, MLK_OPTIMAL } mlk_mode_t; /* defines different mandatory locking modes*/ struct __pl_fd; struct __posix_lock { struct list_head list; off_t fl_start; off_t fl_end; uint32_t lk_flags; short fl_type; short blocked; /* waiting to acquire */ struct gf_flock user_flock; /* the flock supplied by the user */ unsigned long fd_num; fd_t *fd; call_frame_t *frame; time_t blkd_time; /* time at which lock was queued into blkd list */ time_t granted_time; /* time at which lock was queued into active list */ /* These two together serve to uniquely identify each process across nodes */ void *client; /* to identify client node */ /* This field uniquely identifies the client the lock belongs to. As * lock migration is handled by rebalance, the client_t object will be * overwritten by rebalance and can't be deemed as the owner of the * lock on destination. Hence, the below field is migrated from * source to destination by lock_migration_info_t and updated on the * destination. So that on client-server disconnection, server can * cleanup the locks proper;y. */ char *client_uid; gf_lkowner_t owner; pid_t client_pid; /* pid of client process */ int blocking; }; typedef struct __posix_lock posix_lock_t; struct __pl_inode_lock { struct list_head list; struct list_head blocked_locks; /* list_head pointing to blocked_inodelks */ struct list_head contend; /* list of contending locks */ int ref; off_t fl_start; off_t fl_end; const char *volume; struct gf_flock user_flock; /* the flock supplied by the user */ struct __pl_inode *pl_inode; call_frame_t *frame; time_t blkd_time; /* time at which lock was queued into blkd list */ time_t granted_time; /* time at which lock was queued into active list */ /*last time at which lock contention was detected and notified*/ struct timespec contention_time; /* These two together serve to uniquely identify each process across nodes */ void *client; /* to identify client node */ gf_lkowner_t owner; pid_t client_pid; /* pid of client process */ char *connection_id; /* stores the client connection id */ struct list_head client_list; /* list of all locks from a client */ short fl_type; int32_t status; /* Error code when we try to grant a lock in blocked state */ }; typedef struct __pl_inode_lock pl_inode_lock_t; struct _pl_rw_req { struct list_head list; call_stub_t *stub; posix_lock_t region; }; typedef struct _pl_rw_req pl_rw_req_t; struct _pl_dom_list { struct list_head inode_list; /* list_head back to pl_inode_t */ const char *domain; struct list_head entrylk_list; /* List of entry locks */ struct list_head blocked_entrylks; /* List of all blocked entrylks */ struct list_head inodelk_list; /* List of inode locks */ struct list_head blocked_inodelks; /* List of all blocked inodelks */ }; typedef struct _pl_dom_list pl_dom_list_t; struct __entry_lock { struct list_head domain_list; /* list_head back to pl_dom_list_t */ struct list_head blocked_locks; /* list_head back to blocked_entrylks */ struct list_head contend; /* list of contending locks */ int ref; call_frame_t *frame; xlator_t *this; struct __pl_inode *pinode; const char *volume; const char *basename; time_t blkd_time; /* time at which lock was queued into blkd list */ time_t granted_time; /* time at which lock was queued into active list */ /*last time at which lock contention was detected and notified*/ struct timespec contention_time; void *client; gf_lkowner_t owner; pid_t client_pid; /* pid of client process */ char *connection_id; /* stores the client connection id */ struct list_head client_list; /* list of all locks from a client */ entrylk_type type; }; typedef struct __entry_lock pl_entry_lock_t; /* The "simulated" inode. This contains a list of all the locks associated with this file */ struct __pl_inode { pthread_mutex_t mutex; struct list_head dom_list; /* list of domains */ struct list_head ext_list; /* list of fcntl locks */ struct list_head rw_list; /* list of waiting r/w requests */ struct list_head reservelk_list; /* list of reservelks */ struct list_head blocked_reservelks; /* list of blocked reservelks */ struct list_head blocked_calls; /* List of blocked lock calls while a reserve is held*/ struct list_head metalk_list; /* Meta lock list */ struct list_head queued_locks; /* This is to store the incoming lock requests while meta lock is enabled */ struct list_head waiting; /* List of pending fops waiting to unlink/rmdir the inode. */ int mandatory; /* if mandatory locking is enabled */ inode_t *refkeeper; /* hold refs on an inode while locks are held to prevent pruning */ uuid_t gfid; /* placeholder for gfid of the inode */ inode_t *inode; /* pointer to be used for ref and unref of inode_t as long as there are locks on it */ gf_boolean_t migrated; /* Flag to indicate whether to read mlock-enforce xattr from disk */ gf_boolean_t check_mlock_info; /* Mandatory_lock enforce: IO will be allowed if and only if the lkowner has held the lock. Note: An xattr is set on the file to recover this information post reboot. If client does not want mandatory lock to be enforced, then it should remove this xattr explicitly */ gf_boolean_t mlock_enforced; /* There are scenarios where mandatory lock is granted but there are IOs pending at posix level. To avoid this before preempting the previous lock owner, we wait for all the fops to be unwound. */ int fop_wind_count; pthread_cond_t check_fop_wind_count; gf_boolean_t track_fop_wind_count; uint32_t remove_running; /* Number of remove operations running. */ gf_boolean_t is_locked; /* Regular locks will be blocked. */ }; typedef struct __pl_inode pl_inode_t; struct __pl_metalk { pthread_mutex_t mutex; /* For pl_inode meta lock list */ struct list_head list; /* For pl_ctx_t list */ struct list_head client_list; char *client_uid; pl_inode_t *pl_inode; int ref; }; typedef struct __pl_metalk pl_meta_lock_t; typedef struct { char *brickname; uint32_t revocation_secs; uint32_t revocation_max_blocked; uint32_t notify_contention_delay; mlk_mode_t mandatory_mode; /* holds current mandatory locking mode */ gf_boolean_t trace; /* trace lock requests in and out */ gf_boolean_t monkey_unlocking; gf_boolean_t revocation_clear_all; gf_boolean_t notify_contention; gf_boolean_t mlock_enforced; } posix_locks_private_t; typedef struct { data_t *inodelk_dom_count_req; dict_t *xdata; loc_t loc[2]; fd_t *fd; inode_t *inode; off_t offset; glusterfs_fop_t op; uint32_t bitfield; int update_mlock_enforced_flag; } pl_local_t; typedef struct { struct list_head locks_list; } pl_fdctx_t; typedef struct _locks_ctx { pthread_mutex_t lock; struct list_head inodelk_lockers; struct list_head entrylk_lockers; struct list_head metalk_list; } pl_ctx_t; typedef struct _multi_dom_lk_data { xlator_t *this; inode_t *inode; dict_t *xdata_rsp; gf_boolean_t keep_max; } multi_dom_lk_data; typedef enum { DECREMENT, INCREMENT } pl_count_op_t; pl_ctx_t * pl_ctx_get(client_t *client, xlator_t *xlator); int pl_inodelk_client_cleanup(xlator_t *this, pl_ctx_t *ctx); int pl_entrylk_client_cleanup(xlator_t *this, pl_ctx_t *ctx); #endif /* __POSIX_LOCKS_H__ */ glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/clear.c0000644000000000000000000000013214522202451023026 xustar000000000000000030 mtime=1699284265.672027447 30 atime=1699284265.671027444 30 ctime=1699284303.301140785 glusterfs-11.1/xlators/features/locks/src/clear.c0000664000175100017510000003116414522202451023312 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include "locks.h" #include "common.h" #include #include "clear.h" const char *clrlk_type_names[CLRLK_TYPE_MAX] = { [CLRLK_INODE] = "inode", [CLRLK_ENTRY] = "entry", [CLRLK_POSIX] = "posix", }; int clrlk_get_kind(char *kind) { char *clrlk_kinds[CLRLK_KIND_MAX] = {"dummy", "blocked", "granted", "all"}; int ret_kind = CLRLK_KIND_MAX; int i = 0; for (i = CLRLK_BLOCKED; i < CLRLK_KIND_MAX; i++) { if (!strcmp(clrlk_kinds[i], kind)) { ret_kind = i; break; } } return ret_kind; } int clrlk_get_type(char *type) { char *clrlk_types[CLRLK_TYPE_MAX] = {"inode", "entry", "posix"}; int ret_type = CLRLK_TYPE_MAX; int i = 0; for (i = CLRLK_INODE; i < CLRLK_TYPE_MAX; i++) { if (!strcmp(clrlk_types[i], type)) { ret_type = i; break; } } return ret_type; } int clrlk_get_lock_range(char *range_str, struct gf_flock *ulock, gf_boolean_t *chk_range) { int ret = -1; if (!chk_range) goto out; if (!range_str) { ret = 0; *chk_range = _gf_false; goto out; } if (sscanf(range_str, "%hd,%" PRId64 "-" "%" PRId64, &ulock->l_whence, &ulock->l_start, &ulock->l_len) != 3) { goto out; } ret = 0; *chk_range = _gf_true; out: return ret; } int clrlk_parse_args(const char *cmd, clrlk_args *args) { char *opts = NULL; char *cur = NULL; char *tok = NULL; char *sptr = NULL; char *free_ptr = NULL; char kw[KW_MAX] = { [KW_TYPE] = 't', [KW_KIND] = 'k', }; int ret = -1; int i = 0; GF_ASSERT(cmd); free_ptr = opts = GF_CALLOC(1, strlen(cmd), gf_common_mt_char); if (!opts) goto out; if (sscanf(cmd, GF_XATTR_CLRLK_CMD ".%s", opts) < 1 && sscanf(cmd, GF_XATTR_INTRLK_CMD ".%s", opts) < 1) { ret = -1; goto out; } /*clr_lk_prefix.ttype.kkind.args, args - type specific*/ cur = opts; for (i = 0; i < KW_MAX && (tok = strtok_r(cur, ".", &sptr)); cur = NULL, i++) { if (tok[0] != kw[i]) { ret = -1; goto out; } if (i == KW_TYPE) args->type = clrlk_get_type(tok + 1); if (i == KW_KIND) args->kind = clrlk_get_kind(tok + 1); } if ((args->type == CLRLK_TYPE_MAX) || (args->kind == CLRLK_KIND_MAX)) goto out; /*optional args, neither range nor basename can 'legally' contain * "/" in them*/ tok = strtok_r(NULL, "/", &sptr); if (tok) args->opts = gf_strdup(tok); ret = 0; out: GF_FREE(free_ptr); return ret; } int clrlk_clear_posixlk(xlator_t *this, pl_inode_t *pl_inode, clrlk_args *args, int *blkd, int *granted, int *op_errno, char *client_uid, pid_t client_pid, bool setlk_interrupt) { posix_lock_t *plock = NULL; posix_lock_t *tmp = NULL; pl_local_t *local; struct gf_flock ulock = { 0, }; struct list_head blocked_list; int ret = -1; int bcount = 0; int gcount = 0; gf_boolean_t chk_range = _gf_false; if (clrlk_get_lock_range(args->opts, &ulock, &chk_range)) { *op_errno = EINVAL; goto out; } INIT_LIST_HEAD(&blocked_list); pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry_safe(plock, tmp, &pl_inode->ext_list, list) { if ((plock->blocked && !(args->kind & CLRLK_BLOCKED)) || (!plock->blocked && !(args->kind & CLRLK_GRANTED))) continue; if (chk_range && (plock->user_flock.l_whence != ulock.l_whence || plock->user_flock.l_start != ulock.l_start || plock->user_flock.l_len != ulock.l_len)) continue; if (setlk_interrupt) { if ((plock->client_pid != client_pid) || (strcmp(plock->client_uid, client_uid) != 0)) { continue; } } list_del_init(&plock->list); if (plock->blocked) { list_add_tail(&plock->list, &blocked_list); bcount++; } else { gcount++; __destroy_lock(plock); } } } pthread_mutex_unlock(&pl_inode->mutex); plock = NULL; tmp = NULL; /* Perform stack unwind outside of pl_inode lock */ list_for_each_entry_safe(plock, tmp, &blocked_list, list) { list_del_init(&plock->list); pl_trace_out(this, plock->frame, NULL, NULL, F_SETLKW, &plock->user_flock, -1, EINTR, NULL); local = plock->frame->local; PL_STACK_UNWIND_AND_FREE(local, lk, plock->frame, -1, EINTR, &plock->user_flock, NULL); __destroy_lock(plock); } grant_blocked_locks(this, pl_inode); ret = 0; out: *blkd = bcount; *granted = gcount; return ret; } /* Returns 0 on success and -1 on failure */ int clrlk_clear_inodelk(xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, clrlk_args *args, int *blkd, int *granted, int *op_errno) { posix_locks_private_t *priv; pl_inode_lock_t *ilock = NULL; pl_inode_lock_t *tmp = NULL; struct gf_flock ulock = { 0, }; int ret = -1; int bcount = 0; int gcount = 0; gf_boolean_t chk_range = _gf_false; struct list_head *pcontend = NULL; struct list_head released; struct list_head contend; struct timespec now = {}; INIT_LIST_HEAD(&released); priv = this->private; if (priv->notify_contention) { pcontend = &contend; INIT_LIST_HEAD(pcontend); timespec_now(&now); } if (clrlk_get_lock_range(args->opts, &ulock, &chk_range)) { *op_errno = EINVAL; goto out; } if (args->kind & CLRLK_BLOCKED) goto blkd; if (args->kind & CLRLK_GRANTED) goto granted; blkd: pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry_safe(ilock, tmp, &dom->blocked_inodelks, blocked_locks) { if (chk_range && (ilock->user_flock.l_whence != ulock.l_whence || ilock->user_flock.l_start != ulock.l_start || ilock->user_flock.l_len != ulock.l_len)) continue; bcount++; list_del_init(&ilock->client_list); list_del_init(&ilock->blocked_locks); list_add(&ilock->blocked_locks, &released); } } pthread_mutex_unlock(&pl_inode->mutex); if (!list_empty(&released)) { list_for_each_entry_safe(ilock, tmp, &released, blocked_locks) { list_del_init(&ilock->blocked_locks); pl_trace_out(this, ilock->frame, NULL, NULL, F_SETLKW, &ilock->user_flock, -1, EAGAIN, ilock->volume); STACK_UNWIND_STRICT(inodelk, ilock->frame, -1, EAGAIN, NULL); // No need to take lock as the locks are only in one list __pl_inodelk_unref(ilock); } } if (!(args->kind & CLRLK_GRANTED)) { ret = 0; goto out; } granted: pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry_safe(ilock, tmp, &dom->inodelk_list, list) { if (chk_range && (ilock->user_flock.l_whence != ulock.l_whence || ilock->user_flock.l_start != ulock.l_start || ilock->user_flock.l_len != ulock.l_len)) continue; gcount++; list_del_init(&ilock->client_list); list_del_init(&ilock->list); list_add(&ilock->list, &released); } } pthread_mutex_unlock(&pl_inode->mutex); list_for_each_entry_safe(ilock, tmp, &released, list) { list_del_init(&ilock->list); // No need to take lock as the locks are only in one list __pl_inodelk_unref(ilock); } ret = 0; out: grant_blocked_inode_locks(this, pl_inode, dom, &now, pcontend); if (pcontend != NULL) { inodelk_contention_notify(this, pcontend); } *blkd = bcount; *granted = gcount; return ret; } /* Returns 0 on success and -1 on failure */ int clrlk_clear_entrylk(xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, clrlk_args *args, int *blkd, int *granted, int *op_errno) { posix_locks_private_t *priv; pl_entry_lock_t *elock = NULL; pl_entry_lock_t *tmp = NULL; int bcount = 0; int gcount = 0; int ret = -1; struct list_head *pcontend = NULL; struct list_head removed; struct list_head released; struct list_head contend; struct timespec now; INIT_LIST_HEAD(&released); priv = this->private; if (priv->notify_contention) { pcontend = &contend; INIT_LIST_HEAD(pcontend); timespec_now(&now); } if (args->kind & CLRLK_BLOCKED) goto blkd; if (args->kind & CLRLK_GRANTED) goto granted; blkd: pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry_safe(elock, tmp, &dom->blocked_entrylks, blocked_locks) { if (args->opts) { if (!elock->basename || strcmp(elock->basename, args->opts)) continue; } bcount++; list_del_init(&elock->client_list); list_del_init(&elock->blocked_locks); list_add_tail(&elock->blocked_locks, &released); } } pthread_mutex_unlock(&pl_inode->mutex); if (!list_empty(&released)) { list_for_each_entry_safe(elock, tmp, &released, blocked_locks) { list_del_init(&elock->blocked_locks); entrylk_trace_out(this, elock->frame, elock->volume, NULL, NULL, elock->basename, ENTRYLK_LOCK, elock->type, -1, EAGAIN); STACK_UNWIND_STRICT(entrylk, elock->frame, -1, EAGAIN, NULL); __pl_entrylk_unref(elock); } } if (!(args->kind & CLRLK_GRANTED)) { ret = 0; goto out; } granted: INIT_LIST_HEAD(&removed); pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry_safe(elock, tmp, &dom->entrylk_list, domain_list) { if (args->opts) { if (!elock->basename || strcmp(elock->basename, args->opts)) continue; } gcount++; list_del_init(&elock->client_list); list_del_init(&elock->domain_list); list_add_tail(&elock->domain_list, &removed); __pl_entrylk_unref(elock); } } pthread_mutex_unlock(&pl_inode->mutex); grant_blocked_entry_locks(this, pl_inode, dom, &now, pcontend); if (pcontend != NULL) { entrylk_contention_notify(this, pcontend); } ret = 0; out: *blkd = bcount; *granted = gcount; return ret; } int clrlk_clear_lks_in_all_domains(xlator_t *this, pl_inode_t *pl_inode, clrlk_args *args, int *blkd, int *granted, int *op_errno) { pl_dom_list_t *dom = NULL; int ret = -1; int tmp_bcount = 0; int tmp_gcount = 0; if (list_empty(&pl_inode->dom_list)) { ret = 0; goto out; } list_for_each_entry(dom, &pl_inode->dom_list, inode_list) { tmp_bcount = tmp_gcount = 0; switch (args->type) { case CLRLK_INODE: ret = clrlk_clear_inodelk(this, pl_inode, dom, args, &tmp_bcount, &tmp_gcount, op_errno); if (ret) goto out; break; case CLRLK_ENTRY: ret = clrlk_clear_entrylk(this, pl_inode, dom, args, &tmp_bcount, &tmp_gcount, op_errno); if (ret) goto out; break; } *blkd += tmp_bcount; *granted += tmp_gcount; } ret = 0; out: return ret; } glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/locks-mem-types.h0000644000000000000000000000013014522202451024774 xustar000000000000000029 mtime=1699284265.67302745 29 atime=1699284265.67302745 30 ctime=1699284303.287140743 glusterfs-11.1/xlators/features/locks/src/locks-mem-types.h0000664000175100017510000000147614522202451025265 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __LOCKS_MEM_TYPES_H__ #define __LOCKS_MEM_TYPES_H__ #include enum gf_locks_mem_types_ { gf_locks_mt_pl_dom_list_t = gf_common_mt_end + 1, gf_locks_mt_pl_inode_t, gf_locks_mt_posix_lock_t, gf_locks_mt_pl_entry_lock_t, gf_locks_mt_pl_inode_lock_t, gf_locks_mt_pl_rw_req_t, gf_locks_mt_posix_locks_private_t, gf_locks_mt_pl_fdctx_t, gf_locks_mt_pl_meta_lock_t, gf_locks_mt_end }; #endif glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/inodelk.c0000644000000000000000000000013014522202451023363 xustar000000000000000029 mtime=1699284265.67302745 29 atime=1699284265.67302745 30 ctime=1699284303.298140776 glusterfs-11.1/xlators/features/locks/src/inodelk.c0000664000175100017510000010440114522202451023644 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include "locks.h" #include "clear.h" #include "common.h" void __delete_inode_lock(pl_inode_lock_t *lock) { list_del_init(&lock->list); } static void __pl_inodelk_ref(pl_inode_lock_t *lock) { lock->ref++; } void __pl_inodelk_unref(pl_inode_lock_t *lock) { lock->ref--; if (!lock->ref) { GF_FREE(lock->connection_id); GF_FREE(lock); } } /* Check if 2 inodelks are conflicting on type. Only 2 shared locks don't * conflict */ static int inodelk_type_conflict(pl_inode_lock_t *l1, pl_inode_lock_t *l2) { if (l2->fl_type == F_WRLCK || l1->fl_type == F_WRLCK) return 1; return 0; } void pl_print_inodelk(char *str, int size, int cmd, struct gf_flock *flock, const char *domain) { char *cmd_str = NULL; char *type_str = NULL; switch (cmd) { #if F_GETLK != F_GETLK64 case F_GETLK64: #endif case F_GETLK: cmd_str = "GETLK"; break; #if F_SETLK != F_SETLK64 case F_SETLK64: #endif case F_SETLK: cmd_str = "SETLK"; break; #if F_SETLKW != F_SETLKW64 case F_SETLKW64: #endif case F_SETLKW: cmd_str = "SETLKW"; break; default: cmd_str = "UNKNOWN"; break; } switch (flock->l_type) { case F_RDLCK: type_str = "READ"; break; case F_WRLCK: type_str = "WRITE"; break; case F_UNLCK: type_str = "UNLOCK"; break; default: type_str = "UNKNOWN"; break; } snprintf(str, size, "lock=INODELK, cmd=%s, type=%s, " "domain: %s, start=%llu, len=%llu, pid=%llu", cmd_str, type_str, domain, (unsigned long long)flock->l_start, (unsigned long long)flock->l_len, (unsigned long long)flock->l_pid); } /* Determine if the two inodelks overlap reach other's lock regions */ static int inodelk_overlap(pl_inode_lock_t *l1, pl_inode_lock_t *l2) { return ((l1->fl_end >= l2->fl_start) && (l2->fl_end >= l1->fl_start)); } /* Returns true if the 2 inodelks have the same owner */ static int same_inodelk_owner(pl_inode_lock_t *l1, pl_inode_lock_t *l2) { return (is_same_lkowner(&l1->owner, &l2->owner) && (l1->client == l2->client)); } /* Returns true if the 2 inodelks conflict with each other */ static int inodelk_conflict(pl_inode_lock_t *l1, pl_inode_lock_t *l2) { return (inodelk_overlap(l1, l2) && inodelk_type_conflict(l1, l2)); } /* * Check to see if the candidate lock overlaps/conflicts with the * requested lock. If so, determine how old the lock is and return * true if it exceeds the configured threshold, false otherwise. */ static inline gf_boolean_t __stale_inodelk(xlator_t *this, pl_inode_lock_t *candidate_lock, pl_inode_lock_t *requested_lock, time_t *lock_age_sec) { posix_locks_private_t *priv = NULL; priv = this->private; /* Question: Should we just prune them all given the * chance? Or just the locks we are attempting to acquire? */ if (inodelk_conflict(candidate_lock, requested_lock)) { *lock_age_sec = gf_time() - candidate_lock->granted_time; if (*lock_age_sec > priv->revocation_secs) return _gf_true; } return _gf_false; } /* Examine any locks held on this inode and potentially revoke the lock * if the age exceeds revocation_secs. We will clear _only_ those locks * which are granted, and then grant those locks which are blocked. * * Depending on how this patch works in the wild, we may expand this and * introduce a heuristic which clears blocked locks as well if they * are beyond a threshold. */ static gf_boolean_t __inodelk_prune_stale(xlator_t *this, pl_inode_t *pinode, pl_dom_list_t *dom, pl_inode_lock_t *lock) { posix_locks_private_t *priv = NULL; pl_inode_lock_t *tmp = NULL; pl_inode_lock_t *lk = NULL; gf_boolean_t revoke_lock = _gf_false; int bcount = 0; int gcount = 0; int op_errno = 0; clrlk_args args; args.opts = NULL; time_t lk_age_sec = 0; uint32_t max_blocked = 0; char *reason_str = NULL; priv = this->private; args.type = CLRLK_INODE; if (priv->revocation_clear_all == _gf_true) args.kind = CLRLK_ALL; else args.kind = CLRLK_GRANTED; if (list_empty(&dom->inodelk_list)) goto out; pthread_mutex_lock(&pinode->mutex); list_for_each_entry_safe(lk, tmp, &dom->inodelk_list, list) { if (__stale_inodelk(this, lk, lock, &lk_age_sec) == _gf_true) { revoke_lock = _gf_true; reason_str = "age"; break; } } max_blocked = priv->revocation_max_blocked; if (max_blocked != 0 && revoke_lock == _gf_false) { list_for_each_entry_safe(lk, tmp, &dom->blocked_inodelks, blocked_locks) { max_blocked--; if (max_blocked == 0) { revoke_lock = _gf_true; reason_str = "max blocked"; break; } } } pthread_mutex_unlock(&pinode->mutex); out: if (revoke_lock == _gf_true) { clrlk_clear_inodelk(this, pinode, dom, &args, &bcount, &gcount, &op_errno); gf_log(this->name, GF_LOG_WARNING, "Lock revocation [reason: %s; gfid: %s; domain: %s; " "age: %ld sec] - Inode lock revoked: %d granted & %d " "blocked locks cleared", reason_str, uuid_utoa(pinode->gfid), dom->domain, lk_age_sec, gcount, bcount); } return revoke_lock; } void inodelk_contention_notify_check(xlator_t *this, pl_inode_lock_t *lock, struct timespec *now, struct list_head *contend) { posix_locks_private_t *priv; int64_t elapsed; priv = this->private; /* If this lock is in a list, it means that we are about to send a * notification for it, so no need to do anything else. */ if (!list_empty(&lock->contend)) { return; } elapsed = now->tv_sec; elapsed -= lock->contention_time.tv_sec; if (now->tv_nsec < lock->contention_time.tv_nsec) { elapsed--; } if (elapsed < priv->notify_contention_delay) { return; } /* All contention notifications will be sent outside of the locked * region. This means that currently granted locks might have already * been unlocked by that time. To avoid the lock or the inode to be * destroyed before we process them, we take an additional reference * on both. */ inode_ref(lock->pl_inode->inode); __pl_inodelk_ref(lock); lock->contention_time = *now; list_add_tail(&lock->contend, contend); } void inodelk_contention_notify(xlator_t *this, struct list_head *contend) { struct gf_upcall up; struct gf_upcall_inodelk_contention lc; pl_inode_lock_t *lock; pl_inode_t *pl_inode; client_t *client; gf_boolean_t notify; while (!list_empty(contend)) { lock = list_first_entry(contend, pl_inode_lock_t, contend); pl_inode = lock->pl_inode; pthread_mutex_lock(&pl_inode->mutex); /* If the lock has already been released, no notification is * sent. We clear the notification time in this case. */ notify = !list_empty(&lock->list); if (!notify) { lock->contention_time.tv_sec = 0; lock->contention_time.tv_nsec = 0; } else { gf_flock_copy(&lc.flock, &lock->user_flock); lc.pid = lock->client_pid; lc.domain = lock->volume; lc.xdata = NULL; gf_uuid_copy(up.gfid, lock->pl_inode->gfid); client = (client_t *)lock->client; if (client == NULL) { /* A NULL client can be found if the inodelk * was issued by a server side xlator. */ up.client_uid = NULL; } else { up.client_uid = client->client_uid; } } pthread_mutex_unlock(&pl_inode->mutex); if (notify) { up.event_type = GF_UPCALL_INODELK_CONTENTION; up.data = &lc; if (this->notify(this, GF_EVENT_UPCALL, &up) < 0) { gf_msg_debug(this->name, 0, "Inodelk contention notification " "failed"); } else { gf_msg_debug(this->name, 0, "Inodelk contention notification " "sent"); } } pthread_mutex_lock(&pl_inode->mutex); list_del_init(&lock->contend); __pl_inodelk_unref(lock); pthread_mutex_unlock(&pl_inode->mutex); inode_unref(pl_inode->inode); } } /* Determine if lock is grantable or not */ static pl_inode_lock_t * __inodelk_grantable(xlator_t *this, pl_dom_list_t *dom, pl_inode_lock_t *lock, struct timespec *now, struct list_head *contend) { pl_inode_lock_t *l = NULL; pl_inode_lock_t *ret = NULL; list_for_each_entry(l, &dom->inodelk_list, list) { if (inodelk_conflict(lock, l) && !same_inodelk_owner(lock, l)) { if (ret == NULL) { ret = l; if (contend == NULL) { break; } } inodelk_contention_notify_check(this, l, now, contend); } } return ret; } static pl_inode_lock_t * __blocked_lock_conflict(pl_dom_list_t *dom, pl_inode_lock_t *lock) { pl_inode_lock_t *l = NULL; list_for_each_entry(l, &dom->blocked_inodelks, blocked_locks) { if (inodelk_conflict(lock, l)) { return l; } } return NULL; } static int __owner_has_lock(pl_dom_list_t *dom, pl_inode_lock_t *newlock) { pl_inode_lock_t *lock = NULL; list_for_each_entry(lock, &dom->inodelk_list, list) { if (same_inodelk_owner(lock, newlock)) return 1; } list_for_each_entry(lock, &dom->blocked_inodelks, blocked_locks) { if (same_inodelk_owner(lock, newlock)) return 1; } return 0; } static int __lock_blocked_add(xlator_t *this, pl_dom_list_t *dom, pl_inode_lock_t *lock, int can_block) { if (can_block == 0) { goto out; } lock->blkd_time = gf_time(); list_add_tail(&lock->blocked_locks, &dom->blocked_inodelks); gf_msg_trace(this->name, 0, "%s (pid=%d) (lk-owner=%s) %" PRId64 " - " "%" PRId64 " => Blocked", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); pl_trace_block(this, lock->frame, NULL, NULL, F_SETLKW, &lock->user_flock, lock->volume); out: return -EAGAIN; } /* Determines if lock can be granted and adds the lock. If the lock * is blocking, adds it to the blocked_inodelks list of the domain. */ static int __lock_inodelk(xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock, int can_block, pl_dom_list_t *dom, struct timespec *now, struct list_head *contend) { pl_inode_lock_t *conf = NULL; int ret; ret = pl_inode_remove_inodelk(pl_inode, lock); if (ret < 0) { return ret; } if (ret == 0) { conf = __inodelk_grantable(this, dom, lock, now, contend); } if ((ret > 0) || (conf != NULL)) { return __lock_blocked_add(this, dom, lock, can_block); } /* To prevent blocked locks starvation, check if there are any blocked * locks thay may conflict with this lock. If there is then don't grant * the lock. BUT grant the lock if the owner already has lock to allow * nested locks. * Example: * SHD from Machine1 takes (gfid, 0-infinity) and is granted. * SHD from machine2 takes (gfid, 0-infinity) and is blocked. * When SHD from Machine1 takes (gfid, 0-128KB) it * needs to be granted, without which the earlier lock on 0-infinity * will not be unlocked by SHD from Machine1. * TODO: Find why 'owner_has_lock' is checked even for blocked locks. */ if (__blocked_lock_conflict(dom, lock) && !(__owner_has_lock(dom, lock))) { if (can_block != 0) { gf_log(this->name, GF_LOG_DEBUG, "Lock is grantable, but blocking to prevent " "starvation"); } return __lock_blocked_add(this, dom, lock, can_block); } __pl_inodelk_ref(lock); lock->granted_time = gf_time(); list_add(&lock->list, &dom->inodelk_list); return 0; } /* Return true if the two inodelks have exactly same lock boundaries */ static int inodelks_equal(pl_inode_lock_t *l1, pl_inode_lock_t *l2) { if ((l1->fl_start == l2->fl_start) && (l1->fl_end == l2->fl_end)) return 1; return 0; } static pl_inode_lock_t * find_matching_inodelk(pl_inode_lock_t *lock, pl_dom_list_t *dom) { pl_inode_lock_t *l = NULL; list_for_each_entry(l, &dom->inodelk_list, list) { if (inodelks_equal(l, lock) && same_inodelk_owner(l, lock)) return l; } return NULL; } /* Set F_UNLCK removes a lock which has the exact same lock boundaries * as the UNLCK lock specifies. If such a lock is not found, returns invalid */ static pl_inode_lock_t * __inode_unlock_lock(xlator_t *this, pl_inode_lock_t *lock, pl_dom_list_t *dom) { pl_inode_lock_t *conf = NULL; inode_t *inode = NULL; inode = lock->pl_inode->inode; conf = find_matching_inodelk(lock, dom); if (!conf) { gf_log(this->name, GF_LOG_ERROR, " Matching lock not found for unlock %llu-%llu, by %s " "on %p for gfid:%s", (unsigned long long)lock->fl_start, (unsigned long long)lock->fl_end, lkowner_utoa(&lock->owner), lock->client, inode ? uuid_utoa(inode->gfid) : "UNKNOWN"); goto out; } __delete_inode_lock(conf); gf_log(this->name, GF_LOG_DEBUG, " Matching lock found for unlock %llu-%llu, by %s on %p for gfid:%s", (unsigned long long)lock->fl_start, (unsigned long long)lock->fl_end, lkowner_utoa(&lock->owner), lock->client, inode ? uuid_utoa(inode->gfid) : "UNKNOWN"); out: return conf; } void __grant_blocked_inode_locks(xlator_t *this, pl_inode_t *pl_inode, struct list_head *granted, pl_dom_list_t *dom, struct timespec *now, struct list_head *contend) { pl_inode_lock_t *bl = NULL; pl_inode_lock_t *tmp = NULL; struct list_head blocked_list; INIT_LIST_HEAD(&blocked_list); list_splice_init(&dom->blocked_inodelks, &blocked_list); list_for_each_entry_safe(bl, tmp, &blocked_list, blocked_locks) { list_del_init(&bl->blocked_locks); bl->status = __lock_inodelk(this, pl_inode, bl, 1, dom, now, contend); if (bl->status != -EAGAIN) { list_add_tail(&bl->blocked_locks, granted); } } } void unwind_granted_inodes(xlator_t *this, pl_inode_t *pl_inode, struct list_head *granted) { pl_inode_lock_t *lock; pl_inode_lock_t *tmp; int32_t op_ret; int32_t op_errno; list_for_each_entry_safe(lock, tmp, granted, blocked_locks) { if (lock->status == 0) { op_ret = 0; op_errno = 0; gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) (lk-owner=%s) %" PRId64 " - %" PRId64 " => Granted", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); } else { op_ret = -1; op_errno = -lock->status; } pl_trace_out(this, lock->frame, NULL, NULL, F_SETLKW, &lock->user_flock, op_ret, op_errno, lock->volume); STACK_UNWIND_STRICT(inodelk, lock->frame, op_ret, op_errno, NULL); lock->frame = NULL; } pthread_mutex_lock(&pl_inode->mutex); { list_for_each_entry_safe(lock, tmp, granted, blocked_locks) { list_del_init(&lock->blocked_locks); __pl_inodelk_unref(lock); } } pthread_mutex_unlock(&pl_inode->mutex); } /* Grant all inodelks blocked on a lock */ void grant_blocked_inode_locks(xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, struct timespec *now, struct list_head *contend) { struct list_head granted; INIT_LIST_HEAD(&granted); pthread_mutex_lock(&pl_inode->mutex); { __grant_blocked_inode_locks(this, pl_inode, &granted, dom, now, contend); } pthread_mutex_unlock(&pl_inode->mutex); unwind_granted_inodes(this, pl_inode, &granted); } static void pl_inodelk_log_cleanup(pl_inode_lock_t *lock) { pl_inode_t *pl_inode = NULL; pl_inode = lock->pl_inode; gf_log(THIS->name, GF_LOG_WARNING, "releasing lock on %s held by " "{client=%p, pid=%" PRId64 " lk-owner=%s}", uuid_utoa(pl_inode->gfid), lock->client, (uint64_t)lock->client_pid, lkowner_utoa(&lock->owner)); } /* Release all inodelks from this client */ int pl_inodelk_client_cleanup(xlator_t *this, pl_ctx_t *ctx) { posix_locks_private_t *priv; pl_inode_lock_t *tmp = NULL; pl_inode_lock_t *l = NULL; pl_dom_list_t *dom = NULL; pl_inode_t *pl_inode = NULL; struct list_head *pcontend = NULL; struct list_head released; struct list_head unwind; struct list_head contend; struct timespec now = {}; priv = this->private; INIT_LIST_HEAD(&released); INIT_LIST_HEAD(&unwind); if (priv->notify_contention) { pcontend = &contend; INIT_LIST_HEAD(pcontend); timespec_now(&now); } pthread_mutex_lock(&ctx->lock); { list_for_each_entry_safe(l, tmp, &ctx->inodelk_lockers, client_list) { pl_inodelk_log_cleanup(l); pl_inode = l->pl_inode; pthread_mutex_lock(&pl_inode->mutex); { /* If the inodelk object is part of granted list but not * blocked list, then perform the following actions: * i. delete the object from granted list; * ii. grant other locks (from other clients) that may * have been blocked on this inodelk; and * iii. unref the object. * * If the inodelk object (L1) is part of both granted * and blocked lists, then this means that a parallel * unlock on another inodelk (L2 say) may have 'granted' * L1 and added it to 'granted' list in * __grant_blocked_inode_locks() (although using the * 'blocked_locks' member). In that case, the cleanup * codepath must try and grant other overlapping * blocked inodelks from other clients, now that L1 is * out of their way and then unref L1 in the end, and * leave it to the other thread (the one executing * unlock codepath) to unwind L1's frame, delete it from * blocked_locks list, and perform the last unref on L1. * * If the inodelk object (L1) is part of blocked list * only, the cleanup code path must: * i. delete it from the blocked_locks list inside * this critical section, * ii. unwind its frame with EAGAIN, * iii. try and grant blocked inode locks from other * clients that were otherwise grantable, but just * got blocked to avoid leaving L1 to starve * forever. * iv. unref the object. */ list_del_init(&l->client_list); if (!list_empty(&l->list)) { __delete_inode_lock(l); list_add_tail(&l->client_list, &released); } else { list_del_init(&l->blocked_locks); list_add_tail(&l->client_list, &unwind); } } pthread_mutex_unlock(&pl_inode->mutex); } } pthread_mutex_unlock(&ctx->lock); if (!list_empty(&unwind)) { list_for_each_entry_safe(l, tmp, &unwind, client_list) { list_del_init(&l->client_list); if (l->frame) STACK_UNWIND_STRICT(inodelk, l->frame, -1, EAGAIN, NULL); list_add_tail(&l->client_list, &released); } } if (!list_empty(&released)) { list_for_each_entry_safe(l, tmp, &released, client_list) { list_del_init(&l->client_list); pl_inode = l->pl_inode; dom = get_domain(pl_inode, l->volume); grant_blocked_inode_locks(this, pl_inode, dom, &now, pcontend); pthread_mutex_lock(&pl_inode->mutex); { __pl_inodelk_unref(l); } pthread_mutex_unlock(&pl_inode->mutex); inode_unref(pl_inode->inode); } } if (pcontend != NULL) { inodelk_contention_notify(this, pcontend); } return 0; } static int pl_inode_setlk(xlator_t *this, pl_ctx_t *ctx, pl_inode_t *pl_inode, pl_inode_lock_t *lock, int can_block, pl_dom_list_t *dom, inode_t *inode) { posix_locks_private_t *priv = NULL; int ret = -EINVAL; pl_inode_lock_t *retlock = NULL; gf_boolean_t unref = _gf_true; gf_boolean_t need_inode_unref = _gf_false; struct list_head *pcontend = NULL; struct list_head contend; struct list_head wake; struct timespec now = {}; short fl_type; lock->pl_inode = pl_inode; fl_type = lock->fl_type; priv = this->private; /* Ideally, AFTER a successful lock (both blocking and non-blocking) or * an unsuccessful blocking lock operation, the inode needs to be ref'd. * * But doing so might give room to a race where the lock-requesting * client could send a DISCONNECT just before this thread refs the inode * after the locking is done, and the epoll thread could unref the inode * in cleanup which means the inode's refcount would come down to 0, and * the call to pl_forget() at this point destroys @pl_inode. Now when * the io-thread executing this function tries to access pl_inode, * it could crash on account of illegal memory access. * * To get around this problem, the inode is ref'd once even before * adding the lock into client_list as a precautionary measure. * This way even if there are DISCONNECTs, there will always be 1 extra * ref on the inode, so @pl_inode is still alive until after the * current stack unwinds. */ pl_inode->inode = inode_ref(inode); if (priv->revocation_secs != 0) { if (lock->fl_type != F_UNLCK) { __inodelk_prune_stale(this, pl_inode, dom, lock); } else if (priv->monkey_unlocking == _gf_true) { if (pl_does_monkey_want_stuck_lock()) { pthread_mutex_lock(&pl_inode->mutex); { __pl_inodelk_unref(lock); } pthread_mutex_unlock(&pl_inode->mutex); inode_unref(pl_inode->inode); gf_log(this->name, GF_LOG_WARNING, "MONKEY LOCKING (forcing stuck lock)!"); return 0; } } } if (priv->notify_contention) { pcontend = &contend; INIT_LIST_HEAD(pcontend); timespec_now(&now); } INIT_LIST_HEAD(&wake); if (ctx) pthread_mutex_lock(&ctx->lock); pthread_mutex_lock(&pl_inode->mutex); { if (lock->fl_type != F_UNLCK) { ret = __lock_inodelk(this, pl_inode, lock, can_block, dom, &now, pcontend); if (ret == 0) { lock->frame = NULL; gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) (lk-owner=%s) %" PRId64 " - %" PRId64 " => OK", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->fl_start, lock->fl_end); } else if (ret == -EAGAIN) { gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) (lk-owner=%s) %" PRId64 " - %" PRId64 " => NOK", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); if (can_block) { unref = _gf_false; } } /* For all but the case where a non-blocking lock attempt fails * with -EAGAIN, the extra ref taken at the start of this function * must be negated. */ need_inode_unref = (ret != 0) && ((ret != -EAGAIN) || !can_block); if (ctx && !need_inode_unref) { list_add_tail(&lock->client_list, &ctx->inodelk_lockers); } } else { /* Irrespective of whether unlock succeeds or not, * the extra inode ref that was done at the start of * this function must be negated. Towards this, * @need_inode_unref flag is set unconditionally here. */ need_inode_unref = _gf_true; retlock = __inode_unlock_lock(this, lock, dom); if (!retlock) { gf_log(this->name, GF_LOG_DEBUG, "Bad Unlock issued on Inode lock"); ret = -EINVAL; goto out; } list_del_init(&retlock->client_list); __pl_inodelk_unref(retlock); pl_inode_remove_unlocked(this, pl_inode, &wake); ret = 0; } out: if (unref) __pl_inodelk_unref(lock); } pthread_mutex_unlock(&pl_inode->mutex); if (ctx) pthread_mutex_unlock(&ctx->lock); pl_inode_remove_wake(&wake); /* The following (extra) unref corresponds to the ref that * was done at the time the lock was granted. */ if ((fl_type == F_UNLCK) && (ret == 0)) { inode_unref(pl_inode->inode); grant_blocked_inode_locks(this, pl_inode, dom, &now, pcontend); } if (need_inode_unref) { inode_unref(pl_inode->inode); } if (pcontend != NULL) { inodelk_contention_notify(this, pcontend); } return ret; } /* Create a new inode_lock_t */ static pl_inode_lock_t * new_inode_lock(struct gf_flock *flock, client_t *client, pid_t client_pid, call_frame_t *frame, xlator_t *this, const char *volume, char *conn_id, int32_t *op_errno) { pl_inode_lock_t *lock = NULL; if (!pl_is_lk_owner_valid(&frame->root->lk_owner, frame->root->client)) { *op_errno = EINVAL; goto out; } lock = GF_CALLOC(1, sizeof(*lock), gf_locks_mt_pl_inode_lock_t); if (!lock) { *op_errno = ENOMEM; goto out; } lock->fl_start = flock->l_start; lock->fl_type = flock->l_type; if (flock->l_len == 0) lock->fl_end = LLONG_MAX; else lock->fl_end = flock->l_start + flock->l_len - 1; lock->client = client; lock->client_pid = client_pid; lock->volume = volume; lk_owner_copy(&lock->owner, &frame->root->lk_owner); lock->frame = frame; if (conn_id) { lock->connection_id = gf_strdup(conn_id); } INIT_LIST_HEAD(&lock->list); INIT_LIST_HEAD(&lock->blocked_locks); INIT_LIST_HEAD(&lock->client_list); INIT_LIST_HEAD(&lock->contend); __pl_inodelk_ref(lock); out: return lock; } int32_t _pl_convert_volume(const char *volume, char **res) { char *mdata_vol = NULL; int ret = 0; mdata_vol = strrchr(volume, ':'); // if the volume already ends with :metadata don't bother if (mdata_vol && (strcmp(mdata_vol, ":metadata") == 0)) return 0; ret = gf_asprintf(res, "%s:metadata", volume); if (ret <= 0) return ENOMEM; return 0; } int32_t _pl_convert_volume_for_special_range(struct gf_flock *flock, const char *volume, char **res) { int32_t ret = 0; if ((flock->l_start == LLONG_MAX - 1) && (flock->l_len == 0)) { ret = _pl_convert_volume(volume, res); } return ret; } /* Common inodelk code called from pl_inodelk and pl_finodelk */ int pl_common_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, inode_t *inode, int32_t cmd, struct gf_flock *flock, loc_t *loc, fd_t *fd, dict_t *xdata) { int32_t op_ret = -1; int32_t op_errno = 0; int ret = -1; GF_UNUSED int dict_ret = -1; int can_block = 0; short lock_type = 0; pl_inode_t *pinode = NULL; pl_inode_lock_t *reqlock = NULL; pl_dom_list_t *dom = NULL; char *res = NULL; char *res1 = NULL; char *conn_id = NULL; pl_ctx_t *ctx = NULL; if (xdata) dict_ret = dict_get_str(xdata, "connection-id", &conn_id); VALIDATE_OR_GOTO(frame, out); VALIDATE_OR_GOTO(inode, unwind); VALIDATE_OR_GOTO(flock, unwind); if ((flock->l_start < 0) || (flock->l_len < 0)) { op_errno = EINVAL; goto unwind; } op_errno = _pl_convert_volume_for_special_range(flock, volume, &res); if (op_errno) goto unwind; if (res) volume = res; pl_trace_in(this, frame, fd, loc, cmd, flock, volume); if (frame->root->client) { ctx = pl_ctx_get(frame->root->client, this); if (!ctx) { op_errno = ENOMEM; gf_log(this->name, GF_LOG_INFO, "pl_ctx_get() failed"); goto unwind; } } pinode = pl_inode_get(this, inode, NULL); if (!pinode) { op_errno = ENOMEM; goto unwind; } dom = get_domain(pinode, volume); if (!dom) { op_errno = ENOMEM; goto unwind; } reqlock = new_inode_lock(flock, frame->root->client, frame->root->pid, frame, this, dom->domain, conn_id, &op_errno); if (!reqlock) { op_ret = -1; goto unwind; } switch (cmd) { case F_SETLKW: can_block = 1; /* fall through */ case F_SETLK: lock_type = flock->l_type; gf_flock_copy(&reqlock->user_flock, flock); ret = pl_inode_setlk(this, ctx, pinode, reqlock, can_block, dom, inode); if (ret < 0) { if (ret == -EAGAIN) { if (can_block && (F_UNLCK != lock_type)) { goto out; } gf_log(this->name, GF_LOG_TRACE, "returning EAGAIN"); } else { gf_log(this->name, GF_LOG_TRACE, "returning %d", ret); } op_errno = -ret; goto unwind; } break; default: op_errno = ENOTSUP; gf_log(this->name, GF_LOG_DEBUG, "Lock command F_GETLK not supported for [f]inodelk " "(cmd=%d)", cmd); goto unwind; } op_ret = 0; unwind: if (flock != NULL) pl_trace_out(this, frame, fd, loc, cmd, flock, op_ret, op_errno, volume); STACK_UNWIND_STRICT(inodelk, frame, op_ret, op_errno, NULL); out: GF_FREE(res); GF_FREE(res1); return 0; } int pl_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { pl_common_inodelk(frame, this, volume, loc->inode, cmd, flock, loc, NULL, xdata); return 0; } int pl_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { pl_common_inodelk(frame, this, volume, fd->inode, cmd, flock, NULL, fd, xdata); return 0; } static int32_t __get_inodelk_dom_count(pl_dom_list_t *dom) { pl_inode_lock_t *lock = NULL; int32_t count = 0; list_for_each_entry(lock, &dom->inodelk_list, list) { count++; } list_for_each_entry(lock, &dom->blocked_inodelks, blocked_locks) { count++; } return count; } /* Returns the no. of locks (blocked/granted) held on a given domain name * If @domname is NULL, returns the no. of locks in all the domains present. * If @domname is non-NULL and non-existent, returns 0 */ int32_t __get_inodelk_count(xlator_t *this, pl_inode_t *pl_inode, char *domname) { int32_t count = 0; pl_dom_list_t *dom = NULL; list_for_each_entry(dom, &pl_inode->dom_list, inode_list) { if (domname) { if (strcmp(domname, dom->domain) == 0) { count = __get_inodelk_dom_count(dom); goto out; } } else { /* Counting locks from all domains */ count += __get_inodelk_dom_count(dom); } } out: return count; } int32_t get_inodelk_count(xlator_t *this, inode_t *inode, char *domname) { pl_inode_t *pl_inode = NULL; uint64_t tmp_pl_inode = 0; int ret = 0; int32_t count = 0; ret = inode_ctx_get(inode, this, &tmp_pl_inode); if (ret != 0) { goto out; } pl_inode = (pl_inode_t *)(long)tmp_pl_inode; pthread_mutex_lock(&pl_inode->mutex); { count = __get_inodelk_count(this, pl_inode, domname); } pthread_mutex_unlock(&pl_inode->mutex); out: return count; } glusterfs-11.1/xlators/features/locks/src/PaxHeaders.9031/reservelk.c0000644000000000000000000000013214522202451023742 xustar000000000000000030 mtime=1699284265.674027453 30 atime=1699284265.674027453 30 ctime=1699284303.299140779 glusterfs-11.1/xlators/features/locks/src/reservelk.c0000664000175100017510000002501214522202451024221 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "locks.h" #include "common.h" /* Return true if the two reservelks have exactly same lock boundaries */ int reservelks_equal(posix_lock_t *l1, posix_lock_t *l2) { if ((l1->fl_start == l2->fl_start) && (l1->fl_end == l2->fl_end)) return 1; return 0; } /* Determine if lock is grantable or not */ static posix_lock_t * __reservelk_grantable(pl_inode_t *pl_inode, posix_lock_t *lock) { xlator_t *this = THIS; posix_lock_t *l = NULL; posix_lock_t *ret_lock = NULL; if (list_empty(&pl_inode->reservelk_list)) { gf_log(this->name, GF_LOG_TRACE, "No reservelks in list"); goto out; } list_for_each_entry(l, &pl_inode->reservelk_list, list) { if (reservelks_equal(lock, l)) { ret_lock = l; break; } } out: return ret_lock; } static int __same_owner_reservelk(posix_lock_t *l1, posix_lock_t *l2) { return (is_same_lkowner(&l1->owner, &l2->owner)); } static posix_lock_t * __matching_reservelk(pl_inode_t *pl_inode, posix_lock_t *lock) { posix_lock_t *l = NULL; if (list_empty(&pl_inode->reservelk_list)) { gf_log("posix-locks", GF_LOG_TRACE, "reservelk list empty"); return NULL; } list_for_each_entry(l, &pl_inode->reservelk_list, list) { if (reservelks_equal(l, lock)) { gf_log("posix-locks", GF_LOG_TRACE, "equal reservelk found"); break; } } return l; } static int __reservelk_conflict(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock) { int ret = 0; posix_lock_t *conf = __matching_reservelk(pl_inode, lock); if (conf) { gf_log(this->name, GF_LOG_TRACE, "Matching reservelk found"); if (__same_owner_reservelk(lock, conf)) { list_del_init(&conf->list); gf_log(this->name, GF_LOG_TRACE, "Removing the matching reservelk for setlk to progress"); __destroy_lock(conf); ret = 0; } else { gf_log(this->name, GF_LOG_TRACE, "Conflicting reservelk found"); ret = 1; } } return ret; } int pl_verify_reservelk(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, const int can_block) { int ret = 0; pthread_mutex_lock(&pl_inode->mutex); { if (__reservelk_conflict(this, pl_inode, lock)) { lock->blocked = can_block; list_add_tail(&lock->list, &pl_inode->blocked_calls); pthread_mutex_unlock(&pl_inode->mutex); gf_log(this->name, GF_LOG_TRACE, "Found conflicting reservelk. Blocking until reservelk is " "unlocked."); ret = -1; goto out; } } pthread_mutex_unlock(&pl_inode->mutex); gf_log(this->name, GF_LOG_TRACE, "no conflicting reservelk found. Call continuing"); ret = 0; out: return ret; } /* Determines if lock can be granted and adds the lock. If the lock * is blocking, adds it to the blocked_reservelks. */ static int __lock_reservelk(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, const int can_block) { int ret = -EINVAL; posix_lock_t *conf = __reservelk_grantable(pl_inode, lock); if (conf) { ret = -EAGAIN; if (can_block == 0) goto out; list_add_tail(&lock->list, &pl_inode->blocked_reservelks); gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) lk-owner:%s %" PRId64 " - %" PRId64 " => Blocked", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); goto out; } list_add(&lock->list, &pl_inode->reservelk_list); ret = 0; out: return ret; } static posix_lock_t * find_matching_reservelk(posix_lock_t *lock, pl_inode_t *pl_inode) { posix_lock_t *l = NULL; list_for_each_entry(l, &pl_inode->reservelk_list, list) { if (reservelks_equal(l, lock)) return l; } return NULL; } /* Set F_UNLCK removes a lock which has the exact same lock boundaries * as the UNLCK lock specifies. If such a lock is not found, returns invalid */ static posix_lock_t * __reserve_unlock_lock(xlator_t *this, posix_lock_t *lock, pl_inode_t *pl_inode) { posix_lock_t *conf = find_matching_reservelk(lock, pl_inode); if (!conf) { gf_log(this->name, GF_LOG_DEBUG, " Matching lock not found for unlock"); goto out; } __delete_lock(conf); gf_log(this->name, GF_LOG_DEBUG, " Matching lock found for unlock"); out: return conf; } static void __grant_blocked_reserve_locks(xlator_t *this, pl_inode_t *pl_inode, struct list_head *granted) { int bl_ret = 0; posix_lock_t *bl = NULL; posix_lock_t *tmp = NULL; struct list_head blocked_list; INIT_LIST_HEAD(&blocked_list); list_splice_init(&pl_inode->blocked_reservelks, &blocked_list); list_for_each_entry_safe(bl, tmp, &blocked_list, list) { list_del_init(&bl->list); bl_ret = __lock_reservelk(this, pl_inode, bl, 1); if (bl_ret == 0) { list_add(&bl->list, granted); } } return; } /* Grant all reservelks blocked on lock(s) */ void grant_blocked_reserve_locks(xlator_t *this, pl_inode_t *pl_inode) { struct list_head granted; posix_lock_t *lock = NULL; posix_lock_t *tmp = NULL; INIT_LIST_HEAD(&granted); if (list_empty(&pl_inode->blocked_reservelks)) { gf_log(this->name, GF_LOG_TRACE, "No blocked locks to be granted"); return; } pthread_mutex_lock(&pl_inode->mutex); { __grant_blocked_reserve_locks(this, pl_inode, &granted); } pthread_mutex_unlock(&pl_inode->mutex); list_for_each_entry_safe(lock, tmp, &granted, list) { gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) (lk-owner=%s) %" PRId64 " - %" PRId64 " => Granted", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); STACK_UNWIND_STRICT(lk, lock->frame, 0, 0, &lock->user_flock, NULL); } } static void __grant_blocked_lock_calls(xlator_t *this, pl_inode_t *pl_inode, struct list_head *granted) { int bl_ret = 0; posix_lock_t *bl = NULL; posix_lock_t *tmp = NULL; struct list_head blocked_list; INIT_LIST_HEAD(&blocked_list); list_splice_init(&pl_inode->blocked_reservelks, &blocked_list); list_for_each_entry_safe(bl, tmp, &blocked_list, list) { list_del_init(&bl->list); bl_ret = pl_verify_reservelk(this, pl_inode, bl, bl->blocked); if (bl_ret == 0) { list_add_tail(&bl->list, granted); } } return; } void grant_blocked_lock_calls(xlator_t *this, pl_inode_t *pl_inode) { struct list_head granted; posix_lock_t *lock = NULL; posix_lock_t *tmp = NULL; fd_t *fd = NULL; pl_local_t *local; int32_t op_errno; int can_block = 0; int32_t cmd = 0; int ret = 0; if (list_empty(&pl_inode->blocked_calls)) { gf_log(this->name, GF_LOG_TRACE, "No blocked lock calls to be granted"); return; } INIT_LIST_HEAD(&granted); pthread_mutex_lock(&pl_inode->mutex); { __grant_blocked_lock_calls(this, pl_inode, &granted); } pthread_mutex_unlock(&pl_inode->mutex); list_for_each_entry_safe(lock, tmp, &granted, list) { fd = fd_from_fdnum(lock); if (lock->blocked) { can_block = 1; cmd = F_SETLKW; } else cmd = F_SETLK; lock->blocked = 0; ret = pl_setlk(this, pl_inode, lock, can_block); if (ret < 0) { op_errno = -ret; } else if (ret == PL_LOCK_WOULD_BLOCK) { if (can_block) { continue; } else { gf_log(this->name, GF_LOG_DEBUG, "returning EAGAIN"); op_errno = EAGAIN; } } else { continue; } pl_trace_out(this, lock->frame, fd, NULL, cmd, &lock->user_flock, -1, op_errno, NULL); pl_update_refkeeper(this, fd->inode); local = lock->frame->local; PL_STACK_UNWIND_AND_FREE(local, lk, lock->frame, -1, op_errno, &lock->user_flock, NULL); __destroy_lock(lock); } } int pl_reserve_unlock(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock) { posix_lock_t *retlock = NULL; int ret = -1; pthread_mutex_lock(&pl_inode->mutex); { retlock = __reserve_unlock_lock(this, lock, pl_inode); if (!retlock) { pthread_mutex_unlock(&pl_inode->mutex); gf_log(this->name, GF_LOG_DEBUG, "Bad Unlock issued on Inode lock"); ret = -EINVAL; goto out; } gf_log(this->name, GF_LOG_TRACE, "Reservelk Unlock successful"); __destroy_lock(retlock); ret = 0; } pthread_mutex_unlock(&pl_inode->mutex); out: grant_blocked_reserve_locks(this, pl_inode); grant_blocked_lock_calls(this, pl_inode); return ret; } int pl_reserve_setlk(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, int can_block) { int ret = -EINVAL; pthread_mutex_lock(&pl_inode->mutex); { ret = __lock_reservelk(this, pl_inode, lock, can_block); } pthread_mutex_unlock(&pl_inode->mutex); if (ret < 0) gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) (lk-owner=%s) %" PRId64 " - %" PRId64 " => NOK", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); else gf_log(this->name, GF_LOG_TRACE, "%s (pid=%d) (lk-owner=%s) %" PRId64 " - %" PRId64 " => OK", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->fl_start, lock->fl_end); return ret; } glusterfs-11.1/xlators/features/locks/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202464023055 xustar000000000000000030 mtime=1699284276.323059528 30 atime=1699284290.236101434 29 ctime=1699284303.23314058 glusterfs-11.1/xlators/features/locks/Makefile.in0000664000175100017510000005272114522202464023344 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/locks DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/locks/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/locks/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/locks/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023041 xustar000000000000000030 mtime=1699284265.671027444 30 atime=1699284276.299059456 30 ctime=1699284303.235140586 glusterfs-11.1/xlators/features/locks/Makefile.am0000664000175100017510000000003514522202451023316 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/leases0000644000000000000000000000013014522202521021065 xustar000000000000000029 mtime=1699284305.07914614 30 atime=1699284309.687160019 29 ctime=1699284305.07914614 glusterfs-11.1/xlators/features/leases/0002775000175100017510000000000014522202521021425 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/leases/PaxHeaders.9031/src0000644000000000000000000000013214522202521021656 xustar000000000000000030 mtime=1699284305.127146285 30 atime=1699284309.687160019 30 ctime=1699284305.127146285 glusterfs-11.1/xlators/features/leases/src/0002775000175100017510000000000014522202521022214 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/leases/src/PaxHeaders.9031/leases.h0000644000000000000000000000013214522202451023362 xustar000000000000000030 mtime=1699284265.671027444 30 atime=1699284265.671027444 30 ctime=1699284305.122146269 glusterfs-11.1/xlators/features/leases/src/leases.h0000664000175100017510000003051114522202451023641 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015-2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _LEASES_H #define _LEASES_H #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include #include #include #include "timer-wheel.h" #include "leases-mem-types.h" #include "leases-messages.h" /* The time period for which a client lease lock will be stored after its been * recalled for the first time. */ #define RECALL_LEASE_LK_TIMEOUT "60" #define DATA_MODIFY_FOP 0x0001 #define BLOCKING_FOP 0x0002 #define BLOCK_FOP 0x0001 #define WIND_FOP 0x0002 #define EXIT_IF_LEASES_OFF(this, label) \ do { \ if (!is_leases_enabled(this)) \ goto label; \ } while (0) #define EXIT_IF_INTERNAL_FOP(frame, xdata, label) \ do { \ if (frame->root->pid < 0) \ goto label; \ if (xdata && dict_get(xdata, GLUSTERFS_INTERNAL_FOP_KEY)) \ goto label; \ } while (0) #define GET_LEASE_ID(xdata, lease_id, client_uid) \ do { \ int ret_val = -1; \ ret_val = dict_get_bin(xdata, "lease-id", (void **)&lease_id); \ if (ret_val) { \ ret_val = 0; \ gf_msg_debug("leases", 0, "Lease id is not set for client:%s", \ client_uid); \ } \ } while (0) #define GET_FLAGS(fop, fd_flags) \ do { \ if ((fd_flags & (O_WRONLY | O_RDWR)) && fop == GF_FOP_OPEN) \ fop_flags = DATA_MODIFY_FOP; \ \ if (fop == GF_FOP_UNLINK || fop == GF_FOP_RENAME || \ fop == GF_FOP_TRUNCATE || fop == GF_FOP_FTRUNCATE || \ fop == GF_FOP_FLUSH || fop == GF_FOP_FSYNC || \ fop == GF_FOP_WRITE || fop == GF_FOP_FALLOCATE || \ fop == GF_FOP_DISCARD || fop == GF_FOP_ZEROFILL || \ fop == GF_FOP_SETATTR || fop == GF_FOP_FSETATTR || \ fop == GF_FOP_LINK) \ fop_flags = DATA_MODIFY_FOP; \ \ if (!(fd_flags & (O_NONBLOCK | O_NDELAY))) \ fop_flags |= BLOCKING_FOP; \ \ } while (0) #define GET_FLAGS_LK(cmd, l_type, fd_flags) \ do { \ /* TODO: handle F_RESLK_LCK and other glusterfs_lk_recovery_cmds_t */ \ if ((cmd == F_SETLKW || cmd == F_SETLKW64 || cmd == F_SETLK || \ cmd == F_SETLK64) && \ l_type == F_WRLCK) \ fop_flags = DATA_MODIFY_FOP; \ \ if (fd_flags & (O_NONBLOCK | O_NDELAY) && \ (cmd == F_SETLKW || cmd == F_SETLKW64)) \ fop_flags |= BLOCKING_FOP; \ \ } while (0) #define LEASE_BLOCK_FOP(inode, fop_name, frame, this, params...) \ do { \ call_stub_t *__stub = NULL; \ fop_stub_t *blk_fop = NULL; \ lease_inode_ctx_t *lease_ctx = NULL; \ \ __stub = fop_##fop_name##_stub(frame, default_##fop_name##_resume, \ params); \ if (!__stub) { \ gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM, \ "Unable to create stub"); \ ret = -ENOMEM; \ goto __out; \ } \ \ blk_fop = GF_CALLOC(1, sizeof(*blk_fop), gf_leases_mt_fop_stub_t); \ if (!blk_fop) { \ gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM, \ "Unable to create lease fop stub"); \ ret = -ENOMEM; \ goto __out; \ } \ \ lease_ctx = lease_ctx_get(inode, this); \ if (!lease_ctx) { \ gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM, \ "Unable to create/get inode ctx"); \ ret = -ENOMEM; \ goto __out; \ } \ \ blk_fop->stub = __stub; \ pthread_mutex_lock(&lease_ctx->lock); \ { \ /*TODO: If the lease is unlocked btw check lease conflict and \ * by now, then this fop shouldn't be add to the blocked fop \ * list, can use generation number for the same?*/ \ list_add_tail(&blk_fop->list, &lease_ctx->blocked_list); \ } \ pthread_mutex_unlock(&lease_ctx->lock); \ \ __out: \ if (ret < 0) { \ gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM, \ "Unable to create stub for blocking the fop:%s (%s)", \ gf_fop_list[frame->root->op], strerror(ENOMEM)); \ if (__stub != NULL) { \ call_stub_destroy(__stub); \ } \ GF_FREE(blk_fop); \ goto err; \ } \ } while (0) struct _leases_private { struct list_head client_list; struct list_head recall_list; struct tvec_base *timer_wheel; /* timer wheel where the recall request is qued and waits for unlock/expiry */ pthread_t recall_thr; pthread_mutex_t mutex; pthread_cond_t cond; time_t recall_lease_timeout; gf_boolean_t inited_recall_thr; gf_boolean_t fini; gf_boolean_t leases_enabled; char _pad[1]; /* manual padding */ }; typedef struct _leases_private leases_private_t; struct _lease_client { char *client_uid; struct list_head client_list; struct list_head inode_list; }; typedef struct _lease_client lease_client_t; struct _lease_inode { inode_t *inode; struct list_head list; /* This can be part of both inode_list and recall_list */ }; typedef struct _lease_inode lease_inode_t; struct _lease_fd_ctx { char *client_uid; char lease_id[LEASE_ID_SIZE]; }; typedef struct _lease_fd_ctx lease_fd_ctx_t; struct _lease_inode_ctx { struct list_head lease_id_list; /* clients that have taken leases */ int lease_type_cnt[GF_LEASE_MAX_TYPE + 1]; uint64_t lease_cnt; /* Total number of leases on this inode */ uint64_t openfd_cnt; /* number of fds open */ struct list_head blocked_list; /* List of fops blocked until the lease recall is complete */ inode_t *inode; /* this represents the inode on which the lock was taken, required mainly during disconnect cleanup */ struct gf_tw_timer_list *timer; pthread_mutex_t lock; int lease_type; /* Types of leases acquired */ gf_boolean_t recall_in_progress; /* if lease recall is sent on this inode */ gf_boolean_t blocked_fops_resuming; /* if blocked fops are being resumed */ char _pad[2]; /* manual padding */ }; typedef struct _lease_inode_ctx lease_inode_ctx_t; struct _lease_id_entry { struct list_head lease_id_list; char lease_id[LEASE_ID_SIZE]; char *client_uid; /* uid of the client that has taken the lease */ int lease_type_cnt[GF_LEASE_MAX_TYPE + 1]; /* count of each lease type */ uint64_t lease_cnt; /* Number of leases taken under the given lease id */ time_t recall_time; /* time @ which recall was sent */ int lease_type; /* Union of all the leases taken under the given lease id */ char _pad[4]; /* manual padding */ }; typedef struct _lease_id_entry lease_id_entry_t; /* Required? as stub itself will have list */ struct __fop_stub { struct list_head list; call_stub_t *stub; }; typedef struct __fop_stub fop_stub_t; struct __lease_timer_data { inode_t *inode; xlator_t *this; }; typedef struct __lease_timer_data lease_timer_data_t; gf_boolean_t is_leases_enabled(xlator_t *this); lease_inode_ctx_t * lease_ctx_get(inode_t *inode, xlator_t *this); int process_lease_req(call_frame_t *frame, xlator_t *this, inode_t *inode, struct gf_lease *lease); int check_lease_conflict(call_frame_t *frame, inode_t *inode, const char *lease_id, uint32_t fop_flags); int cleanup_client_leases(xlator_t *this, const char *client_uid); void * expired_recall_cleanup(void *data); #endif /* _LEASES_H */ glusterfs-11.1/xlators/features/leases/src/PaxHeaders.9031/leases-internal.c0000644000000000000000000000013214522202451025167 xustar000000000000000030 mtime=1699284265.670027441 30 atime=1699284265.670027441 30 ctime=1699284305.128146288 glusterfs-11.1/xlators/features/leases/src/leases-internal.c0000664000175100017510000012222414522202451025451 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015-2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include #include "leases.h" /* Mutex locks used in this xlator and their order of acquisition: * Check lease conflict: * lease_ctx lock * add_timer => internal timer locks * lease_ctx unlock * * Add/remove lease: * lease_ctx lock * add_timer => internal timer locks * OR * priv lock => Adding/removing to/from the cleanup client list * priv unlock * lease_ctx unlock * * Timer thread: * Timer internal lock * priv lock => By timer handler * priv unlock * Timer internal unlock * * Expired recall cleanup thread: * priv lock * priv condwait * priv unlock * lease_ctx lock * priv lock * priv unlock * lease_ctx unlock */ /* * Check if lease_lk is enabled * Return Value: * _gf_true - lease lock option enabled * _gf_false - lease lock option disabled */ gf_boolean_t is_leases_enabled(xlator_t *this) { leases_private_t *priv = NULL; gf_boolean_t is_enabled = _gf_false; GF_VALIDATE_OR_GOTO("leases", this, out); if (this->private) { priv = (leases_private_t *)this->private; is_enabled = priv->leases_enabled; } out: return is_enabled; } /* * Get the recall_leaselk_timeout * Return Value: * timeout value(in seconds) set as an option to this xlator. * -1 error case */ static time_t get_recall_lease_timeout(xlator_t *this) { leases_private_t *priv = NULL; time_t timeout = (time_t)-1; GF_VALIDATE_OR_GOTO("leases", this, out); if (this->private) { priv = (leases_private_t *)this->private; timeout = priv->recall_lease_timeout; } out: return timeout; } static void __dump_leases_info(xlator_t *this, lease_inode_ctx_t *lease_ctx) { lease_id_entry_t *lease_entry = NULL; lease_id_entry_t *tmp = NULL; GF_VALIDATE_OR_GOTO("leases", this, out); GF_VALIDATE_OR_GOTO("leases", lease_ctx, out); gf_msg_debug(this->name, 0, "Lease held on this inode, lease_type: %d," " lease_cnt:%" PRIu64 ", RD lease:%d, RW lease:%d, " "openfd cnt:%" PRIu64, lease_ctx->lease_type, lease_ctx->lease_cnt, lease_ctx->lease_type_cnt[GF_RD_LEASE], lease_ctx->lease_type_cnt[GF_RW_LEASE], lease_ctx->openfd_cnt); list_for_each_entry_safe(lease_entry, tmp, &lease_ctx->lease_id_list, lease_id_list) { gf_msg_debug(this->name, 0, "Leases held by client: %s, lease " "ID:%s, RD lease:%d, RW lease:%d, lease_type: %d, " "lease_cnt:%" PRIu64, lease_entry->client_uid, lease_entry->lease_id, lease_entry->lease_type_cnt[GF_RD_LEASE], lease_entry->lease_type_cnt[GF_RW_LEASE], lease_entry->lease_type, lease_entry->lease_cnt); } out: return; } static int __lease_ctx_set(inode_t *inode, xlator_t *this) { lease_inode_ctx_t *inode_ctx = NULL; int ret; inode_ctx = GF_CALLOC(1, sizeof(*inode_ctx), gf_leases_mt_lease_inode_ctx_t); GF_CHECK_ALLOC(inode_ctx, ret, out); pthread_mutex_init(&inode_ctx->lock, NULL); INIT_LIST_HEAD(&inode_ctx->lease_id_list); INIT_LIST_HEAD(&inode_ctx->blocked_list); inode_ctx->lease_cnt = 0; ret = __inode_ctx_set(inode, this, (uint64_t *)inode_ctx); if (ret) { GF_FREE(inode_ctx); gf_msg(this->name, GF_LOG_INFO, 0, LEASE_MSG_INVAL_INODE_CTX, "failed to set inode ctx (%p)", inode); } out: return ret; } static lease_inode_ctx_t * __lease_ctx_get(inode_t *inode, xlator_t *this) { lease_inode_ctx_t *inode_ctx = NULL; uint64_t ctx = 0; int ret = 0; ret = __inode_ctx_get(inode, this, &ctx); if (ret < 0) { ret = __lease_ctx_set(inode, this); if (ret < 0) goto out; ret = __inode_ctx_get(inode, this, &ctx); if (ret < 0) { gf_msg(this->name, GF_LOG_WARNING, 0, LEASE_MSG_INVAL_INODE_CTX, "failed to get inode ctx (%p)", inode); goto out; } } inode_ctx = (lease_inode_ctx_t *)(long)ctx; out: return inode_ctx; } lease_inode_ctx_t * lease_ctx_get(inode_t *inode, xlator_t *this) { lease_inode_ctx_t *inode_ctx = NULL; GF_VALIDATE_OR_GOTO("leases", inode, out); GF_VALIDATE_OR_GOTO("leases", this, out); LOCK(&inode->lock); { inode_ctx = __lease_ctx_get(inode, this); } UNLOCK(&inode->lock); out: return inode_ctx; } static lease_id_entry_t * new_lease_id_entry(call_frame_t *frame, const char *lease_id) { lease_id_entry_t *lease_entry = NULL; GF_VALIDATE_OR_GOTO("leases", frame, out); GF_VALIDATE_OR_GOTO("leases", lease_id, out); lease_entry = GF_CALLOC(1, sizeof(*lease_entry), gf_leases_mt_lease_id_entry_t); if (!lease_entry) { gf_msg(frame->this->name, GF_LOG_ERROR, ENOMEM, LEASE_MSG_NO_MEM, "Memory allocation for lease_entry failed"); return NULL; } INIT_LIST_HEAD(&lease_entry->lease_id_list); lease_entry->lease_type = NONE; lease_entry->lease_cnt = 0; lease_entry->recall_time = get_recall_lease_timeout(frame->this); lease_entry->client_uid = gf_strdup(frame->root->client->client_uid); if (!lease_entry->client_uid) { gf_msg(frame->this->name, GF_LOG_ERROR, ENOMEM, LEASE_MSG_NO_MEM, "Memory allocation for client_uid failed"); GF_FREE(lease_entry); lease_entry = NULL; goto out; } memcpy(lease_entry->lease_id, lease_id, LEASE_ID_SIZE); out: return lease_entry; } static void __destroy_lease_id_entry(lease_id_entry_t *lease_entry) { GF_VALIDATE_OR_GOTO("leases", lease_entry, out); list_del_init(&lease_entry->lease_id_list); GF_FREE(lease_entry->client_uid); GF_FREE(lease_entry); out: return; } static inline gf_boolean_t __is_same_lease_id(const char *k1, const char *k2) { if (memcmp(k1, k2, strlen(k1)) == 0) return _gf_true; return _gf_false; } /* Checks if there are any leases, other than the leases taken * by the given lease_id */ static gf_boolean_t __another_lease_found(lease_inode_ctx_t *lease_ctx, const char *lease_id) { lease_id_entry_t *lease_entry = NULL; lease_id_entry_t *tmp = NULL; gf_boolean_t found_lease = _gf_false; GF_VALIDATE_OR_GOTO("leases", lease_id, out); GF_VALIDATE_OR_GOTO("leases", lease_ctx, out); list_for_each_entry_safe(lease_entry, tmp, &lease_ctx->lease_id_list, lease_id_list) { if (!__is_same_lease_id(lease_id, lease_entry->lease_id)) { if (lease_entry->lease_cnt > 0) { found_lease = _gf_true; break; } } } out: return found_lease; } /* Returns the lease_id_entry for a given lease_id and a given inode. * Return values: * NULL - If no client entry found * lease_id_entry_t* - a pointer to the client entry if found */ static lease_id_entry_t * __get_lease_id_entry(lease_inode_ctx_t *lease_ctx, const char *lease_id) { lease_id_entry_t *lease_entry = NULL; lease_id_entry_t *tmp = NULL; lease_id_entry_t *found = NULL; GF_VALIDATE_OR_GOTO("leases", lease_id, out); GF_VALIDATE_OR_GOTO("leases", lease_ctx, out); list_for_each_entry_safe(lease_entry, tmp, &lease_ctx->lease_id_list, lease_id_list) { if (__is_same_lease_id(lease_id, lease_entry->lease_id)) { found = lease_entry; gf_msg_debug("leases", 0, "lease ID entry found " "Client UID:%s, lease id:%s", lease_entry->client_uid, leaseid_utoa(lease_entry->lease_id)); break; } } out: return found; } /* Returns the lease_id_entry for a given lease_id and a given inode, * if none found creates one. * Return values: * lease_id_entry_t* - a pointer to the client entry */ static lease_id_entry_t * __get_or_new_lease_entry(call_frame_t *frame, const char *lease_id, lease_inode_ctx_t *lease_ctx) { lease_id_entry_t *lease_entry = NULL; GF_VALIDATE_OR_GOTO("leases", frame, out); GF_VALIDATE_OR_GOTO("leases", lease_id, out); GF_VALIDATE_OR_GOTO("leases", lease_ctx, out); lease_entry = __get_lease_id_entry(lease_ctx, lease_id); if (!lease_entry) { /* create one */ lease_entry = new_lease_id_entry(frame, lease_id); if (!lease_entry) goto out; list_add_tail(&lease_entry->lease_id_list, &lease_ctx->lease_id_list); gf_msg_debug(frame->this->name, 0, "lease ID entry added," " Client UID:%s, lease id:%s", lease_entry->client_uid, leaseid_utoa(lease_entry->lease_id)); } out: return lease_entry; } static lease_inode_t * new_lease_inode(inode_t *inode) { lease_inode_t *l_inode = GF_MALLOC(sizeof(*l_inode), gf_leases_mt_lease_inode_t); if (!l_inode) goto out; INIT_LIST_HEAD(&l_inode->list); l_inode->inode = inode_ref(inode); out: return l_inode; } static void __destroy_lease_inode(lease_inode_t *l_inode) { list_del_init(&l_inode->list); inode_unref(l_inode->inode); GF_FREE(l_inode); } static lease_client_t * new_lease_client(const char *client_uid) { lease_client_t *clnt = GF_MALLOC(sizeof(*clnt), gf_leases_mt_lease_client_t); if (!clnt) goto out; INIT_LIST_HEAD(&clnt->client_list); INIT_LIST_HEAD(&clnt->inode_list); clnt->client_uid = gf_strdup(client_uid); out: return clnt; } static void __destroy_lease_client(lease_client_t *clnt) { list_del_init(&clnt->inode_list); list_del_init(&clnt->client_list); GF_FREE(clnt); return; } static lease_client_t * __get_lease_client(xlator_t *this, leases_private_t *priv, const char *client_uid) { lease_client_t *clnt = NULL; lease_client_t *tmp = NULL; lease_client_t *found = NULL; list_for_each_entry_safe(clnt, tmp, &priv->client_list, client_list) { if ((strcmp(clnt->client_uid, client_uid) == 0)) { found = clnt; gf_msg_debug(this->name, 0, "Client:%s already found " "in the cleanup list", client_uid); break; } } return found; } static lease_client_t * __get_or_new_lease_client(xlator_t *this, leases_private_t *priv, const char *client_uid) { lease_client_t *found = NULL; found = __get_lease_client(this, priv, client_uid); if (!found) { found = new_lease_client(client_uid); if (!found) goto out; list_add_tail(&found->client_list, &priv->client_list); gf_msg_debug(this->name, 0, "Adding a new client:%s entry " "to the cleanup list", client_uid); } out: return found; } static int add_inode_to_client_list(xlator_t *this, inode_t *inode, const char *client_uid) { leases_private_t *priv = this->private; lease_client_t *clnt = NULL; lease_inode_t *lease_inode = new_lease_inode(inode); if (!lease_inode) return -ENOMEM; pthread_mutex_lock(&priv->mutex); { clnt = __get_or_new_lease_client(this, priv, client_uid); if (!clnt) { pthread_mutex_unlock(&priv->mutex); __destroy_lease_inode(lease_inode); return -ENOMEM; } list_add_tail(&clnt->inode_list, &lease_inode->list); } pthread_mutex_unlock(&priv->mutex); gf_msg_debug(this->name, 0, "Added a new inode:%p to the client(%s) " "cleanup list, gfid(%s)", inode, client_uid, uuid_utoa(inode->gfid)); return 0; } /* Add lease entry to the corresponding client entry. * Return values: * 0 Success * -1 Failure */ static int __add_lease(call_frame_t *frame, inode_t *inode, lease_inode_ctx_t *lease_ctx, const char *client_uid, struct gf_lease *lease) { lease_id_entry_t *lease_entry = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("leases", frame, out); GF_VALIDATE_OR_GOTO("leases", client_uid, out); GF_VALIDATE_OR_GOTO("leases", lease_ctx, out); GF_VALIDATE_OR_GOTO("leases", inode, out); GF_VALIDATE_OR_GOTO("leases", lease, out); gf_msg_trace(frame->this->name, 0, "Granting lease lock to client %s with lease id %s" " on gfid(%s)", client_uid, leaseid_utoa(lease->lease_id), uuid_utoa(inode->gfid)); lease_entry = __get_or_new_lease_entry(frame, lease->lease_id, lease_ctx); if (!lease_entry) { errno = ENOMEM; goto out; } lease_entry->lease_type_cnt[lease->lease_type]++; lease_entry->lease_cnt++; lease_entry->lease_type |= lease->lease_type; /* If this is the first lease taken by the client on the file, then * add this inode/file to the client disconnect cleanup list */ if (lease_entry->lease_cnt == 1) { add_inode_to_client_list(frame->this, inode, client_uid); } lease_ctx->lease_cnt++; lease_ctx->lease_type_cnt[lease->lease_type]++; lease_ctx->lease_type |= lease->lease_type; /* Take a ref for the first lock taken on this inode. Corresponding * unref when all the leases are unlocked or during DISCONNECT * Ref is required because the inode on which lease is acquired should * not be deleted when lru cleanup kicks in*/ if (lease_ctx->lease_cnt == 1) { lease_ctx->inode = inode_ref(inode); } ret = 0; out: return ret; } static gf_boolean_t __is_clnt_lease_none(const char *client_uid, lease_inode_ctx_t *lease_ctx) { gf_boolean_t lease_none = _gf_true; lease_id_entry_t *lease_entry = NULL; lease_id_entry_t *tmp = NULL; list_for_each_entry_safe(lease_entry, tmp, &lease_ctx->lease_id_list, lease_id_list) { if ((strcmp(client_uid, lease_entry->client_uid) == 0) && (lease_entry->lease_cnt != 0)) { lease_none = _gf_false; break; } } return lease_none; } static int __remove_inode_from_clnt_list(xlator_t *this, lease_client_t *clnt, inode_t *inode) { int ret = -1; lease_inode_t *l_inode = NULL; lease_inode_t *tmp1 = NULL; list_for_each_entry_safe(l_inode, tmp1, &clnt->inode_list, list) { if (l_inode->inode == inode) { __destroy_lease_inode(l_inode); gf_msg_debug(this->name, 0, "Removed the inode from the client cleanup list"); ret = 0; } } /* TODO: Remove the client entry from the cleanup list */ return ret; } static int remove_from_clnt_list(xlator_t *this, const char *client_uid, inode_t *inode) { leases_private_t *priv = NULL; int ret = -1; lease_client_t *clnt = NULL; priv = this->private; if (!priv) goto out; pthread_mutex_lock(&priv->mutex); { clnt = __get_lease_client(this, priv, client_uid); if (!clnt) { pthread_mutex_unlock(&priv->mutex); gf_msg(this->name, GF_LOG_ERROR, 0, LEASE_MSG_CLNT_NOTFOUND, "There is no client entry found in the cleanup list"); goto out; } ret = __remove_inode_from_clnt_list(this, clnt, inode); if (ret) { pthread_mutex_unlock(&priv->mutex); gf_msg(this->name, GF_LOG_ERROR, 0, LEASE_MSG_INODE_NOTFOUND, "There is no inode entry found in the cleanup list"); goto out; } } pthread_mutex_unlock(&priv->mutex); out: return ret; } /* Remove lease entry in the corresponding client entry. */ static int __remove_lease(xlator_t *this, inode_t *inode, lease_inode_ctx_t *lease_ctx, const char *client_uid, struct gf_lease *lease) { lease_id_entry_t *lease_entry = NULL; int ret = 0; int32_t lease_type = 0; leases_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("leases", lease_ctx, out); GF_VALIDATE_OR_GOTO("leases", lease, out); priv = this->private; gf_msg_trace(this->name, 0, "Removing lease entry for client: %s, " "lease type:%d, lease id:%s", client_uid, lease->lease_type, leaseid_utoa(lease->lease_id)); /* There could be a race where in server recalled the lease and by the time * client sends lease_unlock request, server may have revoked it. To handle * such cases, if lease doesnt exist treat it as noop and return success. */ lease_entry = __get_lease_id_entry(lease_ctx, lease->lease_id); if (!lease_entry) { gf_msg(this->name, GF_LOG_INFO, 0, LEASE_MSG_INVAL_UNLK_LEASE, "Got unlock lease request from client:%s, but has no " "corresponding lock", client_uid); ret = 0; goto out; } if (!(lease_entry->lease_type & lease->lease_type)) { gf_msg(this->name, GF_LOG_INFO, 0, LEASE_MSG_INVAL_UNLK_LEASE, "Got unlock lease request from client:%s for an invalid " "lease_type", client_uid); ret = -EINVAL; errno = EINVAL; goto out; } lease_type = lease->lease_type; lease_entry->lease_type_cnt[lease_type]--; lease_entry->lease_cnt--; lease_ctx->lease_type_cnt[lease_type]--; lease_ctx->lease_cnt--; if (lease_entry->lease_type_cnt[lease_type] == 0) lease_entry->lease_type = lease_entry->lease_type & (~lease_type); if (lease_ctx->lease_type_cnt[lease_type] == 0) lease_ctx->lease_type = lease_ctx->lease_type & (~lease_type); if (lease_entry->lease_cnt == 0) { if (__is_clnt_lease_none(client_uid, lease_ctx)) { gf_msg_trace(this->name, 0, "Client(%s) has no leases" " on gfid (%s), hence removing the inode" " from the client cleanup list", client_uid, uuid_utoa(inode->gfid)); remove_from_clnt_list(this, client_uid, lease_ctx->inode); } __destroy_lease_id_entry(lease_entry); lease_ctx->blocked_fops_resuming = _gf_true; } if (lease_ctx->lease_cnt == 0 && lease_ctx->timer) { ret = gf_tw_del_timer(priv->timer_wheel, lease_ctx->timer); lease_ctx->recall_in_progress = _gf_false; lease_ctx->timer = NULL; } out: return ret; } static gf_boolean_t __is_lease_grantable(xlator_t *this, lease_inode_ctx_t *lease_ctx, struct gf_lease *lease, inode_t *inode) { uint32_t fd_count = 0; int32_t flags = 0; fd_t *iter_fd = NULL; gf_boolean_t grant = _gf_false; lease_fd_ctx_t *fd_ctx = NULL; GF_VALIDATE_OR_GOTO("leases", lease_ctx, out); GF_VALIDATE_OR_GOTO("leases", lease, out); GF_VALIDATE_OR_GOTO("leases", inode, out); if (lease_ctx->recall_in_progress) { gf_msg_debug(this->name, 0, "Recall in progress, hence " "failing the lease request"); grant = _gf_false; goto out; } if (lease_ctx->blocked_fops_resuming) { gf_msg_debug(this->name, 0, "Previously blocked fops resuming, hence " "failing the lease request"); grant = _gf_false; goto out; } LOCK(&inode->lock); { list_for_each_entry(iter_fd, &inode->fd_list, inode_list) { fd_ctx = fd_ctx_get_ptr(iter_fd, this); if (!fd_ctx) { grant = _gf_false; UNLOCK(&inode->lock); gf_msg(this->name, GF_LOG_ERROR, 0, LEASE_MSG_INVAL_FD_CTX, "Unable to get fd ctx"); goto out; } /* Check for open fd conflict, note that open fds from * the same lease id is not checked for conflict, as it is * lease id based lease. */ if (fd_ctx->client_uid != NULL && !__is_same_lease_id(fd_ctx->lease_id, lease->lease_id)) { fd_count++; flags |= iter_fd->flags; } } } UNLOCK(&inode->lock); gf_msg_debug(this->name, 0, "open fd count:%d flags:%d", fd_count, flags); __dump_leases_info(this, lease_ctx); switch (lease->lease_type) { case GF_RD_LEASE: /* check open fd conflict */ if ((fd_count > 0) && ((flags & O_WRONLY) || (flags & O_RDWR))) { grant = _gf_false; break; } /* check for conflict with existing leases */ if (lease_ctx->lease_type == NONE || lease_ctx->lease_type == GF_RD_LEASE || !(__another_lease_found(lease_ctx, lease->lease_id))) grant = _gf_true; else grant = _gf_false; break; case GF_RW_LEASE: /* check open fd conflict; conflict if there are any fds open * other than the client on which the lease is requested. */ if (fd_count > 0) { grant = _gf_false; break; } /* check existing lease conflict */ if (lease_ctx->lease_type == NONE || !(__another_lease_found(lease_ctx, lease->lease_id))) grant = _gf_true; else grant = _gf_false; break; default: gf_msg(this->name, GF_LOG_ERROR, EINVAL, LEASE_MSG_INVAL_LEASE_TYPE, "Invalid lease type specified"); break; } out: return grant; } static void do_blocked_fops(xlator_t *this, lease_inode_ctx_t *lease_ctx) { struct list_head wind_list; fop_stub_t *blk_fop = NULL; fop_stub_t *tmp = NULL; INIT_LIST_HEAD(&wind_list); pthread_mutex_lock(&lease_ctx->lock); { if (!lease_ctx->blocked_fops_resuming) { /* lease_ctx->blocked_fops_resuming will be set * only when the last lease is released. That * is when we need to resume blocked fops and unref * the inode taken in __add_lease (when lease_cnt == 1). * Return otherwise. */ pthread_mutex_unlock(&lease_ctx->lock); return; } list_for_each_entry_safe(blk_fop, tmp, &lease_ctx->blocked_list, list) { list_del_init(&blk_fop->list); list_add_tail(&blk_fop->list, &wind_list); } } pthread_mutex_unlock(&lease_ctx->lock); gf_msg_trace(this->name, 0, "Executing the blocked stubs on gfid(%s)", uuid_utoa(lease_ctx->inode->gfid)); list_for_each_entry_safe(blk_fop, tmp, &wind_list, list) { list_del_init(&blk_fop->list); gf_msg_trace(this->name, 0, "Executing fop:%d", blk_fop->stub->fop); call_resume(blk_fop->stub); GF_FREE(blk_fop); } pthread_mutex_lock(&lease_ctx->lock); { lease_ctx->lease_type = NONE; /* unref the inode taken in __add_lease * (when lease_cnt == 1) */ lease_ctx->blocked_fops_resuming = _gf_false; inode_unref(lease_ctx->inode); lease_ctx->inode = NULL; } pthread_mutex_unlock(&lease_ctx->lock); return; } void recall_lease_timer_handler(struct gf_tw_timer_list *timer, void *data, unsigned long calltime) { inode_t *inode = NULL; lease_inode_t *lease_inode = NULL; leases_private_t *priv = NULL; lease_timer_data_t *timer_data = NULL; timer_data = data; priv = timer_data->this->private; inode = timer_data->inode; lease_inode = new_lease_inode(inode); if (!lease_inode) { errno = ENOMEM; goto out; } pthread_mutex_lock(&priv->mutex); { list_add_tail(&lease_inode->list, &priv->recall_list); pthread_cond_broadcast(&priv->cond); } pthread_mutex_unlock(&priv->mutex); out: /* unref the inode_ref taken by timer_data in __recall_lease */ inode_unref(timer_data->inode); GF_FREE(timer); } static void __recall_lease(xlator_t *this, lease_inode_ctx_t *lease_ctx) { lease_id_entry_t *lease_entry = NULL; lease_id_entry_t *tmp = NULL; struct gf_upcall up_req = { 0, }; struct gf_upcall_recall_lease recall_req = { 0, }; int notify_ret = -1; struct gf_tw_timer_list *timer = NULL; leases_private_t *priv = NULL; lease_timer_data_t *timer_data = NULL; time_t recall_time; if (lease_ctx->recall_in_progress) { gf_msg_debug(this->name, 0, "Lease recall is already in " "progress, hence not sending another recall"); goto out; } priv = this->private; recall_time = gf_time(); list_for_each_entry_safe(lease_entry, tmp, &lease_ctx->lease_id_list, lease_id_list) { gf_uuid_copy(up_req.gfid, lease_ctx->inode->gfid); up_req.client_uid = lease_entry->client_uid; up_req.event_type = GF_UPCALL_RECALL_LEASE; up_req.data = &recall_req; notify_ret = this->notify(this, GF_EVENT_UPCALL, &up_req); if (notify_ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, LEASE_MSG_RECALL_FAIL, "Recall notification to client: %s failed", lease_entry->client_uid); /* Do not return from here, continue registering the timer, this is required mostly o keep replicas in sync*/ } else { gf_msg_debug(this->name, 0, "Recall lease (all)" "notification sent to client %s", lease_entry->client_uid); } lease_ctx->recall_in_progress = _gf_true; lease_entry->recall_time = recall_time; } timer = GF_MALLOC(sizeof(*timer), gf_common_mt_tw_timer_list); if (!timer) { goto out; } timer_data = GF_MALLOC(sizeof(lease_timer_data_t), gf_leases_mt_timer_data_t); if (!timer_data) { GF_FREE(timer); goto out; } timer_data->inode = inode_ref(lease_ctx->inode); timer_data->this = this; timer->data = timer_data; INIT_LIST_HEAD(&timer->entry); timer->expires = get_recall_lease_timeout(this); timer->function = recall_lease_timer_handler; lease_ctx->timer = timer; gf_tw_add_timer(priv->timer_wheel, timer); gf_msg_trace(this->name, 0, "Registering timer " "%p, after " "sending recall", timer); out: return; } /* ret = 0; STACK_UNWIND Success * ret = -1; STACK_UNWIND failure */ int process_lease_req(call_frame_t *frame, xlator_t *this, inode_t *inode, struct gf_lease *lease) { int ret = 0; char *client_uid = NULL; lease_inode_ctx_t *lease_ctx = NULL; GF_VALIDATE_OR_GOTO("leases", frame, out); GF_VALIDATE_OR_GOTO("leases", this, out); GF_VALIDATE_OR_GOTO("leases", inode, out); GF_VALIDATE_OR_GOTO("leases", lease, out); client_uid = frame->root->client->client_uid; if (!is_valid_lease_id(lease->lease_id)) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, LEASE_MSG_INVAL_LEASE_ID, "Invalid lease id, from" "client:%s", client_uid); ret = -EINVAL; errno = EINVAL; goto out; } lease_ctx = lease_ctx_get(inode, this); if (!lease_ctx) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM, "Unable to create/get inode ctx, " "inode:%p", inode); ret = -ENOMEM; errno = ENOMEM; goto out; } gf_msg_debug(this->name, 0, "Lease request from client: %s, " "lease type:%d, lease cmd:%d, lease ID:%s, gfid:%s", client_uid, lease->lease_type, lease->cmd, leaseid_utoa(lease->lease_id), uuid_utoa(inode->gfid)); pthread_mutex_lock(&lease_ctx->lock); { switch (lease->cmd) { case GF_GET_LEASE: lease->lease_type = lease_ctx->lease_type; gf_msg_debug(this->name, 0, "Get lease, existing lease" "type: %d", lease_ctx->lease_type); /*TODO:Should it consider lease id or client_uid?*/ break; case GF_SET_LEASE: if (__is_lease_grantable(this, lease_ctx, lease, inode)) { __add_lease(frame, inode, lease_ctx, client_uid, lease); ret = 0; } else { gf_msg_debug(this->name, GF_LOG_DEBUG, "Not granting the conflicting lease" " request from %s on gfid(%s)", client_uid, uuid_utoa(inode->gfid)); __recall_lease(this, lease_ctx); ret = -1; } break; case GF_UNLK_LEASE: ret = __remove_lease(this, inode, lease_ctx, client_uid, lease); if ((ret >= 0) && (lease_ctx->lease_cnt == 0)) { pthread_mutex_unlock(&lease_ctx->lock); goto unblock; } break; default: ret = -EINVAL; break; } } pthread_mutex_unlock(&lease_ctx->lock); return ret; unblock: do_blocked_fops(this, lease_ctx); out: return ret; } /* ret = 1 conflict * ret = 0 no conflict */ gf_boolean_t __check_lease_conflict(call_frame_t *frame, lease_inode_ctx_t *lease_ctx, const char *lease_id, gf_boolean_t is_write) { gf_lease_types_t lease_type = { 0, }; gf_boolean_t conflicts = _gf_false; lease_id_entry_t *lease_entry = NULL; GF_VALIDATE_OR_GOTO("leases", frame, out); GF_VALIDATE_OR_GOTO("leases", lease_ctx, out); lease_type = lease_ctx->lease_type; /* If the fop is rename or unlink conflict the lease even if its * from the same client?? */ if ((frame->root->op == GF_FOP_RENAME) || (frame->root->op == GF_FOP_UNLINK)) { conflicts = _gf_true; goto recall; } /* As internal fops are used to maintain data integrity but do not * make modififications to the client data, no need to conflict with * them. * * @todo: like for locks, even lease state has to be handled by * rebalance or self-heal daemon process. */ if (frame->root->pid < 0) { conflicts = _gf_false; goto recall; } /* If lease_id is not sent, set conflicts = true if there is * an existing lease */ if (!lease_id && (lease_ctx->lease_cnt > 0)) { conflicts = _gf_true; goto recall; } switch (lease_type) { case (GF_RW_LEASE | GF_RD_LEASE): case GF_RW_LEASE: lease_entry = __get_lease_id_entry(lease_ctx, lease_id); if (lease_entry && (lease_entry->lease_type & GF_RW_LEASE)) conflicts = _gf_false; else conflicts = _gf_true; break; case GF_RD_LEASE: if (is_write && __another_lease_found(lease_ctx, lease_id)) conflicts = _gf_true; else conflicts = _gf_false; break; default: break; } recall: /* If there is a conflict found and recall is not already sent to all * the clients, then send recall to each of the client holding lease. */ if (conflicts) __recall_lease(frame->this, lease_ctx); out: return conflicts; } /* Return values: * -1 : error, unwind the fop * WIND_FOP: No conflict, wind the fop * BLOCK_FOP: Found a conflicting lease, block the fop */ int check_lease_conflict(call_frame_t *frame, inode_t *inode, const char *lease_id, uint32_t fop_flags) { lease_inode_ctx_t *lease_ctx = NULL; gf_boolean_t is_blocking_fop = _gf_false; gf_boolean_t is_write_fop = _gf_false; gf_boolean_t conflicts = _gf_false; int ret = WIND_FOP; lease_ctx = lease_ctx_get(inode, frame->this); if (!lease_ctx) { gf_msg(frame->this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM, "Unable to create/get inode ctx"); ret = -1; errno = ENOMEM; goto out; } is_blocking_fop = ((fop_flags & BLOCKING_FOP) != 0); is_write_fop = ((fop_flags & DATA_MODIFY_FOP) != 0); pthread_mutex_lock(&lease_ctx->lock); { if (lease_ctx->lease_type == NONE) { pthread_mutex_unlock(&lease_ctx->lock); gf_msg_debug(frame->this->name, 0, "No leases found continuing with the" " fop:%s", gf_fop_list[frame->root->op]); ret = WIND_FOP; goto out; } conflicts = __check_lease_conflict(frame, lease_ctx, lease_id, is_write_fop); if (conflicts) { if (is_blocking_fop) { gf_msg_debug(frame->this->name, 0, "Fop: %s " "conflicting existing " "lease: %d, blocking the" "fop", gf_fop_list[frame->root->op], lease_ctx->lease_type); ret = BLOCK_FOP; } else { gf_msg_debug(frame->this->name, 0, "Fop: %s " "conflicting existing " "lease: %d, sending " "EAGAIN", gf_fop_list[frame->root->op], lease_ctx->lease_type); errno = EAGAIN; ret = -1; } } } pthread_mutex_unlock(&lease_ctx->lock); out: return ret; } static int remove_clnt_leases(const char *client_uid, inode_t *inode, xlator_t *this) { lease_inode_ctx_t *lease_ctx = NULL; lease_id_entry_t *lease_entry = NULL; lease_id_entry_t *tmp = NULL; int ret = 0; int i = 0; lease_ctx = lease_ctx_get(inode, this); if (!lease_ctx) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_INVAL_INODE_CTX, "Unable to create/get inode ctx"); ret = -1; errno = ENOMEM; goto out; } pthread_mutex_lock(&lease_ctx->lock); { list_for_each_entry_safe(lease_entry, tmp, &lease_ctx->lease_id_list, lease_id_list) { if (strcmp(client_uid, lease_entry->client_uid) == 0) { for (i = 0; i < GF_LEASE_MAX_TYPE; i++) { lease_ctx->lease_type_cnt[i] -= lease_entry ->lease_type_cnt[i]; } lease_ctx->lease_cnt -= lease_entry->lease_cnt; __destroy_lease_id_entry(lease_entry); if (lease_ctx->lease_cnt == 0) { lease_ctx->blocked_fops_resuming = _gf_true; pthread_mutex_unlock(&lease_ctx->lock); goto unblock; } } } } pthread_mutex_unlock(&lease_ctx->lock); out: return ret; unblock: do_blocked_fops(this, lease_ctx); return ret; } int cleanup_client_leases(xlator_t *this, const char *client_uid) { lease_client_t *clnt = NULL; lease_client_t *tmp = NULL; struct list_head cleanup_list = { 0, }; lease_inode_t *l_inode = NULL; lease_inode_t *tmp1 = NULL; leases_private_t *priv = NULL; int ret = 0; priv = this->private; if (!priv) { ret = -1; errno = EINVAL; goto out; } INIT_LIST_HEAD(&cleanup_list); pthread_mutex_lock(&priv->mutex); { list_for_each_entry_safe(clnt, tmp, &priv->client_list, client_list) { if ((strcmp(clnt->client_uid, client_uid) == 0)) { list_for_each_entry_safe(l_inode, tmp1, &clnt->inode_list, list) { list_del_init(&l_inode->list); list_add_tail(&l_inode->list, &cleanup_list); } __destroy_lease_client(clnt); break; } } } pthread_mutex_unlock(&priv->mutex); l_inode = tmp1 = NULL; list_for_each_entry_safe(l_inode, tmp1, &cleanup_list, list) { remove_clnt_leases(client_uid, l_inode->inode, this); __destroy_lease_inode(l_inode); } out: return ret; } static void __remove_all_leases(xlator_t *this, lease_inode_ctx_t *lease_ctx) { int i = 0; lease_id_entry_t *lease_entry = NULL; lease_id_entry_t *tmp = NULL; if (lease_ctx->lease_cnt == 0) { /* No leases to remove. Return */ return; } __dump_leases_info(this, lease_ctx); list_for_each_entry_safe(lease_entry, tmp, &lease_ctx->lease_id_list, lease_id_list) { lease_entry->lease_cnt = 0; remove_from_clnt_list(this, lease_entry->client_uid, lease_ctx->inode); __destroy_lease_id_entry(lease_entry); } INIT_LIST_HEAD(&lease_ctx->lease_id_list); for (i = 0; i <= GF_LEASE_MAX_TYPE; i++) lease_ctx->lease_type_cnt[i] = 0; lease_ctx->lease_type = 0; lease_ctx->lease_cnt = 0; lease_ctx->recall_in_progress = _gf_false; lease_ctx->timer = NULL; lease_ctx->blocked_fops_resuming = _gf_true; /* TODO: * - Mark the corresponding fd bad. Could be done on client side * as a result of recall * - Free the lease_ctx */ return; } static int remove_all_leases(xlator_t *this, inode_t *inode) { lease_inode_ctx_t *lease_ctx = NULL; int ret = 0; GF_VALIDATE_OR_GOTO("leases", inode, out); lease_ctx = lease_ctx_get(inode, this); if (!lease_ctx) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_INVAL_INODE_CTX, "Unable to create/get inode ctx"); ret = -1; errno = ENOMEM; goto out; } pthread_mutex_lock(&lease_ctx->lock); { __remove_all_leases(this, lease_ctx); } pthread_mutex_unlock(&lease_ctx->lock); do_blocked_fops(this, lease_ctx); out: return ret; } void * expired_recall_cleanup(void *data) { struct timespec sleep_till = { 0, }; struct list_head recall_cleanup_list; lease_inode_t *recall_entry = NULL; lease_inode_t *tmp = NULL; leases_private_t *priv = NULL; xlator_t *this = NULL; time_t time_now; GF_VALIDATE_OR_GOTO("leases", data, out); this = data; priv = this->private; gf_msg_debug(this->name, 0, "Started the expired_recall_cleanup thread"); while (1) { time_now = gf_time(); pthread_mutex_lock(&priv->mutex); { if (priv->fini) { pthread_mutex_unlock(&priv->mutex); goto out; } INIT_LIST_HEAD(&recall_cleanup_list); if (list_empty(&priv->recall_list)) { sleep_till.tv_sec = time_now + 600; pthread_cond_timedwait(&priv->cond, &priv->mutex, &sleep_till); } if (!list_empty(&priv->recall_list)) { gf_msg_debug(this->name, 0, "Found expired recalls"); list_for_each_entry_safe(recall_entry, tmp, &priv->recall_list, list) { list_del_init(&recall_entry->list); list_add_tail(&recall_entry->list, &recall_cleanup_list); } } } pthread_mutex_unlock(&priv->mutex); recall_entry = tmp = NULL; list_for_each_entry_safe(recall_entry, tmp, &recall_cleanup_list, list) { gf_msg_debug(this->name, 0, "Recall lease was sent on" " inode:%p, recall timer has expired" " and clients haven't unlocked the lease" " hence cleaning up leases on the inode", recall_entry->inode); remove_all_leases(this, recall_entry->inode); /* no need to take priv->mutex lock as this entry * reference is removed from global recall list. */ __destroy_lease_inode(recall_entry); } } out: return NULL; } glusterfs-11.1/xlators/features/leases/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464024006 xustar000000000000000030 mtime=1699284276.288059423 30 atime=1699284291.130104127 30 ctime=1699284305.119146261 glusterfs-11.1/xlators/features/leases/src/Makefile.in0000664000175100017510000005762414522202464024303 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/leases/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) leases_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_leases_la_OBJECTS = leases.lo leases-internal.lo leases_la_OBJECTS = $(am_leases_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = leases_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(leases_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_leases_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(leases_la_SOURCES) DIST_SOURCES = $(leases_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = leases.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features leases_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) leases_la_SOURCES = leases.c leases-internal.c leases_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = leases.h leases-mem-types.h leases-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(CONTRIBDIR)/timer-wheel AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/leases/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/leases/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } leases.la: $(leases_la_OBJECTS) $(leases_la_DEPENDENCIES) $(EXTRA_leases_la_DEPENDENCIES) $(AM_V_CCLD)$(leases_la_LINK) $(am_leases_la_rpath) $(leases_la_OBJECTS) $(leases_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/leases-internal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/leases.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/leases/src/PaxHeaders.9031/leases.c0000644000000000000000000000013214522202451023355 xustar000000000000000030 mtime=1699284265.671027444 30 atime=1699284265.671027444 30 ctime=1699284305.126146281 glusterfs-11.1/xlators/features/leases/src/leases.c0000664000175100017510000007420714522202451023646 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015-2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include "leases.h" int32_t leases_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, xdata); return 0; } int32_t leases_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { uint32_t fop_flags = 0; int32_t op_errno = EINVAL; int ret = 0; lease_fd_ctx_t *fd_ctx = NULL; char *lease_id = NULL; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); fd_ctx = GF_CALLOC(1, sizeof(*fd_ctx), gf_leases_mt_fd_ctx_t); if (!fd_ctx) { op_errno = ENOMEM; goto err; } fd_ctx->client_uid = gf_strdup(frame->root->client->client_uid); if (!fd_ctx->client_uid) { op_errno = ENOMEM; goto err; } GET_FLAGS(frame->root->op, flags); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); if (lease_id != NULL) memcpy(fd_ctx->lease_id, lease_id, LEASE_ID_SIZE); else memset(fd_ctx->lease_id, 0, LEASE_ID_SIZE); ret = fd_ctx_set(fd, this, (uint64_t)(uintptr_t)fd_ctx); if (ret) { op_errno = ENOMEM; goto err; } ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, open, frame, this, loc, flags, fd, xdata); return 0; out: STACK_WIND(frame, leases_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; err: if (fd_ctx) { GF_FREE(fd_ctx->client_uid); GF_FREE(fd_ctx); } STACK_UNWIND_STRICT(open, frame, -1, op_errno, NULL, NULL); return 0; } int32_t leases_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t leases_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, fd->flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, writev, frame, this, fd, vector, count, off, flags, iobref, xdata); return 0; out: STACK_WIND(frame, leases_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, iobref, xdata); return 0; err: STACK_UNWIND_STRICT(writev, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t leases_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iovec *vector, int count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, stbuf, iobref, xdata); return 0; } int32_t leases_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, fd->flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, readv, frame, this, fd, size, offset, flags, xdata); return 0; out: STACK_WIND(frame, leases_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; err: STACK_UNWIND_STRICT(readv, frame, -1, errno, NULL, 0, NULL, NULL, NULL); return 0; } int32_t leases_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { STACK_UNWIND_STRICT(lk, frame, op_ret, op_errno, lock, xdata); return 0; } int32_t leases_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS_LK(cmd, flock->l_type, fd->flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, lk, frame, this, fd, cmd, flock, xdata); return 0; out: STACK_WIND(frame, leases_lk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lk, fd, cmd, flock, xdata); return 0; err: STACK_UNWIND_STRICT(lk, frame, -1, errno, NULL, NULL); return 0; } int32_t leases_lease(call_frame_t *frame, xlator_t *this, loc_t *loc, struct gf_lease *lease, dict_t *xdata) { int32_t op_errno = 0; int ret = 0; struct gf_lease nullease = { 0, }; int32_t op_ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); ret = process_lease_req(frame, this, loc->inode, lease); if (ret < 0) { op_errno = -ret; op_ret = -1; } goto unwind; out: gf_msg(this->name, GF_LOG_ERROR, EINVAL, LEASE_MSG_NOT_ENABLED, "\"features/leases\" translator is not enabled. " "You need to enable it for proper functioning of your " "application"); op_errno = ENOSYS; op_ret = -1; unwind: STACK_UNWIND_STRICT(lease, frame, op_ret, op_errno, (op_errno == ENOSYS) ? &nullease : lease, xdata); return 0; } int32_t leases_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t leases_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, 0); ret = check_lease_conflict(frame, loc->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(loc->inode, truncate, frame, this, loc, offset, xdata); return 0; out: STACK_WIND(frame, leases_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; err: STACK_UNWIND_STRICT(truncate, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t leases_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { STACK_UNWIND_STRICT(setattr, frame, op_ret, op_errno, statpre, statpost, xdata); return 0; } int32_t leases_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, 0); ret = check_lease_conflict(frame, loc->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(loc->inode, setattr, frame, this, loc, stbuf, valid, xdata); return 0; out: STACK_WIND(frame, leases_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; err: STACK_UNWIND_STRICT(setattr, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t leases_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *stbuf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, stbuf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); return 0; } int32_t leases_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); /* should the lease be also checked for newloc */ GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, 0); ret = check_lease_conflict(frame, oldloc->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(oldloc->inode, rename, frame, this, oldloc, newloc, xdata); return 0; out: STACK_WIND(frame, leases_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; err: STACK_UNWIND_STRICT(rename, frame, -1, errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t leases_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int32_t leases_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, 0); ret = check_lease_conflict(frame, loc->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(loc->inode, unlink, frame, this, loc, xflag, xdata); return 0; out: STACK_WIND(frame, leases_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; err: STACK_UNWIND_STRICT(unlink, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t leases_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { STACK_UNWIND_STRICT(link, frame, op_ret, op_errno, inode, stbuf, preparent, postparent, xdata); return 0; } int32_t leases_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, 0); ret = check_lease_conflict(frame, oldloc->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(oldloc->inode, link, frame, this, oldloc, newloc, xdata); return 0; out: STACK_WIND(frame, leases_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; err: STACK_UNWIND_STRICT(link, frame, -1, errno, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t leases_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, stbuf, preparent, postparent, xdata); return 0; } int32_t leases_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, create, frame, this, loc, flags, mode, umask, fd, xdata); return 0; out: STACK_WIND(frame, leases_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; err: STACK_UNWIND_STRICT(create, frame, -1, errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t leases_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { STACK_UNWIND_STRICT(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t leases_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, fd->flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, fsync, frame, this, fd, flags, xdata); return 0; out: STACK_WIND(frame, leases_fsync_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); return 0; err: STACK_UNWIND_STRICT(fsync, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t leases_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t leases_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, 0); /* TODO:fd->flags?*/ ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, ftruncate, frame, this, fd, offset, xdata); return 0; out: STACK_WIND(frame, leases_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; err: STACK_UNWIND_STRICT(ftruncate, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t leases_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { STACK_UNWIND_STRICT(fsetattr, frame, op_ret, op_errno, statpre, statpost, xdata); return 0; } int32_t leases_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, fd->flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, fsetattr, frame, this, fd, stbuf, valid, xdata); return 0; out: STACK_WIND(frame, leases_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; err: STACK_UNWIND_STRICT(fsetattr, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t leases_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, pre, post, xdata); return 0; } int32_t leases_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, fd->flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, fallocate, frame, this, fd, mode, offset, len, xdata); return 0; out: STACK_WIND(frame, leases_fallocate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, xdata); return 0; err: STACK_UNWIND_STRICT(fallocate, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t leases_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, pre, post, xdata); return 0; } int32_t leases_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, fd->flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, discard, frame, this, fd, offset, len, xdata); return 0; out: STACK_WIND(frame, leases_discard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); return 0; err: STACK_UNWIND_STRICT(discard, frame, -1, errno, NULL, NULL, NULL); return 0; } int32_t leases_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata) { STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, pre, post, xdata); return 0; } int leases_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, fd->flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, zerofill, frame, this, fd, offset, len, xdata); return 0; out: STACK_WIND(frame, leases_zerofill_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata); return 0; err: STACK_UNWIND_STRICT(zerofill, frame, -1, errno, NULL, NULL, NULL); return 0; } int leases_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { STACK_UNWIND_STRICT(flush, frame, op_ret, op_errno, xdata); return 0; } int leases_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { uint32_t fop_flags = 0; char *lease_id = NULL; int ret = 0; lease_fd_ctx_t *fd_ctx = NULL; EXIT_IF_LEASES_OFF(this, out); EXIT_IF_INTERNAL_FOP(frame, xdata, out); GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid); GET_FLAGS(frame->root->op, fd->flags); ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags); if (ret < 0) goto err; else if (ret == BLOCK_FOP) goto block; else if (ret == WIND_FOP) goto out; block: LEASE_BLOCK_FOP(fd->inode, flush, frame, this, fd, xdata); return 0; out: /* * * currently release is not called after the close fop from the * application. Hence lease fd ctx is reset on here. * This is actually not the right way, since flush can be called * not only from the close op. * TODO : * - Either identify the flush is called from close call on fd from * from the application. * OR * - Find why release is not called post the last close call */ fd_ctx = fd_ctx_get_ptr(fd, this); if (fd_ctx) { if (fd_ctx->client_uid) { GF_FREE(fd_ctx->client_uid); fd_ctx->client_uid = NULL; } memset(fd_ctx->lease_id, 0, LEASE_ID_SIZE); } STACK_WIND(frame, leases_flush_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush, fd, xdata); return 0; err: STACK_UNWIND_STRICT(create, frame, -1, errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_leases_mt_end); if (ret != 0) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM, "mem account init failed"); return ret; } return ret; } static int leases_init_priv(xlator_t *this) { int ret = 0; leases_private_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (!priv->timer_wheel) { priv->timer_wheel = glusterfs_ctx_tw_get(this->ctx); if (!priv->timer_wheel) { ret = -1; goto out; } } if (!priv->inited_recall_thr) { ret = gf_thread_create(&priv->recall_thr, NULL, expired_recall_cleanup, this, "leasercl"); if (!ret) priv->inited_recall_thr = _gf_true; } out: return ret; } int reconfigure(xlator_t *this, dict_t *options) { leases_private_t *priv = NULL; int ret = -1; priv = this->private; GF_ASSERT(priv); /* TODO: In case of reconfigure, if its enabling the leases * its not an issue, but if its disabling the leases, there * is more to it, like recall all the existing leases, wait * for unlock of all the leases etc., hence not supporting the * reconfigure for now. GF_OPTION_RECONF ("leases", priv->leases_enabled, options, bool, out); if (priv->leases_enabled) { ret = leases_init_priv (this); if (ret) goto out; } */ GF_OPTION_RECONF("lease-lock-recall-timeout", priv->recall_lease_timeout, options, time, out); ret = 0; out: return ret; } int init(xlator_t *this) { int ret = -1; leases_private_t *priv = NULL; priv = GF_CALLOC(1, sizeof(*priv), gf_leases_mt_private_t); if (!priv) { gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM, "Leases init failed"); goto out; } GF_OPTION_INIT("leases", priv->leases_enabled, bool, out); GF_OPTION_INIT("lease-lock-recall-timeout", priv->recall_lease_timeout, time, out); pthread_mutex_init(&priv->mutex, NULL); INIT_LIST_HEAD(&priv->client_list); INIT_LIST_HEAD(&priv->recall_list); this->private = priv; if (priv->leases_enabled) { ret = leases_init_priv(this); if (ret) goto out; } ret = 0; out: if (ret) { GF_FREE(priv); this->private = NULL; } return ret; } void fini(xlator_t *this) { leases_private_t *priv = NULL; priv = this->private; if (!priv) { return; } this->private = NULL; priv->fini = _gf_true; pthread_cond_broadcast(&priv->cond); if (priv->recall_thr) { gf_thread_cleanup_xint(priv->recall_thr); priv->recall_thr = 0; priv->inited_recall_thr = _gf_false; } if (priv->timer_wheel) { glusterfs_ctx_tw_put(this->ctx); } GF_FREE(priv); return; } static int leases_forget(xlator_t *this, inode_t *inode) { /* TODO:leases_cleanup_inode_ctx (this, inode); */ return 0; } static int leases_release(xlator_t *this, fd_t *fd) { int ret = -1; lease_fd_ctx_t *fd_ctx = NULL; if (fd == NULL) { goto out; } gf_log(this->name, GF_LOG_TRACE, "Releasing all leases with fd %p", fd); fd_ctx = fd_ctx_del_ptr(fd, this); if (!fd_ctx) { gf_log(this->name, GF_LOG_DEBUG, "Could not get fdctx"); goto out; } GF_FREE(fd_ctx); ret = 0; out: return ret; } static int leases_clnt_disconnect_cbk(xlator_t *this, client_t *client) { int ret = 0; EXIT_IF_LEASES_OFF(this, out); ret = cleanup_client_leases(this, client->client_uid); out: return ret; } struct xlator_fops fops = { /* Metadata modifying fops */ .fsetattr = leases_fsetattr, .setattr = leases_setattr, /* File Data reading fops */ .open = leases_open, .readv = leases_readv, /* File Data modifying fops */ .truncate = leases_truncate, .ftruncate = leases_ftruncate, .writev = leases_writev, .zerofill = leases_zerofill, .fallocate = leases_fallocate, .discard = leases_discard, .lk = leases_lk, .fsync = leases_fsync, .flush = leases_flush, .lease = leases_lease, /* Directory Data modifying fops */ .create = leases_create, .rename = leases_rename, .unlink = leases_unlink, .link = leases_link, #ifdef NOT_SUPPORTED /* internal lk fops */ .inodelk = leases_inodelk, .finodelk = leases_finodelk, .entrylk = leases_entrylk, .fentrylk = leases_fentrylk, /* Internal special fops*/ .xattrop = leases_xattrop, .fxattrop = leases_fxattrop, #endif }; struct xlator_cbks cbks = { .forget = leases_forget, .release = leases_release, .client_disconnect = leases_clnt_disconnect_cbk, }; struct volume_options options[] = { {.key = {"leases"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", .op_version = {GD_OP_VERSION_3_8_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .description = "When \"on\", enables leases support"}, {.key = {"lease-lock-recall-timeout"}, .type = GF_OPTION_TYPE_INT, .default_value = RECALL_LEASE_LK_TIMEOUT, .op_version = {GD_OP_VERSION_3_8_0}, .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, .description = "After 'timeout' seconds since the recall_lease" " request has been sent to the client, the lease lock" " will be forcefully purged by the server."}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "leases", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/leases/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023771 xustar000000000000000030 mtime=1699284265.670027441 30 atime=1699284276.251059311 30 ctime=1699284305.120146264 glusterfs-11.1/xlators/features/leases/src/Makefile.am0000664000175100017510000000105714522202451024253 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = leases.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features leases_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) leases_la_SOURCES = leases.c leases-internal.c leases_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = leases.h leases-mem-types.h leases-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(CONTRIBDIR)/timer-wheel AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/leases/src/PaxHeaders.9031/leases-mem-types.h0000644000000000000000000000013214522202451025300 xustar000000000000000030 mtime=1699284265.670027441 30 atime=1699284265.670027441 30 ctime=1699284305.123146273 glusterfs-11.1/xlators/features/leases/src/leases-mem-types.h0000664000175100017510000000144214522202451025560 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015-2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __LEASES_MEM_TYPES_H__ #define __LEASES_MEM_TYPES_H__ #include enum gf_leases_mem_types_ { gf_leases_mt_private_t = gf_common_mt_end + 1, gf_leases_mt_lease_client_t, gf_leases_mt_lease_inode_t, gf_leases_mt_fd_ctx_t, gf_leases_mt_lease_inode_ctx_t, gf_leases_mt_lease_id_entry_t, gf_leases_mt_fop_stub_t, gf_leases_mt_timer_data_t, gf_leases_mt_end }; #endif glusterfs-11.1/xlators/features/leases/src/PaxHeaders.9031/leases-messages.h0000644000000000000000000000013214522202451025167 xustar000000000000000030 mtime=1699284265.671027444 30 atime=1699284265.670027441 30 ctime=1699284305.124146276 glusterfs-11.1/xlators/features/leases/src/leases-messages.h0000664000175100017510000000225014522202451025445 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015-2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _LEASES_MESSAGES_H_ #define _LEASES_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(LEASES, LEASE_MSG_NO_MEM, LEASE_MSG_RECALL_FAIL, LEASE_MSG_INVAL_LEASE_ID, LEASE_MSG_INVAL_UNLK_LEASE, LEASE_MSG_INVAL_INODE_CTX, LEASE_MSG_NOT_ENABLED, LEASE_MSG_NO_TIMER_WHEEL, LEASE_MSG_CLNT_NOTFOUND, LEASE_MSG_INODE_NOTFOUND, LEASE_MSG_INVAL_FD_CTX, LEASE_MSG_INVAL_LEASE_TYPE); #endif /* !_LEASES_MESSAGES_H_ */ glusterfs-11.1/xlators/features/leases/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023217 xustar000000000000000030 mtime=1699284276.240059278 30 atime=1699284291.108104061 30 ctime=1699284305.074146125 glusterfs-11.1/xlators/features/leases/Makefile.in0000664000175100017510000005272414522202464023510 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/leases DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/leases/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/leases/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/leases/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023202 xustar000000000000000030 mtime=1699284265.670027441 30 atime=1699284276.216059206 30 ctime=1699284305.075146128 glusterfs-11.1/xlators/features/leases/Makefile.am0000664000175100017510000000003414522202451023456 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/index0000644000000000000000000000013214522202517020727 xustar000000000000000030 mtime=1699284303.785142243 30 atime=1699284309.687160019 30 ctime=1699284303.785142243 glusterfs-11.1/xlators/features/index/0002775000175100017510000000000014522202517021265 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/index/PaxHeaders.9031/src0000644000000000000000000000013214522202517021516 xustar000000000000000030 mtime=1699284303.838142402 30 atime=1699284309.687160019 30 ctime=1699284303.838142402 glusterfs-11.1/xlators/features/index/src/0002775000175100017510000000000014522202517022054 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/index/src/PaxHeaders.9031/index-messages.h0000644000000000000000000000013214522202451024655 xustar000000000000000030 mtime=1699284265.669027438 30 atime=1699284265.669027438 30 ctime=1699284303.836142396 glusterfs-11.1/xlators/features/index/src/index-messages.h0000664000175100017510000000226714522202451025143 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _INDEX_MESSAGES_H_ #define _INDEX_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(INDEX, INDEX_MSG_INDEX_DIR_CREATE_FAILED, INDEX_MSG_INDEX_READDIR_FAILED, INDEX_MSG_INDEX_ADD_FAILED, INDEX_MSG_INDEX_DEL_FAILED, INDEX_MSG_DICT_SET_FAILED, INDEX_MSG_INODE_CTX_GET_SET_FAILED, INDEX_MSG_INVALID_ARGS, INDEX_MSG_FD_OP_FAILED, INDEX_MSG_WORKER_THREAD_CREATE_FAILED, INDEX_MSG_INVALID_GRAPH); #endif /* !_INDEX_MESSAGES_H_ */ glusterfs-11.1/xlators/features/index/src/PaxHeaders.9031/index.h0000644000000000000000000000013214522202451023050 xustar000000000000000030 mtime=1699284265.670027441 30 atime=1699284265.669027438 30 ctime=1699284303.832142384 glusterfs-11.1/xlators/features/index/src/index.h0000664000175100017510000000535314522202451023335 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __INDEX_H__ #define __INDEX_H__ #include #include "index-mem-types.h" #define INDEX_THREAD_STACK_SIZE ((size_t)(1024 * 1024)) typedef enum { UNKNOWN, IN, NOTIN } index_state_t; typedef enum { XATTROP_TYPE_UNSET = -1, XATTROP, DIRTY, ENTRY_CHANGES, XATTROP_TYPE_END } index_xattrop_type_t; typedef struct index_inode_ctx { struct list_head callstubs; uuid_t virtual_pargfid; /* virtual gfid of dir under .glusterfs/indices/entry-changes. */ int state[XATTROP_TYPE_END]; gf_boolean_t processing; } index_inode_ctx_t; typedef struct index_fd_ctx { DIR *dir; off_t dir_eof; } index_fd_ctx_t; typedef struct index_priv { char *index_basepath; char *dirty_basepath; uuid_t index; gf_lock_t lock; uuid_t internal_vgfid[XATTROP_TYPE_END]; struct list_head callstubs; pthread_mutex_t mutex; pthread_cond_t cond; dict_t *dirty_watchlist; dict_t *pending_watchlist; dict_t *complete_watchlist; int64_t pending_count; pthread_t thread; gf_boolean_t down; gf_atomic_t stub_cnt; int32_t curr_count; } index_priv_t; typedef struct index_local { inode_t *inode; dict_t *xdata; } index_local_t; #define INDEX_STACK_UNWIND(fop, frame, params...) \ do { \ index_local_t *__local = NULL; \ if (frame) { \ __local = frame->local; \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ if (__local) { \ inode_unref(__local->inode); \ if (__local->xdata) \ dict_unref(__local->xdata); \ mem_put(__local); \ } \ } while (0) #endif glusterfs-11.1/xlators/features/index/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023641 xustar000000000000000030 mtime=1699284276.205059173 30 atime=1699284290.750102982 30 ctime=1699284303.829142375 glusterfs-11.1/xlators/features/index/src/Makefile.in0000664000175100017510000005740514522202464024133 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/index/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) index_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_index_la_OBJECTS = index.lo index_la_OBJECTS = $(am_index_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = index_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(index_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_index_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(index_la_SOURCES) DIST_SOURCES = $(index_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = index.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features index_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) index_la_SOURCES = index.c index_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = index.h index-mem-types.h index-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/index/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/index/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } index.la: $(index_la_OBJECTS) $(index_la_DEPENDENCIES) $(EXTRA_index_la_DEPENDENCIES) $(AM_V_CCLD)$(index_la_LINK) $(am_index_la_rpath) $(index_la_OBJECTS) $(index_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/index.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/index/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023624 xustar000000000000000030 mtime=1699284265.669027438 30 atime=1699284276.168059061 30 ctime=1699284303.831142381 glusterfs-11.1/xlators/features/index/src/Makefile.am0000664000175100017510000000103014522202451024075 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = index.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features index_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) index_la_SOURCES = index.c index_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = index.h index-mem-types.h index-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ -I$(top_srcdir)/rpc/rpc-lib/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/index/src/PaxHeaders.9031/index-mem-types.h0000644000000000000000000000013114522202451024765 xustar000000000000000030 mtime=1699284265.669027438 30 atime=1699284265.669027438 29 ctime=1699284303.83414239 glusterfs-11.1/xlators/features/index/src/index-mem-types.h0000664000175100017510000000120514522202451025243 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __INDEX_MEM_TYPES_H__ #define __INDEX_MEM_TYPES_H__ #include enum gf_index_mem_types_ { gf_index_mt_priv_t = gf_common_mt_end + 1, gf_index_inode_ctx_t, gf_index_fd_ctx_t, gf_index_mt_local_t, gf_index_mt_end }; #endif glusterfs-11.1/xlators/features/index/src/PaxHeaders.9031/index.c0000644000000000000000000000013214522202451023043 xustar000000000000000030 mtime=1699284265.669027438 30 atime=1699284265.669027438 30 ctime=1699284303.838142402 glusterfs-11.1/xlators/features/index/src/index.c0000664000175100017510000022126014522202451023325 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "index.h" #include #include "glusterfs4-xdr.h" #include #include #include #include "index-messages.h" #include #include /* for dirname() */ #include #define XATTROP_SUBDIR "xattrop" #define DIRTY_SUBDIR "dirty" #define ENTRY_CHANGES_SUBDIR "entry-changes" struct index_syncop_args { inode_t *parent; gf_dirent_t *entries; char *path; }; static char *index_vgfid_xattrs[XATTROP_TYPE_END] = { [XATTROP] = GF_XATTROP_INDEX_GFID, [DIRTY] = GF_XATTROP_DIRTY_GFID, [ENTRY_CHANGES] = GF_XATTROP_ENTRY_CHANGES_GFID}; static char *index_subdirs[XATTROP_TYPE_END] = { [XATTROP] = XATTROP_SUBDIR, [DIRTY] = DIRTY_SUBDIR, [ENTRY_CHANGES] = ENTRY_CHANGES_SUBDIR}; static int index_get_type_from_vgfid(index_priv_t *priv, uuid_t vgfid) { int i = 0; for (i = 0; i < XATTROP_TYPE_END; i++) { if (gf_uuid_compare(priv->internal_vgfid[i], vgfid) == 0) return i; } return -1; } static gf_boolean_t index_is_virtual_gfid(index_priv_t *priv, uuid_t vgfid) { if (index_get_type_from_vgfid(priv, vgfid) < 0) return _gf_false; return _gf_true; } static index_inode_ctx_t * __index_inode_ctx_get(inode_t *inode, xlator_t *this) { int ret = 0; index_inode_ctx_t *ictx = NULL; uint64_t tmpctx = 0; ret = __inode_ctx_get(inode, this, &tmpctx); if (!ret) { ictx = (index_inode_ctx_t *)(long)tmpctx; goto out; } ictx = GF_CALLOC(1, sizeof(*ictx), gf_index_inode_ctx_t); if (ictx == NULL) { goto out; } INIT_LIST_HEAD(&ictx->callstubs); ret = __inode_ctx_put(inode, this, (uint64_t)(uintptr_t)ictx); if (ret) { GF_FREE(ictx); ictx = NULL; } out: return ictx; } static index_inode_ctx_t * index_inode_ctx_get(inode_t *inode, xlator_t *this) { index_inode_ctx_t *ctx = NULL; LOCK(&inode->lock); { ctx = __index_inode_ctx_get(inode, this); } UNLOCK(&inode->lock); return ctx; } static gf_boolean_t index_is_subdir_of_entry_changes(xlator_t *this, inode_t *inode) { index_inode_ctx_t *ctx = NULL; if (!inode) return _gf_false; ctx = index_inode_ctx_get(inode, this); if (ctx && !gf_uuid_is_null(ctx->virtual_pargfid)) return _gf_true; return _gf_false; } static int index_get_type_from_vgfid_xattr(const char *name) { int i = 0; for (i = 0; i < XATTROP_TYPE_END; i++) { if (strcmp(name, index_vgfid_xattrs[i]) == 0) return i; } return -1; } static gf_boolean_t index_is_fop_on_internal_inode(xlator_t *this, inode_t *inode, uuid_t gfid) { index_priv_t *priv = this->private; uuid_t vgfid = {0}; if (!inode) return _gf_false; if (gfid && !gf_uuid_is_null(gfid)) gf_uuid_copy(vgfid, gfid); else gf_uuid_copy(vgfid, inode->gfid); if (index_is_virtual_gfid(priv, vgfid)) return _gf_true; if (index_is_subdir_of_entry_changes(this, inode)) return _gf_true; return _gf_false; } static gf_boolean_t index_is_vgfid_xattr(const char *name) { if (index_get_type_from_vgfid_xattr(name) < 0) return _gf_false; return _gf_true; } static call_stub_t * __index_dequeue(struct list_head *callstubs) { call_stub_t *stub = NULL; if (!list_empty(callstubs)) { stub = list_entry(callstubs->next, call_stub_t, list); list_del_init(&stub->list); } return stub; } static void __index_enqueue(struct list_head *callstubs, call_stub_t *stub) { list_add_tail(&stub->list, callstubs); } static void worker_enqueue(xlator_t *this, call_stub_t *stub) { index_priv_t *priv = NULL; priv = this->private; pthread_mutex_lock(&priv->mutex); { __index_enqueue(&priv->callstubs, stub); GF_ATOMIC_INC(priv->stub_cnt); pthread_cond_signal(&priv->cond); } pthread_mutex_unlock(&priv->mutex); } static void * index_worker(void *data) { index_priv_t *priv = NULL; xlator_t *this = NULL; call_stub_t *stub = NULL; gf_boolean_t bye = _gf_false; THIS = data; this = data; priv = this->private; for (;;) { pthread_mutex_lock(&priv->mutex); { while (list_empty(&priv->callstubs)) { if (priv->down) { bye = _gf_true; /*Avoid wait*/ break; } (void)pthread_cond_wait(&priv->cond, &priv->mutex); if (priv->down) { bye = _gf_true; break; } } if (!bye) stub = __index_dequeue(&priv->callstubs); if (bye) { priv->curr_count--; if (priv->curr_count == 0) pthread_cond_broadcast(&priv->cond); } } pthread_mutex_unlock(&priv->mutex); if (stub) { /* guard against spurious wakeups */ call_resume(stub); GF_ATOMIC_DEC(priv->stub_cnt); } stub = NULL; if (bye) break; } return NULL; } static int make_index_dir_path(char *base, const char *subdir, char *index_dir, size_t len) { return snprintf(index_dir, len, "%s/%s", base, subdir); } static int index_dir_create(xlator_t *this, const char *subdir) { int ret = 0; struct stat st = {0}; char fullpath[PATH_MAX] = {0}; char path[PATH_MAX] = {0}; char *dir = NULL; index_priv_t *priv = NULL; size_t len = 0; size_t pathlen = 0; priv = this->private; pathlen = make_index_dir_path(priv->index_basepath, subdir, fullpath, sizeof(fullpath)); ret = sys_stat(fullpath, &st); if (!ret) { if (!S_ISDIR(st.st_mode)) ret = -2; goto out; } if ((pathlen > 1) && fullpath[pathlen - 1] == '/') fullpath[pathlen - 1] = '\0'; dir = strchr(fullpath, '/'); while (dir) { dir = strchr(dir + 1, '/'); if (dir) len = pathlen - strlen(dir); else len = pathlen; strncpy(path, fullpath, len); path[len] = '\0'; ret = sys_mkdir(path, 0600); if (ret && (errno != EEXIST)) goto out; } ret = 0; out: if (ret == -1) { gf_msg(this->name, GF_LOG_ERROR, errno, INDEX_MSG_INDEX_DIR_CREATE_FAILED, "%s/%s: Failed to " "create", priv->index_basepath, subdir); } else if (ret == -2) { gf_msg(this->name, GF_LOG_ERROR, ENOTDIR, INDEX_MSG_INDEX_DIR_CREATE_FAILED, "%s/%s: Failed to " "create, path exists, not a directory ", priv->index_basepath, subdir); } return ret; } static void index_get_index(index_priv_t *priv, uuid_t index) { LOCK(&priv->lock); { gf_uuid_copy(index, priv->index); } UNLOCK(&priv->lock); } static void index_generate_index(index_priv_t *priv, uuid_t index) { LOCK(&priv->lock); { // To prevent duplicate generates. // This method fails if number of contending threads is greater // than MAX_LINK count of the fs if (!gf_uuid_compare(priv->index, index)) gf_uuid_generate(priv->index); gf_uuid_copy(index, priv->index); } UNLOCK(&priv->lock); } static void make_index_path(char *base, const char *subdir, uuid_t index, char *index_path, size_t len) { int index_path_len; index_path_len = make_index_dir_path(base, subdir, index_path, len); snprintf(index_path + index_path_len, len - index_path_len, "/%s-%s", subdir, uuid_utoa(index)); } static void make_gfid_path(char *base, const char *subdir, uuid_t gfid, char *gfid_path, size_t len) { int gfid_path_len; gfid_path_len = make_index_dir_path(base, subdir, gfid_path, len); snprintf(gfid_path + gfid_path_len, len - gfid_path_len, "/%s", uuid_utoa(gfid)); } static void make_file_path(char *base, const char *subdir, const char *filename, char *file_path, size_t len) { int file_path_len; file_path_len = make_index_dir_path(base, subdir, file_path, len); snprintf(file_path + file_path_len, len - file_path_len, "/%s", filename); } static int is_index_file_current(char *filename, uuid_t priv_index, char *subdir) { char current_index[GF_UUID_BUF_SIZE + 16]; snprintf(current_index, sizeof current_index, "%s-%s", subdir, uuid_utoa(priv_index)); return (!strcmp(filename, current_index)); } static void check_delete_stale_index_file(xlator_t *this, char *filename, char *subdir) { int ret = 0; struct stat st = {0}; char filepath[PATH_MAX] = {0}; index_priv_t *priv = NULL; priv = this->private; if (is_index_file_current(filename, priv->index, subdir)) return; make_file_path(priv->index_basepath, subdir, filename, filepath, sizeof(filepath)); ret = sys_stat(filepath, &st); if (!ret && st.st_nlink == 1) sys_unlink(filepath); } static void index_set_link_count(index_priv_t *priv, int64_t count, index_xattrop_type_t type) { switch (type) { case XATTROP: LOCK(&priv->lock); { priv->pending_count = count; } UNLOCK(&priv->lock); break; default: break; } } static void index_get_link_count(index_priv_t *priv, int64_t *count, index_xattrop_type_t type) { switch (type) { case XATTROP: LOCK(&priv->lock); { *count = priv->pending_count; } UNLOCK(&priv->lock); break; default: break; } } static void index_update_link_count_cache(index_priv_t *priv, index_xattrop_type_t type, int link_count_delta) { switch (type) { case XATTROP: LOCK(&priv->lock); { if (priv->pending_count >= 0) { if (link_count_delta == -1) { priv->pending_count--; } /*If this is the first xattrop, then pending_count needs to * be updated for the next lstat/lookup with link-count * xdata*/ if (priv->pending_count == 0) { priv->pending_count--; /*Invalidate cache*/ } } } UNLOCK(&priv->lock); break; default: break; } } static char * index_get_subdir_from_type(index_xattrop_type_t type) { if (type < XATTROP || type >= XATTROP_TYPE_END) return NULL; return index_subdirs[type]; } static char * index_get_subdir_from_vgfid(index_priv_t *priv, uuid_t vgfid) { return index_get_subdir_from_type(index_get_type_from_vgfid(priv, vgfid)); } static int index_fill_readdir(fd_t *fd, index_fd_ctx_t *fctx, DIR *dir, off_t off, size_t size, gf_dirent_t *entries) { off_t in_case = -1; off_t last_off = 0; size_t filled = 0; int count = 0; struct dirent *entry = NULL; struct dirent scratch[2] = { { 0, }, }; int32_t this_size = -1; gf_dirent_t *this_entry = NULL; xlator_t *this = NULL; size_t entry_dname_len; this = THIS; if (!off) { rewinddir(dir); } else { seekdir(dir, off); #ifndef GF_LINUX_HOST_OS if ((u_long)telldir(dir) != off && off != fctx->dir_eof) { gf_msg(THIS->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_INDEX_READDIR_FAILED, "seekdir(0x%llx) failed on dir=%p: " "Invalid argument (offset reused from " "another DIR * structure?)", off, dir); errno = EINVAL; count = -1; goto out; } #endif /* GF_LINUX_HOST_OS */ } while (filled <= size) { in_case = (u_long)telldir(dir); if (in_case == -1) { gf_msg(THIS->name, GF_LOG_ERROR, errno, INDEX_MSG_INDEX_READDIR_FAILED, "telldir failed on dir=%p", dir); goto out; } errno = 0; entry = sys_readdir(dir, scratch); if (!entry || errno != 0) { if (errno == EBADF) { gf_msg(THIS->name, GF_LOG_WARNING, errno, INDEX_MSG_INDEX_READDIR_FAILED, "readdir failed on dir=%p", dir); goto out; } break; } entry_dname_len = strlen(entry->d_name); /* Skip entry name comparison unless the length is equal to either: * SLEN('dirty-') + '-' + UUID_CANONICAL_FORM_LEN (36) * or * SLEN('xattrop') + '-' + UUID_CANONICAL_FORM_LEN (36) */ if (entry_dname_len == (SLEN(XATTROP_SUBDIR) + 1 + UUID_CANONICAL_FORM_LEN) || entry_dname_len == (SLEN(DIRTY_SUBDIR) + 1 + UUID_CANONICAL_FORM_LEN)) { if (!strncmp(entry->d_name, XATTROP_SUBDIR "-", strlen(XATTROP_SUBDIR "-"))) { check_delete_stale_index_file(this, entry->d_name, XATTROP_SUBDIR); continue; } else if (!strncmp(entry->d_name, DIRTY_SUBDIR "-", strlen(DIRTY_SUBDIR "-"))) { check_delete_stale_index_file(this, entry->d_name, DIRTY_SUBDIR); continue; } } this_size = max(sizeof(gf_dirent_t), sizeof(gfx_dirplist)) + entry_dname_len + 1; if (this_size + filled > size) { seekdir(dir, in_case); #ifndef GF_LINUX_HOST_OS if ((u_long)telldir(dir) != in_case && in_case != fctx->dir_eof) { gf_msg(THIS->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_INDEX_READDIR_FAILED, "seekdir(0x%llx) failed on dir=%p: " "Invalid argument (offset reused from " "another DIR * structure?)", in_case, dir); errno = EINVAL; count = -1; goto out; } #endif /* GF_LINUX_HOST_OS */ break; } /* * we store the offset of next entry here, which is * probably not intended, but code using syncop_readdir() * (glfs-heal.c, afr-self-heald.c) rely on it * for directory read resumption. */ last_off = (u_long)telldir(dir); this_entry = gf_dirent_for_name2(entry->d_name, entry_dname_len, entry->d_ino, last_off, 0, NULL); if (!this_entry) { gf_msg(THIS->name, GF_LOG_ERROR, errno, INDEX_MSG_INDEX_READDIR_FAILED, "could not create gf_dirent for entry %s", entry->d_name); goto out; } list_add_tail(&this_entry->list, &entries->list); filled += this_size; count++; } errno = 0; if ((!sys_readdir(dir, scratch) && (errno == 0))) { /* Indicate EOF */ errno = ENOENT; /* Remember EOF offset for later detection */ fctx->dir_eof = last_off; } out: return count; } static int index_link_to_base(xlator_t *this, char *fpath, const char *subdir) { int ret = 0; int fd = 0; int op_errno = 0; uuid_t index = {0}; index_priv_t *priv = this->private; char base[PATH_MAX] = {0}; index_get_index(priv, index); make_index_path(priv->index_basepath, subdir, index, base, sizeof(base)); ret = sys_link(base, fpath); if (!ret || (errno == EEXIST)) { ret = 0; goto out; } op_errno = errno; if (op_errno == ENOENT) { ret = index_dir_create(this, subdir); if (ret) { op_errno = errno; goto out; } } else if (op_errno == EMLINK) { index_generate_index(priv, index); make_index_path(priv->index_basepath, subdir, index, base, sizeof(base)); } else { goto out; } op_errno = 0; fd = sys_creat(base, 0); if ((fd < 0) && (errno != EEXIST)) { op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, op_errno, INDEX_MSG_INDEX_ADD_FAILED, "%s: Not able to " "create index", fpath); goto out; } if (fd >= 0) sys_close(fd); ret = sys_link(base, fpath); if (ret && (errno != EEXIST)) { op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, errno, INDEX_MSG_INDEX_ADD_FAILED, "%s: Not able to " "add to index", fpath); goto out; } out: return -op_errno; } static int index_add(xlator_t *this, uuid_t gfid, const char *subdir, index_xattrop_type_t type) { char gfid_path[PATH_MAX] = {0}; int ret = -1; index_priv_t *priv = NULL; struct stat st = {0}; priv = this->private; if (gf_uuid_is_null(gfid)) { GF_ASSERT(0); goto out; } make_gfid_path(priv->index_basepath, subdir, gfid, gfid_path, sizeof(gfid_path)); ret = sys_stat(gfid_path, &st); if (!ret) goto out; ret = index_link_to_base(this, gfid_path, subdir); if (ret == 0) { index_update_link_count_cache(priv, type, 1); } out: return ret; } static int index_del(xlator_t *this, uuid_t gfid, const char *subdir, int type) { int32_t op_errno __attribute__((unused)) = 0; index_priv_t *priv = NULL; int ret = 0; char gfid_path[PATH_MAX] = {0}; char rename_dst[PATH_MAX] = { 0, }; uuid_t uuid; priv = this->private; GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(gfid), out, op_errno, EINVAL); make_gfid_path(priv->index_basepath, subdir, gfid, gfid_path, sizeof(gfid_path)); if ((strcmp(subdir, ENTRY_CHANGES_SUBDIR)) == 0) { ret = sys_rmdir(gfid_path); /* rmdir above could fail with ENOTEMPTY if the indices under * it were created when granular-entry-heal was enabled, whereas * the actual heal that happened was non-granular (or full) in * nature, resulting in name indices getting left out. To * clean up this directory without it affecting the IO path perf, * the directory is renamed to a unique name under * indices/entry-changes. Self-heal will pick up this entry * during crawl and on lookup into the file system figure that * the index is stale and subsequently wipe it out using rmdir(). */ if ((ret) && (errno == ENOTEMPTY)) { gf_uuid_generate(uuid); make_gfid_path(priv->index_basepath, subdir, uuid, rename_dst, sizeof(rename_dst)); ret = sys_rename(gfid_path, rename_dst); } } else { ret = sys_unlink(gfid_path); } if (ret && (errno != ENOENT)) { gf_msg(this->name, GF_LOG_ERROR, errno, INDEX_MSG_INDEX_DEL_FAILED, "%s: failed to delete" " from index", gfid_path); ret = -errno; goto out; } /* If errno is ENOENT then ret won't be zero */ if (ret == 0) { index_update_link_count_cache(priv, type, -1); } ret = 0; out: return ret; } static gf_boolean_t _is_xattr_in_watchlist(dict_t *d, char *k, data_t *v, void *tmp) { if (!strncmp(k, tmp, strlen(k))) return _gf_true; return _gf_false; } static gf_boolean_t is_xattr_in_watchlist(dict_t *this, char *key, data_t *value, void *matchdata) { int ret = -1; // matchdata is a list of xattrs // key is strncmp'ed with each xattr in matchdata. // ret will be 0 if key pattern is not present in the matchdata // else ret will be count number of xattrs the key pattern-matches with. ret = dict_foreach_match(matchdata, _is_xattr_in_watchlist, key, dict_null_foreach_fn, NULL); if (ret > 0) return _gf_true; return _gf_false; } static int index_find_xattr_type(dict_t *d, char *k, data_t *v) { int idx = -1; index_priv_t *priv = THIS->private; if (priv->dirty_watchlist && is_xattr_in_watchlist(d, k, v, priv->dirty_watchlist)) idx = DIRTY; else if (priv->pending_watchlist && is_xattr_in_watchlist(d, k, v, priv->pending_watchlist)) idx = XATTROP; return idx; } static int index_fill_zero_array(dict_t *d, char *k, data_t *v, void *adata) { int idx = -1; int *zfilled = adata; // zfilled array contains `state` for all types xattrs. // state : whether the gfid file of this file exists in // corresponding xattr directory or not. idx = index_find_xattr_type(d, k, v); if (idx == -1) return 0; /* If an xattr value is all-zero leave zfilled[idx] as -1 so that xattrop * index add/del won't happen */ if (!memeqzero((const char *)v->data, v->len)) { zfilled[idx] = 0; } return 0; } static int _check_key_is_zero_filled(dict_t *d, char *k, data_t *v, void *tmp) { int *zfilled = tmp; int idx = -1; idx = index_find_xattr_type(d, k, v); if (idx == -1) return 0; /* Along with checking that the value of a key is zero filled * the key's corresponding index should be assigned * appropriate value. * zfilled[idx] will be 0(false) if value not zero. * will be 1(true) if value is zero. */ if (!memeqzero((const char *)v->data, v->len)) { zfilled[idx] = 0; return 0; } /* If zfilled[idx] was previously 0, it means at least * one xattr of its "kind" is non-zero. Keep its value * the same. */ if (zfilled[idx]) zfilled[idx] = 1; return 0; } static int index_entry_create(xlator_t *this, inode_t *inode, char *filename) { int ret = -1; int op_errno = 0; char pgfid_path[PATH_MAX] = {0}; char entry_path[PATH_MAX] = {0}; index_priv_t *priv = NULL; index_inode_ctx_t *ctx = NULL; int32_t len = 0; priv = this->private; GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(inode->gfid), out, op_errno, EINVAL); GF_ASSERT_AND_GOTO_WITH_ERROR(filename, out, op_errno, EINVAL); ctx = index_inode_ctx_get(inode, this); if (ctx == NULL) { op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, op_errno, INDEX_MSG_INODE_CTX_GET_SET_FAILED, "Not able to get inode ctx for %s", uuid_utoa(inode->gfid)); goto out; } make_gfid_path(priv->index_basepath, ENTRY_CHANGES_SUBDIR, inode->gfid, pgfid_path, sizeof(pgfid_path)); if (ctx->state[ENTRY_CHANGES] != IN) { ret = sys_mkdir(pgfid_path, 0600); if (ret != 0 && errno != EEXIST) { op_errno = errno; goto out; } ctx->state[ENTRY_CHANGES] = IN; } if (strchr(filename, '/')) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_INDEX_ADD_FAILED, "Got invalid entry (%s) for pargfid path (%s)", filename, pgfid_path); op_errno = EINVAL; goto out; } len = snprintf(entry_path, sizeof(entry_path), "%s/%s", pgfid_path, filename); if ((len < 0) || (len >= sizeof(entry_path))) { op_errno = EINVAL; goto out; } op_errno = 0; ret = index_link_to_base(this, entry_path, ENTRY_CHANGES_SUBDIR); out: if (op_errno) ret = -op_errno; return ret; } static int index_entry_delete(xlator_t *this, uuid_t pgfid, char *filename) { int op_errno = 0; char pgfid_path[PATH_MAX] = {0}; char entry_path[PATH_MAX] = {0}; index_priv_t *priv = NULL; int32_t len = 0; priv = this->private; GF_ASSERT_AND_GOTO_WITH_ERROR(!gf_uuid_is_null(pgfid), out, op_errno, EINVAL); GF_ASSERT_AND_GOTO_WITH_ERROR(filename, out, op_errno, EINVAL); make_gfid_path(priv->index_basepath, ENTRY_CHANGES_SUBDIR, pgfid, pgfid_path, sizeof(pgfid_path)); if (strchr(filename, '/')) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_INDEX_DEL_FAILED, "Got invalid entry (%s) for pargfid path (%s)", filename, pgfid_path); op_errno = EINVAL; goto out; } len = snprintf(entry_path, sizeof(entry_path), "%s/%s", pgfid_path, filename); if ((len < 0) || (len >= sizeof(entry_path))) { op_errno = EINVAL; goto out; } if (!gf_unlink(entry_path)) op_errno = errno; out: return -op_errno; } static int index_entry_action(xlator_t *this, inode_t *inode, dict_t *xdata, char *key) { int ret = 0; char *filename = NULL; ret = dict_get_str(xdata, key, &filename); if (ret != 0) { ret = 0; goto out; } if (strcmp(key, GF_XATTROP_ENTRY_IN_KEY) == 0) ret = index_entry_create(this, inode, filename); else if (strcmp(key, GF_XATTROP_ENTRY_OUT_KEY) == 0) ret = index_entry_delete(this, inode->gfid, filename); out: return ret; } static void _index_action(xlator_t *this, inode_t *inode, int *zfilled) { int ret = 0; int i = 0; index_inode_ctx_t *ctx = NULL; char *subdir = NULL; ctx = index_inode_ctx_get(inode, this); if (ctx == NULL) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_INODE_CTX_GET_SET_FAILED, "Not able to get" " inode context for %s.", uuid_utoa(inode->gfid)); return; } for (i = 0; i < XATTROP_TYPE_END; i++) { subdir = index_get_subdir_from_type(i); if (zfilled[i] == 1) { if (ctx->state[i] == NOTIN) continue; ret = index_del(this, inode->gfid, subdir, i); if (!ret) ctx->state[i] = NOTIN; } else if (zfilled[i] == 0) { if (ctx->state[i] == IN) continue; ret = index_add(this, inode->gfid, subdir, i); if (!ret) ctx->state[i] = IN; } } } static void index_init_state(xlator_t *this, inode_t *inode, index_inode_ctx_t *ctx, char *subdir) { int ret = -1; char pgfid_path[PATH_MAX] = {0}; struct stat st = {0}; index_priv_t *priv = NULL; priv = this->private; make_gfid_path(priv->index_basepath, subdir, inode->gfid, pgfid_path, sizeof(pgfid_path)); ret = sys_stat(pgfid_path, &st); if (ret == 0) ctx->state[ENTRY_CHANGES] = IN; else if (ret != 0 && errno == ENOENT) ctx->state[ENTRY_CHANGES] = NOTIN; return; } static void xattrop_index_action(xlator_t *this, index_local_t *local, dict_t *xattr, dict_match_t match, void *match_data) { int ret = 0; int zfilled[XATTROP_TYPE_END] = { 0, }; int8_t value = 0; char *subdir = NULL; dict_t *req_xdata = NULL; inode_t *inode = NULL; index_inode_ctx_t *ctx = NULL; inode = local->inode; req_xdata = local->xdata; memset(zfilled, -1, sizeof(zfilled)); ret = dict_foreach_match(xattr, match, match_data, _check_key_is_zero_filled, zfilled); _index_action(this, inode, zfilled); if (req_xdata) { ret = index_entry_action(this, inode, req_xdata, GF_XATTROP_ENTRY_OUT_KEY); ret = dict_get_int8(req_xdata, GF_XATTROP_PURGE_INDEX, &value); if ((ret) || (value == 0)) goto out; } if (zfilled[XATTROP] != 1) goto out; if (inode->ia_type != IA_IFDIR) goto out; subdir = index_get_subdir_from_type(ENTRY_CHANGES); ctx = index_inode_ctx_get(inode, this); if (ctx == NULL) goto out; if (ctx->state[ENTRY_CHANGES] == UNKNOWN) index_init_state(this, inode, ctx, subdir); if (ctx->state[ENTRY_CHANGES] == IN) { ret = index_del(this, inode->gfid, subdir, ENTRY_CHANGES); ctx->state[ENTRY_CHANGES] = NOTIN; } out: return; } static gf_boolean_t index_xattrop_track(xlator_t *this, gf_xattrop_flags_t flags, dict_t *dict) { index_priv_t *priv = this->private; if (flags == GF_XATTROP_ADD_ARRAY) return _gf_true; if (flags != GF_XATTROP_ADD_ARRAY64) return _gf_false; if (!priv->pending_watchlist) return _gf_false; if (dict_foreach_match(dict, is_xattr_in_watchlist, priv->pending_watchlist, dict_null_foreach_fn, NULL) > 0) return _gf_true; return _gf_false; } static int index_inode_path(xlator_t *this, inode_t *inode, char *dirpath, size_t len) { char *subdir = NULL; int ret = 0; index_priv_t *priv = NULL; index_inode_ctx_t *ictx = NULL; int dir_path_len; priv = this->private; if (!index_is_fop_on_internal_inode(this, inode, NULL)) { ret = -EINVAL; goto out; } subdir = index_get_subdir_from_vgfid(priv, inode->gfid); if (subdir) { if (len <= strlen(priv->index_basepath) + 1 /*'/'*/ + strlen(subdir)) { ret = -EINVAL; goto out; } (void)make_index_dir_path(priv->index_basepath, subdir, dirpath, len); } else { ictx = index_inode_ctx_get(inode, this); if (ictx == NULL) { ret = -1; goto out; } else if (gf_uuid_is_null(ictx->virtual_pargfid)) { ret = -EINVAL; goto out; } dir_path_len = make_index_dir_path(priv->index_basepath, ENTRY_CHANGES_SUBDIR, dirpath, len); if (len <= dir_path_len + 1 /*'/'*/ + SLEN(UUID0_STR)) { ret = -EINVAL; goto out; } strcat(dirpath, "/"); strcat(dirpath, uuid_utoa(ictx->virtual_pargfid)); } out: return ret; } static int __index_fd_ctx_get(fd_t *fd, xlator_t *this, index_fd_ctx_t **ctx) { int ret = 0; index_fd_ctx_t *fctx = NULL; char dirpath[PATH_MAX] = {0}; fctx = __fd_ctx_get_ptr(fd, this); if (fctx) { *ctx = fctx; goto out; } ret = index_inode_path(this, fd->inode, dirpath, sizeof(dirpath)); if (ret) goto out; fctx = GF_CALLOC(1, sizeof(*fctx), gf_index_fd_ctx_t); if (!fctx) { ret = -ENOMEM; goto out; } fctx->dir = sys_opendir(dirpath); if (!fctx->dir) { ret = -errno; GF_FREE(fctx); fctx = NULL; goto out; } fctx->dir_eof = -1; ret = __fd_ctx_set(fd, this, (uint64_t)(long)fctx); if (ret) { (void)sys_closedir(fctx->dir); GF_FREE(fctx); fctx = NULL; ret = -EINVAL; goto out; } *ctx = fctx; out: return ret; } static int index_fd_ctx_get(fd_t *fd, xlator_t *this, index_fd_ctx_t **ctx) { int ret = 0; LOCK(&fd->lock); { ret = __index_fd_ctx_get(fd, this, ctx); } UNLOCK(&fd->lock); return ret; } // new - Not NULL means start a fop // new - NULL means done processing the fop static void index_queue_process(xlator_t *this, inode_t *inode, call_stub_t *new) { call_stub_t *stub = NULL; index_inode_ctx_t *ctx = NULL; call_frame_t *frame = NULL; LOCK(&inode->lock); { ctx = __index_inode_ctx_get(inode, this); if (!ctx) goto unlock; if (new) { __index_enqueue(&ctx->callstubs, new); new = NULL; } else { ctx->processing = _gf_false; } if (!ctx->processing) { stub = __index_dequeue(&ctx->callstubs); if (stub) ctx->processing = _gf_true; else ctx->processing = _gf_false; } } unlock: UNLOCK(&inode->lock); if (!ctx && new) { frame = new->frame; if (new->fop == GF_FOP_XATTROP) { INDEX_STACK_UNWIND(xattrop, frame, -1, ENOMEM, NULL, NULL); } else if (new->fop == GF_FOP_FXATTROP) { INDEX_STACK_UNWIND(fxattrop, frame, -1, ENOMEM, NULL, NULL); } call_stub_destroy(new); } else if (stub) { call_resume(stub); } return; } static int xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata, dict_match_t match, dict_t *matchdata) { inode_t *inode = NULL; index_local_t *local = NULL; local = frame->local; inode = inode_ref(local->inode); if (op_ret < 0) goto out; xattrop_index_action(this, local, xattr, match, matchdata); out: INDEX_STACK_UNWIND(xattrop, frame, op_ret, op_errno, xattr, xdata); index_queue_process(this, inode, NULL); inode_unref(inode); return 0; } static int32_t index_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata) { index_priv_t *priv = this->private; xattrop_cbk(frame, cookie, this, op_ret, op_errno, xattr, xdata, is_xattr_in_watchlist, priv->complete_watchlist); return 0; } static int32_t index_xattrop64_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata) { index_priv_t *priv = this->private; return xattrop_cbk(frame, cookie, this, op_ret, op_errno, xattr, xdata, is_xattr_in_watchlist, priv->pending_watchlist); } static void index_xattrop_do(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { int ret = -1; int zfilled[XATTROP_TYPE_END] = { 0, }; index_local_t *local = NULL; fop_xattrop_cbk_t x_cbk = NULL; local = frame->local; if (optype == GF_XATTROP_ADD_ARRAY) x_cbk = index_xattrop_cbk; else x_cbk = index_xattrop64_cbk; /* In wind phase bring the gfid into index. This way if the brick crashes * just after posix performs xattrop before _cbk reaches index xlator * we will still have the gfid in index. */ memset(zfilled, -1, sizeof(zfilled)); /* zfilled[index] = 0 implies the xattr's value is not zero filled * and should be added in its corresponding index subdir. * * zfilled should be set to 0 only for those index that * exist in xattr variable and xattr value non-zero. This is to distinguish * between different types of volumes. * For e.g., if the check is not made, * zfilled[DIRTY] is set to 0 for EC volumes, * index file will be created in indices/dirty dir * which doesn't exist for an EC volume. */ ret = dict_foreach(xattr, index_fill_zero_array, zfilled); _index_action(this, local->inode, zfilled); if (xdata) ret = index_entry_action(this, local->inode, xdata, GF_XATTROP_ENTRY_IN_KEY); if (ret < 0) { x_cbk(frame, NULL, this, -1, -ret, NULL, NULL); return; } if (loc) STACK_WIND(frame, x_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, optype, xattr, xdata); else STACK_WIND(frame, x_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, optype, xattr, xdata); } static int index_xattrop_wrapper(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { index_xattrop_do(frame, this, loc, NULL, optype, xattr, xdata); return 0; } static int index_fxattrop_wrapper(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata) { index_xattrop_do(frame, this, NULL, fd, optype, xattr, xdata); return 0; } int32_t index_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { call_stub_t *stub = NULL; index_local_t *local = NULL; if (!index_xattrop_track(this, flags, dict)) goto out; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->inode = inode_ref(loc->inode); if (xdata) local->xdata = dict_ref(xdata); stub = fop_xattrop_stub(frame, index_xattrop_wrapper, loc, flags, dict, xdata); err: if ((!local) || (!stub)) { INDEX_STACK_UNWIND(xattrop, frame, -1, ENOMEM, NULL, NULL); return 0; } index_queue_process(this, loc->inode, stub); return 0; out: STACK_WIND(frame, default_xattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata); return 0; } int32_t index_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { call_stub_t *stub = NULL; index_local_t *local = NULL; if (!index_xattrop_track(this, flags, dict)) goto out; local = mem_get0(this->local_pool); if (!local) goto err; frame->local = local; local->inode = inode_ref(fd->inode); if (xdata) local->xdata = dict_ref(xdata); stub = fop_fxattrop_stub(frame, index_fxattrop_wrapper, fd, flags, dict, xdata); err: if ((!local) || (!stub)) { INDEX_STACK_UNWIND(fxattrop, frame, -1, ENOMEM, NULL, xdata); return 0; } index_queue_process(this, fd->inode, stub); return 0; out: STACK_WIND(frame, default_fxattrop_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata); return 0; } static uint64_t index_entry_count(xlator_t *this, const char *subdir, const int subdir_len) { uint64_t count = 0; index_priv_t *priv = NULL; DIR *dirp = NULL; struct dirent *entry = NULL; struct dirent scratch[2] = { { 0, }, }; char index_dir[PATH_MAX] = { 0, }; priv = this->private; (void)make_index_dir_path(priv->index_basepath, subdir, index_dir, sizeof(index_dir)); dirp = sys_opendir(index_dir); if (!dirp) return 0; for (;;) { errno = 0; entry = sys_readdir(dirp, scratch); if (!entry || errno != 0) break; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; if (!strncmp(entry->d_name, subdir, subdir_len)) continue; count++; } (void)sys_closedir(dirp); return count; } static int32_t index_getxattr_wrapper(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { index_priv_t *priv = NULL; dict_t *xattr = NULL; int ret = 0; int vgfid_type = 0; uint64_t count = 0; priv = this->private; xattr = dict_new(); if (!xattr) { ret = -ENOMEM; goto done; } vgfid_type = index_get_type_from_vgfid_xattr(name); if (vgfid_type >= 0) { ret = dict_set_static_bin(xattr, (char *)name, priv->internal_vgfid[vgfid_type], sizeof(priv->internal_vgfid[vgfid_type])); if (ret) { ret = -EINVAL; gf_msg(this->name, GF_LOG_ERROR, -ret, INDEX_MSG_DICT_SET_FAILED, "xattrop index " "gfid set failed"); goto done; } } /* TODO: Need to check what kind of link-counts are needed for * ENTRY-CHANGES before refactor of this block with array*/ if (strcmp(name, GF_XATTROP_INDEX_COUNT) == 0) { count = index_entry_count(this, XATTROP_SUBDIR, SLEN(XATTROP_SUBDIR)); ret = dict_set_uint64(xattr, (char *)name, count); if (ret) { ret = -EINVAL; gf_msg(this->name, GF_LOG_ERROR, -ret, INDEX_MSG_DICT_SET_FAILED, "xattrop index " "count set failed"); goto done; } } else if (strcmp(name, GF_XATTROP_DIRTY_COUNT) == 0) { count = index_entry_count(this, DIRTY_SUBDIR, SLEN(DIRTY_SUBDIR)); ret = dict_set_uint64(xattr, (char *)name, count); if (ret) { ret = -EINVAL; gf_msg(this->name, GF_LOG_ERROR, -ret, INDEX_MSG_DICT_SET_FAILED, "dirty index " "count set failed"); goto done; } } done: if (ret) STACK_UNWIND_STRICT(getxattr, frame, -1, -ret, xattr, NULL); else STACK_UNWIND_STRICT(getxattr, frame, 0, 0, xattr, NULL); if (xattr) dict_unref(xattr); return 0; } static int index_save_pargfid_for_entry_changes(xlator_t *this, loc_t *loc, char *path) { index_priv_t *priv = NULL; index_inode_ctx_t *ctx = NULL; int ret = 0; priv = this->private; if (!loc) return -1; if (gf_uuid_compare(loc->pargfid, priv->internal_vgfid[ENTRY_CHANGES])) return 0; ctx = index_inode_ctx_get(loc->inode, this); if (ctx == NULL) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_INODE_CTX_GET_SET_FAILED, "Unable to get inode context for %s", path); return -EINVAL; } ret = gf_uuid_parse(loc->name, ctx->virtual_pargfid); if (ret) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_INODE_CTX_GET_SET_FAILED, "Unable to store " "virtual gfid in inode context for %s", path); return -EINVAL; } return 0; } static int32_t index_lookup_wrapper(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { index_priv_t *priv = NULL; struct stat lstatbuf = {0}; int ret = 0; int32_t op_errno = EINVAL; int32_t op_ret = -1; uint64_t val = IA_INVAL; char path[PATH_MAX] = {0}; struct iatt stbuf = { 0, }; struct iatt postparent = { 0, }; dict_t *xattr = NULL; gf_boolean_t is_dir = _gf_false; char *subdir = NULL; loc_t iloc = {0}; priv = this->private; loc_copy(&iloc, loc); VALIDATE_OR_GOTO(loc, done); if (index_is_fop_on_internal_inode(this, loc->parent, loc->pargfid)) { subdir = index_get_subdir_from_vgfid(priv, loc->pargfid); ret = index_inode_path(this, loc->parent, path, sizeof(path)); if (ret < 0) { op_errno = -ret; goto done; } ret = snprintf(path + strlen(path), PATH_MAX - strlen(path), "/%s", loc->name); if ((ret < 0) || (ret > (PATH_MAX - strlen(path)))) { op_errno = EINVAL; op_ret = -1; goto done; } } else if (index_is_virtual_gfid(priv, loc->gfid)) { subdir = index_get_subdir_from_vgfid(priv, loc->gfid); (void)make_index_dir_path(priv->index_basepath, subdir, path, sizeof(path)); is_dir = _gf_true; if ((xattr_req) && (dict_get(xattr_req, GF_INDEX_IA_TYPE_GET_REQ))) { if (0 == strcmp(subdir, index_get_subdir_from_type(ENTRY_CHANGES))) val = IA_IFDIR; else val = IA_IFREG; } } else { if (!inode_is_linked(loc->inode)) { inode_unref(iloc.inode); iloc.inode = inode_find(loc->inode->table, loc->gfid); } ret = index_inode_path(this, iloc.inode, path, sizeof(path)); if (ret < 0) { op_errno = -ret; goto done; } } ret = sys_lstat(path, &lstatbuf); if (ret) { gf_msg_debug(this->name, errno, "Stat failed on %s dir ", path); op_errno = errno; goto done; } else if (!S_ISDIR(lstatbuf.st_mode) && is_dir) { op_errno = ENOTDIR; gf_msg_debug(this->name, op_errno, "Stat failed on %s dir, " "not a directory", path); goto done; } xattr = dict_new(); if (!xattr) { op_errno = ENOMEM; goto done; } if (val != IA_INVAL) { ret = dict_set_uint64(xattr, GF_INDEX_IA_TYPE_GET_RSP, val); if (ret) { op_ret = -1; op_errno = -ret; goto done; } } iatt_from_stat(&stbuf, &lstatbuf); if (is_dir || inode_is_linked(iloc.inode)) loc_gfid(&iloc, stbuf.ia_gfid); else gf_uuid_generate(stbuf.ia_gfid); ret = index_save_pargfid_for_entry_changes(this, &iloc, path); if (ret) { op_ret = -1; op_errno = -ret; goto done; } stbuf.ia_ino = -1; op_ret = 0; done: STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, loc ? loc->inode : NULL, &stbuf, xattr, &postparent); if (xattr) dict_unref(xattr); loc_wipe(&iloc); return 0; } static int index_get_gfid_type(void *opaque) { gf_dirent_t *entry = NULL; xlator_t *this = THIS; struct index_syncop_args *args = opaque; loc_t loc = {0}; struct iatt iatt = {0}; int ret = 0; list_for_each_entry(entry, &args->entries->list, list) { /* skip . and .. */ if (inode_dir_or_parentdir(entry)) continue; loc_wipe(&loc); entry->d_type = gf_d_type_from_ia_type(IA_INVAL); entry->d_stat.ia_type = IA_INVAL; if (gf_uuid_parse(entry->d_name, loc.gfid)) continue; loc.inode = inode_find(args->parent->table, loc.gfid); if (loc.inode) { entry->d_stat.ia_type = loc.inode->ia_type; entry->d_type = gf_d_type_from_ia_type(loc.inode->ia_type); continue; } loc.inode = inode_new(args->parent->table); if (!loc.inode) continue; ret = syncop_lookup(FIRST_CHILD(this), &loc, &iatt, 0, 0, 0); if (ret == 0) { entry->d_type = gf_d_type_from_ia_type(iatt.ia_type); entry->d_stat = iatt; } } loc_wipe(&loc); return 0; } static int32_t index_readdir_wrapper(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { index_fd_ctx_t *fctx = NULL; index_priv_t *priv = NULL; DIR *dir = NULL; int ret = -1; int32_t op_ret = -1; int32_t op_errno = 0; int count = 0; gf_dirent_t entries; struct index_syncop_args args = {0}; priv = this->private; INIT_LIST_HEAD(&entries.list); ret = index_fd_ctx_get(fd, this, &fctx); if (ret < 0) { op_errno = -ret; gf_msg(this->name, GF_LOG_WARNING, op_errno, INDEX_MSG_FD_OP_FAILED, "pfd is NULL, fd=%p", fd); goto done; } dir = fctx->dir; if (!dir) { op_errno = EINVAL; gf_msg(this->name, GF_LOG_WARNING, op_errno, INDEX_MSG_INDEX_READDIR_FAILED, "dir is NULL for fd=%p", fd); goto done; } count = index_fill_readdir(fd, fctx, dir, off, size, &entries); /* pick ENOENT to indicate EOF */ op_errno = errno; op_ret = count; if (index_is_virtual_gfid(priv, fd->inode->gfid) && xdata && dict_get(xdata, "get-gfid-type")) { args.parent = fd->inode; args.entries = &entries; ret = synctask_new(this->ctx->env, index_get_gfid_type, NULL, NULL, &args); } done: STACK_UNWIND_STRICT(readdir, frame, op_ret, op_errno, &entries, NULL); gf_dirent_free(&entries); return 0; } static int deletion_handler(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { ia_type_t type = IA_INVAL; switch (sb->st_mode & S_IFMT) { case S_IFREG: sys_unlink(fpath); break; case S_IFDIR: sys_rmdir(fpath); break; default: type = ia_type_from_st_mode(sb->st_mode); gf_msg(THIS->name, GF_LOG_WARNING, EINVAL, INDEX_MSG_INVALID_ARGS, "%s neither a regular file nor a directory - type:%s", fpath, gf_inode_type_to_str(type)); break; } return 0; } static int index_wipe_index_subdir(void *opaque) { struct index_syncop_args *args = opaque; nftw(args->path, deletion_handler, 1, FTW_DEPTH | FTW_PHYS); return 0; } static void index_get_parent_iatt(struct iatt *parent, char *path, loc_t *loc, int32_t *op_ret, int32_t *op_errno) { int ret = -1; struct stat lstatbuf = { 0, }; ret = sys_lstat(path, &lstatbuf); if (ret < 0) { *op_ret = -1; *op_errno = errno; return; } iatt_from_stat(parent, &lstatbuf); gf_uuid_copy(parent->ia_gfid, loc->pargfid); parent->ia_ino = -1; return; } static int index_rmdir_wrapper(call_frame_t *frame, xlator_t *this, loc_t *loc, int flag, dict_t *xdata) { int ret = 0; int32_t op_ret = 0; int32_t op_errno = 0; char *subdir = NULL; char index_dir[PATH_MAX] = {0}; char index_subdir[PATH_MAX] = {0}; uuid_t gfid = {0}; struct iatt preparent = {0}; struct iatt postparent = {0}; index_priv_t *priv = NULL; index_xattrop_type_t type = XATTROP_TYPE_UNSET; struct index_syncop_args args = { 0, }; priv = this->private; type = index_get_type_from_vgfid(priv, loc->pargfid); subdir = index_get_subdir_from_vgfid(priv, loc->pargfid); (void)make_index_dir_path(priv->index_basepath, subdir, index_dir, sizeof(index_dir)); index_get_parent_iatt(&preparent, index_dir, loc, &op_ret, &op_errno); if (op_ret < 0) goto done; gf_uuid_parse(loc->name, gfid); make_gfid_path(priv->index_basepath, subdir, gfid, index_subdir, sizeof(index_subdir)); if (flag == 0) { ret = index_del(this, gfid, subdir, type); if (ret < 0) { op_ret = -1; op_errno = -ret; goto done; } } else { args.path = index_subdir; ret = synctask_new(this->ctx->env, index_wipe_index_subdir, NULL, NULL, &args); } index_get_parent_iatt(&postparent, index_dir, loc, &op_ret, &op_errno); if (op_ret < 0) goto done; done: INDEX_STACK_UNWIND(rmdir, frame, op_ret, op_errno, &preparent, &postparent, xdata); return 0; } static int index_unlink_wrapper(call_frame_t *frame, xlator_t *this, loc_t *loc, int flag, dict_t *xdata) { index_priv_t *priv = NULL; index_inode_ctx_t *ictx = NULL; int32_t op_ret = 0; int32_t op_errno = 0; int ret = 0; index_xattrop_type_t type = XATTROP_TYPE_UNSET; struct iatt preparent = {0}; struct iatt postparent = {0}; char index_dir[PATH_MAX] = {0}; char filepath[PATH_MAX] = {0}; uuid_t gfid = {0}; char *subdir = NULL; priv = this->private; type = index_get_type_from_vgfid(priv, loc->pargfid); ret = index_inode_path(this, loc->parent, index_dir, sizeof(index_dir)); if (ret < 0) { op_ret = -1; op_errno = -ret; goto done; } index_get_parent_iatt(&preparent, index_dir, loc, &op_ret, &op_errno); if (op_ret < 0) goto done; if (type <= XATTROP_TYPE_UNSET) { ictx = index_inode_ctx_get(loc->parent, this); if (ictx) { if (gf_uuid_is_null(ictx->virtual_pargfid)) { ret = -EINVAL; } else { ret = index_entry_delete(this, ictx->virtual_pargfid, (char *)loc->name); } } else { // ictx is NUILL ret = -1; } } else if (type == ENTRY_CHANGES) { make_file_path(priv->index_basepath, ENTRY_CHANGES_SUBDIR, (char *)loc->name, filepath, sizeof(filepath)); ret = sys_unlink(filepath); } else { subdir = index_get_subdir_from_type(type); gf_uuid_parse(loc->name, gfid); ret = index_del(this, gfid, subdir, type); } if (ret < 0) { op_ret = -1; op_errno = -ret; goto done; } index_get_parent_iatt(&postparent, index_dir, loc, &op_ret, &op_errno); if (op_ret < 0) goto done; done: INDEX_STACK_UNWIND(unlink, frame, op_ret, op_errno, &preparent, &postparent, xdata); return 0; } int32_t index_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { call_stub_t *stub = NULL; if (!name || (!index_is_vgfid_xattr(name) && strcmp(GF_XATTROP_INDEX_COUNT, name) && strcmp(GF_XATTROP_DIRTY_COUNT, name))) goto out; stub = fop_getxattr_stub(frame, index_getxattr_wrapper, loc, name, xdata); if (!stub) { STACK_UNWIND_STRICT(getxattr, frame, -1, ENOMEM, NULL, NULL); return 0; } worker_enqueue(this, stub); return 0; out: STACK_WIND(frame, default_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); return 0; } static int64_t index_fetch_link_count(xlator_t *this, index_xattrop_type_t type) { index_priv_t *priv = this->private; char *subdir = NULL; struct stat lstatbuf = { 0, }; int ret = -1; int64_t count = -1; DIR *dirp = NULL; struct dirent *entry = NULL; struct dirent scratch[2] = { { 0, }, }; char index_dir[PATH_MAX] = { 0, }; char index_path[PATH_MAX] = { 0, }; subdir = index_get_subdir_from_type(type); (void)make_index_dir_path(priv->index_basepath, subdir, index_dir, sizeof(index_dir)); dirp = sys_opendir(index_dir); if (!dirp) goto out; for (;;) { errno = 0; entry = sys_readdir(dirp, scratch); if (!entry || errno != 0) { if (count == -1) count = 0; goto out; } if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; make_file_path(priv->index_basepath, subdir, entry->d_name, index_path, sizeof(index_path)); ret = sys_lstat(index_path, &lstatbuf); if (ret < 0) { count = -2; continue; } else { count = lstatbuf.st_nlink - 1; if (count == 0) continue; else break; } } out: if (dirp) (void)sys_closedir(dirp); return count; } static dict_t * index_fill_link_count(xlator_t *this, dict_t *xdata) { int ret = -1; index_priv_t *priv = NULL; int64_t count = -1; priv = this->private; xdata = (xdata) ? dict_ref(xdata) : dict_new(); if (!xdata) goto out; index_get_link_count(priv, &count, XATTROP); if (count < 0) { count = index_fetch_link_count(this, XATTROP); index_set_link_count(priv, count, XATTROP); } if (count == 0) { ret = dict_set_int8(xdata, "link-count", 0); if (ret < 0) gf_msg(this->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_DICT_SET_FAILED, "Unable to set link-count"); } else { ret = dict_set_int8(xdata, "link-count", 1); if (ret < 0) gf_msg(this->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_DICT_SET_FAILED, "Unable to set link-count"); } out: return xdata; } static int32_t index_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { xdata = index_fill_link_count(this, xdata); STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata, postparent); if (xdata) dict_unref(xdata); return 0; } int32_t index_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { inode_t *inode = NULL; call_stub_t *stub = NULL; char *flag = NULL; int ret = -1; if (!index_is_fop_on_internal_inode(this, loc->parent, loc->pargfid) && !index_is_fop_on_internal_inode(this, loc->inode, loc->gfid)) { if (!inode_is_linked(loc->inode)) { inode = inode_find(loc->inode->table, loc->gfid); if (!index_is_fop_on_internal_inode(this, inode, loc->gfid)) { inode_unref(inode); goto normal; } inode_unref(inode); } else { goto normal; } } stub = fop_lookup_stub(frame, index_lookup_wrapper, loc, xattr_req); if (!stub) { STACK_UNWIND_STRICT(lookup, frame, -1, ENOMEM, loc->inode, NULL, NULL, NULL); return 0; } worker_enqueue(this, stub); return 0; normal: ret = dict_get_str_sizen(xattr_req, "link-count", &flag); if ((ret == 0) && (strcmp(flag, GF_XATTROP_INDEX_COUNT) == 0)) { STACK_WIND(frame, index_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xattr_req); } else { STACK_WIND(frame, default_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xattr_req); } return 0; } static int32_t index_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { xdata = index_fill_link_count(this, xdata); STACK_UNWIND_STRICT(fstat, frame, op_ret, op_errno, buf, xdata); if (xdata) dict_unref(xdata); return 0; } int32_t index_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int ret = -1; char *flag = NULL; ret = dict_get_str_sizen(xdata, "link-count", &flag); if ((ret == 0) && (strcmp(flag, GF_XATTROP_INDEX_COUNT) == 0)) { STACK_WIND(frame, index_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); } else { STACK_WIND(frame, default_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); } return 0; } int32_t index_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { if (!index_is_fop_on_internal_inode(this, fd->inode, NULL)) goto normal; frame->local = NULL; STACK_UNWIND_STRICT(opendir, frame, 0, 0, fd, NULL); return 0; normal: STACK_WIND(frame, default_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); return 0; } int32_t index_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { call_stub_t *stub = NULL; if (!index_is_fop_on_internal_inode(this, fd->inode, NULL)) goto out; stub = fop_readdir_stub(frame, index_readdir_wrapper, fd, size, off, xdata); if (!stub) { STACK_UNWIND_STRICT(readdir, frame, -1, ENOMEM, NULL, NULL); return 0; } worker_enqueue(this, stub); return 0; out: STACK_WIND(frame, default_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, fd, size, off, xdata); return 0; } int index_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { call_stub_t *stub = NULL; if (!index_is_fop_on_internal_inode(this, loc->parent, NULL)) goto out; stub = fop_unlink_stub(frame, index_unlink_wrapper, loc, xflag, xdata); if (!stub) { STACK_UNWIND_STRICT(unlink, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } worker_enqueue(this, stub); return 0; out: STACK_WIND(frame, default_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; } int index_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, dict_t *xdata) { call_stub_t *stub = NULL; if (!index_is_fop_on_internal_inode(this, loc->parent, NULL)) goto out; stub = fop_rmdir_stub(frame, index_rmdir_wrapper, loc, flags, xdata); if (!stub) { STACK_UNWIND_STRICT(rmdir, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; } worker_enqueue(this, stub); return 0; out: STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); return 0; } static int index_make_xattrop_watchlist(xlator_t *this, index_priv_t *priv, char *watchlist, index_xattrop_type_t type) { char *delim = NULL; char *dup_watchlist = NULL; char *key = NULL; char *saveptr = NULL; dict_t *xattrs = NULL; data_t *dummy = NULL; int ret = 0; if (!watchlist) return 0; dup_watchlist = gf_strdup(watchlist); if (!dup_watchlist) return -1; xattrs = dict_new(); if (!xattrs) { ret = -1; goto out; } dummy = data_from_int32(1); if (!dummy) { ret = -1; goto out; } data_ref(dummy); delim = ","; key = strtok_r(dup_watchlist, delim, &saveptr); while (key) { if (strlen(key) == 0) { ret = -1; goto out; } ret = dict_set(xattrs, key, dummy); if (ret) goto out; key = strtok_r(NULL, delim, &saveptr); } switch (type) { case DIRTY: priv->dirty_watchlist = dict_copy_with_ref(xattrs, priv->dirty_watchlist); if (!priv->dirty_watchlist) { ret = -1; goto out; } break; case XATTROP: priv->pending_watchlist = dict_copy_with_ref( xattrs, priv->pending_watchlist); if (!priv->pending_watchlist) { ret = -1; goto out; } break; default: break; } ret = 0; out: if (xattrs) dict_unref(xattrs); GF_FREE(dup_watchlist); if (dummy) data_unref(dummy); return ret; } static int index_priv_dump(xlator_t *this) { index_priv_t *priv = NULL; char key_prefix[GF_DUMP_MAX_BUF_LEN]; priv = this->private; snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type, this->name); gf_proc_dump_add_section("%s", key_prefix); gf_proc_dump_write("xattrop-pending-count", "%" PRId64, priv->pending_count); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; ret = xlator_mem_acct_init(this, gf_index_mt_end); return ret; } int init(xlator_t *this) { int i = 0; int ret = -1; int64_t count = -1; index_priv_t *priv = NULL; pthread_attr_t w_attr; gf_boolean_t mutex_inited = _gf_false; gf_boolean_t cond_inited = _gf_false; gf_boolean_t attr_inited = _gf_false; char *watchlist = NULL; char *dirtylist = NULL; char *pendinglist = NULL; char *index_base_parent = NULL; char *tmp = NULL; if (!this->children || this->children->next) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, INDEX_MSG_INVALID_GRAPH, "'index' not configured with exactly one child"); goto out; } if (!this->parents) { gf_msg(this->name, GF_LOG_WARNING, EINVAL, INDEX_MSG_INVALID_GRAPH, "dangling volume. check volfile "); } priv = GF_CALLOC(1, sizeof(*priv), gf_index_mt_priv_t); if (!priv) goto out; LOCK_INIT(&priv->lock); if ((ret = pthread_cond_init(&priv->cond, NULL)) != 0) { gf_msg(this->name, GF_LOG_ERROR, ret, INDEX_MSG_INVALID_ARGS, "pthread_cond_init failed"); goto out; } cond_inited = _gf_true; if ((ret = pthread_mutex_init(&priv->mutex, NULL)) != 0) { gf_msg(this->name, GF_LOG_ERROR, ret, INDEX_MSG_INVALID_ARGS, "pthread_mutex_init failed"); goto out; } mutex_inited = _gf_true; if ((ret = pthread_attr_init(&w_attr)) != 0) { gf_msg(this->name, GF_LOG_ERROR, ret, INDEX_MSG_INVALID_ARGS, "pthread_attr_init failed"); goto out; } attr_inited = _gf_true; ret = pthread_attr_setstacksize(&w_attr, INDEX_THREAD_STACK_SIZE); if (ret == EINVAL) { gf_msg(this->name, GF_LOG_WARNING, ret, INDEX_MSG_INVALID_ARGS, "Using default thread stack size"); } GF_OPTION_INIT("index-base", priv->index_basepath, path, out); tmp = gf_strdup(priv->index_basepath); index_base_parent = dirname(tmp); if (gf_lstat_dir(index_base_parent, NULL) != 0) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, errno, INDEX_MSG_INDEX_DIR_CREATE_FAILED, "Failed to find parent dir (%s) of index basepath %s.", index_base_parent, priv->index_basepath); goto out; } GF_OPTION_INIT("xattrop64-watchlist", watchlist, str, out); ret = index_make_xattrop_watchlist(this, priv, watchlist, XATTROP); if (ret) goto out; GF_OPTION_INIT("xattrop-dirty-watchlist", dirtylist, str, out); ret = index_make_xattrop_watchlist(this, priv, dirtylist, DIRTY); if (ret) goto out; GF_OPTION_INIT("xattrop-pending-watchlist", pendinglist, str, out); ret = index_make_xattrop_watchlist(this, priv, pendinglist, XATTROP); if (ret) goto out; if (priv->dirty_watchlist) priv->complete_watchlist = dict_copy_with_ref(priv->dirty_watchlist, priv->complete_watchlist); if (priv->pending_watchlist) priv->complete_watchlist = dict_copy_with_ref(priv->pending_watchlist, priv->complete_watchlist); gf_uuid_generate(priv->index); for (i = 0; i < XATTROP_TYPE_END; i++) gf_uuid_generate(priv->internal_vgfid[i]); INIT_LIST_HEAD(&priv->callstubs); GF_ATOMIC_INIT(priv->stub_cnt, 0); this->local_pool = mem_pool_new(index_local_t, 64); if (!this->local_pool) { ret = -1; goto out; } this->private = priv; ret = index_dir_create(this, XATTROP_SUBDIR); if (ret < 0) goto out; if (priv->dirty_watchlist) { ret = index_dir_create(this, DIRTY_SUBDIR); if (ret < 0) goto out; } ret = index_dir_create(this, ENTRY_CHANGES_SUBDIR); if (ret < 0) goto out; /*init indices files counts*/ count = index_fetch_link_count(this, XATTROP); index_set_link_count(priv, count, XATTROP); priv->down = _gf_false; priv->curr_count = 0; ret = gf_thread_create(&priv->thread, &w_attr, index_worker, this, "idxwrker"); if (ret) { gf_msg(this->name, GF_LOG_WARNING, ret, INDEX_MSG_WORKER_THREAD_CREATE_FAILED, "Failed to create worker thread, aborting"); goto out; } priv->curr_count++; ret = 0; out: GF_FREE(tmp); if (ret) { if (cond_inited) pthread_cond_destroy(&priv->cond); if (mutex_inited) pthread_mutex_destroy(&priv->mutex); if (priv && priv->dirty_watchlist) dict_unref(priv->dirty_watchlist); if (priv && priv->pending_watchlist) dict_unref(priv->pending_watchlist); if (priv && priv->complete_watchlist) dict_unref(priv->complete_watchlist); if (priv) GF_FREE(priv); this->private = NULL; mem_pool_destroy(this->local_pool); this->local_pool = NULL; } if (attr_inited) pthread_attr_destroy(&w_attr); return ret; } void fini(xlator_t *this) { index_priv_t *priv = NULL; priv = this->private; if (!priv) goto out; priv->down = _gf_true; pthread_cond_broadcast(&priv->cond); if (priv->thread) { gf_thread_cleanup_xint(priv->thread); priv->thread = 0; } this->private = NULL; LOCK_DESTROY(&priv->lock); pthread_cond_destroy(&priv->cond); pthread_mutex_destroy(&priv->mutex); if (priv->dirty_watchlist) dict_unref(priv->dirty_watchlist); if (priv->pending_watchlist) dict_unref(priv->pending_watchlist); if (priv->complete_watchlist) dict_unref(priv->complete_watchlist); GF_FREE(priv); if (this->local_pool) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; } out: return; } int index_forget(xlator_t *this, inode_t *inode) { uint64_t tmp_cache = 0; if (!inode_ctx_del(inode, this, &tmp_cache)) GF_FREE((index_inode_ctx_t *)(long)tmp_cache); return 0; } int32_t index_releasedir(xlator_t *this, fd_t *fd) { index_fd_ctx_t *fctx = NULL; int ret = 0; fctx = fd_ctx_del_ptr(fd, this); if (!fctx) goto out; if (fctx->dir) { ret = sys_closedir(fctx->dir); if (ret) gf_msg(this->name, GF_LOG_ERROR, errno, INDEX_MSG_FD_OP_FAILED, "closedir error"); } GF_FREE(fctx); out: return 0; } int32_t index_release(xlator_t *this, fd_t *fd) { index_fd_ctx_t *fctx = NULL; fctx = fd_ctx_del_ptr(fd, this); if (fctx) { GF_FREE(fctx); } return 0; } int notify(xlator_t *this, int event, void *data, ...) { int ret = 0; index_priv_t *priv = NULL; uint64_t stub_cnt = 0; xlator_t *victim = data; struct timespec sleep_till = { 0, }; if (!this) return 0; priv = this->private; if (!priv) return 0; if ((event == GF_EVENT_PARENT_DOWN) && victim->cleanup_starting) { stub_cnt = GF_ATOMIC_GET(priv->stub_cnt); timespec_now_realtime(&sleep_till); sleep_till.tv_sec += 1; /* Wait for draining stub from queue before notify PARENT_DOWN */ pthread_mutex_lock(&priv->mutex); { while (stub_cnt) { (void)pthread_cond_timedwait(&priv->cond, &priv->mutex, &sleep_till); stub_cnt = GF_ATOMIC_GET(priv->stub_cnt); } } pthread_mutex_unlock(&priv->mutex); gf_log(this->name, GF_LOG_INFO, "Notify GF_EVENT_PARENT_DOWN for brick %s", victim->name); } if ((event == GF_EVENT_CHILD_DOWN) && victim->cleanup_starting) { pthread_mutex_lock(&priv->mutex); { priv->down = _gf_true; pthread_cond_broadcast(&priv->cond); while (priv->curr_count) pthread_cond_wait(&priv->cond, &priv->mutex); } pthread_mutex_unlock(&priv->mutex); gf_log(this->name, GF_LOG_INFO, "Notify GF_EVENT_CHILD_DOWN for brick %s", victim->name); } ret = default_notify(this, event, data); return ret; } struct xlator_fops fops = { .xattrop = index_xattrop, .fxattrop = index_fxattrop, // interface functions follow .getxattr = index_getxattr, .lookup = index_lookup, .opendir = index_opendir, .readdir = index_readdir, .unlink = index_unlink, .rmdir = index_rmdir, .fstat = index_fstat, }; struct xlator_dumpops dumpops = { .priv = index_priv_dump, }; struct xlator_cbks cbks = {.forget = index_forget, .release = index_release, .releasedir = index_releasedir}; struct volume_options options[] = { {.key = {"index-base"}, .type = GF_OPTION_TYPE_PATH, .description = "path where the index files need to be stored", .default_value = "{{ brick.path }}/.glusterfs/indices"}, {.key = {"xattrop64-watchlist"}, .type = GF_OPTION_TYPE_STR, .description = "Comma separated list of xattrs that are watched", .default_value = "trusted.ec.dirty"}, {.key = {"xattrop-dirty-watchlist"}, .type = GF_OPTION_TYPE_STR, .description = "Comma separated list of xattrs that are watched", .default_value = "trusted.afr.dirty"}, {.key = {"xattrop-pending-watchlist"}, .type = GF_OPTION_TYPE_STR, .description = "Comma separated list of xattrs that are watched", .default_value = "trusted.afr.{{ volume.name }}"}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "index", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/index/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023052 xustar000000000000000030 mtime=1699284276.158059031 30 atime=1699284290.720102892 30 ctime=1699284303.776142216 glusterfs-11.1/xlators/features/index/Makefile.in0000664000175100017510000005272114522202464023340 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/index DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/index/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/index/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/index/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023035 xustar000000000000000030 mtime=1699284265.668027435 30 atime=1699284276.134058959 30 ctime=1699284303.779142225 glusterfs-11.1/xlators/features/index/Makefile.am0000664000175100017510000000003414522202451023311 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/arbiter0000644000000000000000000000013214522202517021250 xustar000000000000000030 mtime=1699284303.979142827 30 atime=1699284309.688160022 30 ctime=1699284303.979142827 glusterfs-11.1/xlators/features/arbiter/0002775000175100017510000000000014522202517021606 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/arbiter/PaxHeaders.9031/src0000644000000000000000000000013014522202520022027 xustar000000000000000029 mtime=1699284304.03014298 30 atime=1699284309.688160022 29 ctime=1699284304.03014298 glusterfs-11.1/xlators/features/arbiter/src/0002775000175100017510000000000014522202520022367 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/arbiter/src/PaxHeaders.9031/arbiter-mem-types.h0000644000000000000000000000013214522202451025630 xustar000000000000000030 mtime=1699284265.649027378 30 atime=1699284265.649027378 30 ctime=1699284304.028142975 glusterfs-11.1/xlators/features/arbiter/src/arbiter-mem-types.h0000664000175100017510000000113414522202451026106 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __ARBITER_MEM_TYPES_H__ #define __ARBITER_MEM_TYPES_H__ #include typedef enum gf_arbiter_mem_types_ { gf_arbiter_mt_inode_ctx_t = gf_common_mt_end + 1, gf_arbiter_mt_end } gf_arbiter_mem_types_t; #endif glusterfs-11.1/xlators/features/arbiter/src/PaxHeaders.9031/arbiter.h0000644000000000000000000000013014522202451023710 xustar000000000000000029 mtime=1699284265.65002738 29 atime=1699284265.65002738 30 ctime=1699284304.026142968 glusterfs-11.1/xlators/features/arbiter/src/arbiter.h0000664000175100017510000000103214522202451024165 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _ARBITER_H #define _ARBITER_H #include typedef struct arbiter_inode_ctx_ { struct iatt iattbuf; } arbiter_inode_ctx_t; #endif /* _ARBITER_H */ glusterfs-11.1/xlators/features/arbiter/src/PaxHeaders.9031/arbiter.c0000644000000000000000000000013014522202451023703 xustar000000000000000029 mtime=1699284265.65002738 30 atime=1699284265.649027378 29 ctime=1699284304.03014298 glusterfs-11.1/xlators/features/arbiter/src/arbiter.c0000664000175100017510000002305014522202451024164 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "arbiter.h" #include "arbiter-mem-types.h" #include #include #include #include static arbiter_inode_ctx_t * __arbiter_inode_ctx_get(inode_t *inode, xlator_t *this) { arbiter_inode_ctx_t *ctx = NULL; int ret = 0; uint64_t ctx_addr = 0; ret = __inode_ctx_get(inode, this, &ctx_addr); if (ret == 0) { ctx = (arbiter_inode_ctx_t *)(long)ctx_addr; goto out; } ctx = GF_CALLOC(1, sizeof(*ctx), gf_arbiter_mt_inode_ctx_t); if (!ctx) goto out; ret = __inode_ctx_put(inode, this, (uint64_t)(uintptr_t)ctx); if (ret) { GF_FREE(ctx); ctx = NULL; gf_log_callingfn(this->name, GF_LOG_ERROR, "failed to " "set the inode ctx (%s)", uuid_utoa(inode->gfid)); } out: return ctx; } static arbiter_inode_ctx_t * arbiter_inode_ctx_get(inode_t *inode, xlator_t *this) { arbiter_inode_ctx_t *ctx = NULL; LOCK(&inode->lock); { ctx = __arbiter_inode_ctx_get(inode, this); } UNLOCK(&inode->lock); return ctx; } int32_t arbiter_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { arbiter_inode_ctx_t *ctx = NULL; if (op_ret != 0) goto unwind; ctx = arbiter_inode_ctx_get(inode, this); if (!ctx) { op_ret = -1; op_errno = ENOMEM; goto unwind; } memcpy(&ctx->iattbuf, buf, sizeof(ctx->iattbuf)); unwind: STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata, postparent); return 0; } int32_t arbiter_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { STACK_WIND(frame, arbiter_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); return 0; } int32_t arbiter_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { arbiter_inode_ctx_t *ctx = NULL; struct iatt *buf = NULL; int32_t op_ret = 0; int32_t op_errno = 0; ctx = arbiter_inode_ctx_get(loc->inode, this); if (!ctx) { op_ret = -1; op_errno = ENOMEM; goto unwind; } buf = &ctx->iattbuf; unwind: STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, buf, buf, NULL); return 0; } int32_t arbiter_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { arbiter_inode_ctx_t *ctx = NULL; struct iatt *buf = NULL; int32_t op_ret = 0; int32_t op_errno = 0; ctx = arbiter_inode_ctx_get(fd->inode, this); if (!ctx) { op_ret = -1; op_errno = ENOMEM; goto unwind; } buf = &ctx->iattbuf; unwind: STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, buf, buf, NULL); return 0; } dict_t * arbiter_fill_writev_xdata(fd_t *fd, dict_t *xdata, xlator_t *this) { dict_t *rsp_xdata = NULL; int32_t ret = 0; int is_append = 1; if (!fd || !fd->inode || gf_uuid_is_null(fd->inode->gfid)) { goto out; } if (!xdata) goto out; rsp_xdata = dict_new(); if (!rsp_xdata) goto out; if (dict_get(xdata, GLUSTERFS_OPEN_FD_COUNT)) { ret = dict_set_uint32(rsp_xdata, GLUSTERFS_OPEN_FD_COUNT, fd->inode->fd_count); if (ret < 0) { gf_msg_debug(this->name, 0, "Failed to set dict value" " for GLUSTERFS_OPEN_FD_COUNT"); } } if (dict_get(xdata, GLUSTERFS_WRITE_IS_APPEND)) { ret = dict_set_uint32(rsp_xdata, GLUSTERFS_WRITE_IS_APPEND, is_append); if (ret < 0) { gf_msg_debug(this->name, 0, "Failed to set dict value" " for GLUSTERFS_WRITE_IS_APPEND"); } } out: return rsp_xdata; } int32_t arbiter_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { arbiter_inode_ctx_t *ctx = NULL; struct iatt *buf = NULL; dict_t *rsp_xdata = NULL; int op_ret = 0; int op_errno = 0; ctx = arbiter_inode_ctx_get(fd->inode, this); if (!ctx) { op_ret = -1; op_errno = ENOMEM; goto unwind; } buf = &ctx->iattbuf; op_ret = iov_length(vector, count); rsp_xdata = arbiter_fill_writev_xdata(fd, xdata, this); unwind: STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, buf, buf, rsp_xdata); if (rsp_xdata) dict_unref(rsp_xdata); return 0; } int32_t arbiter_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_size, off_t offset, size_t len, dict_t *xdata) { arbiter_inode_ctx_t *ctx = NULL; struct iatt *buf = NULL; int op_ret = 0; int op_errno = 0; ctx = arbiter_inode_ctx_get(fd->inode, this); if (!ctx) { op_ret = -1; op_errno = ENOMEM; goto unwind; } buf = &ctx->iattbuf; unwind: STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, buf, buf, NULL); return 0; } int32_t arbiter_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { arbiter_inode_ctx_t *ctx = NULL; struct iatt *buf = NULL; int op_ret = 0; int op_errno = 0; ctx = arbiter_inode_ctx_get(fd->inode, this); if (!ctx) { op_ret = -1; op_errno = ENOMEM; goto unwind; } buf = &ctx->iattbuf; unwind: STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, buf, buf, NULL); return 0; } int32_t arbiter_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { arbiter_inode_ctx_t *ctx = NULL; struct iatt *buf = NULL; int op_ret = 0; int op_errno = 0; ctx = arbiter_inode_ctx_get(fd->inode, this); if (!ctx) { op_ret = -1; op_errno = ENOMEM; goto unwind; } buf = &ctx->iattbuf; unwind: STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, buf, buf, NULL); return 0; } static int32_t arbiter_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { STACK_UNWIND_STRICT(readv, frame, -1, ENOSYS, NULL, 0, NULL, NULL, NULL); return 0; } static int32_t arbiter_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, gf_seek_what_t what, dict_t *xdata) { STACK_UNWIND_STRICT(seek, frame, -1, ENOSYS, 0, xdata); return 0; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; ret = xlator_mem_acct_init(this, gf_arbiter_mt_end); if (ret) gf_log(this->name, GF_LOG_ERROR, "Memory accounting " "initialization failed."); return ret; } int reconfigure(xlator_t *this, dict_t *options) { return 0; } int arbiter_forget(xlator_t *this, inode_t *inode) { arbiter_inode_ctx_t *ctx = NULL; uint64_t ctx_addr = 0; inode_ctx_del(inode, this, &ctx_addr); if (!ctx_addr) return 0; ctx = (arbiter_inode_ctx_t *)(long)ctx_addr; GF_FREE(ctx); return 0; } int32_t init(xlator_t *this) { if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "'arbiter' not configured with exactly one child"); return -1; } if (!this->parents) gf_log(this->name, GF_LOG_ERROR, "dangling volume. check volfile "); return 0; } void fini(xlator_t *this) { return; } struct xlator_fops fops = { .lookup = arbiter_lookup, /* Return success for these inode write FOPS without winding it down to * posix; this is needed for AFR write transaction logic to work.*/ .truncate = arbiter_truncate, .writev = arbiter_writev, .ftruncate = arbiter_ftruncate, .fallocate = arbiter_fallocate, .discard = arbiter_discard, .zerofill = arbiter_zerofill, /* AFR is not expected to wind these inode read FOPS initiated by the * application to the arbiter brick. But in case a bug causes them * to be called, we return ENOSYS. */ .readv = arbiter_readv, .seek = arbiter_seek, /* The following inode read FOPS initiated by the application are not * wound by AFR either but internal logic like shd, glfsheal and * client side healing in AFR will send them for selfheal/ inode refresh * operations etc.,so we need to wind them down to posix: * * (f)stat, readdir(p), readlink, (f)getxattr.*/ /* All other FOPs not listed here are safe to be wound down to posix.*/ }; struct xlator_cbks cbks = { .forget = arbiter_forget, }; struct volume_options options[] = { {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "arbiter", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/arbiter/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013114522202463024160 xustar000000000000000030 mtime=1699284275.201056149 30 atime=1699284290.084100976 29 ctime=1699284304.02314296 glusterfs-11.1/xlators/features/arbiter/src/Makefile.in0000664000175100017510000005741314522202463024452 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/arbiter/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) arbiter_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_arbiter_la_OBJECTS = arbiter.lo arbiter_la_OBJECTS = $(am_arbiter_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = arbiter_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(arbiter_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_SERVER_TRUE@am_arbiter_la_rpath = -rpath $(xlatordir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(arbiter_la_SOURCES) DIST_SOURCES = $(arbiter_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_SERVER_TRUE@xlator_LTLIBRARIES = arbiter.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features arbiter_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) arbiter_la_SOURCES = arbiter.c arbiter_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = arbiter.h arbiter-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/arbiter/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/arbiter/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } arbiter.la: $(arbiter_la_OBJECTS) $(arbiter_la_DEPENDENCIES) $(EXTRA_arbiter_la_DEPENDENCIES) $(AM_V_CCLD)$(arbiter_la_LINK) $(am_arbiter_la_rpath) $(arbiter_la_OBJECTS) $(arbiter_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arbiter.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/arbiter/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024145 xustar000000000000000030 mtime=1699284265.649027378 30 atime=1699284275.164056037 30 ctime=1699284304.024142962 glusterfs-11.1/xlators/features/arbiter/src/Makefile.am0000664000175100017510000000076314522202451024432 0ustar00jenkinsjenkins00000000000000if WITH_SERVER xlator_LTLIBRARIES = arbiter.la endif xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features arbiter_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) arbiter_la_SOURCES = arbiter.c arbiter_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = arbiter.h arbiter-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/arbiter/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463023372 xustar000000000000000030 mtime=1699284275.154056007 30 atime=1699284290.064100916 30 ctime=1699284303.972142806 glusterfs-11.1/xlators/features/arbiter/Makefile.in0000664000175100017510000005272714522202463023666 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/arbiter DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/arbiter/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/arbiter/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/arbiter/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023356 xustar000000000000000030 mtime=1699284265.649027378 30 atime=1699284275.130055935 30 ctime=1699284303.974142812 glusterfs-11.1/xlators/features/arbiter/Makefile.am0000664000175100017510000000003414522202451023632 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/barrier0000644000000000000000000000013214522202517021246 xustar000000000000000030 mtime=1699284303.884142541 30 atime=1699284309.688160022 30 ctime=1699284303.884142541 glusterfs-11.1/xlators/features/barrier/0002775000175100017510000000000014522202517021604 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/barrier/PaxHeaders.9031/src0000644000000000000000000000013214522202517022035 xustar000000000000000030 mtime=1699284303.934142691 30 atime=1699284309.688160022 30 ctime=1699284303.934142691 glusterfs-11.1/xlators/features/barrier/src/0002775000175100017510000000000014522202517022373 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/barrier/src/PaxHeaders.9031/barrier-mem-types.h0000644000000000000000000000013014522202451025622 xustar000000000000000029 mtime=1699284265.65002738 29 atime=1699284265.65002738 30 ctime=1699284303.932142685 glusterfs-11.1/xlators/features/barrier/src/barrier-mem-types.h0000664000175100017510000000110014522202451026073 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __BARRIER_MEM_TYPES_H__ #define __BARRIER_MEM_TYPES_H__ #include enum gf_barrier_mem_types_ { gf_barrier_mt_priv_t = gf_common_mt_end + 1, gf_barrier_mt_end }; #endif glusterfs-11.1/xlators/features/barrier/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013014522202463024155 xustar000000000000000030 mtime=1699284275.283056396 29 atime=1699284290.69610282 29 ctime=1699284303.92714267 glusterfs-11.1/xlators/features/barrier/src/Makefile.in0000664000175100017510000005727214522202463024453 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/barrier/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) barrier_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_barrier_la_OBJECTS = barrier.lo barrier_la_OBJECTS = $(am_barrier_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = barrier_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(barrier_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(barrier_la_SOURCES) DIST_SOURCES = $(barrier_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = barrier.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features barrier_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) barrier_la_SOURCES = barrier.c barrier_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = barrier.h barrier-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/barrier/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/barrier/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } barrier.la: $(barrier_la_OBJECTS) $(barrier_la_DEPENDENCIES) $(EXTRA_barrier_la_DEPENDENCIES) $(AM_V_CCLD)$(barrier_la_LINK) -rpath $(xlatordir) $(barrier_la_OBJECTS) $(barrier_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/barrier.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/barrier/src/PaxHeaders.9031/barrier.c0000644000000000000000000000013014522202451023677 xustar000000000000000029 mtime=1699284265.65002738 29 atime=1699284265.65002738 30 ctime=1699284303.934142691 glusterfs-11.1/xlators/features/barrier/src/barrier.c0000664000175100017510000005330214522202451024163 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "barrier.h" #include void barrier_local_set_gfid(call_frame_t *frame, uuid_t gfid, xlator_t *this) { if (gfid) { uuid_t *id = GF_MALLOC(sizeof(uuid_t), gf_common_mt_uuid_t); if (!id) { gf_log(this->name, GF_LOG_WARNING, "Could not set gfid" ". gfid will not be dumped in statedump file."); return; } gf_uuid_copy(*id, gfid); frame->local = id; } } void barrier_local_free_gfid(call_frame_t *frame) { if (frame->local) { GF_FREE(frame->local); frame->local = NULL; } } int32_t barrier_truncate_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { barrier_local_free_gfid(frame); STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t barrier_ftruncate_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { barrier_local_free_gfid(frame); STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t barrier_unlink_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { barrier_local_free_gfid(frame); STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int32_t barrier_rmdir_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { barrier_local_free_gfid(frame); STACK_UNWIND_STRICT(rmdir, frame, op_ret, op_errno, preparent, postparent, xdata); return 0; } int32_t barrier_rename_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { barrier_local_free_gfid(frame); STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); return 0; } int32_t barrier_writev_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { barrier_local_free_gfid(frame); STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t barrier_fsync_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { barrier_local_free_gfid(frame); STACK_UNWIND_STRICT(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); return 0; } int32_t barrier_removexattr_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { barrier_local_free_gfid(frame); STACK_UNWIND_STRICT(removexattr, frame, op_ret, op_errno, xdata); return 0; } int32_t barrier_fremovexattr_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { barrier_local_free_gfid(frame); STACK_UNWIND_STRICT(fremovexattr, frame, op_ret, op_errno, xdata); return 0; } int32_t barrier_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { BARRIER_FOP_CBK(writev, out, frame, this, op_ret, op_errno, prebuf, postbuf, xdata); out: return 0; } int32_t barrier_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { BARRIER_FOP_CBK(fremovexattr, out, frame, this, op_ret, op_errno, xdata); out: return 0; } int32_t barrier_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { BARRIER_FOP_CBK(removexattr, out, frame, this, op_ret, op_errno, xdata); out: return 0; } int32_t barrier_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { BARRIER_FOP_CBK(truncate, out, frame, this, op_ret, op_errno, prebuf, postbuf, xdata); out: return 0; } int32_t barrier_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { BARRIER_FOP_CBK(ftruncate, out, frame, this, op_ret, op_errno, prebuf, postbuf, xdata); out: return 0; } int32_t barrier_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { BARRIER_FOP_CBK(rename, out, frame, this, op_ret, op_errno, buf, preoldparent, postoldparent, prenewparent, postnewparent, xdata); out: return 0; } int32_t barrier_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { BARRIER_FOP_CBK(rmdir, out, frame, this, op_ret, op_errno, preparent, postparent, xdata); out: return 0; } int32_t barrier_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { BARRIER_FOP_CBK(unlink, out, frame, this, op_ret, op_errno, preparent, postparent, xdata); out: return 0; } int32_t barrier_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { BARRIER_FOP_CBK(fsync, out, frame, this, op_ret, op_errno, prebuf, postbuf, xdata); out: return 0; } int32_t barrier_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { if (!((flags | fd->flags) & (O_SYNC | O_DSYNC))) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, iobref, xdata); return 0; } barrier_local_set_gfid(frame, fd->inode->gfid, this); STACK_WIND(frame, barrier_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, iobref, xdata); return 0; } int32_t barrier_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { barrier_local_set_gfid(frame, fd->inode->gfid, this); STACK_WIND(frame, barrier_fremovexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; } int32_t barrier_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { barrier_local_set_gfid(frame, loc->inode->gfid, this); STACK_WIND(frame, barrier_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; } int32_t barrier_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { barrier_local_set_gfid(frame, loc->inode->gfid, this); STACK_WIND(frame, barrier_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } int32_t barrier_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { barrier_local_set_gfid(frame, oldloc->inode->gfid, this); STACK_WIND(frame, barrier_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; } int barrier_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { barrier_local_set_gfid(frame, loc->inode->gfid, this); STACK_WIND(frame, barrier_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); return 0; } int32_t barrier_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { barrier_local_set_gfid(frame, loc->inode->gfid, this); STACK_WIND(frame, barrier_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; } int32_t barrier_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { barrier_local_set_gfid(frame, fd->inode->gfid, this); STACK_WIND(frame, barrier_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } int32_t barrier_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { barrier_local_set_gfid(frame, fd->inode->gfid, this); STACK_WIND(frame, barrier_fsync_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); return 0; } call_stub_t * __barrier_dequeue(xlator_t *this, struct list_head *queue) { call_stub_t *stub = NULL; barrier_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (list_empty(queue)) goto out; stub = list_entry(queue->next, call_stub_t, list); list_del_init(&stub->list); out: return stub; } void barrier_dequeue_all(xlator_t *this, struct list_head *queue) { call_stub_t *stub = NULL; gf_log(this->name, GF_LOG_INFO, "Dequeuing all the barriered fops"); /* TODO: Start the below task in a new thread */ while ((stub = __barrier_dequeue(this, queue))) call_resume(stub); gf_log(this->name, GF_LOG_INFO, "Dequeuing the barriered fops is " "finished"); return; } void barrier_timeout(void *data) { xlator_t *this = NULL; barrier_priv_t *priv = NULL; struct list_head queue = { 0, }; this = data; THIS = this; priv = this->private; INIT_LIST_HEAD(&queue); gf_log(this->name, GF_LOG_CRITICAL, "Disabling barrier because of " "the barrier timeout."); LOCK(&priv->lock); { __barrier_disable(this, &queue); } UNLOCK(&priv->lock); barrier_dequeue_all(this, &queue); return; } void __barrier_enqueue(xlator_t *this, call_stub_t *stub) { barrier_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); list_add_tail(&stub->list, &priv->queue); priv->queue_size++; return; } void __barrier_disable(xlator_t *this, struct list_head *queue) { GF_UNUSED int ret = 0; barrier_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (priv->timer) { ret = gf_timer_call_cancel(this->ctx, priv->timer); priv->timer = NULL; } list_splice_init(&priv->queue, queue); priv->queue_size = 0; priv->barrier_enabled = _gf_false; } int __barrier_enable(xlator_t *this, barrier_priv_t *priv) { int ret = -1; priv->timer = gf_timer_call_after(this->ctx, priv->timeout, barrier_timeout, (void *)this); if (!priv->timer) { gf_log(this->name, GF_LOG_CRITICAL, "Couldn't add barrier " "timeout event."); goto out; } priv->barrier_enabled = _gf_true; ret = 0; out: return ret; } int notify(xlator_t *this, int event, void *data, ...) { barrier_priv_t *priv = this->private; dict_t *dict = NULL; int ret = -1; int barrier_enabled = _gf_false; struct list_head queue = { 0, }; GF_ASSERT(priv); INIT_LIST_HEAD(&queue); switch (event) { case GF_EVENT_TRANSLATOR_OP: { dict = data; barrier_enabled = dict_get_str_boolean(dict, "barrier", -1); if (barrier_enabled == -1) { gf_log(this->name, GF_LOG_ERROR, "Could not fetch " " barrier key from the dictionary."); goto out; } LOCK(&priv->lock); { if (!priv->barrier_enabled) { if (barrier_enabled) { ret = __barrier_enable(this, priv); } else { UNLOCK(&priv->lock); gf_log(this->name, GF_LOG_ERROR, "Already disabled."); goto post_unlock; } } else { if (!barrier_enabled) { __barrier_disable(this, &queue); ret = 0; } else { UNLOCK(&priv->lock); gf_log(this->name, GF_LOG_ERROR, "Already enabled"); goto post_unlock; } } } UNLOCK(&priv->lock); post_unlock: if (!list_empty(&queue)) barrier_dequeue_all(this, &queue); break; } default: { default_notify(this, event, data); ret = 0; goto out; } } out: return ret; } int reconfigure(xlator_t *this, dict_t *options) { barrier_priv_t *priv = NULL; int ret = -1; gf_boolean_t barrier_enabled = _gf_false; time_t timeout = 0; struct list_head queue = { 0, }; priv = this->private; GF_ASSERT(priv); GF_OPTION_RECONF("barrier", barrier_enabled, options, bool, out); GF_OPTION_RECONF("barrier-timeout", timeout, options, time, out); INIT_LIST_HEAD(&queue); LOCK(&priv->lock); { if (!priv->barrier_enabled) { if (barrier_enabled) { ret = __barrier_enable(this, priv); if (ret) { goto unlock; } } } else { if (!barrier_enabled) { __barrier_disable(this, &queue); } } priv->timeout.tv_sec = timeout; ret = 0; } unlock: UNLOCK(&priv->lock); if (!list_empty(&queue)) barrier_dequeue_all(this, &queue); out: return ret; } int32_t mem_acct_init(xlator_t *this) { int ret = -1; ret = xlator_mem_acct_init(this, gf_barrier_mt_end); if (ret) gf_log(this->name, GF_LOG_ERROR, "Memory accounting " "initialization failed."); return ret; } int init(xlator_t *this) { int ret = -1; barrier_priv_t *priv = NULL; time_t timeout = 0; if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "'barrier' not configured with exactly one child"); goto out; } if (!this->parents) gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); priv = GF_CALLOC(1, sizeof(*priv), gf_barrier_mt_priv_t); if (!priv) goto out; LOCK_INIT(&priv->lock); GF_OPTION_INIT("barrier", priv->barrier_enabled, bool, out); GF_OPTION_INIT("barrier-timeout", timeout, time, out); priv->timeout.tv_sec = timeout; INIT_LIST_HEAD(&priv->queue); if (priv->barrier_enabled) { ret = __barrier_enable(this, priv); if (ret == -1) goto out; } this->private = priv; ret = 0; out: if (ret && priv) GF_FREE(priv); return ret; } void fini(xlator_t *this) { barrier_priv_t *priv = NULL; struct list_head queue = { 0, }; priv = this->private; if (!priv) goto out; INIT_LIST_HEAD(&queue); gf_log(this->name, GF_LOG_INFO, "Disabling barriering and dequeuing " "all the queued fops"); LOCK(&priv->lock); { __barrier_disable(this, &queue); } UNLOCK(&priv->lock); if (!list_empty(&queue)) barrier_dequeue_all(this, &queue); this->private = NULL; LOCK_DESTROY(&priv->lock); GF_FREE(priv); out: return; } static void barrier_dump_stub(call_stub_t *stub, char *prefix) { char key[GF_DUMP_MAX_BUF_LEN] = { 0, }; gf_proc_dump_build_key(key, prefix, "fop"); gf_proc_dump_write(key, "%s", gf_fop_list[stub->fop]); if (stub->frame->local) { gf_proc_dump_build_key(key, prefix, "gfid"); gf_proc_dump_write(key, "%s", uuid_utoa(*(uuid_t *)(stub->frame->local))); } if (stub->args.loc.path) { gf_proc_dump_build_key(key, prefix, "path"); gf_proc_dump_write(key, "%s", stub->args.loc.path); } if (stub->args.loc.name) { gf_proc_dump_build_key(key, prefix, "name"); gf_proc_dump_write(key, "%s", stub->args.loc.name); } return; } static void __barrier_dump_queue(barrier_priv_t *priv) { call_stub_t *stub = NULL; char key[GF_DUMP_MAX_BUF_LEN] = { 0, }; int i = 0; GF_VALIDATE_OR_GOTO("barrier", priv, out); list_for_each_entry(stub, &priv->queue, list) { snprintf(key, sizeof(key), "stub.%d", i++); gf_proc_dump_add_section("%s", key); barrier_dump_stub(stub, key); } out: return; } int barrier_dump_priv(xlator_t *this) { int ret = -1; char key[GF_DUMP_MAX_BUF_LEN] = { 0, }; barrier_priv_t *priv = NULL; GF_VALIDATE_OR_GOTO("barrier", this, out); priv = this->private; if (!priv) return 0; gf_proc_dump_build_key(key, "xlator.features.barrier", "priv"); gf_proc_dump_add_section("%s", key); gf_proc_dump_build_key(key, "barrier", "enabled"); LOCK(&priv->lock); { gf_proc_dump_write(key, "%d", priv->barrier_enabled); gf_proc_dump_build_key(key, "barrier", "timeout"); gf_proc_dump_write(key, "%ld", priv->timeout.tv_sec); if (priv->barrier_enabled) { gf_proc_dump_build_key(key, "barrier", "queue_size"); gf_proc_dump_write(key, "%d", priv->queue_size); __barrier_dump_queue(priv); } } UNLOCK(&priv->lock); out: return ret; } struct xlator_fops fops = { /* Barrier Class fops */ .rmdir = barrier_rmdir, .unlink = barrier_unlink, .rename = barrier_rename, .removexattr = barrier_removexattr, .fremovexattr = barrier_fremovexattr, .truncate = barrier_truncate, .ftruncate = barrier_ftruncate, .fsync = barrier_fsync, /* Writes with only O_SYNC flag */ .writev = barrier_writev, }; struct xlator_dumpops dumpops = { .priv = barrier_dump_priv, }; struct xlator_cbks cbks; struct volume_options options[] = { {.key = {"barrier"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "disable", .op_version = {GD_OP_VERSION_3_6_0}, .flags = OPT_FLAG_SETTABLE, .description = "When \"enabled\", blocks acknowledgements to application " "for file operations such as rmdir, rename, unlink, " "removexattr, fremovexattr, truncate, ftruncate, " "write (with O_SYNC), fsync. It is turned \"off\" by " "default."}, {.key = {"barrier-timeout"}, .type = GF_OPTION_TYPE_TIME, .default_value = TOSTRING(BARRIER_TIMEOUT), .op_version = {GD_OP_VERSION_3_6_0}, .flags = OPT_FLAG_SETTABLE, .description = "After 'timeout' seconds since the time 'barrier' " "option was set to \"on\", acknowledgements to file " "operations are no longer blocked and previously " "blocked acknowledgements are sent to the application"}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "barrier", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/barrier/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451024142 xustar000000000000000029 mtime=1699284265.65002738 30 atime=1699284275.247056287 30 ctime=1699284303.928142673 glusterfs-11.1/xlators/features/barrier/src/Makefile.am0000664000175100017510000000073614522202451024430 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = barrier.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features barrier_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) barrier_la_SOURCES = barrier.c barrier_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = barrier.h barrier-mem-types.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/barrier/src/PaxHeaders.9031/barrier.h0000644000000000000000000000013214522202451023706 xustar000000000000000030 mtime=1699284265.651027384 30 atime=1699284265.651027384 30 ctime=1699284303.930142679 glusterfs-11.1/xlators/features/barrier/src/barrier.h0000664000175100017510000001114314522202451024165 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __BARRIER_H__ #define __BARRIER_H__ #include "barrier-mem-types.h" #define BARRIER_FOP_CBK(fop_name, label, frame, this, params...) \ do { \ barrier_priv_t *_priv = NULL; \ call_stub_t *_stub = NULL; \ gf_boolean_t _barrier_enabled = _gf_false; \ struct list_head queue = { \ 0, \ }; \ \ INIT_LIST_HEAD(&queue); \ \ _priv = this->private; \ GF_ASSERT(_priv); \ \ LOCK(&_priv->lock); \ { \ if (_priv->barrier_enabled) { \ _barrier_enabled = _priv->barrier_enabled; \ \ _stub = fop_##fop_name##_cbk_stub( \ frame, barrier_##fop_name##_cbk_resume, params); \ if (!_stub) { \ __barrier_disable(this, &queue); \ goto unlock; \ } \ \ __barrier_enqueue(this, _stub); \ } \ } \ unlock: \ UNLOCK(&_priv->lock); \ \ if (_stub) \ goto label; \ \ if (_barrier_enabled && !_stub) { \ gf_log(this->name, GF_LOG_CRITICAL, \ "Failed to barrier FOPs, disabling " \ "barrier. FOP: %s, ERROR: %s", \ #fop_name, strerror(ENOMEM)); \ barrier_dequeue_all(this, &queue); \ } \ barrier_local_free_gfid(frame); \ STACK_UNWIND_STRICT(fop_name, frame, params); \ goto label; \ } while (0) typedef struct { gf_timer_t *timer; gf_lock_t lock; struct list_head queue; struct timespec timeout; uint32_t queue_size; gf_boolean_t barrier_enabled; char _pad[3]; /* manual padding */ } barrier_priv_t; int __barrier_enable(xlator_t *this, barrier_priv_t *priv); void __barrier_enqueue(xlator_t *this, call_stub_t *stub); void __barrier_disable(xlator_t *this, struct list_head *queue); void barrier_timeout(void *data); void barrier_dequeue_all(xlator_t *this, struct list_head *queue); call_stub_t * __barrier_dequeue(xlator_t *this, struct list_head *queue); #endif glusterfs-11.1/xlators/features/barrier/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202463023370 xustar000000000000000030 mtime=1699284275.236056254 30 atime=1699284290.676102759 30 ctime=1699284303.878142523 glusterfs-11.1/xlators/features/barrier/Makefile.in0000664000175100017510000005272714522202463023664 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/barrier DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/barrier/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/barrier/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/barrier/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451023353 xustar000000000000000029 mtime=1699284265.65002738 30 atime=1699284275.212056182 30 ctime=1699284303.880142529 glusterfs-11.1/xlators/features/barrier/Makefile.am0000664000175100017510000000003414522202451023630 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/features/PaxHeaders.9031/snapview-client0000644000000000000000000000013214522202520022722 xustar000000000000000030 mtime=1699284304.594144679 30 atime=1699284309.688160022 30 ctime=1699284304.594144679 glusterfs-11.1/xlators/features/snapview-client/0002775000175100017510000000000014522202520023260 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/snapview-client/PaxHeaders.9031/src0000644000000000000000000000013214522202520023511 xustar000000000000000030 mtime=1699284304.639144815 30 atime=1699284309.688160022 30 ctime=1699284304.639144815 glusterfs-11.1/xlators/features/snapview-client/src/0002775000175100017510000000000014522202520024047 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/snapview-client/src/PaxHeaders.9031/snapview-client-mem-types.h0000644000000000000000000000013214522202451030770 xustar000000000000000030 mtime=1699284265.692027507 30 atime=1699284265.692027507 30 ctime=1699284304.636144806 glusterfs-11.1/xlators/features/snapview-client/src/snapview-client-mem-types.h0000664000175100017510000000110214522202451031241 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _SVC_MEM_TYPES_H #define _SVC_MEM_TYPES_H #include enum svc_mem_types { gf_svc_mt_svc_private_t = gf_common_mt_end + 1, gf_svc_mt_svc_fd_t, gf_svc_mt_end }; #endif glusterfs-11.1/xlators/features/snapview-client/src/PaxHeaders.9031/snapview-client.c0000644000000000000000000000013114522202451027044 xustar000000000000000029 mtime=1699284265.69302751 30 atime=1699284265.692027507 30 ctime=1699284304.639144815 glusterfs-11.1/xlators/features/snapview-client/src/snapview-client.c0000664000175100017510000023614614522202451027340 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "snapview-client.h" #include static void svc_local_free(svc_local_t *local) { if (local) { loc_wipe(&local->loc); if (local->fd) fd_unref(local->fd); if (local->xdata) dict_unref(local->xdata); mem_put(local); } } static xlator_t * svc_get_subvolume(xlator_t *this, int inode_type) { xlator_t *subvolume = NULL; GF_VALIDATE_OR_GOTO("snapview-client", this, out); if (inode_type == VIRTUAL_INODE) subvolume = SECOND_CHILD(this); else subvolume = FIRST_CHILD(this); out: return subvolume; } static int32_t __svc_inode_ctx_set(xlator_t *this, inode_t *inode, int inode_type) { uint64_t value = 0; int32_t ret = -1; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); value = inode_type; ret = __inode_ctx_set(inode, this, &value); out: return ret; } static int __svc_inode_ctx_get(xlator_t *this, inode_t *inode, int *inode_type) { uint64_t value = 0; int ret = -1; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); ret = __inode_ctx_get(inode, this, &value); if (ret < 0) goto out; *inode_type = (int)(value); out: return ret; } static int svc_inode_ctx_get(xlator_t *this, inode_t *inode, int *inode_type) { int ret = -1; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { ret = __svc_inode_ctx_get(this, inode, inode_type); } UNLOCK(&inode->lock); out: return ret; } static int32_t svc_inode_ctx_set(xlator_t *this, inode_t *inode, int inode_type) { int32_t ret = -1; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { ret = __svc_inode_ctx_set(this, inode, inode_type); } UNLOCK(&inode->lock); out: return ret; } static svc_fd_t * svc_fd_new(void) { svc_fd_t *svc_fd = NULL; svc_fd = GF_CALLOC(1, sizeof(*svc_fd), gf_svc_mt_svc_fd_t); return svc_fd; } static svc_fd_t * __svc_fd_ctx_get(xlator_t *this, fd_t *fd) { svc_fd_t *svc_fd = NULL; svc_fd = __fd_ctx_get_ptr(fd, this); if (!svc_fd) { GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); } out: return svc_fd; } static svc_fd_t * svc_fd_ctx_get(xlator_t *this, fd_t *fd) { svc_fd_t *svc_fd = NULL; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); LOCK(&fd->lock); { svc_fd = __svc_fd_ctx_get(this, fd); } UNLOCK(&fd->lock); out: return svc_fd; } static int __svc_fd_ctx_set(xlator_t *this, fd_t *fd, svc_fd_t *svc_fd) { uint64_t value = 0; int ret = -1; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, svc_fd, out); value = (uint64_t)(long)svc_fd; ret = __fd_ctx_set(fd, this, value); out: return ret; } static svc_fd_t * __svc_fd_ctx_get_or_new(xlator_t *this, fd_t *fd) { svc_fd_t *svc_fd = NULL; int ret = -1; inode_t *inode = NULL; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); inode = fd->inode; svc_fd = __svc_fd_ctx_get(this, fd); if (svc_fd) { ret = 0; goto out; } svc_fd = svc_fd_new(); if (!svc_fd) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, SVC_MSG_ALLOC_FD_FAILED, "gfid=%s", uuid_utoa(inode->gfid), NULL); goto out; } ret = __svc_fd_ctx_set(this, fd, svc_fd); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_SET_FD_CONTEXT_FAILED, "gfid=%s", uuid_utoa(inode->gfid), NULL); ret = -1; } out: if (ret) { GF_FREE(svc_fd); svc_fd = NULL; } return svc_fd; } static svc_fd_t * svc_fd_ctx_get_or_new(xlator_t *this, fd_t *fd) { svc_fd_t *svc_fd = NULL; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); LOCK(&fd->lock); { svc_fd = __svc_fd_ctx_get_or_new(this, fd); } UNLOCK(&fd->lock); out: return svc_fd; } /** * @this: xlator * @entry_point: pointer to the buffer provided by consumer * * This function is mainly for copying the entry point name * (stored as string in priv->path) to a buffer point to by * @entry_point within the lock. It is for the consumer to * allocate the memory for the buffer. * * This function is called by all the functions (or fops) * who need to use priv->path for avoiding the race. * For example, either in lookup or in any other fop, * while priv->path is being accessed, a reconfigure can * happen to change priv->path. This ensures that, a lock * is taken before accessing priv->path. **/ static int gf_svc_get_entry_point(xlator_t *this, char *entry_point, size_t dest_size) { int ret = -1; svc_private_t *priv = NULL; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, entry_point, out); priv = this->private; LOCK(&priv->lock); { if (dest_size <= strlen(priv->path)) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_STR_LEN, "dest-size=%zu", dest_size, "priv-path-len=%zu", strlen(priv->path), "path=%s", priv->path, NULL); } else { snprintf(entry_point, dest_size, "%s", priv->path); ret = 0; } } UNLOCK(&priv->lock); out: return ret; } static int32_t gf_svc_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { svc_local_t *local = NULL; xlator_t *subvolume = NULL; gf_boolean_t do_unwind = _gf_true; int inode_type = -1; int ret = -1; local = frame->local; subvolume = local->subvolume; if (!subvolume) { gf_msg_callingfn(this->name, GF_LOG_ERROR, 0, SVC_MSG_SUBVOLUME_NULL, "path: %s gfid: %s ", local->loc.path, inode ? uuid_utoa(inode->gfid) : ""); GF_ASSERT(0); } /* There is a possibility that, the client process just came online and does not have the inode on which the lookup came. In that case, the fresh inode created from fuse for the lookup fop, won't have the inode context set without which svc cannot decide where to STACK_WIND to. So by default it decides to send the fop to the regular subvolume (i.e first child of the xlator). If lookup fails on the regular volume, then there is a possibility that the lookup is happening on a virtual inode (i.e history data residing in snaps). So if lookup fails with ENOENT and the inode context is not there, then send the lookup to the 2nd child of svc. If there are any changes in volfile/client-restarted then inode-ctx is lost. In this case if nameless lookup fails with ESTALE, then send the lookup to the 2nd child of svc. */ if (op_ret) { if (subvolume == FIRST_CHILD(this)) { gf_smsg(this->name, (op_errno == ENOENT || op_errno == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, op_errno, SVC_MSG_NORMAL_GRAPH_LOOKUP_FAIL, "error=%s", strerror(op_errno), NULL); } else { gf_smsg(this->name, (op_errno == ENOENT || op_errno == ESTALE) ? GF_LOG_DEBUG : GF_LOG_ERROR, op_errno, SVC_MSG_SNAPVIEW_GRAPH_LOOKUP_FAIL, "error=%s", strerror(op_errno), NULL); goto out; } if ((op_errno == ENOENT || op_errno == ESTALE) && !gf_uuid_is_null(local->loc.gfid)) { if (inode != NULL) ret = svc_inode_ctx_get(this, inode, &inode_type); if (ret < 0 || inode == NULL) { gf_msg_debug(this->name, 0, "Lookup on normal graph failed. " " Sending lookup to snapview-server"); subvolume = SECOND_CHILD(this); local->subvolume = subvolume; STACK_WIND(frame, gf_svc_lookup_cbk, subvolume, subvolume->fops->lookup, &local->loc, xdata); do_unwind = _gf_false; } } goto out; } if (subvolume == FIRST_CHILD(this)) inode_type = NORMAL_INODE; else inode_type = VIRTUAL_INODE; ret = svc_inode_ctx_set(this, inode, inode_type); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_SET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(inode->gfid), NULL); out: if (do_unwind) { SVC_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, buf, xdata, postparent); } return 0; } static int32_t gf_svc_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int32_t ret = -1; svc_local_t *local = NULL; xlator_t *subvolume = NULL; int op_ret = -1; int op_errno = EINVAL; inode_t *parent = NULL; dict_t *new_xdata = NULL; int inode_type = -1; int parent_type = -1; gf_boolean_t wind = _gf_false; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = svc_inode_ctx_get(this, loc->inode, &inode_type); if (!__is_root_gfid(loc->gfid)) { if (loc->parent) { parent = inode_ref(loc->parent); ret = svc_inode_ctx_get(this, loc->parent, &parent_type); } else { parent = inode_parent(loc->inode, loc->pargfid, NULL); if (parent) ret = svc_inode_ctx_get(this, parent, &parent_type); } } local = mem_get0(this->local_pool); if (!local) { op_ret = -1; op_errno = ENOMEM; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_NO_MEMORY, NULL); goto out; } frame->local = local; loc_copy(&local->loc, loc); if (__is_root_gfid(loc->inode->gfid)) { subvolume = FIRST_CHILD(this); GF_ASSERT(subvolume); local->subvolume = subvolume; wind = _gf_true; goto out; } /* nfs sends nameless lookups directly using the gfid. In that case loc->name will be NULL. So check if loc->name is NULL. If so, then try to get the subvolume using inode context. But if the inode has not been looked up yet, then send the lookup call to the first subvolume. */ if (!loc->name) { if (gf_uuid_is_null(loc->inode->gfid)) { subvolume = FIRST_CHILD(this); local->subvolume = subvolume; wind = _gf_true; goto out; } else { if (inode_type >= 0) subvolume = svc_get_subvolume(this, inode_type); else subvolume = FIRST_CHILD(this); local->subvolume = subvolume; wind = _gf_true; goto out; } } if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } if (strcmp(loc->name, entry_point)) { if (parent_type == VIRTUAL_INODE) { subvolume = SECOND_CHILD(this); } else { /* * Either parent type is normal graph, or the parent * type is uncertain. */ subvolume = FIRST_CHILD(this); } local->subvolume = subvolume; } else { subvolume = SECOND_CHILD(this); local->subvolume = subvolume; if (parent_type == NORMAL_INODE) { /* Indication of whether the lookup is happening on the entry point or not, to the snapview-server. */ SVC_ENTRY_POINT_SET(this, xdata, op_ret, op_errno, new_xdata, ret, out); } } wind = _gf_true; out: if (wind) STACK_WIND(frame, gf_svc_lookup_cbk, subvolume, subvolume->fops->lookup, loc, xdata); else SVC_STACK_UNWIND(lookup, frame, op_ret, op_errno, NULL, NULL, NULL, NULL); if (new_xdata) dict_unref(new_xdata); if (parent) inode_unref(parent); return 0; } static int32_t gf_svc_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { xlator_t *subvolume = NULL; int32_t ret = -1; int inode_type = -1; int32_t op_ret = -1; int32_t op_errno = EINVAL; gf_boolean_t wind = _gf_false; svc_private_t *priv = NULL; const char *path = NULL; int path_len = -1; int snap_len = -1; loc_t root_loc = { 0, }; loc_t *temp_loc = NULL; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); priv = this->private; SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, loc->inode, subvolume, out); path_len = strlen(loc->path); snap_len = strlen(priv->path); temp_loc = loc; if (path_len >= snap_len && inode_type == VIRTUAL_INODE) { path = &loc->path[path_len - snap_len]; if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } if (!strcmp(path, entry_point)) { /* * statfs call for virtual snap directory. * Sent the fops to parent volume by removing * virtual directory from path */ subvolume = FIRST_CHILD(this); root_loc.path = gf_strdup("/"); gf_uuid_clear(root_loc.gfid); root_loc.gfid[15] = 1; root_loc.inode = inode_ref(loc->inode->table->root); temp_loc = &root_loc; } } STACK_WIND_TAIL(frame, subvolume, subvolume->fops->statfs, temp_loc, xdata); if (temp_loc == &root_loc) loc_wipe(temp_loc); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(statfs, frame, op_ret, op_errno, NULL, NULL); return 0; } static int32_t gf_svc_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { /* TODO: FIX ME * Consider a testcase: * #mount -t nfs host1:/vol1 /mnt * #ls /mnt * #ls /mnt/.snaps (As expected this fails) * #gluster volume set vol1 features.uss enable * Now `ls /mnt/.snaps` should work, but fails with No such file or * directory. This is because NFS client (gNFS) caches the list of files * in a directory. This cache is updated if there are any changes in the * directory attributes. So, one way to solve this problem is to change * 'ctime' attribute when USS is enabled as below. * * if (op_ret == 0 && IA_ISDIR(buf->ia_type)) * buf->ia_ctime_nsec++; * * But this is not the ideal solution as applications see the unexpected * ctime change causing failures. */ SVC_STACK_UNWIND(stat, frame, op_ret, op_errno, buf, xdata); return 0; } /* should all the fops be handled like lookup is supposed to be handled? i.e just based on inode type decide where the call should be sent and in the call back update the contexts. */ static int32_t gf_svc_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int32_t ret = -1; int inode_type = -1; xlator_t *subvolume = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, loc->inode, subvolume, out); STACK_WIND(frame, gf_svc_stat_cbk, subvolume, subvolume->fops->stat, loc, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(stat, frame, op_ret, op_errno, NULL, NULL); return 0; } static int32_t gf_svc_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int32_t ret = -1; int inode_type = -1; xlator_t *subvolume = NULL; int32_t op_ret = -1; int32_t op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, fd->inode, subvolume, out); STACK_WIND_TAIL(frame, subvolume, subvolume->fops->fstat, fd, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(fstat, frame, op_ret, op_errno, NULL, NULL); return ret; } static int32_t gf_svc_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { svc_fd_t *svc_fd = NULL; svc_local_t *local = NULL; svc_private_t *priv = NULL; gf_boolean_t special_dir = _gf_false; char path[PATH_MAX] = { 0, }; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); if (op_ret) goto out; priv = this->private; local = frame->local; if (local->subvolume == FIRST_CHILD(this) && priv->special_dir && strcmp(priv->special_dir, "")) { if (!__is_root_gfid(fd->inode->gfid)) snprintf(path, sizeof(path), "%s/.", priv->special_dir); else snprintf(path, sizeof(path), "/."); if (!strcmp(local->loc.path, priv->special_dir) || !strcmp(local->loc.path, path)) { gf_msg_debug(this->name, 0, "got opendir on special directory" " %s (gfid: %s)", path, uuid_utoa(fd->inode->gfid)); special_dir = _gf_true; } } if (special_dir) { svc_fd = svc_fd_ctx_get_or_new(this, fd); if (!svc_fd) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_GET_FD_CONTEXT_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } svc_fd->last_offset = -1; svc_fd->special_dir = special_dir; } out: STACK_UNWIND_STRICT(opendir, frame, op_ret, op_errno, fd, xdata); return 0; } /* If the inode represents a directory which is actually present in a snapshot, then opendir on that directory should be sent to the snap-view-server which opens the directory in the corresponding graph. In fact any opendir call on a virtual directory should be sent to svs. Because if it fakes success here, then later when readdir on that fd comes, there will not be any corresponding fd opened on svs and svc has to do things that open-behind is doing. */ static int32_t gf_svc_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { int32_t ret = -1; int inode_type = -1; xlator_t *subvolume = NULL; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; svc_local_t *local = NULL; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_NO_MEMORY, "path=%s", loc->path, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } loc_copy(&local->loc, loc); frame->local = local; SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, loc->inode, subvolume, out); local->subvolume = subvolume; STACK_WIND(frame, gf_svc_opendir_cbk, subvolume, subvolume->fops->opendir, loc, fd, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(opendir, frame, op_ret, op_errno, NULL, NULL); return 0; } static int32_t gf_svc_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int32_t ret = -1; int inode_type = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = svc_inode_ctx_get(this, loc->inode, &inode_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "path=%s", loc->path, "gfid= %s", uuid_utoa(loc->inode->gfid), NULL); goto out; } if (inode_type == NORMAL_INODE) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(setattr, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } /* XXX: This function is currently not used. Remove "#if 0" when required */ #if 0 static int32_t gf_svc_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { int32_t ret = -1; int inode_type = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO ("svc", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); GF_VALIDATE_OR_GOTO (this->name, fd, out); GF_VALIDATE_OR_GOTO (this->name, fd->inode, out); ret = svc_inode_ctx_get (this, fd->inode, &inode_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_msg (this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "failed to " "get the inode context for %s", uuid_utoa (fd->inode->gfid)); goto out; } if (inode_type == NORMAL_INODE) { STACK_WIND_TAIL (frame, FIRST_CHILD (this), FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } #endif /* gf_svc_fsetattr() is not used */ static int32_t gf_svc_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int32_t ret = -1; int inode_type = -1; xlator_t *subvolume = NULL; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; svc_private_t *priv = NULL; char attrname[PATH_MAX] = ""; char attrval[64] = ""; dict_t *dict = NULL; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); /* * Samba sends this special key for case insensitive * filename check. This request comes with a parent * path and with a special key GF_XATTR_GET_REAL_FILENAME_KEY. * e.g. "glusterfs.get_real_filename:.snaps". * If the name variable matches this key then we have * to send back .snaps as the real filename. */ if (!name) goto stack_wind; sscanf(name, "%[^:]:%[^@]", attrname, attrval); strcat(attrname, ":"); if (!strcmp(attrname, GF_XATTR_GET_REAL_FILENAME_KEY)) { if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } if (!strcasecmp(attrval, entry_point)) { dict = dict_new(); if (NULL == dict) { op_errno = ENOMEM; goto out; } ret = dict_set_dynstr_with_alloc(dict, (char *)name, entry_point); if (ret) { op_errno = ENOMEM; goto out; } op_errno = 0; op_ret = strlen(entry_point) + 1; /* We should return from here */ goto out; } } stack_wind: SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, loc->inode, subvolume, out); STACK_WIND_TAIL(frame, subvolume, subvolume->fops->getxattr, loc, name, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, NULL); if (dict) dict_unref(dict); return 0; } /* XXX: This function is currently not used. Mark it '#if 0' when required */ #if 0 static int32_t gf_svc_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { int32_t ret = -1; int inode_type = -1; xlator_t *subvolume = NULL; gf_boolean_t wind = _gf_false; int op_ret = -1; int op_errno = EINVAL; GF_VALIDATE_OR_GOTO ("svc", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); GF_VALIDATE_OR_GOTO (this->name, fd, out); GF_VALIDATE_OR_GOTO (this->name, fd->inode, out); SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret, fd->inode, subvolume, out); STACK_WIND_TAIL (frame, subvolume, subvolume->fops->fgetxattr, fd, name, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, NULL, NULL); return 0; } #endif /* gf_svc_fgetxattr() is not used */ static int32_t gf_svc_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { int32_t ret = -1; int inode_type = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = svc_inode_ctx_get(this, loc->inode, &inode_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "name=%s", loc->name, "gfid=%s", uuid_utoa(loc->inode->gfid), NULL); goto out; } if (inode_type == NORMAL_INODE) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(setxattr, frame, op_ret, op_errno, NULL); return 0; } static int32_t gf_svc_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { int32_t ret = -1; int inode_type = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); ret = svc_inode_ctx_get(this, fd->inode, &inode_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } if (inode_type == NORMAL_INODE) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, NULL); return 0; } static int32_t gf_svc_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { int inode_type = -1; int ret = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = svc_inode_ctx_get(this, loc->inode, &inode_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "name=%s", loc->name, "gfid=%s", uuid_utoa(loc->inode->gfid), NULL); goto out; } if (inode_type == NORMAL_INODE) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(rmdir, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } static int32_t gf_svc_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int inode_type = -1; int ret = -1; if (op_ret < 0) goto out; inode_type = NORMAL_INODE; ret = svc_inode_ctx_set(this, inode, inode_type); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_SET_INODE_CONTEXT_FAILED, NULL); out: SVC_STACK_UNWIND(mkdir, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } static int32_t gf_svc_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { int parent_type = -1; int ret = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = svc_inode_ctx_get(this, loc->parent, &parent_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(loc->parent->gfid), NULL); goto out; } if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } if (strcmp(loc->name, entry_point) && parent_type == NORMAL_INODE) { STACK_WIND(frame, gf_svc_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(mkdir, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t gf_svc_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int inode_type = -1; int ret = -1; if (op_ret < 0) goto out; inode_type = NORMAL_INODE; ret = svc_inode_ctx_set(this, inode, inode_type); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_SET_INODE_CONTEXT_FAILED, NULL); out: SVC_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } static int32_t gf_svc_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { int parent_type = -1; int ret = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = svc_inode_ctx_get(this, loc->parent, &parent_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(loc->parent->gfid), NULL); goto out; } if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } if (strcmp(loc->name, entry_point) && parent_type == NORMAL_INODE) { STACK_WIND(frame, gf_svc_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(mknod, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } /* If the flags of the open call contain O_WRONLY or O_RDWR and the inode is a virtual inode, then unwind the call back with EROFS. Otherwise simply STACK_WIND the call to the first child of svc xlator. */ static int32_t gf_svc_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { xlator_t *subvolume = NULL; int inode_type = -1; int op_ret = -1; int op_errno = EINVAL; int ret = -1; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); /* Another way is to STACK_WIND to normal subvolume, if inode type is not there in the context. If the file actually resides in snapshots, then ENOENT would be returned. Needs more analysis. */ SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, loc->inode, subvolume, out); if (((flags & O_ACCMODE) == O_WRONLY) || ((flags & O_ACCMODE) == O_RDWR)) { if (subvolume != FIRST_CHILD(this)) { op_ret = -1; op_errno = EINVAL; goto out; } } STACK_WIND_TAIL(frame, subvolume, subvolume->fops->open, loc, flags, fd, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(open, frame, op_ret, op_errno, NULL, NULL); return 0; } static int32_t gf_svc_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int inode_type = -1; int ret = -1; if (op_ret < 0) goto out; inode_type = NORMAL_INODE; ret = svc_inode_ctx_set(this, inode, inode_type); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_SET_INODE_CONTEXT_FAILED, NULL); out: SVC_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, stbuf, preparent, postparent, xdata); return 0; } static int32_t gf_svc_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { int parent_type = -1; int ret = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); ret = svc_inode_ctx_get(this, loc->parent, &parent_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(loc->parent->gfid), NULL); goto out; } if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } if (strcmp(loc->name, entry_point) && parent_type == NORMAL_INODE) { STACK_WIND(frame, gf_svc_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(create, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t gf_svc_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int inode_type = -1; int ret = -1; if (op_ret < 0) goto out; inode_type = NORMAL_INODE; ret = svc_inode_ctx_set(this, inode, inode_type); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_SET_INODE_CONTEXT_FAILED, NULL); out: SVC_STACK_UNWIND(symlink, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata); return 0; } static int32_t gf_svc_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { int parent_type = -1; int op_ret = -1; int op_errno = EINVAL; int ret = -1; gf_boolean_t wind = _gf_false; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = svc_inode_ctx_get(this, loc->parent, &parent_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(loc->parent->gfid), NULL); goto out; } if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } if (strcmp(loc->name, entry_point) && parent_type == NORMAL_INODE) { STACK_WIND(frame, gf_svc_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(symlink, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t gf_svc_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { int inode_type = -1; int op_ret = -1; int op_errno = EINVAL; int ret = -1; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = svc_inode_ctx_get(this, loc->inode, &inode_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(loc->parent->gfid), NULL); goto out; } if (inode_type == NORMAL_INODE) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, flags, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(unlink, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } static int32_t gf_svc_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata) { int inode_type = -1; xlator_t *subvolume = NULL; int ret = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, fd->inode, subvolume, out); STACK_WIND_TAIL(frame, subvolume, subvolume->fops->readv, fd, size, offset, flags, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(readv, frame, op_ret, op_errno, NULL, 0, NULL, NULL, NULL); return 0; } static int32_t gf_svc_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata) { int inode_type = -1; xlator_t *subvolume = NULL; int ret = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, loc->inode, subvolume, out); STACK_WIND_TAIL(frame, subvolume, subvolume->fops->readlink, loc, size, xdata); wind = _gf_true; out: if (!wind) STACK_UNWIND_STRICT(readlink, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } static int32_t gf_svc_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata) { int ret = -1; int inode_type = -1; xlator_t *subvolume = NULL; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, loc->inode, subvolume, out); STACK_WIND_TAIL(frame, subvolume, subvolume->fops->access, loc, mask, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(access, frame, op_ret, op_errno, NULL); return 0; } static int32_t gf_svc_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { gf_dirent_t *entry = NULL; gf_dirent_t *tmpentry = NULL; svc_local_t *local = NULL; char entry_point[NAME_MAX + 1] = { 0, }; if (op_ret < 0) goto out; local = frame->local; /* If .snaps pre-exists, then it should not be listed * in the NORMAL INODE directory when USS is enabled, * so filter the .snaps entry if exists. * However it is OK to list .snaps in VIRTUAL world */ if (local->subvolume != FIRST_CHILD(this)) goto out; /* * Better to goto out if getting the entry point * fails. We might end up sending the directory * entry for the snapview entry point in the readdir * response. But, the intention is to avoid the race * condition where priv->path is being changed in * reconfigure while this is accessing it. */ if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, op_errno, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } list_for_each_entry_safe(entry, tmpentry, &entries->list, list) { if (strcmp(entry_point, entry->d_name) == 0) gf_dirent_entry_free(entry); } out: SVC_STACK_UNWIND(readdir, frame, op_ret, op_errno, entries, xdata); return 0; } static int32_t gf_svc_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { int inode_type = -1; xlator_t *subvolume = NULL; svc_local_t *local = NULL; int ret = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; svc_fd_t *svc_fd = NULL; gf_dirent_t entries; INIT_LIST_HEAD(&entries); GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); svc_fd = svc_fd_ctx_get_or_new(this, fd); if (!svc_fd) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_GET_FD_CONTEXT_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); else { if (svc_fd->entry_point_handled && off == svc_fd->last_offset) { op_ret = 0; op_errno = ENOENT; goto out; } } SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, fd->inode, subvolume, out); local = mem_get0(this->local_pool); if (!local) { gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_NO_MEMORY, "inode-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } local->subvolume = subvolume; frame->local = local; STACK_WIND(frame, gf_svc_readdir_cbk, subvolume, subvolume->fops->readdir, fd, size, off, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(readdir, frame, op_ret, op_errno, &entries, NULL); gf_dirent_free(&entries); return 0; } /* * This lookup if mainly for supporting USS for windows. * Since the dentry for the entry-point directory is not sent in * the readdir response, from windows explorer, there is no way * to access the snapshots. If the explicit path of the entry-point * directory is mentioned in the address bar, then windows sends * readdir on the parent directory and compares if the entry point * directory's name is there in readdir response. If it is not there * then access to snapshot world is denied. And windows users cannot * access snapshots via samba. * So, to handle this a new option called special-directory is created, * which if set, snapview-client will send the entry-point's dentry * in readdirp o/p for the special directory, so that it will be * visible from windows explorer. * But to send that virtual entry, the following mechanism is used. * 1) Check if readdir from posix is over. * 2) If so, then send a lookup on entry point directory to snap daemon * (this is needed because in readdirp inodes are linked, so we need to * maintain 1:1 mapping between inodes (gfids) from snapview server to * snapview client). * 3) Once successful lookup response received, send a new entry to * windows. */ static int32_t gf_svc_readdirp_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *postparent) { gf_dirent_t entries; gf_dirent_t *entry = NULL; svc_fd_t *svc_fd = NULL; svc_local_t *local = NULL; int inode_type = -1; int ret = -1; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("snapview-client", this, out); INIT_LIST_HEAD(&entries.list); local = frame->local; if (op_ret) { if (op_errno == ESTALE && !local->revalidate) { local->revalidate = 1; ret = gf_svc_special_dir_revalidate_lookup(frame, this, xdata); if (!ret) return 0; } op_ret = 0; op_errno = ENOENT; goto out; } svc_fd = svc_fd_ctx_get(this, local->fd); if (!svc_fd) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_GET_FD_CONTEXT_FAILED, "gfid=%s", uuid_utoa(local->fd->inode->gfid), NULL); op_ret = 0; op_errno = ENOENT; goto out; } if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, 0, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); op_ret = 0; op_errno = ENOENT; goto out; } entry = gf_dirent_for_name(entry_point); if (!entry) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_NO_MEMORY, "entry-point=%s", entry_point, NULL); op_ret = 0; op_errno = ENOMEM; goto out; } entry->inode = inode_ref(inode); entry->d_off = svc_fd->last_offset + 22; entry->d_ino = buf->ia_ino; entry->d_type = DT_DIR; entry->d_stat = *buf; inode_type = VIRTUAL_INODE; ret = svc_inode_ctx_set(this, entry->inode, inode_type); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_SET_INODE_CONTEXT_FAILED, "entry-name=%s", entry->d_name, NULL); list_add_tail(&entry->list, &entries.list); op_ret = 1; svc_fd->last_offset = entry->d_off; svc_fd->entry_point_handled = _gf_true; out: SVC_STACK_UNWIND(readdirp, frame, op_ret, op_errno, &entries, local ? local->xdata : NULL); gf_dirent_free(&entries); return 0; } int gf_svc_special_dir_revalidate_lookup(call_frame_t *frame, xlator_t *this, dict_t *xdata) { svc_local_t *local = NULL; loc_t *loc = NULL; dict_t *tmp_xdata = NULL; char *path = NULL; int ret = -1; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("snapview-client", this, out); local = frame->local; loc = &local->loc; if (local->xdata) { dict_unref(local->xdata); local->xdata = NULL; } if (xdata) local->xdata = dict_ref(xdata); inode_unref(loc->inode); loc->inode = inode_new(loc->parent->table); if (!loc->inode) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, SVC_MSG_ALLOC_INODE_FAILED, NULL); goto out; } if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, 0, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } gf_uuid_copy(local->loc.gfid, loc->inode->gfid); ret = inode_path(loc->parent, entry_point, &path); if (ret < 0) goto out; if (loc->path) GF_FREE((char *)loc->path); loc->path = gf_strdup(path); if (loc->path) { if (!loc->name || (loc->name && !strcmp(loc->name, ""))) { loc->name = strrchr(loc->path, '/'); if (loc->name) loc->name++; } } else loc->path = NULL; tmp_xdata = dict_new(); if (!tmp_xdata) { ret = -1; goto out; } ret = dict_set_str(tmp_xdata, "entry-point", "true"); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_DICT_SET_FAILED, NULL); goto out; } STACK_WIND(frame, gf_svc_readdirp_lookup_cbk, SECOND_CHILD(this), SECOND_CHILD(this)->fops->lookup, loc, tmp_xdata); out: if (tmp_xdata) dict_unref(tmp_xdata); GF_FREE(path); return ret; } static gf_boolean_t gf_svc_readdir_on_special_dir(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { svc_local_t *local = NULL; svc_private_t *private = NULL; inode_t *inode = NULL; fd_t *fd = NULL; char *path = NULL; loc_t *loc = NULL; dict_t *tmp_xdata = NULL; int ret = -1; gf_boolean_t unwind = _gf_true; svc_fd_t *svc_fd = NULL; char entry_point[NAME_MAX + 1] = { 0, }; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, this->private, out); private = this->private; local = frame->local; loc = &local->loc; fd = local->fd; svc_fd = svc_fd_ctx_get(this, fd); if (!svc_fd) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_GET_FD_CONTEXT_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } /* * check if its end of readdir operation from posix, if special_dir * option is set, if readdir is done on special directory and if * readdirp is from normal regular graph. */ if (!private->show_entry_point) goto out; if (op_ret == 0 && op_errno == ENOENT && private->special_dir && strcmp(private->special_dir, "") && svc_fd->special_dir && local->subvolume == FIRST_CHILD(this)) { if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, 0, SVC_MSG_GET_FD_CONTEXT_FAILED, NULL); goto out; } inode = inode_grep(fd->inode->table, fd->inode, entry_point); if (!inode) { inode = inode_new(fd->inode->table); if (!inode) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_ALLOC_INODE_FAILED, NULL); goto out; } } gf_uuid_copy(local->loc.pargfid, fd->inode->gfid); gf_uuid_copy(local->loc.gfid, inode->gfid); if (gf_uuid_is_null(inode->gfid)) ret = inode_path(fd->inode, entry_point, &path); else ret = inode_path(inode, NULL, &path); if (ret < 0) goto out; loc->path = gf_strdup(path); if (loc->path) { if (!loc->name || (loc->name && !strcmp(loc->name, ""))) { loc->name = strrchr(loc->path, '/'); if (loc->name) loc->name++; } } loc->inode = inode; loc->parent = inode_ref(fd->inode); tmp_xdata = dict_new(); if (!tmp_xdata) goto out; ret = dict_set_str(tmp_xdata, "entry-point", "true"); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_DICT_SET_FAILED, NULL); goto out; } local->cookie = cookie; if (local->xdata) { dict_unref(local->xdata); local->xdata = NULL; } if (xdata) local->xdata = dict_ref(xdata); STACK_WIND(frame, gf_svc_readdirp_lookup_cbk, SECOND_CHILD(this), SECOND_CHILD(this)->fops->lookup, loc, tmp_xdata); unwind = _gf_false; } out: if (tmp_xdata) dict_unref(tmp_xdata); GF_FREE(path); return unwind; } static int32_t gf_svc_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { gf_dirent_t *entry = NULL; gf_dirent_t *tmpentry = NULL; svc_local_t *local = NULL; int inode_type = -1; int ret = -1; svc_fd_t *svc_fd = NULL; gf_boolean_t unwind = _gf_true; char entry_point[NAME_MAX + 1] = { 0, }; if (op_ret < 0) goto out; GF_VALIDATE_OR_GOTO("snapview-client", this, out); local = frame->local; svc_fd = svc_fd_ctx_get(this, local->fd); if (!svc_fd) { gf_smsg(this->name, GF_LOG_WARNING, 0, SVC_MSG_GET_FD_CONTEXT_FAILED, "gfid=%s", uuid_utoa(local->fd->inode->gfid), NULL); } if (local->subvolume == FIRST_CHILD(this)) inode_type = NORMAL_INODE; else inode_type = VIRTUAL_INODE; /* * Better to goto out and return whatever is there in the * readdirp response (even if the readdir response contains * a directory entry for the snapshot entry point). Otherwise * if we ignore the error, then there is a chance of race * condition where, priv->path is changed in reconfigure */ if (gf_svc_get_entry_point(this, entry_point, sizeof(entry_point))) { gf_smsg(this->name, GF_LOG_WARNING, 0, SVC_MSG_COPY_ENTRY_POINT_FAILED, NULL); goto out; } list_for_each_entry_safe(entry, tmpentry, &entries->list, list) { /* If .snaps pre-exists, then it should not be listed * in the NORMAL INODE directory when USS is enabled, * so filter the .snaps entry if exists. * However it is OK to list .snaps in VIRTUAL world */ if (inode_type == NORMAL_INODE && !strcmp(entry_point, entry->d_name)) { gf_dirent_entry_free(entry); continue; } if (!entry->inode) continue; ret = svc_inode_ctx_set(this, entry->inode, inode_type); if (ret) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_SET_INODE_CONTEXT_FAILED, NULL); if (svc_fd) svc_fd->last_offset = entry->d_off; } unwind = gf_svc_readdir_on_special_dir(frame, cookie, this, op_ret, op_errno, entries, xdata); out: if (unwind) SVC_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata); return 0; } static int32_t gf_svc_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata) { int inode_type = -1; xlator_t *subvolume = NULL; svc_local_t *local = NULL; int ret = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; svc_fd_t *svc_fd = NULL; gf_dirent_t entries; INIT_LIST_HEAD(&entries.list); GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); local = mem_get0(this->local_pool); if (!local) { op_errno = ENOMEM; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_NO_MEMORY, NULL); goto out; } frame->local = local; /* * This is mainly for samba shares (or windows clients). As part of * readdirp on the directory used as samba share, the entry point * directory would have been added at the end. So when a new readdirp * request comes, we have to check if the entry point has been handled * or not in readdirp. That information and the offset used for it * is remembered in fd context. If it has been handled, then simply * unwind indication end of readdir operation. */ svc_fd = svc_fd_ctx_get_or_new(this, fd); if (!svc_fd) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_GET_FD_CONTEXT_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); else { if (svc_fd->entry_point_handled && off == svc_fd->last_offset) { op_ret = 0; op_errno = ENOENT; goto out; } } SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, fd->inode, subvolume, out); local->subvolume = subvolume; local->fd = fd_ref(fd); STACK_WIND(frame, gf_svc_readdirp_cbk, subvolume, subvolume->fops->readdirp, fd, size, off, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(readdirp, frame, op_ret, op_errno, &entries, NULL); gf_dirent_free(&entries); return 0; } /* Renaming the entries from or to snapshots is not allowed as the snapshots are read-only. */ static int32_t gf_svc_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int src_inode_type = -1; int dst_inode_type = -1; int dst_parent_type = -1; int32_t op_ret = -1; int32_t op_errno = 0; int32_t ret = -1; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, oldloc, out); GF_VALIDATE_OR_GOTO(this->name, oldloc->inode, out); GF_VALIDATE_OR_GOTO(this->name, newloc, out); ret = svc_inode_ctx_get(this, oldloc->inode, &src_inode_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(oldloc->inode->gfid), NULL); goto out; } if (src_inode_type == VIRTUAL_INODE) { op_ret = -1; op_errno = EROFS; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_RENAME_SNAPSHOT_ENTRY, "name=%s", oldloc->name, NULL); goto out; } if (newloc->inode) { ret = svc_inode_ctx_get(this, newloc->inode, &dst_inode_type); if (!ret && dst_inode_type == VIRTUAL_INODE) { op_ret = -1; op_errno = EROFS; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_RENAME_SNAPSHOT_ENTRY, "oldloc-name=%s", oldloc->name, "newloc-name=%s", newloc->name, NULL); goto out; } } if (dst_inode_type < 0) { ret = svc_inode_ctx_get(this, newloc->parent, &dst_parent_type); if (!ret && dst_parent_type == VIRTUAL_INODE) { op_ret = -1; op_errno = EROFS; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_RENAME_SNAPSHOT_ENTRY, "oldloc-name=%s", oldloc->name, "newloc-name=%s", newloc->name, NULL); goto out; } } STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(rename, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } /* Creating hardlinks for the files from the snapshot is not allowed as it will be equivalent of creating hardlinks across different filesystems. And so is vice versa. */ static int32_t gf_svc_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int src_inode_type = -1; int dst_parent_type = -1; int32_t op_ret = -1; int32_t op_errno = 0; int32_t ret = -1; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, oldloc, out); GF_VALIDATE_OR_GOTO(this->name, oldloc->inode, out); GF_VALIDATE_OR_GOTO(this->name, newloc, out); ret = svc_inode_ctx_get(this, oldloc->inode, &src_inode_type); if (!ret && src_inode_type == VIRTUAL_INODE) { op_ret = -1; op_errno = EROFS; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_LINK_SNAPSHOT_ENTRY, "oldloc-name=%s", oldloc->name, NULL); goto out; } ret = svc_inode_ctx_get(this, newloc->parent, &dst_parent_type); if (!ret && dst_parent_type == VIRTUAL_INODE) { op_ret = -1; op_errno = EROFS; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_LINK_SNAPSHOT_ENTRY, "oldloc-name=%s", oldloc->name, "newloc-name=%s", newloc->name, NULL); goto out; } STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(link, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } static int32_t gf_svc_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int ret = -1; int inode_type = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, loc, out); GF_VALIDATE_OR_GOTO(this->name, loc->inode, out); ret = svc_inode_ctx_get(this, loc->inode, &inode_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "path=%s", loc->path, "gfid=%s", uuid_utoa(loc->inode->gfid), NULL); goto out; } if (inode_type == NORMAL_INODE) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(removexattr, frame, op_ret, op_errno, NULL); return 0; } static int gf_svc_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync, dict_t *xdata) { int inode_type = -1; int ret = -1; int op_ret = -1; int op_errno = EINVAL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); ret = svc_inode_ctx_get(this, fd->inode, &inode_type); if (ret < 0) { op_ret = -1; op_errno = EINVAL; gf_smsg(this->name, GF_LOG_ERROR, op_errno, SVC_MSG_GET_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); goto out; } if (inode_type == NORMAL_INODE) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata); } else { op_ret = -1; op_errno = EROFS; goto out; } wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(fsync, frame, op_ret, op_errno, NULL, NULL, NULL); return 0; } static int32_t gf_svc_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int32_t op_ret = -1; int32_t op_errno = 0; int ret = -1; int inode_type = -1; xlator_t *subvolume = NULL; gf_boolean_t wind = _gf_false; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, frame, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); GF_VALIDATE_OR_GOTO(this->name, fd->inode, out); SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, fd->inode, subvolume, out); STACK_WIND_TAIL(frame, subvolume, subvolume->fops->flush, fd, xdata); wind = _gf_true; out: if (!wind) SVC_STACK_UNWIND(flush, frame, op_ret, op_errno, NULL); return 0; } static int32_t gf_svc_releasedir(xlator_t *this, fd_t *fd) { svc_fd_t *sfd = NULL; GF_VALIDATE_OR_GOTO("snapview-client", this, out); GF_VALIDATE_OR_GOTO(this->name, fd, out); sfd = fd_ctx_del_ptr(fd, this); if (!sfd) { gf_msg_debug(this->name, 0, "pfd from fd=%p is NULL", fd); goto out; } GF_FREE(sfd); out: return 0; } static int32_t gf_svc_forget(xlator_t *this, inode_t *inode) { int ret = -1; uint64_t value = 0; GF_VALIDATE_OR_GOTO("svc", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); ret = inode_ctx_del(inode, this, &value); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_DELETE_INODE_CONTEXT_FAILED, "gfid=%s", uuid_utoa(inode->gfid), NULL); goto out; } out: return 0; } static int gf_svc_priv_destroy(xlator_t *this, svc_private_t *priv) { int ret = -1; if (!priv) { gf_smsg(this->name, GF_LOG_WARNING, 0, SVC_MSG_NULL_PRIV, NULL); goto out; } GF_FREE(priv->path); GF_FREE(priv->special_dir); LOCK_DESTROY(&priv->lock); GF_FREE(priv); if (this->local_pool) { mem_pool_destroy(this->local_pool); this->local_pool = NULL; } ret = 0; out: return ret; } /** * ** NOTE **: * ============= * The option "snapdir-entry-path" is NOT reconfigurable. * That option as of now is only for the consumption of * samba, where, it needs to tell glusterfs about the * directory that is shared with windows client for the * access. Now, in windows-explorer (GUI) interface, for * the directory shared, the entry point to the snapshot * world (snapshot-directory option) should be visible, * atleast as a hidden entry. For that to happen, glusterfs * has to send that entry in the readdir response coming on * the directory used as the smb share. Therefore, samba, * while initializing the gluster volume (via gfapi) sets * the xlator option "snapdir-entry-path" to the directory * which is to be shared with windows (check the file * vfs_glusterfs.c from samba source code). So to avoid * problems with smb access, not allowing snapdir-entry-path * option to be configurable. That option is for those * consumers who know what they are doing. **/ int reconfigure(xlator_t *this, dict_t *options) { svc_private_t *priv = NULL; char *path = NULL; gf_boolean_t show_entry_point = _gf_false; char *tmp = NULL; priv = this->private; GF_OPTION_RECONF("snapshot-directory", path, options, str, out); if (!path || (strlen(path) > NAME_MAX) || path[0] != '.') { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_INVALID_ENTRY_POINT, "path=%s", path, NULL); goto out; } GF_OPTION_RECONF("show-snapshot-directory", show_entry_point, options, bool, out); /* * The assumption now is that priv->path is an allocated memory (either * in init or in a previous reconfigure). * So, the intention here is to preserve the older contents of the option * until the new option's value has been completely stored in the priv. * So, do this. * - Store the pointer of priv->path in a temporary pointer. * - Allocate new memory for the new value of the option that is just * obtained from the above call to GF_OPTION_RECONF. * - If the above allocation fails, again set the pointer from priv * to the address stored in tmp. i.e. the previous value. * - If the allocation succeeds, then free the tmp pointer. * WARNING: Before changing the allocation and freeing logic of * priv->path, always check the init function to see how * priv->path is set. Take decisions accordingly. As of now, * the assumption is that, the string elements of private * structure of snapview-client are allocated (either in * init or here in reconfugure). */ LOCK(&priv->lock); { tmp = priv->path; priv->path = NULL; priv->path = gf_strdup(path); if (!priv->path) { gf_log(this->name, GF_LOG_ERROR, "failed to reconfigure snapshot-directory option to %s", path); priv->path = tmp; } else { GF_FREE(tmp); tmp = NULL; } priv->show_entry_point = show_entry_point; } UNLOCK(&priv->lock); out: return 0; } int32_t mem_acct_init(xlator_t *this) { int32_t ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, gf_svc_mt_end); if (ret != 0) { gf_smsg(this->name, GF_LOG_WARNING, 0, SVC_MSG_MEM_ACNT_FAILED, NULL); } return ret; } int32_t init(xlator_t *this) { svc_private_t *private = NULL; int ret = -1; int children = 0; xlator_list_t *xl = NULL; char *path = NULL; char *special_dir = NULL; if (!this->children) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_NO_CHILD_FOR_XLATOR, NULL); goto out; } xl = this->children; while (xl) { children++; xl = xl->next; } if (children != 2) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_XLATOR_CHILDREN_WRONG, "subvol-num=%d", children, NULL); goto out; } /* This can be the top of graph in certain cases */ if (!this->parents) { gf_msg_debug(this->name, 0, "dangling volume. Check " "volfile"); } private = GF_CALLOC(1, sizeof(*private), gf_svc_mt_svc_private_t); if (!private) goto out; LOCK_INIT(&private->lock); GF_OPTION_INIT("snapshot-directory", path, str, out); if (!path || (strlen(path) > NAME_MAX) || path[0] != '.') { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_INVALID_ENTRY_POINT, "path=%s", path, NULL); goto out; } private->path = gf_strdup(path); if (!private->path) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_NO_MEMORY, "entry-point-path=%s", path, NULL); goto out; } GF_OPTION_INIT("snapdir-entry-path", special_dir, str, out); if (!special_dir || strstr(special_dir, path)) { if (special_dir) gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_ENTRY_POINT_SPECIAL_DIR, "path=%s", path, "special-dir=%s", special_dir); else gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_NULL_SPECIAL_DIR, NULL); goto out; } private->special_dir = gf_strdup(special_dir); if (!private->special_dir) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_NO_MEMORY, "special-directory=%s", special_dir, NULL); goto out; } GF_OPTION_INIT("show-snapshot-directory", private->show_entry_point, bool, out); this->local_pool = mem_pool_new(svc_local_t, 128); if (!this->local_pool) { gf_smsg(this->name, GF_LOG_ERROR, 0, SVC_MSG_MEM_POOL_GET_FAILED, NULL); goto out; } this->private = private; ret = 0; out: if (ret) (void)gf_svc_priv_destroy(this, private); return ret; } void fini(xlator_t *this) { svc_private_t *priv = NULL; if (!this) return; priv = this->private; if (!priv) return; /* * Just log the failure and go ahead to * set this->priv to NULL. */ if (gf_svc_priv_destroy(this, priv)) gf_smsg(this->name, GF_LOG_WARNING, 0, SVC_MSG_PRIV_DESTROY_FAILED, NULL); this->private = NULL; return; } int notify(xlator_t *this, int event, void *data, ...) { xlator_t *subvol = NULL; int ret = 0; subvol = data; /* As there are two subvolumes in snapview-client, there is * a possibility that the regular subvolume is still down and * snapd subvolume come up first. So if we don't handle this situation * CHILD_UP event will be propagated upwards to fuse when * regular subvolume is still down. * This can cause data unavailable for the application. * So for now send notifications up only for regular subvolume. * * TODO: In future if required we may need to handle * notifications from virtual subvolume */ if (subvol != SECOND_CHILD(this)) ret = default_notify(this, event, data); return ret; } struct xlator_fops fops = { .lookup = gf_svc_lookup, .opendir = gf_svc_opendir, .stat = gf_svc_stat, .fstat = gf_svc_fstat, .statfs = gf_svc_statfs, .rmdir = gf_svc_rmdir, .rename = gf_svc_rename, .mkdir = gf_svc_mkdir, .open = gf_svc_open, .unlink = gf_svc_unlink, .setattr = gf_svc_setattr, .getxattr = gf_svc_getxattr, .setxattr = gf_svc_setxattr, .fsetxattr = gf_svc_fsetxattr, .readv = gf_svc_readv, .readdir = gf_svc_readdir, .readdirp = gf_svc_readdirp, .create = gf_svc_create, .readlink = gf_svc_readlink, .mknod = gf_svc_mknod, .symlink = gf_svc_symlink, .flush = gf_svc_flush, .link = gf_svc_link, .access = gf_svc_access, .removexattr = gf_svc_removexattr, .fsync = gf_svc_fsync, }; struct xlator_cbks cbks = { .forget = gf_svc_forget, .releasedir = gf_svc_releasedir, }; struct volume_options options[] = { { .key = {"snapshot-directory"}, .type = GF_OPTION_TYPE_STR, .default_value = ".snaps", }, { .key = {"snapdir-entry-path"}, .type = GF_OPTION_TYPE_STR, .description = "An option to set the path of a directory on which " "when readdir comes, dentry for the snapshot-directory" " should be created and added in the readdir response", .default_value = "", }, { .key = {"show-snapshot-directory"}, .type = GF_OPTION_TYPE_BOOL, .description = "If this option is set, and the option " "\"snapdir-entry-path\" is set (which is set by samba " "vfs plugin for glusterfs, then send the entry point " "when readdir comes on the snapdir-entry-path", .default_value = "off", }, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, .fops = &fops, .cbks = &cbks, .options = options, .identifier = "snapview-client", .category = GF_MAINTAINED, }; glusterfs-11.1/xlators/features/snapview-client/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013014522202465025641 xustar000000000000000030 mtime=1699284277.295062456 28 atime=1699284290.9221035 30 ctime=1699284304.632144794 glusterfs-11.1/xlators/features/snapview-client/src/Makefile.in0000664000175100017510000005766014522202465026140 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/snapview-client/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) snapview_client_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_snapview_client_la_OBJECTS = snapview-client.lo snapview_client_la_OBJECTS = $(am_snapview_client_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = snapview_client_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(snapview_client_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(snapview_client_la_SOURCES) DIST_SOURCES = $(snapview_client_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = snapview-client.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features snapview_client_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) snapview_client_la_SOURCES = snapview-client.c snapview_client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = snapview-client.h snapview-client-mem-types.h snapview-client-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/snapview-client/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/snapview-client/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } snapview-client.la: $(snapview_client_la_OBJECTS) $(snapview_client_la_DEPENDENCIES) $(EXTRA_snapview_client_la_DEPENDENCIES) $(AM_V_CCLD)$(snapview_client_la_LINK) -rpath $(xlatordir) $(snapview_client_la_OBJECTS) $(snapview_client_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snapview-client.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/snapview-client/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013014522202451025623 xustar000000000000000030 mtime=1699284265.692027507 30 atime=1699284277.258062345 28 ctime=1699284304.6341448 glusterfs-11.1/xlators/features/snapview-client/src/Makefile.am0000664000175100017510000000106014522202451026101 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = snapview-client.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features snapview_client_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) snapview_client_la_SOURCES = snapview-client.c snapview_client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = snapview-client.h snapview-client-mem-types.h snapview-client-messages.h AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/snapview-client/src/PaxHeaders.9031/snapview-client-messages.h0000644000000000000000000000013214522202451030657 xustar000000000000000030 mtime=1699284265.692027507 30 atime=1699284265.692027507 30 ctime=1699284304.638144812 glusterfs-11.1/xlators/features/snapview-client/src/snapview-client-messages.h0000664000175100017510000000747414522202451031152 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _SNAPVIEW_CLIENT_MESSAGES_H_ #define _SNAPVIEW_CLIENT_MESSAGES_H_ #include /* To add new message IDs, append new identifiers at the end of the list. * * Never remove a message ID. If it's not used anymore, you can rename it or * leave it as it is, but not delete it. This is to prevent reutilization of * IDs by other messages. * * The component name must match one of the entries defined in * glfs-message-id.h. */ GLFS_MSGID(SNAPVIEW_CLIENT, SVC_MSG_NO_MEMORY, SVC_MSG_MEM_ACNT_FAILED, SVC_MSG_SET_INODE_CONTEXT_FAILED, SVC_MSG_GET_INODE_CONTEXT_FAILED, SVC_MSG_DELETE_INODE_CONTEXT_FAILED, SVC_MSG_SET_FD_CONTEXT_FAILED, SVC_MSG_GET_FD_CONTEXT_FAILED, SVC_MSG_DICT_SET_FAILED, SVC_MSG_SUBVOLUME_NULL, SVC_MSG_NO_CHILD_FOR_XLATOR, SVC_MSG_XLATOR_CHILDREN_WRONG, SVC_MSG_NORMAL_GRAPH_LOOKUP_FAIL, SVC_MSG_SNAPVIEW_GRAPH_LOOKUP_FAIL, SVC_MSG_OPENDIR_SPECIAL_DIR, SVC_MSG_RENAME_SNAPSHOT_ENTRY, SVC_MSG_LINK_SNAPSHOT_ENTRY, SVC_MSG_COPY_ENTRY_POINT_FAILED, SVC_MSG_ENTRY_POINT_SPECIAL_DIR, SVC_MSG_STR_LEN, SVC_MSG_INVALID_ENTRY_POINT, SVC_MSG_NULL_PRIV, SVC_MSG_PRIV_DESTROY_FAILED, SVC_MSG_ALLOC_FD_FAILED, SVC_MSG_ALLOC_INODE_FAILED, SVC_MSG_NULL_SPECIAL_DIR, SVC_MSG_MEM_POOL_GET_FAILED); #define SVC_MSG_ALLOC_FD_FAILED_STR "failed to allocate new fd context" #define SVC_MSG_SET_FD_CONTEXT_FAILED_STR "failed to set fd context" #define SVC_MSG_STR_LEN_STR \ "destination buffer size is less than the length of entry point name" #define SVC_MSG_NORMAL_GRAPH_LOOKUP_FAIL_STR "lookup failed on normal graph" #define SVC_MSG_SNAPVIEW_GRAPH_LOOKUP_FAIL_STR "lookup failed on snapview graph" #define SVC_MSG_SET_INODE_CONTEXT_FAILED_STR "failed to set inode context" #define SVC_MSG_NO_MEMORY_STR "failed to allocate memory" #define SVC_MSG_COPY_ENTRY_POINT_FAILED_STR \ "failed to copy the entry point string" #define SVC_MSG_GET_FD_CONTEXT_FAILED_STR "fd context not found" #define SVC_MSG_GET_INODE_CONTEXT_FAILED_STR "failed to get inode context" #define SVC_MSG_ALLOC_INODE_FAILED_STR "failed to allocate new inode" #define SVC_MSG_DICT_SET_FAILED_STR "failed to set dict" #define SVC_MSG_RENAME_SNAPSHOT_ENTRY_STR \ "rename happening on a entry residing in snapshot" #define SVC_MSG_DELETE_INODE_CONTEXT_FAILED_STR "failed to delete inode context" #define SVC_MSG_NULL_PRIV_STR "priv NULL" #define SVC_MSG_INVALID_ENTRY_POINT_STR "not a valid entry point" #define SVC_MSG_MEM_ACNT_FAILED_STR "Memory accouting init failed" #define SVC_MSG_NO_CHILD_FOR_XLATOR_STR "configured without any child" #define SVC_MSG_XLATOR_CHILDREN_WRONG_STR \ "snap-view-client has got wrong subvolumes. It can have only 2" #define SVC_MSG_ENTRY_POINT_SPECIAL_DIR_STR \ "entry point directory cannot be part of special directory" #define SVC_MSG_NULL_SPECIAL_DIR_STR "null special directory" #define SVC_MSG_MEM_POOL_GET_FAILED_STR \ "could not get mem pool for frame->local" #define SVC_MSG_PRIV_DESTROY_FAILED_STR "failed to destroy private" #define SVC_MSG_LINK_SNAPSHOT_ENTRY_STR \ "link happening on a entry residin gin snapshot" #endif /* !_SNAPVIEW_CLIENT_MESSAGES_H_ */ glusterfs-11.1/xlators/features/snapview-client/src/PaxHeaders.9031/snapview-client.h0000644000000000000000000000013014522202451027050 xustar000000000000000029 mtime=1699284265.69302751 29 atime=1699284265.69302751 30 ctime=1699284304.635144803 glusterfs-11.1/xlators/features/snapview-client/src/snapview-client.h0000664000175100017510000001151114522202451027330 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __SNAP_VIEW_CLIENT_H__ #define __SNAP_VIEW_CLIENT_H__ #include #include #include #include #include "snapview-client-mem-types.h" #include "snapview-client-messages.h" struct __svc_local { loc_t loc; xlator_t *subvolume; fd_t *fd; void *cookie; dict_t *xdata; uint16_t revalidate; }; typedef struct __svc_local svc_local_t; #define SVC_STACK_UNWIND(fop, frame, params...) \ do { \ svc_local_t *__local = NULL; \ if (frame) { \ __local = frame->local; \ frame->local = NULL; \ } \ STACK_UNWIND_STRICT(fop, frame, params); \ svc_local_free(__local); \ } while (0) #define SVC_ENTRY_POINT_SET(this, xdata, op_ret, op_errno, new_xdata, ret, \ label) \ do { \ if (!xdata) { \ xdata = new_xdata = dict_new(); \ if (!new_xdata) { \ gf_log(this->name, GF_LOG_ERROR, \ "failed to allocate new dict"); \ op_ret = -1; \ op_errno = ENOMEM; \ goto label; \ } \ } \ ret = dict_set_str(xdata, "entry-point", "true"); \ if (ret) { \ gf_log(this->name, GF_LOG_ERROR, "failed to set dict"); \ op_ret = -1; \ op_errno = ENOMEM; \ goto label; \ } \ } while (0); #define SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, \ inode, subvolume, label) \ do { \ ret = svc_inode_ctx_get(this, inode, &inode_type); \ if (ret < 0) { \ gf_log(this->name, GF_LOG_ERROR, \ "inode context not found for gfid %s", \ uuid_utoa(inode->gfid)); \ op_ret = -1; \ op_errno = EINVAL; \ goto label; \ } \ \ subvolume = svc_get_subvolume(this, inode_type); \ } while (0); struct svc_private { char *path; char *special_dir; /* needed for samba */ gf_boolean_t show_entry_point; gf_lock_t lock; /* mainly to guard private->path */ }; typedef struct svc_private svc_private_t; struct svc_fd { off_t last_offset; gf_boolean_t entry_point_handled; gf_boolean_t special_dir; }; typedef struct svc_fd svc_fd_t; typedef enum { NORMAL_INODE = 1, VIRTUAL_INODE } inode_type_t; int gf_svc_special_dir_revalidate_lookup(call_frame_t *frame, xlator_t *this, dict_t *xdata); #endif /* __SNAP_VIEW_CLIENT_H__ */ glusterfs-11.1/xlators/features/snapview-client/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465025054 xustar000000000000000030 mtime=1699284277.248062314 30 atime=1699284290.901103437 30 ctime=1699284304.587144658 glusterfs-11.1/xlators/features/snapview-client/Makefile.in0000664000175100017510000005266014522202465025344 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/snapview-client DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/snapview-client/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/snapview-client/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/snapview-client/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451025036 xustar000000000000000030 mtime=1699284265.691027504 30 atime=1699284277.224062242 30 ctime=1699284304.589144664 glusterfs-11.1/xlators/features/snapview-client/Makefile.am0000664000175100017510000000001614522202451025312 0ustar00jenkinsjenkins00000000000000SUBDIRS = src glusterfs-11.1/xlators/features/PaxHeaders.9031/read-only0000644000000000000000000000013214522202517021512 xustar000000000000000030 mtime=1699284303.455141249 30 atime=1699284309.688160022 30 ctime=1699284303.455141249 glusterfs-11.1/xlators/features/read-only/0002775000175100017510000000000014522202517022050 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/read-only/PaxHeaders.9031/src0000644000000000000000000000013214522202517022301 xustar000000000000000030 mtime=1699284303.515141429 30 atime=1699284309.688160022 30 ctime=1699284303.515141429 glusterfs-11.1/xlators/features/read-only/src/0002775000175100017510000000000014522202517022637 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/worm-helper.c0000644000000000000000000000013214522202451024760 xustar000000000000000030 mtime=1699284265.686027489 30 atime=1699284265.686027489 30 ctime=1699284303.513141423 glusterfs-11.1/xlators/features/read-only/src/worm-helper.c0000664000175100017510000003022514522202451025241 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "read-only-mem-types.h" #include "read-only.h" #include #include "worm-helper.h" /*Function to check whether file is read-only. * The input *stbuf contains the attributes of the file, which is used to check * the write protection bits for all the users of the file. * Return true if all the write bits are disabled,false otherwise*/ gf_boolean_t gf_worm_write_disabled(struct iatt *stbuf) { gf_boolean_t ret = _gf_false; GF_VALIDATE_OR_GOTO("worm", stbuf, out); if (stbuf->ia_prot.owner.write == 0 && stbuf->ia_prot.group.write == 0 && stbuf->ia_prot.other.write == 0) ret = _gf_true; out: return ret; } int32_t worm_init_state(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr) { int ret = -1; uint64_t start_time = 0; dict_t *dict = NULL; GF_VALIDATE_OR_GOTO("worm", this, out); GF_VALIDATE_OR_GOTO(this->name, file_ptr, out); start_time = gf_time(); dict = dict_new(); if (!dict) { gf_log(this->name, GF_LOG_ERROR, "Error creating the dict"); goto out; } ret = dict_set_uint64(dict, "trusted.start_time", start_time); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Error in setting the dict"); goto out; } if (fop_with_fd) ret = syncop_fsetxattr(this, (fd_t *)file_ptr, dict, 0, NULL, NULL); else ret = syncop_setxattr(this, (loc_t *)file_ptr, dict, 0, NULL, NULL); out: if (dict) dict_unref(dict); return ret; } /*Function to set the retention state for a file. * It loads the WORM/Retention state into the retention_state pointer.*/ int32_t worm_set_state(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, worm_reten_state_t *retention_state, struct iatt *stbuf) { read_only_priv_t *priv = NULL; struct iatt stpre = { 0, }; int ret = -1; GF_VALIDATE_OR_GOTO("worm", this, out); GF_VALIDATE_OR_GOTO(this->name, file_ptr, out); GF_VALIDATE_OR_GOTO(this->name, retention_state, out); GF_VALIDATE_OR_GOTO(this->name, stbuf, out); priv = this->private; GF_ASSERT(priv); retention_state->worm = 1; retention_state->retain = 1; retention_state->legal_hold = 0; retention_state->ret_mode = priv->reten_mode; retention_state->ret_period = priv->reten_period; retention_state->auto_commit_period = priv->com_period; if (fop_with_fd) ret = syncop_fstat(this, (fd_t *)file_ptr, &stpre, NULL, NULL); else ret = syncop_stat(this, (loc_t *)file_ptr, &stpre, NULL, NULL); if (ret) goto out; stbuf->ia_mtime = stpre.ia_mtime; stbuf->ia_atime = gf_time() + retention_state->ret_period; if (fop_with_fd) ret = syncop_fsetattr(this, (fd_t *)file_ptr, stbuf, GF_SET_ATTR_ATIME, NULL, NULL, NULL, NULL); else ret = syncop_setattr(this, (loc_t *)file_ptr, stbuf, GF_SET_ATTR_ATIME, NULL, NULL, NULL, NULL); if (ret) goto out; ret = gf_worm_set_xattr(this, retention_state, fop_with_fd, file_ptr); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Error setting xattr"); goto out; } ret = 0; out: return ret; } /*This function gets the state of the WORM/Retention xattr and loads it in the * dict pointer.*/ int32_t worm_get_state(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, worm_reten_state_t *reten_state) { dict_t *dict = NULL; char *val = NULL; int ret = -1; GF_VALIDATE_OR_GOTO("worm", this, out); GF_VALIDATE_OR_GOTO(this->name, file_ptr, out); GF_VALIDATE_OR_GOTO(this->name, reten_state, out); if (fop_with_fd) ret = syncop_fgetxattr(this, (fd_t *)file_ptr, &dict, "trusted.reten_state", NULL, NULL); else ret = syncop_getxattr(this, (loc_t *)file_ptr, &dict, "trusted.reten_state", NULL, NULL); if (ret < 0 || !dict) { ret = -1; goto out; } ret = dict_get_str(dict, "trusted.reten_state", &val); if (ret) { ret = -2; gf_log(this->name, GF_LOG_ERROR, "Empty val"); } gf_worm_deserialize_state(val, reten_state); out: if (dict) dict_unref(dict); return ret; } /*Function to lookup the current state of the WORM/Retention profile. * Based on the retain value and the access time of the file, the transition * from WORM/Retention to WORM is made.*/ void gf_worm_state_lookup(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, worm_reten_state_t *reten_state, struct iatt *stbuf) { int ret = -1; GF_VALIDATE_OR_GOTO("worm", this, out); GF_VALIDATE_OR_GOTO(this->name, file_ptr, out); GF_VALIDATE_OR_GOTO(this->name, reten_state, out); GF_VALIDATE_OR_GOTO(this->name, stbuf, out); stbuf->ia_atime -= reten_state->ret_period; reten_state->retain = 0; reten_state->ret_period = 0; reten_state->auto_commit_period = 0; ret = gf_worm_set_xattr(this, reten_state, fop_with_fd, file_ptr); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Error setting xattr"); goto out; } if (fop_with_fd) ret = syncop_fsetattr(this, (fd_t *)file_ptr, stbuf, GF_SET_ATTR_ATIME, NULL, NULL, NULL, NULL); else ret = syncop_setattr(this, (loc_t *)file_ptr, stbuf, GF_SET_ATTR_ATIME, NULL, NULL, NULL, NULL); if (ret) goto out; gf_log(this->name, GF_LOG_INFO, "Retention state reset"); out: return; } /*This function serializes and stores the WORM/Retention state of a file in an * uint64_t variable by setting the bits using the bitwise operations.*/ void gf_worm_serialize_state(worm_reten_state_t *reten_state, char *val) { uint32_t state = 0; GF_VALIDATE_OR_GOTO("worm", reten_state, out); GF_VALIDATE_OR_GOTO("worm", val, out); state |= reten_state->worm << 0; state |= reten_state->retain << 1; state |= reten_state->legal_hold << 2; state |= reten_state->ret_mode << 3; sprintf(val, "%d/%" PRIu64 "/%" PRIu64, state, reten_state->ret_period, reten_state->auto_commit_period); out: return; } /*This function deserializes the data stored in the xattr of the file and loads * the value to the reten_state structure.*/ void gf_worm_deserialize_state(char *val, worm_reten_state_t *reten_state) { char *token = NULL; uint32_t state = 0; GF_VALIDATE_OR_GOTO("worm", val, out); GF_VALIDATE_OR_GOTO("worm", reten_state, out); token = strtok(val, "/"); state = atoi(token); reten_state->worm = (state >> 0) & 1; reten_state->retain = (state >> 1) & 1; reten_state->legal_hold = (state >> 2) & 1; reten_state->ret_mode = (state >> 3) & 1; token = strtok(NULL, "/"); reten_state->ret_period = atoi(token); token = strtok(NULL, "/"); reten_state->auto_commit_period = atoi(token); out: return; } /*Function to set the xattr for a file. * If the xattr is already present then it will replace that.*/ int32_t gf_worm_set_xattr(xlator_t *this, worm_reten_state_t *reten_state, gf_boolean_t fop_with_fd, void *file_ptr) { char val[100] = ""; int ret = -1; dict_t *dict = NULL; GF_VALIDATE_OR_GOTO("worm", this, out); GF_VALIDATE_OR_GOTO(this->name, reten_state, out); GF_VALIDATE_OR_GOTO(this->name, file_ptr, out); gf_worm_serialize_state(reten_state, val); dict = dict_new(); if (!dict) { gf_log(this->name, GF_LOG_ERROR, "Error creating the dict"); goto out; } ret = dict_set_str(dict, "trusted.reten_state", val); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Error in setting the dict"); goto out; } if (fop_with_fd) ret = syncop_fsetxattr(this, (fd_t *)file_ptr, dict, 0, NULL, NULL); else ret = syncop_setxattr(this, (loc_t *)file_ptr, dict, 0, NULL, NULL); out: if (dict) dict_unref(dict); return ret; } /*This function checks whether a file's timeout is happened for the state * transition and if yes, then it will do the transition from the current state * to the appropriate state. It also decides whether to continue or to block * the FOP. * Return: * 0 : If the FOP should continue i.e., if the file is not in the WORM-Retained * state or if the FOP is unlink and the file is not in the Retained state. * 1: If the FOP sholud block i.e., if the file is in WORM-Retained/WORM state. * 2: Blocks the FOP if any operation fails while doing the state transition or * fails to get the state of the file.*/ int gf_worm_state_transition(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, glusterfs_fop_t op) { int op_errno = EROFS; int ret = -1; time_t now = 0; uint64_t com_period = 0; uint64_t start_time = 0; dict_t *dict = NULL; worm_reten_state_t reten_state = { 0, }; read_only_priv_t *priv = NULL; struct iatt stbuf = { 0, }; priv = this->private; GF_ASSERT(priv); if (fop_with_fd) ret = syncop_fgetxattr(this, (fd_t *)file_ptr, &dict, "trusted.start_time", NULL, NULL); else ret = syncop_getxattr(this, (loc_t *)file_ptr, &dict, "trusted.start_time", NULL, NULL); if (ret < 0 || !dict) { op_errno = ret; gf_msg(this->name, GF_LOG_ERROR, -ret, 0, "Error getting xattr"); goto out; } ret = dict_get_uint64(dict, "trusted.start_time", &start_time); if (ret) { op_errno = ret; gf_msg(this->name, GF_LOG_ERROR, -ret, 0, "Error getting start time"); goto out; } com_period = priv->com_period; if (fop_with_fd) ret = syncop_fstat(this, (fd_t *)file_ptr, &stbuf, NULL, NULL); else ret = syncop_stat(this, (loc_t *)file_ptr, &stbuf, NULL, NULL); if (ret) { op_errno = ret; gf_msg(this->name, GF_LOG_ERROR, -ret, 0, "Error getting file stat"); goto out; } ret = worm_get_state(this, fop_with_fd, file_ptr, &reten_state); if (ret == -2) { op_errno = ret; gf_msg(this->name, GF_LOG_ERROR, -ret, 0, "Error getting worm/retention state"); goto out; } now = gf_time(); if (ret == -1 && (now - start_time) >= com_period) { if ((now - stbuf.ia_mtime) >= com_period) { ret = worm_set_state(this, fop_with_fd, file_ptr, &reten_state, &stbuf); if (ret) { op_errno = ret; gf_msg(this->name, GF_LOG_ERROR, -ret, 0, "Error setting worm/retention state"); goto out; } goto out; } else { op_errno = 0; goto out; } } else if (ret == -1 && (now - start_time) < com_period) { op_errno = 0; goto out; } else if (reten_state.retain && ((now >= stbuf.ia_atime))) { gf_worm_state_lookup(this, fop_with_fd, file_ptr, &reten_state, &stbuf); } if (reten_state.worm && !reten_state.retain && priv->worm_files_deletable && op == GF_FOP_UNLINK) { op_errno = 0; goto out; } out: if (dict) dict_unref(dict); return op_errno; } /*Function to check whether a file is independently WORMed (i.e., file level * WORM is set on the file). */ int32_t is_wormfile(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr) { int ret = -1; dict_t *dict = NULL; if (fop_with_fd) ret = syncop_fgetxattr(this, (fd_t *)file_ptr, &dict, "trusted.worm_file", NULL, NULL); else ret = syncop_getxattr(this, (loc_t *)file_ptr, &dict, "trusted.worm_file", NULL, NULL); if (dict) { ret = 0; dict_unref(dict); } return ret; } glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/read-only-common.h0000644000000000000000000000013214522202451025704 xustar000000000000000030 mtime=1699284265.685027486 30 atime=1699284265.685027486 30 ctime=1699284303.506141402 glusterfs-11.1/xlators/features/read-only/src/read-only-common.h0000664000175100017510000000747614522202451026201 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include gf_boolean_t is_readonly_or_worm_enabled(call_frame_t *frame, xlator_t *this); int32_t ro_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata); int32_t ro_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata); int32_t ro_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata); int32_t ro_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata); int32_t ro_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata); int32_t ro_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata); int32_t ro_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int cmd, struct gf_flock *flock, dict_t *xdata); int32_t ro_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata); int32_t ro_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata); int32_t ro_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata); int32_t ro_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata); int ro_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata); int ro_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata); int32_t ro_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata); int ro_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata); int ro_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata); int32_t ro_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata); int32_t ro_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata); int32_t ro_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata); int32_t ro_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata); int32_t ro_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata); int32_t ro_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata); int32_t ro_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata); int32_t ro_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata); int32_t ro_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata); int32_t ro_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata); glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/read-only.h0000644000000000000000000000013114522202451024415 xustar000000000000000030 mtime=1699284265.686027489 30 atime=1699284265.686027489 29 ctime=1699284303.50214139 glusterfs-11.1/xlators/features/read-only/src/read-only.h0000664000175100017510000000177414522202451024706 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __READONLY_H__ #define __READONLY_H__ #include // for uint64_t, uint8_t #include // for time_t #include "glusterfs/glusterfs.h" // for gf_boolean_t typedef struct { uint8_t worm : 1; uint8_t retain : 1; uint8_t legal_hold : 1; uint8_t ret_mode : 1; int64_t ret_period; int64_t auto_commit_period; } worm_reten_state_t; typedef struct { gf_boolean_t readonly_or_worm_enabled; gf_boolean_t worm_file; gf_boolean_t worm_files_deletable; int64_t reten_period; int64_t com_period; int reten_mode; time_t start_time; } read_only_priv_t; #endif glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/read-only.c0000644000000000000000000000013214522202451024411 xustar000000000000000030 mtime=1699284265.686027489 30 atime=1699284265.685027486 30 ctime=1699284303.510141414 glusterfs-11.1/xlators/features/read-only/src/read-only.c0000664000175100017510000000654614522202451024703 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "read-only-common.h" #include "read-only-mem-types.h" #include "read-only.h" int32_t mem_acct_init(xlator_t *this) { int ret = -1; ret = xlator_mem_acct_init(this, gf_read_only_mt_end); if (ret) gf_log(this->name, GF_LOG_ERROR, "Memory accounting " "initialization failed."); return ret; } int32_t init(xlator_t *this) { int ret = -1; read_only_priv_t *priv = NULL; if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "translator not configured with exactly one child"); return -1; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); } priv = GF_CALLOC(1, sizeof(*priv), gf_read_only_mt_priv_t); if (!priv) goto out; this->private = priv; GF_OPTION_INIT("read-only", priv->readonly_or_worm_enabled, bool, out); ret = 0; out: return ret; } int reconfigure(xlator_t *this, dict_t *options) { read_only_priv_t *priv = NULL; int ret = -1; gf_boolean_t readonly_or_worm_enabled = _gf_false; priv = this->private; GF_ASSERT(priv); GF_OPTION_RECONF("read-only", readonly_or_worm_enabled, options, bool, out); priv->readonly_or_worm_enabled = readonly_or_worm_enabled; ret = 0; out: gf_log(this->name, GF_LOG_DEBUG, "returning %d", ret); return ret; } void fini(xlator_t *this) { read_only_priv_t *priv = NULL; priv = this->private; if (!priv) return; this->private = NULL; GF_FREE(priv); return; } struct xlator_fops fops = { .mknod = ro_mknod, .mkdir = ro_mkdir, .unlink = ro_unlink, .rmdir = ro_rmdir, .symlink = ro_symlink, .rename = ro_rename, .link = ro_link, .truncate = ro_truncate, .open = ro_open, .writev = ro_writev, .setxattr = ro_setxattr, .fsetxattr = ro_fsetxattr, .removexattr = ro_removexattr, .fsyncdir = ro_fsyncdir, .ftruncate = ro_ftruncate, .create = ro_create, .setattr = ro_setattr, .fsetattr = ro_fsetattr, .xattrop = ro_xattrop, .fxattrop = ro_fxattrop, .inodelk = ro_inodelk, .finodelk = ro_finodelk, .entrylk = ro_entrylk, .fentrylk = ro_fentrylk, .lk = ro_lk, .fallocate = ro_fallocate, }; struct xlator_cbks cbks = {}; struct volume_options options[] = { {.key = {"read-only"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", /*.validate_fn = validate_boolean,*/ .op_version = {1}, .flags = OPT_FLAG_SETTABLE, .description = "When \"on\", makes a volume read-only. It is turned " "\"off\" by default."}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "read-only", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/Makefile.in0000644000000000000000000000013014522202464024422 xustar000000000000000028 mtime=1699284276.8780612 30 atime=1699284290.521102293 30 ctime=1699284303.499141381 glusterfs-11.1/xlators/features/read-only/src/Makefile.in0000664000175100017510000006141014522202464024705 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/read-only/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(noinst_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xlatordir)" LTLIBRARIES = $(xlator_LTLIBRARIES) read_only_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_read_only_la_OBJECTS = read-only.lo read-only-common.lo read_only_la_OBJECTS = $(am_read_only_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = read_only_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(read_only_la_LDFLAGS) $(LDFLAGS) -o $@ worm_la_DEPENDENCIES = \ $(top_builddir)/libglusterfs/src/libglusterfs.la am_worm_la_OBJECTS = read-only-common.lo worm-helper.lo worm.lo worm_la_OBJECTS = $(am_worm_la_OBJECTS) worm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(worm_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(read_only_la_SOURCES) $(worm_la_SOURCES) DIST_SOURCES = $(read_only_la_SOURCES) $(worm_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xlator_LTLIBRARIES = read-only.la worm.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features noinst_HEADERS = read-only.h read-only-mem-types.h read-only-common.h worm-helper.h read_only_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) read_only_la_SOURCES = read-only.c read-only-common.c read_only_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la worm_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) worm_la_SOURCES = read-only-common.c worm-helper.c worm.c worm_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/read-only/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/read-only/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-xlatorLTLIBRARIES: $(xlator_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(xlatordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xlatordir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(xlatordir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(xlatordir)"; \ } uninstall-xlatorLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(xlator_LTLIBRARIES)'; test -n "$(xlatordir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(xlatordir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(xlatordir)/$$f"; \ done clean-xlatorLTLIBRARIES: -test -z "$(xlator_LTLIBRARIES)" || rm -f $(xlator_LTLIBRARIES) @list='$(xlator_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } read-only.la: $(read_only_la_OBJECTS) $(read_only_la_DEPENDENCIES) $(EXTRA_read_only_la_DEPENDENCIES) $(AM_V_CCLD)$(read_only_la_LINK) -rpath $(xlatordir) $(read_only_la_OBJECTS) $(read_only_la_LIBADD) $(LIBS) worm.la: $(worm_la_OBJECTS) $(worm_la_DEPENDENCIES) $(EXTRA_worm_la_DEPENDENCIES) $(AM_V_CCLD)$(worm_la_LINK) -rpath $(xlatordir) $(worm_la_OBJECTS) $(worm_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read-only-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read-only.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/worm-helper.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/worm.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(xlatordir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-xlatorLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xlatorLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-xlatorLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-xlatorLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-xlatorLTLIBRARIES installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-xlatorLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/read-only-common.c0000644000000000000000000000013214522202451025677 xustar000000000000000030 mtime=1699284265.685027486 30 atime=1699284265.685027486 30 ctime=1699284303.511141417 glusterfs-11.1/xlators/features/read-only/src/read-only-common.c0000664000175100017510000003025614522202451026164 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "read-only.h" #include "read-only-mem-types.h" #include gf_boolean_t is_readonly_or_worm_enabled(call_frame_t *frame, xlator_t *this) { read_only_priv_t *priv = NULL; gf_boolean_t readonly_or_worm_enabled = _gf_false; priv = this->private; GF_ASSERT(priv); readonly_or_worm_enabled = priv->readonly_or_worm_enabled; if (frame->root->pid < GF_CLIENT_PID_MAX) readonly_or_worm_enabled = _gf_false; return readonly_or_worm_enabled; } static int _check_key_is_zero_filled(dict_t *d, char *k, data_t *v, void *tmp) { if (mem_0filled((const char *)v->data, v->len)) { /* -1 means, no more iterations, treat as 'break' */ return -1; } return 0; } int32_t ro_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { gf_boolean_t allzero = _gf_false; int ret = 0; ret = dict_foreach(dict, _check_key_is_zero_filled, NULL); if (ret == 0) allzero = _gf_true; if (is_readonly_or_worm_enabled(frame, this) && !allzero) STACK_UNWIND_STRICT(xattrop, frame, -1, EROFS, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata); return 0; } int32_t ro_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { gf_boolean_t allzero = _gf_false; int ret = 0; ret = dict_foreach(dict, _check_key_is_zero_filled, NULL); if (ret == 0) allzero = _gf_true; if (is_readonly_or_worm_enabled(frame, this) && !allzero) STACK_UNWIND_STRICT(fxattrop, frame, -1, EROFS, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata); return 0; } int32_t ro_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, volume, loc, basename, cmd, type, xdata); return 0; } int32_t ro_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fentrylk, volume, fd, basename, cmd, type, xdata); return 0; } int32_t ro_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, volume, loc, cmd, lock, xdata); return 0; } int32_t ro_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd, lock, xdata); return 0; } int32_t ro_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int cmd, struct gf_flock *flock, dict_t *xdata) { STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lk, fd, cmd, flock, xdata); return 0; } int32_t ro_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(setattr, frame, -1, EROFS, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } int32_t ro_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(fsetattr, frame, -1, EROFS, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } int32_t ro_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(truncate, frame, -1, EROFS, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } int32_t ro_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(ftruncate, frame, -1, EROFS, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } int32_t ro_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, off_t offset, size_t len, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(fallocate, frame, -1, EROFS, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, xdata); return 0; } int ro_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(mknod, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); return 0; } int ro_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(mkdir, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); return 0; } int32_t ro_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(unlink, frame, -1, EROFS, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); return 0; } int ro_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(rmdir, frame, -1, EROFS, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); return 0; } int ro_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(symlink, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); return 0; } int32_t ro_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(rename, frame, -1, EROFS, NULL, NULL, NULL, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; } int32_t ro_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(link, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; } int32_t ro_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(create, frame, -1, EROFS, NULL, NULL, NULL, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; } static int32_t ro_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, xdata); return 0; } int32_t ro_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this) && (((flags & O_ACCMODE) == O_WRONLY) || ((flags & O_ACCMODE) == O_RDWR))) { STACK_UNWIND_STRICT(open, frame, -1, EROFS, NULL, xdata); return 0; } STACK_WIND(frame, ro_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; } int32_t ro_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(fsetxattr, frame, -1, EROFS, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; } int32_t ro_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(fsyncdir, frame, -1, EROFS, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsyncdir, fd, flags, xdata); return 0; } int32_t ro_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(writev, frame, -1, EROFS, NULL, NULL, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, iobref, xdata); return 0; } int32_t ro_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(setxattr, frame, -1, EROFS, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; } int32_t ro_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this)) STACK_UNWIND_STRICT(removexattr, frame, -1, EROFS, xdata); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; } glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/worm-helper.h0000644000000000000000000000013214522202451024765 xustar000000000000000030 mtime=1699284265.686027489 30 atime=1699284265.686027489 30 ctime=1699284303.508141408 glusterfs-11.1/xlators/features/read-only/src/worm-helper.h0000664000175100017510000000266114522202451025251 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ gf_boolean_t gf_worm_write_disabled(struct iatt *stbuf); int32_t worm_init_state(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr); int32_t worm_set_state(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, worm_reten_state_t *retention_state, struct iatt *stbuf); int32_t worm_get_state(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, worm_reten_state_t *reten_state); void gf_worm_state_lookup(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, worm_reten_state_t *reten_state, struct iatt *stbuf); void gf_worm_serialize_state(worm_reten_state_t *reten_state, char *val); void gf_worm_deserialize_state(char *val, worm_reten_state_t *reten_state); int32_t gf_worm_set_xattr(xlator_t *this, worm_reten_state_t *reten_state, gf_boolean_t fop_with_fd, void *file_ptr); int gf_worm_state_transition(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, glusterfs_fop_t op); int32_t is_wormfile(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr); glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451024407 xustar000000000000000030 mtime=1699284265.685027486 30 atime=1699284276.839061082 30 ctime=1699284303.501141387 glusterfs-11.1/xlators/features/read-only/src/Makefile.am0000664000175100017510000000134014522202451024664 0ustar00jenkinsjenkins00000000000000xlator_LTLIBRARIES = read-only.la worm.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features noinst_HEADERS = read-only.h read-only-mem-types.h read-only-common.h worm-helper.h read_only_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) read_only_la_SOURCES = read-only.c read-only-common.c read_only_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la worm_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) worm_la_SOURCES = read-only-common.c worm-helper.c worm.c worm_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/read-only-mem-types.h0000644000000000000000000000013214522202451026334 xustar000000000000000030 mtime=1699284265.685027486 30 atime=1699284265.685027486 30 ctime=1699284303.504141396 glusterfs-11.1/xlators/features/read-only/src/read-only-mem-types.h0000664000175100017510000000111014522202451026604 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __READONLY_MEM_TYPES_H__ #define __READONLY_MEM_TYPES_H__ #include enum gf_read_only_mem_types_ { gf_read_only_mt_priv_t = gf_common_mt_end + 1, gf_read_only_mt_end }; #endif glusterfs-11.1/xlators/features/read-only/src/PaxHeaders.9031/worm.c0000644000000000000000000000013214522202451023503 xustar000000000000000030 mtime=1699284265.686027489 30 atime=1699284265.686027489 30 ctime=1699284303.515141429 glusterfs-11.1/xlators/features/read-only/src/worm.c0000664000175100017510000005064714522202451023776 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2008-2012, 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "read-only-common.h" #include "read-only-mem-types.h" #include "read-only.h" #include #include "worm-helper.h" int32_t mem_acct_init(xlator_t *this) { int ret = -1; ret = xlator_mem_acct_init(this, gf_read_only_mt_end); if (ret) gf_log(this->name, GF_LOG_ERROR, "Memory accounting " "initialization failed."); return ret; } static int32_t worm_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { if (is_readonly_or_worm_enabled(frame, this) && (flags & (O_WRONLY | O_RDWR | O_APPEND | O_TRUNC))) { STACK_UNWIND_STRICT(open, frame, -1, EROFS, NULL, NULL); return 0; } STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); return 0; } static int32_t worm_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int op_errno = EROFS; read_only_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (is_readonly_or_worm_enabled(frame, this)) goto out; if (!priv->worm_file || (frame->root->pid < 0)) { op_errno = 0; goto out; } gf_uuid_copy(oldloc->gfid, oldloc->inode->gfid); if (is_wormfile(this, _gf_false, oldloc)) { op_errno = 0; goto out; } op_errno = gf_worm_state_transition(this, _gf_false, oldloc, GF_FOP_LINK); out: if (op_errno) { if (op_errno < 0) op_errno = EROFS; STACK_UNWIND_STRICT(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); } else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; } static int32_t worm_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, dict_t *xdata) { int op_errno = EROFS; read_only_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (is_readonly_or_worm_enabled(frame, this)) { goto out; } if (!priv->worm_file || (frame->root->pid < 0)) { op_errno = 0; goto out; } gf_uuid_copy(loc->gfid, loc->inode->gfid); if (is_wormfile(this, _gf_false, loc)) { op_errno = 0; goto out; } op_errno = gf_worm_state_transition(this, _gf_false, loc, GF_FOP_UNLINK); out: if (op_errno) { if (op_errno < 0) op_errno = EROFS; STACK_UNWIND_STRICT(unlink, frame, -1, op_errno, NULL, NULL, NULL); } else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, flags, xdata); return 0; } static int32_t worm_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int op_errno = EROFS; read_only_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (is_readonly_or_worm_enabled(frame, this)) goto out; if (!priv->worm_file || (frame->root->pid < 0)) { op_errno = 0; goto out; } gf_uuid_copy(oldloc->gfid, oldloc->inode->gfid); if (is_wormfile(this, _gf_false, oldloc)) { op_errno = 0; goto check_newloc; } op_errno = gf_worm_state_transition(this, _gf_false, oldloc, GF_FOP_RENAME); if (op_errno == 0) { check_newloc: if (newloc->inode != NULL) { gf_uuid_copy(newloc->gfid, newloc->inode->gfid); if (is_wormfile(this, _gf_false, newloc)) { op_errno = 0; goto out; } op_errno = gf_worm_state_transition(this, _gf_false, newloc, GF_FOP_RENAME); } } out: if (op_errno) { if (op_errno < 0) op_errno = EROFS; STACK_UNWIND_STRICT(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); } else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); return 0; } static int32_t worm_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { int op_errno = EROFS; read_only_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (is_readonly_or_worm_enabled(frame, this)) goto out; if (!priv->worm_file || (frame->root->pid < 0)) { op_errno = 0; goto out; } if (is_wormfile(this, _gf_false, loc)) { op_errno = 0; goto out; } op_errno = gf_worm_state_transition(this, _gf_false, loc, GF_FOP_TRUNCATE); out: if (op_errno) { if (op_errno < 0) op_errno = EROFS; STACK_UNWIND_STRICT(truncate, frame, -1, op_errno, NULL, NULL, NULL); } else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; } static int32_t worm_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { int op_errno = EROFS; read_only_priv_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (is_readonly_or_worm_enabled(frame, this)) goto out; if (!priv->worm_file || (frame->root->pid < 0)) { op_errno = 0; goto out; } if (is_wormfile(this, _gf_true, fd)) { op_errno = 0; goto out; } op_errno = gf_worm_state_transition(this, _gf_true, fd, GF_FOP_FTRUNCATE); out: if (op_errno) { if (op_errno < 0) op_errno = EROFS; STACK_UNWIND_STRICT(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); } else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); return 0; } static int32_t worm_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { gf_boolean_t rd_only = _gf_false; worm_reten_state_t reten_state = { 0, }; struct iatt stpre = { 0, }; read_only_priv_t *priv = NULL; int op_errno = EROFS; int ret = -1; priv = this->private; GF_ASSERT(priv); if (!priv->worm_file) { op_errno = 0; goto out; } if (is_wormfile(this, _gf_false, loc)) { op_errno = 0; goto out; } if (valid & GF_SET_ATTR_MODE) { rd_only = gf_worm_write_disabled(stbuf); if (!rd_only) { op_errno = 0; goto out; } ret = worm_set_state(this, _gf_false, loc, &reten_state, stbuf); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Error setting worm state"); goto out; } } else if (valid & GF_SET_ATTR_ATIME) { ret = worm_get_state(this, _gf_false, loc, &reten_state); if (ret) { op_errno = 0; goto out; } if (reten_state.retain) { ret = syncop_stat(this, loc, &stpre, NULL, NULL); if (ret) goto out; if (reten_state.ret_mode == 0) { if (stbuf->ia_atime < stpre.ia_mtime) { gf_log(this->name, GF_LOG_ERROR, "Cannot set atime less than " "the mtime for a WORM-Retained " "file"); goto out; } } else { if (stbuf->ia_atime < stpre.ia_atime) { gf_log(this->name, GF_LOG_ERROR, "Cannot decrease the atime of a" " WORM-Retained file in " "Enterprise mode"); goto out; } } reten_state.ret_period = reten_state.ret_period + stbuf->ia_atime - stpre.ia_atime; ret = gf_worm_set_xattr(this, &reten_state, _gf_false, loc); if (ret) { goto out; } stbuf->ia_mtime = stpre.ia_mtime; } } op_errno = 0; out: if (op_errno) STACK_UNWIND_STRICT(setattr, frame, -1, EROFS, NULL, NULL, NULL); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); return 0; } static int32_t worm_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { gf_boolean_t rd_only = _gf_false; worm_reten_state_t reten_state = { 0, }; struct iatt stpre = { 0, }; read_only_priv_t *priv = NULL; int op_errno = EROFS; int ret = -1; priv = this->private; GF_ASSERT(priv); if (!priv->worm_file) { op_errno = 0; goto out; } if (is_wormfile(this, _gf_true, fd)) { op_errno = 0; goto out; } if (valid & GF_SET_ATTR_MODE) { rd_only = gf_worm_write_disabled(stbuf); if (!rd_only) { op_errno = 0; goto out; } ret = worm_set_state(this, _gf_true, fd, &reten_state, stbuf); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Error setting worm state"); goto out; } } else if (valid & GF_SET_ATTR_ATIME) { ret = worm_get_state(this, _gf_true, fd, &reten_state); if (ret) { op_errno = 0; goto out; } if (reten_state.retain) { ret = syncop_fstat(this, fd, &stpre, NULL, NULL); if (ret) goto out; if (reten_state.ret_mode == 0) { if (stbuf->ia_atime < stpre.ia_mtime) { gf_log(this->name, GF_LOG_ERROR, "Cannot set atime less than " "the mtime for a WORM-Retained " "file"); goto out; } } else { if (stbuf->ia_atime < stpre.ia_atime) { gf_log(this->name, GF_LOG_ERROR, "Cannot decrease the atime of a" " WORM-Retained file in " "Enterprise mode"); goto out; } } reten_state.ret_period = reten_state.ret_period + stbuf->ia_atime - stpre.ia_atime; ret = gf_worm_set_xattr(this, &reten_state, _gf_true, fd); if (ret) { goto out; } stbuf->ia_mtime = stpre.ia_mtime; } } op_errno = 0; out: if (op_errno) STACK_UNWIND_STRICT(fsetattr, frame, -1, op_errno, NULL, NULL, NULL); else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; } static int32_t worm_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { read_only_priv_t *priv = NULL; int op_errno = EROFS; priv = this->private; GF_ASSERT(priv); if (!priv->worm_file || (frame->root->pid < 0)) { op_errno = 0; goto out; } if (is_wormfile(this, _gf_true, fd)) { op_errno = 0; goto out; } op_errno = gf_worm_state_transition(this, _gf_true, fd, GF_FOP_WRITE); out: if (op_errno) { if (op_errno < 0) op_errno = EROFS; STACK_UNWIND_STRICT(writev, frame, -1, op_errno, NULL, NULL, NULL); } else STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, flags, iobref, xdata); return 0; } static int32_t worm_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { int ret = 0; read_only_priv_t *priv = NULL; // In case of an error exit because fd can be NULL and this would // cause an segfault when performing fsetxattr . We explicitly // unwind to avoid future problems if (op_ret < 0) { goto out; } priv = this->private; GF_ASSERT(priv); if (priv->worm_file) { ret = fd_ctx_set(fd, this, 1); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Failed to set the fd ctx " "for gfid:%s . Worm feature may not work for the gfid", uuid_utoa(inode->gfid)); } ret = worm_init_state(this, _gf_true, fd); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Error initializing state"); } } out: STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent, xdata); return ret; } static int32_t worm_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { STACK_WIND(frame, worm_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; } static void set_reten_mode(read_only_priv_t *priv, char *reten_mode) { if (strcmp(reten_mode, "relax") == 0) priv->reten_mode = 0; else priv->reten_mode = 1; } int32_t init(xlator_t *this) { int ret = -1; read_only_priv_t *priv = NULL; char *reten_mode = NULL; if (!this->children || this->children->next) { gf_log(this->name, GF_LOG_ERROR, "translator not configured with exactly one child"); return -1; } if (!this->parents) { gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); } this->local_pool = mem_pool_new(read_only_priv_t, 64); if (!this->local_pool) { ret = -1; gf_log(this->name, GF_LOG_ERROR, "failed to create read_only_priv_t's memory pool"); goto out; } priv = mem_get0(this->local_pool); if (!priv) { gf_log(this->name, GF_LOG_ERROR, "Error allocating priv"); goto out; } this->private = priv; GF_OPTION_INIT("worm", priv->readonly_or_worm_enabled, bool, out); GF_OPTION_INIT("worm-file-level", priv->worm_file, bool, out); GF_OPTION_INIT("default-retention-period", priv->reten_period, int64, out); GF_OPTION_INIT("auto-commit-period", priv->com_period, int64, out); GF_OPTION_INIT("retention-mode", reten_mode, str, out); set_reten_mode(priv, reten_mode); GF_OPTION_INIT("worm-files-deletable", priv->worm_files_deletable, bool, out); ret = 0; out: return ret; } int reconfigure(xlator_t *this, dict_t *options) { read_only_priv_t *priv = NULL; char *reten_mode = NULL; int ret = -1; priv = this->private; GF_ASSERT(priv); GF_OPTION_RECONF("worm", priv->readonly_or_worm_enabled, options, bool, out); GF_OPTION_RECONF("worm-file-level", priv->worm_file, options, bool, out); GF_OPTION_RECONF("default-retention-period", priv->reten_period, options, int64, out); GF_OPTION_RECONF("retention-mode", reten_mode, options, str, out); set_reten_mode(priv, reten_mode); GF_OPTION_RECONF("auto-commit-period", priv->com_period, options, int64, out); GF_OPTION_RECONF("worm-files-deletable", priv->worm_files_deletable, options, bool, out); ret = 0; out: gf_log(this->name, GF_LOG_DEBUG, "returning %d", ret); return ret; } void fini(xlator_t *this) { read_only_priv_t *priv = NULL; priv = this->private; if (!priv) goto out; mem_put(priv); this->private = NULL; mem_pool_destroy(this->local_pool); this->local_pool = NULL; out: return; } struct xlator_fops fops = { .open = worm_open, .writev = worm_writev, .setattr = worm_setattr, .fsetattr = worm_fsetattr, .rename = worm_rename, .link = worm_link, .unlink = worm_unlink, .truncate = worm_truncate, .ftruncate = worm_ftruncate, .create = worm_create, .rmdir = ro_rmdir, .removexattr = ro_removexattr, .fsyncdir = ro_fsyncdir, .xattrop = ro_xattrop, .inodelk = ro_inodelk, .finodelk = ro_finodelk, .entrylk = ro_entrylk, .fentrylk = ro_fentrylk, .lk = ro_lk, }; int32_t worm_release(xlator_t *this, fd_t *fd) { dict_t *dict = NULL; int ret = -1; dict = dict_new(); uint64_t value = 0; loc_t loc = { 0, }; read_only_priv_t *priv = NULL; priv = this->private; if (priv->worm_file) { if (!dict) { gf_log(this->name, GF_LOG_ERROR, "Error creating the dict"); goto out; } value = fd_ctx_get(fd, this); if (!value) { gf_log(this->name, GF_LOG_DEBUG, "Failed to get the fd ctx"); goto out; } ret = dict_set_int8(dict, "trusted.worm_file", 1); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Error in setting " "the dict"); goto out; } loc.inode = inode_ref(fd->inode); gf_uuid_copy(loc.gfid, fd->inode->gfid); ret = syncop_setxattr(this, &loc, dict, 0, NULL, NULL); if (ret) { gf_log(this->name, GF_LOG_ERROR, "Error setting xattr"); goto out; } gf_worm_state_transition(this, _gf_false, &loc, GF_FOP_WRITE); } out: loc_wipe(&loc); if (dict) dict_unref(dict); return 0; } struct xlator_cbks cbks = { .release = worm_release, }; struct volume_options options[] = { {.key = {"worm"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", /*.validate_fn = validate_boolean,*/ .op_version = {2}, .flags = OPT_FLAG_SETTABLE, .description = "When \"on\", makes a volume get write once read many " " feature. It is turned \"off\" by default."}, {.key = {"worm-file-level"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", /*.validate_fn = validate_boolean,*/ .op_version = {GD_OP_VERSION_3_8_0}, .flags = OPT_FLAG_SETTABLE, .description = "When \"on\", activates the file level worm. " "It is turned \"off\" by default."}, {.key = {"worm-files-deletable"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", /*.validate_fn = validate_boolean,*/ .op_version = {GD_OP_VERSION_3_13_0}, .flags = OPT_FLAG_SETTABLE, .description = "When \"off\", doesn't allow the Worm files" "to be deleted. It is turned \"on\" by default."}, {.key = {"default-retention-period"}, .type = GF_OPTION_TYPE_TIME, .default_value = "120", /*.validate_fn = validate_worm_period,*/ .op_version = {GD_OP_VERSION_3_8_0}, .flags = OPT_FLAG_SETTABLE, .description = "The default retention period for the files."}, {.key = {"retention-mode"}, .type = GF_OPTION_TYPE_STR, .default_value = "relax", /*.validate_fn = validate_reten_mode,*/ .op_version = {GD_OP_VERSION_3_8_0}, .flags = OPT_FLAG_SETTABLE, .description = "The mode of retention (relax/enterprise). " "It is relax by default."}, {.key = {"auto-commit-period"}, .type = GF_OPTION_TYPE_TIME, .default_value = "180", /*.validate_fn = validate_worm_period,*/ .op_version = {GD_OP_VERSION_3_8_0}, .flags = OPT_FLAG_SETTABLE, .description = "Auto commit period for the files."}, {.key = {NULL}}, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .reconfigure = reconfigure, .mem_acct_init = mem_acct_init, .op_version = {1}, /* Present from the initial version */ .fops = &fops, .cbks = &cbks, .options = options, .identifier = "worm", .category = GF_TECH_PREVIEW, }; glusterfs-11.1/xlators/features/read-only/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202464023635 xustar000000000000000030 mtime=1699284276.828061049 30 atime=1699284290.496102217 30 ctime=1699284303.447141225 glusterfs-11.1/xlators/features/read-only/Makefile.in0000664000175100017510000005273514522202464024130 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/features/read-only DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/features/read-only/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/features/read-only/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/features/read-only/PaxHeaders.9031/Makefile.am0000644000000000000000000000013214522202451023620 xustar000000000000000030 mtime=1699284265.685027486 30 atime=1699284276.804060977 30 ctime=1699284303.449141231 glusterfs-11.1/xlators/features/read-only/Makefile.am0000664000175100017510000000003514522202451024075 0ustar00jenkinsjenkins00000000000000SUBDIRS = src CLEANFILES = glusterfs-11.1/xlators/PaxHeaders.9031/mgmt0000644000000000000000000000013214522202522016742 xustar000000000000000030 mtime=1699284306.461150302 30 atime=1699284309.688160022 30 ctime=1699284306.461150302 glusterfs-11.1/xlators/mgmt/0002775000175100017510000000000014522202522017300 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/mgmt/PaxHeaders.9031/Makefile.in0000644000000000000000000000013214522202465021072 xustar000000000000000030 mtime=1699284277.845064113 30 atime=1699284291.588105506 30 ctime=1699284306.455150284 glusterfs-11.1/xlators/mgmt/Makefile.in0000664000175100017510000005267014522202465021363 0ustar00jenkinsjenkins00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xlators/mgmt DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \ $(top_srcdir)/contrib/aclocal/python.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/site.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ACL_LIBS = @ACL_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ ARGP_LDADD = @ARGP_LDADD@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_GNFS = @BUILD_GNFS@ BUILD_PYTHON_SITE_PACKAGES = @BUILD_PYTHON_SITE_PACKAGES@ BUILD_PYTHON_SITE_PACKAGES_EXPANDED = @BUILD_PYTHON_SITE_PACKAGES_EXPANDED@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONTRIBDIR = @CONTRIBDIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EVENTS_ENABLED = @EVENTS_ENABLED@ EVENTS_SUBDIR = @EVENTS_SUBDIR@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@ FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@ GEOREP_EXTRAS_SUBDIR = @GEOREP_EXTRAS_SUBDIR@ GFAPI_EXTRA_LDFLAGS = @GFAPI_EXTRA_LDFLAGS@ GFAPI_LIBS = @GFAPI_LIBS@ GFAPI_LT_VERSION = @GFAPI_LT_VERSION@ GFAPI_VERSION = @GFAPI_VERSION@ GF_CFLAGS = @GF_CFLAGS@ GF_CPPFLAGS = @GF_CPPFLAGS@ GF_DISTRIBUTION = @GF_DISTRIBUTION@ GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@ GF_FUSE_LDADD = @GF_FUSE_LDADD@ GF_HOST_OS = @GF_HOST_OS@ GF_LDADD = @GF_LDADD@ GF_LDFLAGS = @GF_LDFLAGS@ GF_NO_UNDEFINED = @GF_NO_UNDEFINED@ GF_XLATOR_DEFAULT_LDFLAGS = @GF_XLATOR_DEFAULT_LDFLAGS@ GF_XLATOR_LDFLAGS = @GF_XLATOR_LDFLAGS@ GF_XLATOR_MGNT_LIBADD = @GF_XLATOR_MGNT_LIBADD@ GLUSTERD_VOLFILE = @GLUSTERD_VOLFILE@ GLUSTERD_WORKDIR = @GLUSTERD_WORKDIR@ GLUSTERFSD_MISCDIR = @GLUSTERFSD_MISCDIR@ GLUSTERFS_LIBEXECDIR = @GLUSTERFS_LIBEXECDIR@ GREP = @GREP@ HAVE_ATOMIC_BUILTINS = @HAVE_ATOMIC_BUILTINS@ HAVE_BACKTRACE = @HAVE_BACKTRACE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_FUTIMES = @HAVE_FUTIMES@ HAVE_LINKAT = @HAVE_LINKAT@ HAVE_MALLINFO = @HAVE_MALLINFO@ HAVE_MALLINFO2 = @HAVE_MALLINFO2@ HAVE_STRNLEN = @HAVE_STRNLEN@ HAVE_SYNC_BUILTINS = @HAVE_SYNC_BUILTINS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAIO = @LIBAIO@ LIBGFCHANGELOG_LT_VERSION = @LIBGFCHANGELOG_LT_VERSION@ LIBGFCHANGELOG_VERSION = @LIBGFCHANGELOG_VERSION@ LIBGFRPC_LT_VERSION = @LIBGFRPC_LT_VERSION@ LIBGFXDR_LT_VERSION = @LIBGFXDR_LT_VERSION@ LIBGLUSTERFS_LT_VERSION = @LIBGLUSTERFS_LT_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBURING = @LIBURING@ LIB_DL = @LIB_DL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OCF_SUBDIR = @OCF_SUBDIR@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_RELEASE = @PACKAGE_RELEASE@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGCONFIG_UUID = @PKGCONFIG_UUID@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ READLINE_CFLAGS = @READLINE_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ RLLIBS = @RLLIBS@ RPCBIND_SERVICE = @RPCBIND_SERVICE@ RPCGEN = @RPCGEN@ SBIN_DIR = @SBIN_DIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIZEOF_INT = @SIZEOF_INT@ SIZEOF_LONG = @SIZEOF_LONG@ SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@ SIZEOF_SHORT = @SIZEOF_SHORT@ SSL_CERT_PATH = @SSL_CERT_PATH@ STRIP = @STRIP@ SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@ SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@ SYSCONF_DIR = @SYSCONF_DIR@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ UMOUNTD_SUBDIR = @UMOUNTD_SUBDIR@ UNITTEST_CFLAGS = @UNITTEST_CFLAGS@ UNITTEST_LDFLAGS = @UNITTEST_LDFLAGS@ UNITTEST_LIBS = @UNITTEST_LIBS@ URCU_CDS_CFLAGS = @URCU_CDS_CFLAGS@ URCU_CDS_LIBS = @URCU_CDS_LIBS@ URCU_CFLAGS = @URCU_CFLAGS@ URCU_LIBS = @URCU_LIBS@ USE_EC_DYNAMIC_AVX = @USE_EC_DYNAMIC_AVX@ USE_EC_DYNAMIC_NEON = @USE_EC_DYNAMIC_NEON@ USE_EC_DYNAMIC_SSE = @USE_EC_DYNAMIC_SSE@ USE_EC_DYNAMIC_X64 = @USE_EC_DYNAMIC_X64@ USE_POSIX_ACLS = @USE_POSIX_ACLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ XXHASH_CFLAGS = @XXHASH_CFLAGS@ XXHASH_LIBS = @XXHASH_LIBS@ XXHSUM = @XXHSUM@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bashcompdir = @bashcompdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ launchddir = @launchddir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ mountutildir = @mountutildir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shrext_cmds = @shrext_cmds@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ systemddir = @systemddir@ target_alias = @target_alias@ tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = glusterd CLEANFILES = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xlators/mgmt/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xlators/mgmt/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: glusterfs-11.1/xlators/mgmt/PaxHeaders.9031/Makefile.am0000644000000000000000000000013114522202451021053 xustar000000000000000030 mtime=1699284265.704027543 30 atime=1699284277.820064037 29 ctime=1699284306.45715029 glusterfs-11.1/xlators/mgmt/Makefile.am0000664000175100017510000000004214522202451021327 0ustar00jenkinsjenkins00000000000000SUBDIRS = glusterd CLEANFILES = glusterfs-11.1/xlators/mgmt/PaxHeaders.9031/glusterd0000644000000000000000000000013214522202522020573 xustar000000000000000030 mtime=1699284306.495150405 30 atime=1699284309.688160022 30 ctime=1699284306.495150405 glusterfs-11.1/xlators/mgmt/glusterd/0002775000175100017510000000000014522202522021131 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/mgmt/glusterd/PaxHeaders.9031/src0000644000000000000000000000013214522202522021362 xustar000000000000000030 mtime=1699284306.660150902 30 atime=1699284309.688160022 30 ctime=1699284306.660150902 glusterfs-11.1/xlators/mgmt/glusterd/src/0002775000175100017510000000000014522202522021720 5ustar00jenkinsjenkins00000000000000glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-quotad-svc.h0000644000000000000000000000013214522202451025526 xustar000000000000000030 mtime=1699284265.722027598 30 atime=1699284265.722027598 30 ctime=1699284306.574150643 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-quotad-svc.h0000664000175100017510000000136614522202451026013 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GLUSTERD_QUOTAD_SVC_H_ #define _GLUSTERD_QUOTAD_SVC_H_ #include "glusterd-svc-mgmt.h" void glusterd_quotadsvc_build(glusterd_svc_t *svc); int glusterd_quotadsvc_init(glusterd_svc_t *svc); int glusterd_quotadsvc_start(glusterd_svc_t *svc, int flags); int glusterd_quotadsvc_manager(glusterd_svc_t *svc, void *data, int flags); int glusterd_quotadsvc_reconfigure(void); #endif glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-proc-mgmt.c0000644000000000000000000000013214522202451025340 xustar000000000000000030 mtime=1699284265.721027594 30 atime=1699284265.721027594 30 ctime=1699284306.638150836 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-proc-mgmt.c0000664000175100017510000000771614522202451025632 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "glusterd-utils.h" #include #include #include "glusterd-messages.h" #include "glusterd-proc-mgmt.h" int glusterd_proc_init(glusterd_proc_t *proc, char *name, char *pidfile, char *logdir, char *logfile, char *volfile, char *volfileid, char *volfileserver) { int ret = -1; ret = snprintf(proc->name, sizeof(proc->name), "%s", name); if (ret < 0) goto out; ret = snprintf(proc->pidfile, sizeof(proc->pidfile), "%s", pidfile); if (ret < 0) goto out; ret = snprintf(proc->logdir, sizeof(proc->logdir), "%s", logdir); if (ret < 0) goto out; ret = snprintf(proc->logfile, sizeof(proc->logfile), "%s", logfile); if (ret < 0) goto out; ret = snprintf(proc->volfile, sizeof(proc->volfile), "%s", volfile); if (ret < 0) goto out; ret = snprintf(proc->volfileid, sizeof(proc->volfileid), "%s", volfileid); if (ret < 0) goto out; ret = snprintf(proc->volfileserver, sizeof(proc->volfileserver), "%s", volfileserver); if (ret < 0) goto out; out: if (ret > 0) ret = 0; return ret; } int glusterd_proc_stop(glusterd_proc_t *proc, int sig, int flags) { /* NB: Copy-paste code from glusterd_service_stop, the source may be * removed once all daemon management use proc */ int32_t ret = -1; pid_t pid = -1; xlator_t *this = THIS; glusterd_conf_t *conf = NULL; int tries; conf = this->private; GF_ASSERT(conf); if (!gf_is_service_running(proc->pidfile, &pid)) { ret = 0; gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_ALREADY_STOPPED, "%s already stopped", proc->name); goto out; } gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_SVC_STOP_SUCCESS, "Stopping %s daemon running in pid: " "%d", proc->name, pid); ret = kill(pid, sig); if (ret) { switch (errno) { case ESRCH: gf_msg_debug(this->name, 0, "%s is already " "stopped", proc->name); ret = 0; goto out; default: gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_SVC_KILL_FAIL, "Unable to kill %s " "service, reason:%s", proc->name, strerror(errno)); } } else { gf_unlink(proc->pidfile); } if (flags != PROC_STOP_FORCE) goto out; for (tries = 10; tries > 0; --tries) { if (gf_is_service_running(proc->pidfile, &pid)) { synclock_unlock(&conf->big_lock); synctask_usleep(100000); synclock_lock(&conf->big_lock); } else { ret = 0; goto out; } } if (gf_is_service_running(proc->pidfile, &pid)) { ret = kill(pid, SIGKILL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_PID_KILL_FAIL, "Unable to kill pid:%d, " "reason:%s", pid, strerror(errno)); goto out; } gf_unlink(proc->pidfile); } ret = 0; out: return ret; } int glusterd_proc_get_pid(glusterd_proc_t *proc) { int pid = -1; (void)gf_is_service_running(proc->pidfile, &pid); return pid; } int glusterd_proc_is_running(glusterd_proc_t *proc) { int pid = -1; return gf_is_service_running(proc->pidfile, &pid); } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-sm.h0000644000000000000000000000013214522202451024057 xustar000000000000000030 mtime=1699284265.725027606 30 atime=1699284265.725027606 30 ctime=1699284306.545150555 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-sm.h0000664000175100017510000001224014522202451024335 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GLUSTERD_SM_H_ #define _GLUSTERD_SM_H_ #include #include #include "rpc-clnt.h" #include #include "rpcsvc.h" #include #include "glusterd-rcu.h" typedef enum gd_quorum_contribution_ { QUORUM_NONE, QUORUM_WAITING, QUORUM_DOWN, QUORUM_UP } gd_quorum_contrib_t; typedef enum glusterd_friend_sm_state_ { GD_FRIEND_STATE_DEFAULT = 0, GD_FRIEND_STATE_REQ_SENT, GD_FRIEND_STATE_REQ_RCVD, GD_FRIEND_STATE_BEFRIENDED, GD_FRIEND_STATE_REQ_ACCEPTED, GD_FRIEND_STATE_REQ_SENT_RCVD, GD_FRIEND_STATE_REJECTED, GD_FRIEND_STATE_UNFRIEND_SENT, GD_FRIEND_STATE_PROBE_RCVD, GD_FRIEND_STATE_CONNECTED_RCVD, GD_FRIEND_STATE_CONNECTED_ACCEPTED, GD_FRIEND_STATE_MAX } glusterd_friend_sm_state_t; typedef struct glusterd_peer_hostname_ { char *hostname; struct cds_list_head hostname_list; } glusterd_peer_hostname_t; typedef struct glusterd_sm_transition_ { int old_state; int event; int new_state; time_t time; } glusterd_sm_transition_t; typedef struct glusterd_sm_tr_log_ { glusterd_sm_transition_t *transitions; size_t current; size_t size; size_t count; char *(*state_name_get)(int); char *(*event_name_get)(int); } glusterd_sm_tr_log_t; struct glusterd_peerinfo_ { uuid_t uuid; char uuid_str[50]; /* Retrieve this using * gd_peer_uuid_str () */ glusterd_friend_sm_state_t state; char *hostname; struct cds_list_head hostnames; int connected; int port; struct cds_list_head uuid_list; struct rpc_clnt *rpc; rpc_clnt_prog_t *mgmt; rpc_clnt_prog_t *peer; rpc_clnt_prog_t *mgmt_v3; gf_store_handle_t *shandle; glusterd_sm_tr_log_t sm_log; gd_quorum_contrib_t quorum_contrib; uint32_t generation; /* Members required for proper cleanup using RCU */ gd_rcu_head rcu_head; pthread_mutex_t delete_lock; gf_boolean_t locked; gf_boolean_t detaching; gf_boolean_t quorum_action; }; typedef struct glusterd_peerinfo_ glusterd_peerinfo_t; typedef enum glusterd_ev_gen_mode_ { GD_MODE_OFF, GD_MODE_ON, GD_MODE_SWITCH_ON } glusterd_ev_gen_mode_t; typedef struct glusterd_peer_ctx_args_ { rpcsvc_request_t *req; glusterd_ev_gen_mode_t mode; dict_t *dict; } glusterd_peerctx_args_t; typedef struct glusterd_peer_ctx_ { glusterd_peerctx_args_t args; uuid_t peerid; char *peername; uint32_t peerinfo_gen; char *errstr; } glusterd_peerctx_t; typedef enum glusterd_friend_sm_event_type_ { GD_FRIEND_EVENT_NONE = 0, GD_FRIEND_EVENT_PROBE, GD_FRIEND_EVENT_INIT_FRIEND_REQ, GD_FRIEND_EVENT_RCVD_ACC, GD_FRIEND_EVENT_LOCAL_ACC, GD_FRIEND_EVENT_RCVD_RJT, GD_FRIEND_EVENT_LOCAL_RJT, GD_FRIEND_EVENT_RCVD_FRIEND_REQ, GD_FRIEND_EVENT_INIT_REMOVE_FRIEND, GD_FRIEND_EVENT_RCVD_REMOVE_FRIEND, GD_FRIEND_EVENT_REMOVE_FRIEND, GD_FRIEND_EVENT_CONNECTED, GD_FRIEND_EVENT_NEW_NAME, GD_FRIEND_EVENT_MAX } glusterd_friend_sm_event_type_t; typedef enum glusterd_friend_update_op_ { GD_FRIEND_UPDATE_NONE = 0, GD_FRIEND_UPDATE_ADD, GD_FRIEND_UPDATE_DEL, } glusterd_friend_update_op_t; struct glusterd_friend_sm_event_ { struct cds_list_head list; uuid_t peerid; char *peername; void *ctx; glusterd_friend_sm_event_type_t event; }; typedef struct glusterd_friend_sm_event_ glusterd_friend_sm_event_t; typedef int (*glusterd_friend_sm_ac_fn)(glusterd_friend_sm_event_t *, void *); typedef struct glusterd_sm_ { glusterd_friend_sm_state_t next_state; glusterd_friend_sm_ac_fn handler; } glusterd_sm_t; typedef struct glusterd_friend_req_ctx_ { uuid_t uuid; char *hostname; rpcsvc_request_t *req; int port; dict_t *vols; dict_t *peer_ver; // Dictionary to save peer ver data } glusterd_friend_req_ctx_t; typedef struct glusterd_friend_update_ctx_ { uuid_t uuid; char *hostname; int op; } glusterd_friend_update_ctx_t; typedef struct glusterd_probe_ctx_ { char *hostname; rpcsvc_request_t *req; int port; dict_t *dict; } glusterd_probe_ctx_t; int glusterd_friend_sm_new_event(glusterd_friend_sm_event_type_t event_type, glusterd_friend_sm_event_t **new_event); int glusterd_friend_sm_inject_event(glusterd_friend_sm_event_t *event); int glusterd_friend_sm_init(void); int glusterd_friend_sm(void); void glusterd_destroy_probe_ctx(glusterd_probe_ctx_t *ctx); void glusterd_destroy_friend_req_ctx(glusterd_friend_req_ctx_t *ctx); char * glusterd_friend_sm_state_name_get(int state); char * glusterd_friend_sm_event_name_get(int event); int glusterd_broadcast_friend_delete(char *hostname, uuid_t uuid); void glusterd_destroy_friend_update_ctx(glusterd_friend_update_ctx_t *ctx); #endif glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-op-sm.c0000644000000000000000000000013214522202451024466 xustar000000000000000030 mtime=1699284265.720027591 30 atime=1699284265.718027585 30 ctime=1699284306.598150715 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-op-sm.c0000664000175100017510000100703014522202451024746 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include "fnmatch.h" #include #include #include #include #include "glusterd-op-sm.h" #include "glusterd-utils.h" #include "glusterd-store.h" #include "glusterd-locks.h" #include "glusterd-quota.h" #include #include "glusterd-snapshot-utils.h" #include "glusterd-svc-mgmt.h" #include "glusterd-svc-helper.h" #include "glusterd-shd-svc-helper.h" #include "glusterd-shd-svc.h" #include "glusterd-quotad-svc.h" #include "glusterd-server-quorum.h" #include #include #include #include "glusterd-gfproxyd-svc-helper.h" #define len_strcmp(key, len, str) \ ((len == SLEN(str)) && (strcmp(key, str) == 0)) extern char local_node_hostname[PATH_MAX]; static int glusterd_set_shared_storage(dict_t *dict, char *key, char *value, char **op_errstr); /* * Valid options for all volumes to be listed in the valid_all_vol_opts table. * To add newer options to all volumes, we can just add more entries to this * table. * * It's important that every value have a default, or have a special handler * in glusterd_get_global_options_for_all_vols, or else we might crash there. */ const glusterd_all_vol_opts valid_all_vol_opts[] = { {GLUSTERD_QUORUM_RATIO_KEY, "51"}, {GLUSTERD_SHARED_STORAGE_KEY, "disable"}, /* This one actually gets filled in dynamically. */ {GLUSTERD_GLOBAL_OP_VERSION_KEY, "BUG_NO_OP_VERSION"}, /* * This one should be filled in dynamically, but it didn't used to be * (before the defaults were added here) so the value is unclear. * * TBD: add a dynamic handler to set the appropriate value */ {GLUSTERD_MAX_OP_VERSION_KEY, "BUG_NO_MAX_OP_VERSION"}, {GLUSTERD_BRICK_MULTIPLEX_KEY, "disable"}, /* Set this value to 0 by default implying brick-multiplexing * behaviour with no limit set on the number of brick instances that * can be attached per process. * TBD: Discuss the default value for this. Maybe this should be a * dynamic value depending on the memory specifications per node */ {GLUSTERD_BRICKMUX_LIMIT_KEY, GLUSTERD_BRICKMUX_LIMIT_DFLT_VALUE}, {GLUSTERD_VOL_CNT_PER_THRD, GLUSTERD_VOL_CNT_PER_THRD_DEFAULT_VALUE}, {GLUSTERD_LOCALTIME_LOGGING_KEY, "disable"}, {GLUSTERD_DAEMON_LOG_LEVEL_KEY, "INFO"}, {GLUSTER_BRICK_GRACEFUL_CLEANUP, "disable"}, {NULL}, }; static struct cds_list_head gd_op_sm_queue; synclock_t gd_op_sm_lock; glusterd_op_info_t opinfo = { GD_OP_STATE_DEFAULT, }; int32_t glusterd_txn_opinfo_dict_init(void) { int32_t ret = -1; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; priv = this->private; GF_ASSERT(priv); priv->glusterd_txn_opinfo = dict_new(); if (!priv->glusterd_txn_opinfo) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); ret = -1; goto out; } memset(priv->global_txn_id, '\0', sizeof(uuid_t)); ret = 0; out: return ret; } void glusterd_txn_opinfo_dict_fini(void) { glusterd_conf_t *priv = NULL; priv = THIS->private; GF_ASSERT(priv); if (priv->glusterd_txn_opinfo) dict_unref(priv->glusterd_txn_opinfo); } void glusterd_txn_opinfo_init(glusterd_op_info_t *opinfo, glusterd_op_sm_state_t state, int *op, dict_t *op_ctx, rpcsvc_request_t *req) { glusterd_conf_t *conf = NULL; GF_ASSERT(opinfo); conf = THIS->private; GF_ASSERT(conf); if (state) opinfo->state = state; if (op) opinfo->op = *op; if (op_ctx) opinfo->op_ctx = dict_ref(op_ctx); else opinfo->op_ctx = NULL; if (req) opinfo->req = req; opinfo->txn_generation = conf->generation; cmm_smp_rmb(); return; } int32_t glusterd_generate_txn_id(dict_t *dict, uuid_t **txn_id) { int32_t ret = -1; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); GF_ASSERT(dict); *txn_id = GF_MALLOC(sizeof(uuid_t), gf_common_mt_uuid_t); if (!*txn_id) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } if (priv->op_version < GD_OP_VERSION_3_6_0) gf_uuid_copy(**txn_id, priv->global_txn_id); else gf_uuid_generate(**txn_id); ret = dict_set_bin(dict, "transaction_id", *txn_id, sizeof(**txn_id)); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to set transaction id."); goto out; } gf_msg_debug(this->name, 0, "Transaction_id = %s", uuid_utoa(**txn_id)); out: if (ret && *txn_id) { GF_FREE(*txn_id); *txn_id = NULL; } return ret; } int32_t glusterd_get_txn_opinfo(uuid_t *txn_id, glusterd_op_info_t *opinfo) { int32_t ret = -1; glusterd_txn_opinfo_obj *opinfo_obj = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); if (!txn_id || !opinfo) { gf_msg_callingfn(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_ID_GET_FAIL, "Empty transaction id or opinfo received."); ret = -1; goto out; } ret = dict_get_bin(priv->glusterd_txn_opinfo, uuid_utoa(*txn_id), (void **)&opinfo_obj); if (ret) goto out; (*opinfo) = opinfo_obj->opinfo; gf_msg_debug(this->name, 0, "Successfully got opinfo for transaction ID : %s", uuid_utoa(*txn_id)); ret = 0; out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } int32_t glusterd_set_txn_opinfo(uuid_t *txn_id, glusterd_op_info_t *opinfo) { int32_t ret = -1; glusterd_txn_opinfo_obj *opinfo_obj = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); if (!txn_id) { gf_msg_callingfn(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_ID_GET_FAIL, "Empty transaction id received."); ret = -1; goto out; } ret = dict_get_bin(priv->glusterd_txn_opinfo, uuid_utoa(*txn_id), (void **)&opinfo_obj); if (ret) { opinfo_obj = GF_CALLOC(1, sizeof(glusterd_txn_opinfo_obj), gf_common_mt_txn_opinfo_obj_t); if (!opinfo_obj) { ret = -1; goto out; } ret = dict_set_bin(priv->glusterd_txn_opinfo, uuid_utoa(*txn_id), opinfo_obj, sizeof(glusterd_txn_opinfo_obj)); if (ret) { gf_msg_callingfn(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Unable to set opinfo for transaction" " ID : %s", uuid_utoa(*txn_id)); goto out; } } opinfo_obj->opinfo = (*opinfo); gf_msg_debug(this->name, 0, "Successfully set opinfo for transaction ID : %s", uuid_utoa(*txn_id)); ret = 0; out: if (ret) if (opinfo_obj) GF_FREE(opinfo_obj); gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } int32_t glusterd_clear_txn_opinfo(uuid_t *txn_id) { int32_t ret = -1; glusterd_op_info_t txn_op_info = { GD_OP_STATE_DEFAULT, }; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); if (!txn_id) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_ID_GET_FAIL, "Empty transaction id received."); ret = -1; goto out; } ret = glusterd_get_txn_opinfo(txn_id, &txn_op_info); if (ret) { gf_msg_callingfn(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_GET_FAIL, "Unable to get transaction opinfo " "for transaction ID : %s", uuid_utoa(*txn_id)); goto out; } if (txn_op_info.op_ctx) dict_unref(txn_op_info.op_ctx); dict_del(priv->glusterd_txn_opinfo, uuid_utoa(*txn_id)); gf_msg_debug(this->name, 0, "Successfully cleared opinfo for transaction ID : %s", uuid_utoa(*txn_id)); ret = 0; out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int glusterfs_port = GLUSTERD_DEFAULT_PORT; static char *glusterd_op_sm_state_names[] = { "Default", "Lock sent", "Locked", "Stage op sent", "Staged", "Commit op sent", "Committed", "Unlock sent", "Stage op failed", "Commit op failed", "Brick op sent", "Brick op failed", "Brick op Committed", "Brick op Commit failed", "Ack drain", "Invalid", }; static char *glusterd_op_sm_event_names[] = { "GD_OP_EVENT_NONE", "GD_OP_EVENT_START_LOCK", "GD_OP_EVENT_LOCK", "GD_OP_EVENT_RCVD_ACC", "GD_OP_EVENT_ALL_ACC", "GD_OP_EVENT_STAGE_ACC", "GD_OP_EVENT_COMMIT_ACC", "GD_OP_EVENT_RCVD_RJT", "GD_OP_EVENT_STAGE_OP", "GD_OP_EVENT_COMMIT_OP", "GD_OP_EVENT_UNLOCK", "GD_OP_EVENT_START_UNLOCK", "GD_OP_EVENT_ALL_ACK", "GD_OP_EVENT_LOCAL_UNLOCK_NO_RESP", "GD_OP_EVENT_INVALID"}; char * glusterd_op_sm_state_name_get(int state) { if (state < 0 || state >= GD_OP_STATE_MAX) return glusterd_op_sm_state_names[GD_OP_STATE_MAX]; return glusterd_op_sm_state_names[state]; } char * glusterd_op_sm_event_name_get(int event) { if (event < 0 || event >= GD_OP_EVENT_MAX) return glusterd_op_sm_event_names[GD_OP_EVENT_MAX]; return glusterd_op_sm_event_names[event]; } static void glusterd_destroy_lock_ctx(glusterd_op_lock_ctx_t *ctx) { if (!ctx) return; GF_FREE(ctx); } void glusterd_set_volume_status(glusterd_volinfo_t *volinfo, glusterd_volume_status status) { GF_ASSERT(volinfo); volinfo->status = status; } static int glusterd_op_sm_inject_all_acc(uuid_t *txn_id) { int ret = -1; ret = glusterd_op_sm_inject_event(GD_OP_EVENT_ALL_ACC, txn_id, NULL); gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int glusterd_check_bitrot_cmd(char *key, const int keylen, char *errstr, const size_t size) { int ret = -1; if (len_strcmp(key, keylen, "bitrot") || len_strcmp(key, keylen, "features.bitrot")) { snprintf(errstr, size, " 'gluster volume set %s' is invalid command." " Use 'gluster volume bitrot {enable|disable}'" " instead.", key); goto out; } else if (len_strcmp(key, keylen, "scrub-freq") || len_strcmp(key, keylen, "features.scrub-freq")) { snprintf(errstr, size, " 'gluster volume set %s' is invalid command." " Use 'gluster volume bitrot scrub-frequency" " {hourly|daily|weekly|biweekly|monthly}' instead.", key); goto out; } else if (len_strcmp(key, keylen, "scrub") || len_strcmp(key, keylen, "features.scrub")) { snprintf(errstr, size, " 'gluster volume set %s' is invalid command." " Use 'gluster volume bitrot scrub {pause|resume}'" " instead.", key); goto out; } else if (len_strcmp(key, keylen, "scrub-throttle") || len_strcmp(key, keylen, "features.scrub-throttle")) { snprintf(errstr, size, " 'gluster volume set %s' is invalid command." " Use 'gluster volume bitrot scrub-throttle " " {lazy|normal|aggressive}' instead.", key); goto out; } ret = 0; out: return ret; } static int glusterd_check_quota_cmd(char *key, const int keylen, char *value, char *errstr, size_t size) { int ret = -1; gf_boolean_t b = _gf_false; if (len_strcmp(key, keylen, "quota") || len_strcmp(key, keylen, "features.quota")) { ret = gf_string2boolean(value, &b); if (ret) goto out; ret = -1; if (b) { snprintf(errstr, size, " 'gluster volume set %s %s' is deprecated." " Use 'gluster volume quota enable' instead.", key, value); } else { snprintf(errstr, size, " 'gluster volume set %s %s' is deprecated." " Use 'gluster volume quota disable' instead.", key, value); } goto out; } else if (len_strcmp(key, keylen, "inode-quota") || len_strcmp(key, keylen, "features.inode-quota")) { ret = gf_string2boolean(value, &b); if (ret) goto out; ret = -1; if (b) { snprintf( errstr, size, " 'gluster volume set %s %s' is deprecated." " Use 'gluster volume inode-quota enable' instead.", key, value); } else { /* inode-quota disable not supported, * use quota disable */ snprintf(errstr, size, " 'gluster volume set %s %s' is deprecated." " Use 'gluster volume quota disable' instead.", key, value); } goto out; } ret = 0; out: return ret; } int glusterd_brick_op_build_payload(glusterd_op_t op, glusterd_brickinfo_t *brickinfo, gd1_mgmt_brick_op_req **req, dict_t *dict) { int ret = -1; gd1_mgmt_brick_op_req *brick_req = NULL; char *volname = NULL; char name[1024] = { 0, }; gf_xl_afr_op_t heal_op = GF_SHD_OP_INVALID; xlator_t *this = THIS; glusterd_volinfo_t *volinfo = NULL; GF_ASSERT(op < GD_OP_MAX); GF_ASSERT(op > GD_OP_NONE); GF_ASSERT(req); switch (op) { case GD_OP_REMOVE_BRICK: case GD_OP_STOP_VOLUME: brick_req = GF_CALLOC(1, sizeof(*brick_req), gf_gld_mt_mop_brick_req_t); if (!brick_req) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } brick_req->op = GLUSTERD_BRICK_TERMINATE; brick_req->name = brickinfo->path; glusterd_set_brick_status(brickinfo, GF_BRICK_STOPPING); break; case GD_OP_PROFILE_VOLUME: brick_req = GF_CALLOC(1, sizeof(*brick_req), gf_gld_mt_mop_brick_req_t); if (!brick_req) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } brick_req->op = GLUSTERD_BRICK_XLATOR_INFO; brick_req->name = brickinfo->path; break; case GD_OP_HEAL_VOLUME: { brick_req = GF_CALLOC(1, sizeof(*brick_req), gf_gld_mt_mop_brick_req_t); if (!brick_req) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } brick_req->op = GLUSTERD_BRICK_XLATOR_OP; brick_req->name = ""; ret = dict_get_int32(dict, "heal-op", (int32_t *)&heal_op); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=heal-op", NULL); goto out; } ret = dict_set_int32_sizen(dict, "xl-op", heal_op); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=xl-op", NULL); goto out; } } break; case GD_OP_STATUS_VOLUME: { brick_req = GF_CALLOC(1, sizeof(*brick_req), gf_gld_mt_mop_brick_req_t); if (!brick_req) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } brick_req->op = GLUSTERD_BRICK_STATUS; brick_req->name = ""; ret = dict_set_str_sizen(dict, "brick-name", brickinfo->path); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=brick-name", NULL); goto out; } } break; case GD_OP_REBALANCE: case GD_OP_DEFRAG_BRICK_VOLUME: brick_req = GF_CALLOC(1, sizeof(*brick_req), gf_gld_mt_mop_brick_req_t); if (!brick_req) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } brick_req->op = GLUSTERD_BRICK_XLATOR_DEFRAG; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=volname", NULL); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_VOLINFO_GET_FAIL, "Volume=%s", volname, NULL); goto out; } snprintf(name, sizeof(name), "%s-dht", volname); brick_req->name = gf_strdup(name); break; case GD_OP_SNAP: case GD_OP_BARRIER: brick_req = GF_CALLOC(1, sizeof(*brick_req), gf_gld_mt_mop_brick_req_t); if (!brick_req) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } brick_req->op = GLUSTERD_BRICK_BARRIER; brick_req->name = brickinfo->path; break; default: goto out; break; } brick_req->dict.dict_len = 0; brick_req->dict.dict_val = NULL; ret = dict_allocate_and_serialize(dict, &brick_req->input.input_val, &brick_req->input.input_len); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_ALLOC_AND_SERL_LENGTH_GET_FAIL, NULL); goto out; } *req = brick_req; ret = 0; out: if (ret && brick_req) GF_FREE(brick_req); gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } int glusterd_node_op_build_payload(glusterd_op_t op, gd1_mgmt_brick_op_req **req, dict_t *dict) { int ret = -1; gd1_mgmt_brick_op_req *brick_req = NULL; char *volname = NULL; GF_ASSERT(op < GD_OP_MAX); GF_ASSERT(op > GD_OP_NONE); GF_ASSERT(req); xlator_t *this = THIS; switch (op) { case GD_OP_PROFILE_VOLUME: brick_req = GF_CALLOC(1, sizeof(*brick_req), gf_gld_mt_mop_brick_req_t); if (!brick_req) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } brick_req->op = GLUSTERD_NODE_PROFILE; brick_req->name = ""; break; case GD_OP_STATUS_VOLUME: brick_req = GF_CALLOC(1, sizeof(*brick_req), gf_gld_mt_mop_brick_req_t); if (!brick_req) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } brick_req->op = GLUSTERD_NODE_STATUS; brick_req->name = ""; break; case GD_OP_SCRUB_STATUS: case GD_OP_SCRUB_ONDEMAND: brick_req = GF_CALLOC(1, sizeof(*brick_req), gf_gld_mt_mop_brick_req_t); if (!brick_req) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } brick_req->op = GLUSTERD_NODE_BITROT; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=volname", NULL); goto out; } brick_req->name = gf_strdup(volname); break; default: goto out; } brick_req->dict.dict_len = 0; brick_req->dict.dict_val = NULL; ret = dict_allocate_and_serialize(dict, &brick_req->input.input_val, &brick_req->input.input_len); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_ALLOC_AND_SERL_LENGTH_GET_FAIL, NULL); goto out; } *req = brick_req; ret = 0; out: if (ret && brick_req) GF_FREE(brick_req); gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_validate_quorum_options(xlator_t *this, char *fullkey, char *value, char **op_errstr) { int ret = 0; char *key = NULL; volume_option_t *opt = NULL; if (!glusterd_is_quorum_option(fullkey)) goto out; key = strchr(fullkey, '.'); if (key == NULL) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_STRCHR_FAIL, NULL); ret = -1; goto out; } key++; opt = xlator_volume_option_get(this, key); if (!opt) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_VOLINFO_GET_FAIL, NULL); ret = -1; goto out; } ret = xlator_option_validate(this, key, value, opt, op_errstr); out: return ret; } static int glusterd_validate_brick_mx_options(xlator_t *this, char *fullkey, char *value, char **op_errstr) { int ret = 0; // Placeholder function for now return ret; } static int32_t glusterd_count_connected_peers(int32_t *count) { glusterd_peerinfo_t *peerinfo = NULL; glusterd_conf_t *conf = NULL; int32_t ret = -1; xlator_t *this = THIS; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); GF_VALIDATE_OR_GOTO(this->name, count, out); *count = 1; RCU_READ_LOCK; cds_list_for_each_entry_rcu(peerinfo, &conf->peers, uuid_list) { /* Find peer who is connected and is a friend */ if ((peerinfo->connected) && (peerinfo->state == GD_FRIEND_STATE_BEFRIENDED)) { (*count)++; } } RCU_READ_UNLOCK; ret = 0; out: return ret; } static int glusterd_validate_shared_storage(char *value, char *errstr) { int32_t ret = -1; int32_t count = -1; char *op = NULL; char hook_script[PATH_MAX] = ""; xlator_t *this = THIS; glusterd_conf_t *conf = NULL; int32_t len = 0; glusterd_volinfo_t *volinfo = NULL; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); GF_VALIDATE_OR_GOTO(this->name, value, out); GF_VALIDATE_OR_GOTO(this->name, errstr, out); if ((strcmp(value, "enable")) && (strcmp(value, "disable"))) { snprintf(errstr, PATH_MAX, "Invalid option(%s). Valid options " "are 'enable' and 'disable'", value); gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "%s", errstr); ret = -1; goto out; } len = snprintf(hook_script, sizeof(hook_script), "%s" GLUSTERD_SHRD_STRG_HOOK_SCRIPT, conf->workdir); if ((len < 0) || (len >= sizeof(hook_script))) { ret = -1; goto out; } ret = sys_access(hook_script, R_OK | X_OK); if (ret) { len = snprintf(errstr, PATH_MAX, "The hook-script (%s) required " "for this operation is not present. " "Please install the hook-script " "and retry", hook_script); if (len < 0) { strncpy(errstr, "", PATH_MAX); } gf_msg(this->name, GF_LOG_ERROR, ENOENT, GD_MSG_FILE_OP_FAILED, "%s", errstr); goto out; } if (!strncmp(value, "disable", SLEN("disable"))) { ret = dict_get_str(conf->opts, GLUSTERD_SHARED_STORAGE_KEY, &op); if (ret || !strncmp(op, "disable", SLEN("disable"))) { snprintf(errstr, PATH_MAX, "Shared storage volume " "does not exist. Please enable shared storage" " for creating shared storage volume."); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SHARED_STORAGE_DOES_NOT_EXIST, "%s", errstr); ret = -1; goto out; } goto out; } ret = glusterd_volinfo_find(GLUSTER_SHARED_STORAGE, &volinfo); if (!ret) { snprintf(errstr, PATH_MAX, "Shared storage volume(" GLUSTER_SHARED_STORAGE ") already exists."); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_ALREADY_EXIST, "%s", errstr); ret = -1; goto out; } ret = glusterd_count_connected_peers(&count); if (ret) { snprintf(errstr, PATH_MAX, "Failed to calculate number of connected peers."); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_COUNT_GET_FAIL, "%s", errstr); goto out; } if (count <= 1) { snprintf(errstr, PATH_MAX, "More than one node should " "be up/present in the cluster to enable this option"); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INSUFFICIENT_UP_NODES, "%s", errstr); ret = -1; goto out; } out: return ret; } static int glusterd_validate_localtime_logging(char *value, char *errstr) { int32_t ret = -1; xlator_t *this = THIS; glusterd_conf_t *conf = NULL; int already_enabled = 0; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); GF_VALIDATE_OR_GOTO(this->name, value, out); already_enabled = gf_log_get_localtime(); ret = 0; if (strcmp(value, "enable") == 0) { gf_log_set_localtime(1); if (!already_enabled) gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_LOCALTIME_LOGGING_ENABLE, "localtime logging enable"); } else if (strcmp(value, "disable") == 0) { gf_log_set_localtime(0); if (already_enabled) gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_LOCALTIME_LOGGING_DISABLE, "localtime logging disable"); } else { ret = -1; GF_VALIDATE_OR_GOTO(this->name, errstr, out); snprintf(errstr, PATH_MAX, "Invalid option(%s). Valid options " "are 'enable' and 'disable'", value); gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "%s", errstr); } out: return ret; } static int glusterd_validate_daemon_log_level(char *value, char *errstr) { int32_t ret = -1; xlator_t *this = THIS; glusterd_conf_t *conf = NULL; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); GF_VALIDATE_OR_GOTO(this->name, value, out); ret = 0; if ((strcmp(value, "INFO")) && (strcmp(value, "WARNING")) && (strcmp(value, "DEBUG")) && (strcmp(value, "TRACE")) && (strcmp(value, "ERROR"))) { ret = -1; GF_VALIDATE_OR_GOTO(this->name, errstr, out); snprintf(errstr, PATH_MAX, "Invalid option(%s). Valid options " "are 'INFO' or 'WARNING' or 'ERROR' or 'DEBUG' or " " 'TRACE'", value); gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "%s", errstr); } out: return ret; } static int glusterd_op_stage_set_volume(dict_t *dict, char **op_errstr) { int ret = -1; char *volname = NULL; int exists = 0; char *key = NULL; char *key_fixed = NULL; char *value = NULL; char *val_dup = NULL; char keystr[100] = { 0, }; int keystr_len; int keylen; char *trash_path = NULL; int trash_path_len = 0; int count = 0; int dict_count = 0; char errstr[PATH_MAX] = { 0, }; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; dict_t *val_dict = NULL; gf_boolean_t global_opt = _gf_false; gf_boolean_t key_matched = _gf_false; /* if a key was processed or not*/ glusterd_volinfo_t *voliter = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; uint32_t new_op_version = GD_OP_VERSION_MIN; uint32_t local_new_op_version = GD_OP_VERSION_MIN; uint32_t local_new_client_op_version = GD_OP_VERSION_MIN; uint32_t key_op_version = GD_OP_VERSION_MIN; uint32_t local_key_op_version = GD_OP_VERSION_MIN; gf_boolean_t origin_glusterd = _gf_true; gf_boolean_t check_op_version = _gf_true; gf_boolean_t trash_enabled = _gf_false; gf_boolean_t all_vol = _gf_false; struct volopt_map_entry *vmep = NULL; GF_ASSERT(dict); priv = this->private; GF_ASSERT(priv); /* Check if we can support the required op-version * This check is not done on the originator glusterd. The originator * glusterd sets this value. */ origin_glusterd = is_origin_glusterd(dict); if (!origin_glusterd) { /* Check for v3.3.x origin glusterd */ check_op_version = dict_get_str_boolean(dict, "check-op-version", _gf_false); if (check_op_version) { ret = dict_get_uint32(dict, "new-op-version", &new_op_version); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Key=new-op-version", NULL); goto out; } if ((new_op_version > GD_OP_VERSION_MAX) || (new_op_version < GD_OP_VERSION_MIN)) { ret = -1; snprintf(errstr, sizeof(errstr), "Required op_version (%d) is not supported." " Max supported op version is %d", new_op_version, priv->op_version); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_UNSUPPORTED_VERSION, "%s", errstr); goto out; } } } ret = dict_get_int32(dict, "count", &dict_count); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Count(dict),not set in Volume-Set"); goto out; } if (dict_count == 0) { /*No options would be specified of volume set help */ if (dict_get_sizen(dict, "help")) { ret = 0; goto out; } if (dict_get_sizen(dict, "help-xml")) { #if (HAVE_LIB_XML) ret = 0; goto out; #else ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MODULE_NOT_INSTALLED, "libxml not present in the system"); *op_errstr = gf_strdup( "Error: xml libraries not present to produce xml-output"); goto out; #endif } gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_NO_OPTIONS_GIVEN, "No options received "); *op_errstr = gf_strdup("Options not specified"); ret = -1; goto out; } ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Key=volname", NULL); goto out; } if (strcasecmp(volname, "all") != 0) { ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(errstr, sizeof(errstr), FMTSTR_CHECK_VOL_EXISTS, volname); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, FMTSTR_CHECK_VOL_EXISTS, volname); goto out; } ret = glusterd_validate_volume_id(dict, volinfo); if (ret) goto out; local_new_op_version = volinfo->op_version; local_new_client_op_version = volinfo->client_op_version; } else { all_vol = _gf_true; } val_dict = dict_new(); if (!val_dict) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } for (count = 1; ret != 1; count++) { keystr_len = sprintf(keystr, "key%d", count); ret = dict_get_strn(dict, keystr, keystr_len, &key); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=%s", keystr, NULL); break; } keystr_len = sprintf(keystr, "value%d", count); ret = dict_get_strn(dict, keystr, keystr_len, &value); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "invalid key,value pair in 'volume set'"); ret = -1; goto out; } key_matched = _gf_false; keylen = strlen(key); if (len_strcmp(key, keylen, "config.memory-accounting")) { key_matched = _gf_true; gf_msg_debug(this->name, 0, "enabling memory accounting for volume %s", volname); ret = 0; } else if (len_strcmp(key, keylen, "config.transport")) { key_matched = _gf_true; gf_msg_debug(this->name, 0, "changing transport-type for volume %s", volname); ret = 0; /* if value is none of 'tcp/rdma/tcp,rdma' error out */ if (!((strcasecmp(value, "rdma") == 0) || (strcasecmp(value, "tcp") == 0) || (strcasecmp(value, "tcp,rdma") == 0) || (strcasecmp(value, "rdma,tcp") == 0))) { ret = snprintf(errstr, sizeof(errstr), "transport-type %s does not exist", value); /* lets not bother about above return value, its a failure anyways */ ret = -1; goto out; } } else if (len_strcmp(key, keylen, "ganesha.enable")) { key_matched = _gf_true; if (strcmp(value, "off") == 0) { ret = ganesha_manage_export(dict, "off", _gf_true, op_errstr); if (ret) goto out; } } if (!key_matched) { ret = glusterd_check_bitrot_cmd(key, keylen, errstr, sizeof(errstr)); if (ret) goto out; ret = glusterd_check_quota_cmd(key, keylen, value, errstr, sizeof(errstr)); if (ret) goto out; } if (is_key_glusterd_hooks_friendly(key)) continue; ret = glusterd_volopt_validate(volinfo, dict, key, value, op_errstr); if (ret) goto out; exists = glusterd_check_option_exists(key, &key_fixed); if (exists == -1) { ret = -1; goto out; } if (!exists) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "Option with name: %s does not exist", key); ret = snprintf(errstr, sizeof(errstr), "option : %s does not exist", key); if (key_fixed) snprintf(errstr + ret, sizeof(errstr) - ret, "\nDid you mean %s?", key_fixed); ret = -1; goto out; } if (key_fixed) { key = key_fixed; keylen = strlen(key_fixed); } #ifdef HAVE_LIBAIO if (len_strcmp(key, keylen, "storage.linux-aio")) { if (volinfo && volinfo->status == GLUSTERD_STATUS_STARTED) { snprintf(errstr, sizeof(errstr), "Changing 'storage.linux-aio' is not" " supported when the volume is in started" " state. Please stop the volume first."); ret = -1; goto out; } } #endif /* HAVE_LIBAIO */ #ifdef HAVE_LIBURING if (len_strcmp(key, keylen, "storage.linux-io_uring")) { if (volinfo && volinfo->status == GLUSTERD_STATUS_STARTED) { snprintf(errstr, sizeof(errstr), "Changing 'storage.linux-io_uring' is not" " supported when the volume is in started" " state. Please stop the volume first."); ret = -1; goto out; } } #endif /* HAVE_LIBURING */ if (len_strcmp(key, keylen, "cluster.granular-entry-heal")) { /* For granular entry-heal, if the set command was * invoked through volume-set CLI, then allow the * command only if the volume is still in 'Created' * state */ if (volinfo && volinfo->status != GLUSTERD_STATUS_NONE && (dict_get_sizen(dict, "is-special-key") == NULL)) { snprintf(errstr, sizeof(errstr), " 'gluster volume set %s {enable, disable}'" " is not supported." " Use 'gluster volume heal " "granular-entry-heal {enable, disable}' instead.", key); ret = -1; goto out; } } else if (len_strcmp(key, keylen, GLUSTERD_GLOBAL_OP_VERSION_KEY)) { /* Check if the key is cluster.op-version and set * local_new_op_version to the value given if possible. */ if (!all_vol) { ret = -1; snprintf(errstr, sizeof(errstr), "Option \"%s\" is not valid for a single volume", key); goto out; } /* Check if cluster.op-version is the only option being * set */ if (count != 1) { ret = -1; snprintf(errstr, sizeof(errstr), "Option \"%s\" cannot be set along with other options", key); goto out; } /* Just reusing the variable, but I'm using it for * storing the op-version from value */ ret = gf_string2uint(value, &local_key_op_version); if (ret) { snprintf(errstr, sizeof(errstr), "invalid number format \"%s\" in option \"%s\"", value, key); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", errstr); goto out; } if (local_key_op_version > GD_OP_VERSION_MAX || local_key_op_version < GD_OP_VERSION_MIN) { ret = -1; snprintf(errstr, sizeof(errstr), "Required op_version (%d) is not supported." " Max supported op version is %d", local_key_op_version, priv->op_version); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VERSION_UNSUPPORTED, "%s", errstr); goto out; } if (local_key_op_version > priv->op_version) { local_new_op_version = local_key_op_version; } else { ret = -1; snprintf(errstr, sizeof(errstr), "Required op-version (%d) should" " not be equal or lower than current" " cluster op-version (%d).", local_key_op_version, priv->op_version); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VERSION_UNSUPPORTED, "%s", errstr); goto out; } goto cont; } ALL_VOLUME_OPTION_CHECK(volname, _gf_false, key, ret, op_errstr, out); ret = glusterd_validate_quorum_options(this, key, value, op_errstr); if (ret) goto out; ret = glusterd_validate_brick_mx_options(this, key, value, op_errstr); if (ret) goto out; vmep = gd_get_vmep(key); local_key_op_version = glusterd_get_op_version_from_vmep(vmep); if (local_key_op_version > local_new_op_version) local_new_op_version = local_key_op_version; if (gd_is_client_option(vmep) && (local_key_op_version > local_new_client_op_version)) local_new_client_op_version = local_key_op_version; sprintf(keystr, "op-version%d", count); if (origin_glusterd) { ret = dict_set_uint32(dict, keystr, local_key_op_version); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to set key-op-version in dict"); goto out; } } else if (check_op_version) { ret = dict_get_uint32(dict, keystr, &key_op_version); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Failed to get key-op-version from dict"); goto out; } if (local_key_op_version != key_op_version) { ret = -1; snprintf(errstr, sizeof(errstr), "option: %s op-version mismatch", key); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_VERSION_MISMATCH, "%s, required op-version = %" PRIu32 ", available op-version = %" PRIu32, errstr, key_op_version, local_key_op_version); goto out; } } global_opt = glusterd_check_globaloption(key); if (len_strcmp(key, keylen, GLUSTERD_SHARED_STORAGE_KEY)) { ret = glusterd_validate_shared_storage(value, errstr); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SHARED_STRG_VOL_OPT_VALIDATE_FAIL, "Failed to validate shared storage volume options"); goto out; } } else if (len_strcmp(key, keylen, GLUSTERD_LOCALTIME_LOGGING_KEY)) { ret = glusterd_validate_localtime_logging(value, errstr); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_LOCALTIME_LOGGING_VOL_OPT_VALIDATE_FAIL, "Failed to validate localtime logging volume options"); goto out; } } else if (len_strcmp(key, keylen, GLUSTERD_DAEMON_LOG_LEVEL_KEY)) { ret = glusterd_validate_daemon_log_level(value, errstr); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DAEMON_LOG_LEVEL_VOL_OPT_VALIDATE_FAIL, "Failed to validate daemon-log-level volume options"); goto out; } } else if (len_strcmp(key, keylen, "features.trash-dir")) { if (volinfo) { ret = glusterd_volinfo_get(volinfo, VKEY_FEATURES_TRASH, &val_dup); if (!ret && val_dup) { ret = gf_string2boolean(val_dup, &trash_enabled); if (ret) goto out; } } if (!trash_enabled) { snprintf(errstr, sizeof(errstr), "Trash translator is not enabled. " "Use volume set %s trash on", volname); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_SET_FAIL, "Unable to set the options in 'volume set': %s", errstr); ret = -1; goto out; } if (strchr(value, '/')) { snprintf(errstr, sizeof(errstr), "Path is not allowed as option"); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_SET_FAIL, "Unable to set the options in 'volume set': %s", errstr); ret = -1; goto out; } list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { /* Check for local brick */ if (!gf_uuid_compare(brickinfo->uuid, MY_UUID)) { trash_path_len = strlen(value) + strlen(brickinfo->path) + 2; trash_path = GF_MALLOC(trash_path_len, gf_common_mt_char); snprintf(trash_path, trash_path_len, "%s/%s", brickinfo->path, value); /* Checks whether a directory with given option exists or not */ if (!sys_access(trash_path, R_OK)) { snprintf(errstr, sizeof(errstr), "Path %s exists", value); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_SET_FAIL, "Unable to set the options in 'volume set': %s", errstr); ret = -1; goto out; } else { gf_msg_debug(this->name, 0, "Directory with given name does not exist," " continuing"); } if (volinfo->status == GLUSTERD_STATUS_STARTED && brickinfo->status != GF_BRICK_STARTED) { /* If volume is in started state , checks whether bricks are online */ snprintf(errstr, sizeof(errstr), "One or more bricks are down"); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_SET_FAIL, "Unable to set the options in 'volume set': %s", errstr); ret = -1; goto out; } } if (trash_path) { GF_FREE(trash_path); trash_path = NULL; } } } ret = dict_set_strn(val_dict, key, keylen, value); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Unable to set the options in 'volume set'"); ret = -1; goto out; } *op_errstr = NULL; if (!global_opt && !all_vol) ret = glusterd_validate_reconfopts(volinfo, val_dict, op_errstr); else if (!all_vol) { voliter = NULL; cds_list_for_each_entry(voliter, &priv->volumes, vol_list) { ret = glusterd_validate_globalopts(voliter, val_dict, op_errstr); if (ret) break; } } if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL, "Could not create temp volfile, some option failed: %s", *op_errstr); goto out; } dict_deln(val_dict, key, keylen); if (key_fixed) { GF_FREE(key_fixed); key_fixed = NULL; } } /* Check if all the connected clients support the new client-op-version */ ret = glusterd_check_client_op_version_support( volname, local_new_client_op_version, op_errstr); if (ret) goto out; cont: if (origin_glusterd) { ret = dict_set_uint32(dict, "new-op-version", local_new_op_version); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to set new-op-version in dict"); goto out; } /* Set this value in dict so other peers know to check for * op-version. This is a hack for 3.3.x compatibility * * TODO: Remove this and the other places this is referred once * 3.3.x compatibility is not required */ ret = dict_set_int32_sizen(dict, "check-op-version", 1); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to set check-op-version in dict"); goto out; } } ret = 0; out: if (val_dict) dict_unref(val_dict); if (trash_path) GF_FREE(trash_path); GF_FREE(key_fixed); if (errstr[0] != '\0') *op_errstr = gf_strdup(errstr); if (ret) { if (!(*op_errstr)) { *op_errstr = gf_strdup("Error, Validation Failed"); gf_msg_debug(this->name, 0, "Error, Cannot Validate option :%s", *op_errstr); } else { gf_msg_debug(this->name, 0, "Error, Cannot Validate option"); } } return ret; } static int glusterd_op_stage_reset_volume(dict_t *dict, char **op_errstr) { int ret = 0; char *volname = NULL; int exists = 0; char msg[2048] = {0}; char *key = NULL; char *key_fixed = NULL; glusterd_volinfo_t *volinfo = NULL; xlator_t *this = THIS; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get volume name"); goto out; } if (strcasecmp(volname, "all") != 0) { ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), FMTSTR_CHECK_VOL_EXISTS, volname); goto out; } ret = glusterd_validate_volume_id(dict, volinfo); if (ret) goto out; } ret = dict_get_str(dict, "key", &key); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get option key"); goto out; } /* * * If key ganesha.enable is set, then volume should be unexported from * ganesha server. Also it is a volume-level option, perform only when * volume name not equal to "all"(in other words if volinfo != NULL) */ if (volinfo && (!strcmp(key, "all") || !strcmp(key, "ganesha.enable"))) { if (glusterd_check_ganesha_export(volinfo)) { ret = ganesha_manage_export(dict, "off", _gf_true, op_errstr); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_NFS_GNS_RESET_FAIL, "Could not reset ganesha.enable key"); } } if (strcmp(key, "all")) { exists = glusterd_check_option_exists(key, &key_fixed); if (exists == -1) { ret = -1; goto out; } if (!exists) { ret = snprintf(msg, sizeof(msg), "Option %s does not exist", key); if (key_fixed) snprintf(msg + ret, sizeof(msg) - ret, "\nDid you mean %s?", key_fixed); ret = -1; goto out; } else if (exists > 0) { if (key_fixed) key = key_fixed; /* 'gluster volume set/reset * features.quota/features.inode-quota' should * not be allowed as it is deprecated. * Setting and resetting quota/inode-quota features * should be allowed only through 'gluster volume quota * enable/disable'. * But, 'gluster volume set features.quota-deem-statfs' * can be turned on/off when quota is enabled. */ if (strcmp(VKEY_FEATURES_INODE_QUOTA, key) == 0 || strcmp(VKEY_FEATURES_QUOTA, key) == 0) { snprintf(msg, sizeof(msg), "'gluster volume " "reset %s' is deprecated. " "Use 'gluster volume quota " "disable' instead.", key); ret = -1; goto out; } ALL_VOLUME_OPTION_CHECK(volname, _gf_false, key, ret, op_errstr, out); } } out: GF_FREE(key_fixed); if (msg[0] != '\0') { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_STAGE_RESET_VOL_FAIL, "%s", msg); *op_errstr = gf_strdup(msg); } gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_stage_sync_volume(dict_t *dict, char **op_errstr) { int ret = -1; char *volname = NULL; char *hostname = NULL; glusterd_peerinfo_t *peerinfo = NULL; char msg[2048] = { 0, }; glusterd_volinfo_t *volinfo = NULL; xlator_t *this = THIS; ret = dict_get_str(dict, "hostname", &hostname); if (ret) { snprintf(msg, sizeof(msg), "hostname couldn't be " "retrieved from msg"); gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=hostname", NULL); *op_errstr = gf_strdup(msg); goto out; } if (glusterd_gf_is_local_addr(hostname)) { // volname is not present in case of sync all ret = dict_get_str(dict, "volname", &volname); if (!ret) { ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), "Volume %s " "does not exist", volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_VOL_NOT_FOUND, "Volume=%s", volname, NULL); *op_errstr = gf_strdup(msg); goto out; } } } else { RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(NULL, hostname); if (peerinfo == NULL) { RCU_READ_UNLOCK; ret = -1; snprintf(msg, sizeof(msg), "%s, is not a friend", hostname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_PEER_NOT_FOUND, "Peer_name=%s", hostname, NULL); *op_errstr = gf_strdup(msg); goto out; } else if (!peerinfo->connected) { RCU_READ_UNLOCK; ret = -1; snprintf(msg, sizeof(msg), "%s, is not connected at " "the moment", hostname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_PEER_DISCONNECTED, "Peer_name=%s", hostname, NULL); *op_errstr = gf_strdup(msg); goto out; } RCU_READ_UNLOCK; } out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int glusterd_op_stage_status_volume(dict_t *dict, char **op_errstr) { int ret = -1; uint32_t cmd = 0; char msg[2048] = { 0, }; char *volname = NULL; char *brick = NULL; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; glusterd_brickinfo_t *brickinfo = NULL; glusterd_volinfo_t *volinfo = NULL; dict_t *vol_opts = NULL; #ifdef BUILD_GNFS gf_boolean_t nfs_disabled = _gf_false; #endif gf_boolean_t shd_enabled = _gf_false; GF_ASSERT(dict); priv = this->private; GF_ASSERT(priv); ret = dict_get_uint32(dict, "cmd", &cmd); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=cmd", NULL); goto out; } if (cmd & GF_CLI_STATUS_ALL) goto out; if ((cmd & GF_CLI_STATUS_QUOTAD) && (priv->op_version == GD_OP_VERSION_MIN)) { snprintf(msg, sizeof(msg), "The cluster is operating at " "version 1. Getting the status of quotad is not " "allowed in this state."); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_QUOTA_GET_STAT_FAIL, msg, NULL); ret = -1; goto out; } if ((cmd & GF_CLI_STATUS_SNAPD) && (priv->op_version < GD_OP_VERSION_3_6_0)) { snprintf(msg, sizeof(msg), "The cluster is operating at " "version less than %d. Getting the " "status of snapd is not allowed in this state.", GD_OP_VERSION_3_6_0); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_SNAP_STATUS_FAIL, msg, NULL); ret = -1; goto out; } ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get volume name"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), FMTSTR_CHECK_VOL_EXISTS, volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_VOLINFO_GET_FAIL, "Volume=%s", volname, NULL); ret = -1; goto out; } ret = glusterd_validate_volume_id(dict, volinfo); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_VALIDATE_FAILED, NULL); goto out; } ret = glusterd_is_volume_started(volinfo); if (!ret) { snprintf(msg, sizeof(msg), "Volume %s is not started", volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_VOL_NOT_STARTED, "Volume=%s", volname, NULL); ret = -1; goto out; } vol_opts = volinfo->dict; if ((cmd & GF_CLI_STATUS_SHD) != 0) { if (glusterd_is_shd_compatible_volume(volinfo)) { shd_enabled = gd_is_self_heal_enabled(volinfo, vol_opts); } else { ret = -1; snprintf(msg, sizeof(msg), "Volume %s is not Self-heal compatible", volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_VOL_SHD_NOT_COMP, "Volume=%s", volname, NULL); goto out; } if (!shd_enabled) { ret = -1; snprintf(msg, sizeof(msg), "Self-heal Daemon is disabled for volume %s", volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_SELF_HEALD_DISABLED, "Volume=%s", volname, NULL); goto out; } #ifdef BUILD_GNFS } else if ((cmd & GF_CLI_STATUS_NFS) != 0) { nfs_disabled = dict_get_str_boolean(vol_opts, NFS_DISABLE_MAP_KEY, _gf_false); if (nfs_disabled) { ret = -1; snprintf(msg, sizeof(msg), "NFS server is disabled for volume %s", volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NFS_GANESHA_DISABLED, "Volume=%s", volname, NULL); goto out; } #endif } else if ((cmd & GF_CLI_STATUS_QUOTAD) != 0) { if (!glusterd_is_volume_quota_enabled(volinfo)) { ret = -1; snprintf(msg, sizeof(msg), "Volume %s does not have " "quota enabled", volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_QUOTA_DISABLED, "Volume=%s", volname, NULL); goto out; } } else if ((cmd & GF_CLI_STATUS_BITD) != 0) { if (!glusterd_is_bitrot_enabled(volinfo)) { ret = -1; snprintf(msg, sizeof(msg), "Volume %s does not have " "bitrot enabled", volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_BITROT_NOT_ENABLED, "Volume=%s", volname, NULL); goto out; } } else if ((cmd & GF_CLI_STATUS_SCRUB) != 0) { if (!glusterd_is_bitrot_enabled(volinfo)) { ret = -1; snprintf(msg, sizeof(msg), "Volume %s does not have " "bitrot enabled. Scrubber will be enabled " "automatically if bitrot is enabled", volname); gf_smsg( this->name, GF_LOG_ERROR, errno, GD_MSG_BITROT_NOT_ENABLED, "Scrubber will be enabled automatically if bitrot is enabled", "Volume=%s", volname, NULL); goto out; } } else if ((cmd & GF_CLI_STATUS_SNAPD) != 0) { if (!glusterd_is_snapd_enabled(volinfo)) { ret = -1; snprintf(msg, sizeof(msg), "Volume %s does not have " "uss enabled", volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_SNAPD_NOT_RUNNING, "Volume=%s", volname, NULL); goto out; } } else if ((cmd & GF_CLI_STATUS_BRICK) != 0) { ret = dict_get_str(dict, "brick", &brick); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Key=brick", NULL); goto out; } ret = glusterd_volume_brickinfo_get_by_brick(brick, volinfo, &brickinfo, _gf_false); if (ret) { snprintf(msg, sizeof(msg), "No brick %s in" " volume %s", brick, volname); gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_BRICK_NOT_FOUND, "Brick=%s, Volume=%s", brick, volname, NULL); ret = -1; goto out; } } ret = 0; out: if (ret) { if (msg[0] != '\0') *op_errstr = gf_strdup(msg); else *op_errstr = gf_strdup("Validation Failed for Status"); } gf_msg_debug(this->name, 0, "Returning: %d", ret); return ret; } int glusterd_op_stage_stats_volume(dict_t *dict, char **op_errstr) { int ret = -1; char *volname = NULL; char msg[2048] = { 0, }; int32_t stats_op = GF_CLI_STATS_NONE; glusterd_volinfo_t *volinfo = NULL; ret = dict_get_str(dict, "volname", &volname); if (ret) { snprintf(msg, sizeof(msg), "Volume name get failed"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), "Volume %s, " "doesn't exist", volname); goto out; } ret = glusterd_validate_volume_id(dict, volinfo); if (ret) goto out; ret = dict_get_int32(dict, "op", &stats_op); if (ret) { snprintf(msg, sizeof(msg), "Volume profile op get failed"); goto out; } if (GF_CLI_STATS_START == stats_op) { if (_gf_true == glusterd_is_profile_on(volinfo)) { snprintf(msg, sizeof(msg), "Profile on Volume %s is" " already started", volinfo->volname); ret = -1; goto out; } } else if ((GF_CLI_STATS_STOP == stats_op) || (GF_CLI_STATS_INFO == stats_op)) { if (_gf_false == glusterd_is_profile_on(volinfo)) { snprintf(msg, sizeof(msg), "Profile on Volume %s is" " not started", volinfo->volname); ret = -1; goto out; } } if ((GF_CLI_STATS_TOP == stats_op) || (GF_CLI_STATS_INFO == stats_op)) { if (_gf_false == glusterd_is_volume_started(volinfo)) { snprintf(msg, sizeof(msg), "Volume %s is not started.", volinfo->volname); gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_STARTED, "%s", msg); ret = -1; goto out; } } ret = 0; out: if (msg[0] != '\0') { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_OP_STAGE_STATS_VOL_FAIL, "%s", msg); *op_errstr = gf_strdup(msg); } gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int _delete_reconfig_opt(dict_t *this, char *key, data_t *value, void *data) { int32_t *is_force = 0; GF_ASSERT(data); is_force = (int32_t *)data; /* Keys which has the flag VOLOPT_FLAG_NEVER_RESET * should not be deleted */ if (_gf_true == glusterd_check_voloption_flags(key, VOLOPT_FLAG_NEVER_RESET)) { if (*is_force != 1) *is_force = *is_force | GD_OP_PROTECTED; goto out; } if (*is_force != 1) { if (_gf_true == glusterd_check_voloption_flags(key, VOLOPT_FLAG_FORCE)) { /* indicate to caller that we don't set the option * due to being protected */ *is_force = *is_force | GD_OP_PROTECTED; goto out; } else { *is_force = *is_force | GD_OP_UNPROTECTED; } } gf_msg_debug("glusterd", 0, "deleting dict with key=%s,value=%s", key, value->data); dict_del(this, key); /**Delete scrubber (pause/resume) option from the dictionary if bitrot * option is going to be reset * */ if (!strncmp(key, VKEY_FEATURES_BITROT, strlen(VKEY_FEATURES_BITROT))) { dict_del_sizen(this, VKEY_FEATURES_SCRUB); } out: return 0; } static int _delete_reconfig_global_opt(dict_t *this, char *key, data_t *value, void *data) { GF_ASSERT(data); if (strcmp(GLUSTERD_GLOBAL_OPT_VERSION, key) == 0) goto out; _delete_reconfig_opt(this, key, value, data); out: return 0; } static int glusterd_options_reset(glusterd_volinfo_t *volinfo, char *key, int32_t *is_force) { int ret = 0; data_t *value = NULL; char *key_fixed = NULL; xlator_t *this = THIS; glusterd_svc_t *svc = NULL; GF_ASSERT(volinfo->dict); GF_ASSERT(key); if (!strncmp(key, "all", 3)) { dict_foreach(volinfo->dict, _delete_reconfig_opt, is_force); ret = glusterd_enable_default_options(volinfo, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_FAIL_DEFAULT_OPT_SET, "Failed to set " "default options on reset for volume %s", volinfo->volname); goto out; } } else { value = dict_get(volinfo->dict, key); if (!value) { gf_msg_debug(this->name, 0, "no value set for option %s", key); goto out; } _delete_reconfig_opt(volinfo->dict, key, value, is_force); ret = glusterd_enable_default_options(volinfo, key); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_FAIL_DEFAULT_OPT_SET, "Failed to set " "default value for option '%s' on reset for " "volume %s", key, volinfo->volname); goto out; } } gd_update_volume_op_versions(volinfo); if (!volinfo->is_snap_volume) { svc = &(volinfo->snapd.svc); ret = svc->manager(svc, volinfo, PROC_START_NO_WAIT); if (ret) goto out; } svc = &(volinfo->gfproxyd.svc); ret = svc->reconfigure(volinfo); if (ret) goto out; svc = &(volinfo->shd.svc); ret = svc->reconfigure(volinfo); if (ret) goto out; ret = glusterd_create_volfiles_and_notify_services(volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL, "Unable to create volfile for" " 'volume reset'"); ret = -1; goto out; } ret = glusterd_store_volinfo(volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); if (ret) goto out; if (GLUSTERD_STATUS_STARTED == volinfo->status) { ret = glusterd_svcs_reconfigure(volinfo); if (ret) goto out; } ret = 0; out: GF_FREE(key_fixed); gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_reset_all_volume_options(xlator_t *this, dict_t *dict) { char *key = NULL; char *key_fixed = NULL; int ret = -1; int32_t is_force = 0; glusterd_conf_t *conf = NULL; dict_t *dup_opt = NULL; gf_boolean_t all = _gf_false; char *next_version = NULL; gf_boolean_t quorum_action = _gf_false; conf = this->private; ret = dict_get_str(dict, "key", &key); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Failed to get key"); goto out; } ret = dict_get_int32(dict, "force", &is_force); if (ret) is_force = 0; if (strcmp(key, "all")) { ret = glusterd_check_option_exists(key, &key_fixed); if (ret <= 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "Option %s does not " "exist", key); ret = -1; goto out; } } else { all = _gf_true; } if (key_fixed) key = key_fixed; ret = -1; dup_opt = dict_new(); if (!dup_opt) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } if (!all) { dict_copy(conf->opts, dup_opt); dict_del(dup_opt, key); } ret = glusterd_get_next_global_opt_version_str(conf->opts, &next_version); if (ret) goto out; ret = dict_set_str_sizen(dup_opt, GLUSTERD_GLOBAL_OPT_VERSION, next_version); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", GLUSTERD_GLOBAL_OPT_VERSION, NULL); goto out; } ret = glusterd_store_options(this, dup_opt); if (ret) goto out; if (glusterd_is_quorum_changed(conf->opts, key, NULL)) quorum_action = _gf_true; ret = dict_set_dynstr_sizen(conf->opts, GLUSTERD_GLOBAL_OPT_VERSION, next_version); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", GLUSTERD_GLOBAL_OPT_VERSION, NULL); goto out; } else next_version = NULL; if (!all) { dict_del(conf->opts, key); } else { dict_foreach(conf->opts, _delete_reconfig_global_opt, &is_force); } out: GF_FREE(key_fixed); if (dup_opt) dict_unref(dup_opt); gf_msg_debug(this->name, 0, "returning %d", ret); if (quorum_action) glusterd_do_quorum_action(); GF_FREE(next_version); return ret; } static int glusterd_op_reset_volume(dict_t *dict, char **op_rspstr) { glusterd_volinfo_t *volinfo = NULL; int ret = -1; char *volname = NULL; char *key = NULL; char *key_fixed = NULL; int32_t is_force = 0; gf_boolean_t quorum_action = _gf_false; xlator_t *this = THIS; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get volume name"); goto out; } if (strcasecmp(volname, "all") == 0) { ret = glusterd_op_reset_all_volume_options(this, dict); goto out; } ret = dict_get_int32(dict, "force", &is_force); if (ret) is_force = 0; ret = dict_get_str(dict, "key", &key); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get option key"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, FMTSTR_CHECK_VOL_EXISTS, volname); goto out; } if (strcmp(key, "all") && glusterd_check_option_exists(key, &key_fixed) != 1) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "volinfo dict inconsistency: option %s not found", key); ret = -1; goto out; } if (key_fixed) key = key_fixed; if (glusterd_is_quorum_changed(volinfo->dict, key, NULL)) quorum_action = _gf_true; ret = glusterd_options_reset(volinfo, key, &is_force); if (ret == -1) { gf_asprintf(op_rspstr, "Volume reset : failed"); } else if (is_force & GD_OP_PROTECTED) { if (is_force & GD_OP_UNPROTECTED) { gf_asprintf(op_rspstr, "All unprotected fields were" " reset. To reset the protected fields," " use 'force'."); } else { ret = -1; gf_asprintf(op_rspstr, "'%s' is protected. To reset" " use 'force'.", key); } } if (!strcmp(key, "ganesha.enable") || !strcmp(key, "all")) { if (glusterd_check_ganesha_export(volinfo) && is_origin_glusterd(dict)) { ret = manage_export_config(volname, "off", op_rspstr); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_NFS_GNS_RESET_FAIL, "Could not reset ganesha.enable key"); } } out: GF_FREE(key_fixed); if (quorum_action) glusterd_do_quorum_action(); gf_msg_debug(this->name, 0, "'volume reset' returning %d", ret); return ret; } int glusterd_stop_bricks(glusterd_volinfo_t *volinfo) { glusterd_brickinfo_t *brickinfo = NULL; cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { /*TODO: Need to change @del_brick in brick_stop to _gf_true * once we enable synctask in peer rpc prog */ if (glusterd_brick_stop(volinfo, brickinfo, _gf_false)) { gf_event(EVENT_BRICK_STOP_FAILED, "peer=%s;volume=%s;brick=%s", brickinfo->hostname, volinfo->volname, brickinfo->path); return -1; } } return 0; } int glusterd_start_bricks(glusterd_volinfo_t *volinfo) { int ret = -1; glusterd_brickinfo_t *brickinfo = NULL; GF_ASSERT(volinfo); cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (!brickinfo->start_triggered) { pthread_mutex_lock(&brickinfo->restart_mutex); { /* coverity[SLEEP] */ ret = glusterd_brick_start(volinfo, brickinfo, _gf_false, _gf_false); } pthread_mutex_unlock(&brickinfo->restart_mutex); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_DISCONNECTED, "Failed to start %s:%s for %s", brickinfo->hostname, brickinfo->path, volinfo->volname); gf_event(EVENT_BRICK_START_FAILED, "peer=%s;volume=%s;brick=%s", brickinfo->hostname, volinfo->volname, brickinfo->path); goto out; } } } ret = 0; out: return ret; } static int glusterd_update_volumes_dict(glusterd_volinfo_t *volinfo) { int ret = -1; xlator_t *this = THIS; glusterd_conf_t *conf = NULL; char *address_family_str = NULL; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); /* 3.9.0 onwards gNFS will be disabled by default. In case of an upgrade * from anything below than 3.9.0 to 3.9.x the volume's dictionary will * not have 'nfs.disable' key set which means the same will not be set * to on until explicitly done. setnfs.disable to 'on' at op-version * bump up flow is the ideal way here. The same is also applicable for * transport.address-family where if the transport type is set to tcp * then transport.address-family is defaulted to 'inet'. */ if (conf->op_version >= GD_OP_VERSION_3_9_0) { if (dict_get_str_boolean(volinfo->dict, NFS_DISABLE_MAP_KEY, 1)) { ret = dict_set_dynstr_with_alloc(volinfo->dict, NFS_DISABLE_MAP_KEY, "on"); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Failed to set " "option ' NFS_DISABLE_MAP_KEY ' on " "volume %s", volinfo->volname); goto out; } } ret = dict_get_str(volinfo->dict, "transport.address-family", &address_family_str); if (ret) { if (volinfo->transport_type == GF_TRANSPORT_TCP) { ret = dict_set_dynstr_with_alloc( volinfo->dict, "transport.address-family", "inet"); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "failed to set transport." "address-family on %s", volinfo->volname); goto out; } } } } ret = glusterd_store_volinfo(volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); out: return ret; } static int glusterd_set_brick_mx_opts(dict_t *dict, char *key, char *value, char **op_errstr) { int32_t ret = -1; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; GF_VALIDATE_OR_GOTO(this->name, dict, out); GF_VALIDATE_OR_GOTO(this->name, key, out); GF_VALIDATE_OR_GOTO(this->name, value, out); GF_VALIDATE_OR_GOTO(this->name, op_errstr, out); ret = 0; priv = this->private; if (!strcmp(key, GLUSTERD_BRICK_MULTIPLEX_KEY)) { ret = dict_set_dynstr_sizen(priv->opts, GLUSTERD_BRICK_MULTIPLEX_KEY, gf_strdup(value)); } out: return ret; } static int glusterd_set_brick_graceful_cleanup(dict_t *dict, char *key, char *value, glusterd_conf_t *priv) { int ret = 0; char *dup_value = NULL; if (!strcmp(key, GLUSTER_BRICK_GRACEFUL_CLEANUP)) { dup_value = gf_strdup(value); if (!dup_value) { ret = -1; goto out; } ret = dict_set_dynstr_sizen(priv->opts, GLUSTER_BRICK_GRACEFUL_CLEANUP, dup_value); } out: if (ret && dup_value) GF_FREE(dup_value); return ret; } /* This is a hack to prevent client-io-threads from being loaded in the graph * when the cluster-op-version is bumped up from 3.8.x to 3.13.x. The key is * deleted subsequently in glusterd_create_volfiles(). */ static int glusterd_dict_set_skip_cliot_key(glusterd_volinfo_t *volinfo) { return dict_set_int32_sizen(volinfo->dict, "skip-CLIOT", 1); } static int glusterd_op_set_all_volume_options(xlator_t *this, dict_t *dict, char **op_errstr) { char *key = NULL; char *key_fixed = NULL; char *value = NULL; char *dup_value = NULL; int ret = -1; glusterd_conf_t *conf = NULL; dict_t *dup_opt = NULL; char *next_version = NULL; gf_boolean_t quorum_action = _gf_false; uint32_t op_version = 0; glusterd_volinfo_t *volinfo = NULL; glusterd_svc_t *svc = NULL; gf_boolean_t svcs_reconfigure = _gf_false; conf = this->private; ret = dict_get_str(dict, "key1", &key); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=key1", NULL); goto out; } ret = dict_get_str(dict, "value1", &value); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "invalid key,value pair in 'volume set'"); goto out; } ret = glusterd_check_option_exists(key, &key_fixed); if (ret <= 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_UNKNOWN_KEY, "Invalid key %s", key); ret = -1; goto out; } if (key_fixed) key = key_fixed; ret = glusterd_set_shared_storage(dict, key, value, op_errstr); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SHARED_STRG_SET_FAIL, "Failed to set shared storage option"); goto out; } ret = glusterd_set_brick_mx_opts(dict, key, value, op_errstr); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_MX_SET_FAIL, "Failed to set brick multiplexing option"); goto out; } ret = glusterd_set_brick_graceful_cleanup(dict, key, value, conf); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_GRACEFUL_CLEANUP_SET_FAIL, "Failed to set brick graceful option"); goto out; } /* If the key is cluster.op-version, set conf->op_version to the value * if needed and save it. */ if (strcmp(key, GLUSTERD_GLOBAL_OP_VERSION_KEY) == 0) { ret = 0; ret = gf_string2uint(value, &op_version); if (ret) goto out; if (op_version >= conf->op_version) { conf->op_version = op_version; /* When a bump up happens, update the quota.conf file * as well. This is because, till 3.7 we had a quota * conf version v1.1 in quota.conf. When inode-quota * feature is introduced, this needs to be changed to * v1.2 in quota.conf and 16 bytes uuid in quota.conf * needs to be changed to 17 bytes. Look * glusterd_store_quota_config for more details. */ cds_list_for_each_entry(volinfo, &conf->volumes, vol_list) { ret = glusterd_store_quota_config( volinfo, NULL, NULL, GF_QUOTA_OPTION_TYPE_UPGRADE, NULL); if (ret) goto out; ret = glusterd_update_volumes_dict(volinfo); if (ret) goto out; if (glusterd_dict_set_skip_cliot_key(volinfo)) goto out; if (!volinfo->is_snap_volume) { svc = &(volinfo->snapd.svc); ret = svc->manager(svc, volinfo, PROC_START_NO_WAIT); if (ret) goto out; } svc = &(volinfo->gfproxyd.svc); ret = svc->reconfigure(volinfo); if (ret) goto out; svc = &(volinfo->shd.svc); ret = svc->reconfigure(volinfo); if (ret) goto out; ret = glusterd_create_volfiles_and_notify_services(volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL, "Unable to create volfile for" " 'volume set'"); goto out; } if (GLUSTERD_STATUS_STARTED == volinfo->status) { svcs_reconfigure = _gf_true; } } if (svcs_reconfigure) { ret = glusterd_svcs_reconfigure(NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_RESTART_FAIL, "Unable to restart " "services"); goto out; } } ret = glusterd_store_global_info(this); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_VERS_STORE_FAIL, "Failed to store op-version."); } } /* No need to save cluster.op-version in conf->opts */ goto out; } ret = -1; dup_opt = dict_new(); if (!dup_opt) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } dict_copy(conf->opts, dup_opt); ret = dict_set_str(dup_opt, key, value); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } ret = glusterd_get_next_global_opt_version_str(conf->opts, &next_version); if (ret) goto out; ret = dict_set_str_sizen(dup_opt, GLUSTERD_GLOBAL_OPT_VERSION, next_version); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", GLUSTERD_GLOBAL_OPT_VERSION, NULL); goto out; } ret = glusterd_store_options(this, dup_opt); if (ret) goto out; if (glusterd_is_quorum_changed(conf->opts, key, value)) quorum_action = _gf_true; ret = dict_set_dynstr_sizen(conf->opts, GLUSTERD_GLOBAL_OPT_VERSION, next_version); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", GLUSTERD_GLOBAL_OPT_VERSION, NULL); goto out; } else next_version = NULL; dup_value = gf_strdup(value); if (!dup_value) goto out; ret = dict_set_dynstr(conf->opts, key, dup_value); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } else dup_value = NULL; /* Protect the allocation from GF_FREE */ out: GF_FREE(dup_value); GF_FREE(key_fixed); if (dup_opt) dict_unref(dup_opt); gf_msg_debug(this->name, 0, "returning %d", ret); if (quorum_action) glusterd_do_quorum_action(); GF_FREE(next_version); return ret; } int glusterd_op_get_max_opversion(char **op_errstr, dict_t *rsp_dict) { int ret = -1; GF_VALIDATE_OR_GOTO(THIS->name, rsp_dict, out); ret = dict_set_int32_sizen(rsp_dict, "max-opversion", GD_OP_VERSION_MAX); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Setting value for max-opversion to dict failed"); goto out; } out: gf_msg_debug(THIS->name, 0, "Returning %d", ret); return ret; } static int glusterd_set_shared_storage(dict_t *dict, char *key, char *value, char **op_errstr) { int32_t ret = -1; char hooks_args[PATH_MAX] = { 0, }; char errstr[PATH_MAX] = { 0, }; xlator_t *this = THIS; int32_t len = 0; GF_VALIDATE_OR_GOTO(this->name, dict, out); GF_VALIDATE_OR_GOTO(this->name, key, out); GF_VALIDATE_OR_GOTO(this->name, value, out); GF_VALIDATE_OR_GOTO(this->name, op_errstr, out); ret = 0; if (strcmp(key, GLUSTERD_SHARED_STORAGE_KEY)) { goto out; } /* Re-create the brick path so as to be * * able to re-use it * */ ret = recursive_rmdir(GLUSTER_SHARED_STORAGE_BRICK_DIR); if (ret) { snprintf(errstr, PATH_MAX, "Failed to remove shared " "storage brick(%s). " "Reason: %s", GLUSTER_SHARED_STORAGE_BRICK_DIR, strerror(errno)); gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_DIR_OP_FAILED, "%s", errstr); ret = -1; goto out; } ret = mkdir_p(GLUSTER_SHARED_STORAGE_BRICK_DIR, 0755, _gf_true); if (-1 == ret) { snprintf(errstr, PATH_MAX, "Failed to create shared " "storage brick(%s). " "Reason: %s", GLUSTER_SHARED_STORAGE_BRICK_DIR, strerror(errno)); gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_CREATE_DIR_FAILED, "%s", errstr); goto out; } if (is_origin_glusterd(dict)) { len = snprintf(hooks_args, sizeof(hooks_args), "is_originator=1,local_node_hostname=%s", local_node_hostname); } else { len = snprintf(hooks_args, sizeof(hooks_args), "is_originator=0,local_node_hostname=%s", local_node_hostname); } if ((len < 0) || (len >= sizeof(hooks_args))) { ret = -1; goto out; } ret = dict_set_dynstr_with_alloc(dict, "hooks_args", hooks_args); if (ret) { gf_msg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Failed to set" " hooks_args in dict."); goto out; } out: if (ret && strlen(errstr)) { *op_errstr = gf_strdup(errstr); } return ret; } static int glusterd_op_set_volume(dict_t *dict, char **errstr) { int ret = 0; glusterd_volinfo_t *volinfo = NULL; char *volname = NULL; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; int count = 1; char *key = NULL; char *key_fixed = NULL; char *value = NULL; char keystr[50] = { 0, }; int keylen; gf_boolean_t global_opt = _gf_false; gf_boolean_t global_opts_set = _gf_false; glusterd_volinfo_t *voliter = NULL; int32_t dict_count = 0; gf_boolean_t check_op_version = _gf_false; uint32_t new_op_version = 0; gf_boolean_t quorum_action = _gf_false; glusterd_svc_t *svc = NULL; dict_t *volinfo_dict_orig = NULL; priv = this->private; GF_ASSERT(priv); volinfo_dict_orig = dict_new(); if (!volinfo_dict_orig) goto out; ret = dict_get_int32(dict, "count", &dict_count); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Count(dict),not set in Volume-Set"); goto out; } if (dict_count == 0) { ret = glusterd_volset_help(NULL, errstr); goto out; } ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get volume name"); goto out; } if (strcasecmp(volname, "all") == 0) { ret = glusterd_op_set_all_volume_options(this, dict, errstr); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, FMTSTR_CHECK_VOL_EXISTS, volname); goto out; } if (dict_copy(volinfo->dict, volinfo_dict_orig) == NULL) { ret = -ENOMEM; goto out; } /* TODO: Remove this once v3.3 compatibility is not required */ check_op_version = dict_get_str_boolean(dict, "check-op-version", _gf_false); if (check_op_version) { ret = dict_get_uint32(dict, "new-op-version", &new_op_version); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get new op-version from dict"); goto out; } } for (count = 1; ret != -1; count++) { keylen = snprintf(keystr, sizeof(keystr), "key%d", count); ret = dict_get_strn(dict, keystr, keylen, &key); if (ret) break; keylen = snprintf(keystr, sizeof(keystr), "value%d", count); ret = dict_get_strn(dict, keystr, keylen, &value); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "invalid key,value pair in 'volume set'"); ret = -1; goto out; } if (strcmp(key, "config.memory-accounting") == 0) { ret = gf_string2boolean(value, &volinfo->memory_accounting); if (ret == -1) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "Invalid value in key-value pair."); goto out; } } if (strcmp(key, "config.transport") == 0) { gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_VOL_TRANSPORT_TYPE_CHANGE, "changing transport-type for volume %s to %s", volname, value); ret = 0; if (strcasecmp(value, "rdma") == 0) { volinfo->transport_type = GF_TRANSPORT_RDMA; } else if (strcasecmp(value, "tcp") == 0) { volinfo->transport_type = GF_TRANSPORT_TCP; } else if ((strcasecmp(value, "tcp,rdma") == 0) || (strcasecmp(value, "rdma,tcp") == 0)) { volinfo->transport_type = GF_TRANSPORT_BOTH_TCP_RDMA; } else { ret = -1; goto out; } } ret = glusterd_check_ganesha_cmd(key, value, errstr, dict); if (ret == -1) goto out; if (!is_key_glusterd_hooks_friendly(key)) { ret = glusterd_check_option_exists(key, &key_fixed); GF_ASSERT(ret); if (ret <= 0) { key_fixed = NULL; goto out; } } global_opt = _gf_false; if (glusterd_check_globaloption(key)) { global_opt = _gf_true; global_opts_set = _gf_true; } if (!global_opt) value = gf_strdup(value); if (!value) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_SET_FAIL, "Unable to set the options in 'volume set'"); ret = -1; goto out; } if (key_fixed) key = key_fixed; if (glusterd_is_quorum_changed(volinfo->dict, key, value)) quorum_action = _gf_true; if (global_opt) { cds_list_for_each_entry(voliter, &priv->volumes, vol_list) { value = gf_strdup(value); ret = dict_set_dynstr(voliter->dict, key, value); if (ret) goto out; } } else { ret = dict_set_dynstr(volinfo->dict, key, value); if (ret) goto out; } if (key_fixed) { GF_FREE(key_fixed); key_fixed = NULL; } } if (count == 1) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_NO_OPTIONS_GIVEN, "No options received "); ret = -1; goto out; } /* Update the cluster op-version before regenerating volfiles so that * correct volfiles are generated */ if (new_op_version > priv->op_version) { priv->op_version = new_op_version; ret = glusterd_store_global_info(this); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_VERS_STORE_FAIL, "Failed to store op-version"); goto out; } } if (!global_opts_set) { gd_update_volume_op_versions(volinfo); if (!volinfo->is_snap_volume) { svc = &(volinfo->snapd.svc); ret = svc->manager(svc, volinfo, PROC_START_NO_WAIT); if (ret) goto out; } svc = &(volinfo->gfproxyd.svc); ret = svc->reconfigure(volinfo); if (ret) goto out; svc = &(volinfo->shd.svc); ret = svc->reconfigure(volinfo); if (ret) goto out; ret = glusterd_create_volfiles_and_notify_services(volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL, "Unable to create volfile for" " 'volume set'"); ret = -1; goto out; } ret = glusterd_store_volinfo(volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); if (ret) goto out; if (GLUSTERD_STATUS_STARTED == volinfo->status) { ret = glusterd_svcs_reconfigure(volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_RESTART_FAIL, "Unable to restart services"); goto out; } } } else { cds_list_for_each_entry(voliter, &priv->volumes, vol_list) { volinfo = voliter; gd_update_volume_op_versions(volinfo); if (!volinfo->is_snap_volume) { svc = &(volinfo->snapd.svc); ret = svc->manager(svc, volinfo, PROC_START_NO_WAIT); if (ret) goto out; } svc = &(volinfo->gfproxyd.svc); ret = svc->reconfigure(volinfo); if (ret) goto out; svc = &(volinfo->shd.svc); ret = svc->reconfigure(volinfo); if (ret) goto out; ret = glusterd_create_volfiles_and_notify_services(volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL, "Unable to create volfile for" " 'volume set'"); ret = -1; goto out; } ret = glusterd_store_volinfo(volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); if (ret) goto out; if (GLUSTERD_STATUS_STARTED == volinfo->status) { ret = glusterd_svcs_reconfigure(volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_RESTART_FAIL, "Unable to restart services"); goto out; } } } } out: GF_FREE(key_fixed); gf_msg_debug(this->name, 0, "returning %d", ret); if (quorum_action) glusterd_do_quorum_action(); if (ret < 0 && count > 1) { if (dict_reset(volinfo->dict) == 0) dict_copy(volinfo_dict_orig, volinfo->dict); } if (volinfo_dict_orig) dict_unref(volinfo_dict_orig); return ret; } static int glusterd_op_sync_volume(dict_t *dict, char **op_errstr, dict_t *rsp_dict) { int ret = -1; char *volname = NULL; char *hostname = NULL; char msg[2048] = { 0, }; int count = 1; int vol_count = 0; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); ret = dict_get_str(dict, "hostname", &hostname); if (ret) { snprintf(msg, sizeof(msg), "hostname couldn't be " "retrieved from msg"); gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=hostname", NULL); *op_errstr = gf_strdup(msg); goto out; } if (!glusterd_gf_is_local_addr(hostname)) { ret = 0; goto out; } // volname is not present in case of sync all ret = dict_get_str(dict, "volname", &volname); if (!ret) { ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "Volume with name: %s " "not exists", volname); goto out; } } if (!rsp_dict) { // this should happen only on source gf_smsg(this->name, GF_LOG_INFO, errno, GD_MSG_INVALID_ARGUMENT, NULL); ret = 0; goto out; } if (volname) { ret = glusterd_add_volume_to_dict(volinfo, rsp_dict, 1, "volume"); if (ret) goto out; vol_count = 1; } else { cds_list_for_each_entry(volinfo, &priv->volumes, vol_list) { ret = glusterd_add_volume_to_dict(volinfo, rsp_dict, count, "volume"); if (ret) goto out; vol_count = count++; } } ret = dict_set_int32_sizen(rsp_dict, "count", vol_count); out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int glusterd_add_profile_volume_options(glusterd_volinfo_t *volinfo) { int ret = -1; GF_ASSERT(volinfo); ret = dict_set_nstrn(volinfo->dict, VKEY_DIAG_LAT_MEASUREMENT, SLEN(VKEY_DIAG_LAT_MEASUREMENT), "on", SLEN("on")); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set the volume %s " "option %s value %s", volinfo->volname, VKEY_DIAG_LAT_MEASUREMENT, "on"); goto out; } ret = dict_set_nstrn(volinfo->dict, VKEY_DIAG_CNT_FOP_HITS, SLEN(VKEY_DIAG_CNT_FOP_HITS), "on", SLEN("on")); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set the volume %s " "option %s value %s", volinfo->volname, VKEY_DIAG_CNT_FOP_HITS, "on"); goto out; } out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static void glusterd_remove_profile_volume_options(glusterd_volinfo_t *volinfo) { GF_ASSERT(volinfo); dict_del_sizen(volinfo->dict, VKEY_DIAG_LAT_MEASUREMENT); dict_del_sizen(volinfo->dict, VKEY_DIAG_CNT_FOP_HITS); } int glusterd_op_stats_volume(dict_t *dict, char **op_errstr, dict_t *rsp_dict) { int ret = -1; char *volname = NULL; char msg[2048] = { 0, }; glusterd_volinfo_t *volinfo = NULL; int32_t stats_op = GF_CLI_STATS_NONE; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "volume name get failed"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), "Volume %s does not exists", volname); gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "%s", msg); goto out; } ret = dict_get_int32(dict, "op", &stats_op); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "volume profile op get failed"); goto out; } switch (stats_op) { case GF_CLI_STATS_START: ret = glusterd_add_profile_volume_options(volinfo); if (ret) goto out; break; case GF_CLI_STATS_STOP: glusterd_remove_profile_volume_options(volinfo); break; case GF_CLI_STATS_INFO: case GF_CLI_STATS_TOP: // info is already collected in brick op. // just goto out; ret = 0; goto out; break; default: GF_ASSERT(0); gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "Invalid profile op: %d", stats_op); ret = -1; goto out; break; } ret = glusterd_create_volfiles_and_notify_services(volinfo); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL, "Unable to create volfile for" " 'volume set'"); ret = -1; goto out; } ret = glusterd_store_volinfo(volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); if (ret) goto out; if (GLUSTERD_STATUS_STARTED == volinfo->status) { ret = glusterd_svcs_reconfigure(volinfo); if (ret) goto out; } ret = 0; out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int _add_remove_bricks_to_dict(dict_t *dict, glusterd_volinfo_t *volinfo, char *prefix) { int ret = -1; int count = 0; int i = 0; char brick_key[16] = { 0, }; char dict_key[64] = { /* dict_key is small as prefix is up to 32 chars */ 0, }; int keylen; char *brick = NULL; xlator_t *this = THIS; GF_ASSERT(dict); GF_ASSERT(volinfo); GF_ASSERT(prefix); ret = dict_get_int32(volinfo->rebal.dict, "count", &count); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Failed to get brick count"); goto out; } keylen = snprintf(dict_key, sizeof(dict_key), "%s.count", prefix); ret = dict_set_int32n(dict, dict_key, keylen, count); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to set brick count in dict"); goto out; } for (i = 1; i <= count; i++) { keylen = snprintf(brick_key, sizeof(brick_key), "brick%d", i); ret = dict_get_strn(volinfo->rebal.dict, brick_key, keylen, &brick); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get %s", brick_key); goto out; } keylen = snprintf(dict_key, sizeof(dict_key), "%s.%s", prefix, brick_key); if ((keylen < 0) || (keylen >= sizeof(dict_key))) { ret = -1; goto out; } ret = dict_set_strn(dict, dict_key, keylen, brick); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to add brick to dict"); goto out; } brick = NULL; } out: return ret; } /* This adds the respective task-id and all available parameters of a task into * a dictionary */ static int _add_task_to_dict(dict_t *dict, glusterd_volinfo_t *volinfo, int op, int index) { int ret = -1; char key[32] = { 0, }; int keylen; char *uuid_str = NULL; int status = 0; xlator_t *this = THIS; GF_ASSERT(dict); GF_ASSERT(volinfo); switch (op) { case GD_OP_REMOVE_BRICK: snprintf(key, sizeof(key), "task%d", index); ret = _add_remove_bricks_to_dict(dict, volinfo, key); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_ADD_REMOVE_BRICK_FAIL, "Failed to add remove bricks to dict"); goto out; } case GD_OP_REBALANCE: uuid_str = gf_strdup(uuid_utoa(volinfo->rebal.rebalance_id)); status = volinfo->rebal.defrag_status; break; default: ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_NO_TASK_ID, "%s operation doesn't have a" " task_id", gd_op_list[op]); goto out; } keylen = snprintf(key, sizeof(key), "task%d.type", index); ret = dict_set_strn(dict, key, keylen, (char *)gd_op_list[op]); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Error setting task type in dict"); goto out; } keylen = snprintf(key, sizeof(key), "task%d.id", index); if (!uuid_str) goto out; ret = dict_set_dynstrn(dict, key, keylen, uuid_str); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Error setting task id in dict"); goto out; } uuid_str = NULL; keylen = snprintf(key, sizeof(key), "task%d.status", index); ret = dict_set_int32n(dict, key, keylen, status); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Error setting task status in dict"); goto out; } out: if (uuid_str) GF_FREE(uuid_str); return ret; } static int glusterd_aggregate_task_status(dict_t *rsp_dict, glusterd_volinfo_t *volinfo) { int ret = -1; int tasks = 0; xlator_t *this = THIS; if (!gf_uuid_is_null(volinfo->rebal.rebalance_id)) { ret = _add_task_to_dict(rsp_dict, volinfo, volinfo->rebal.op, tasks); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to add task details to dict"); goto out; } tasks++; } ret = dict_set_int32_sizen(rsp_dict, "tasks", tasks); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Error setting tasks count in dict"); goto out; } out: return ret; } static int glusterd_add_node_to_dict(char *server, dict_t *dict, int count, dict_t *vol_opts) { int ret = -1; char pidfile[PATH_MAX] = ""; gf_boolean_t running = _gf_false; int pid = -1; int port = 0; glusterd_svc_t *svc = NULL; char key[64] = ""; int keylen; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; priv = this->private; GF_ASSERT(priv); if (!strcmp(server, "")) { ret = 0; goto out; } glusterd_svc_build_pidfile_path(server, priv->rundir, pidfile, sizeof(pidfile)); if (strcmp(server, priv->quotad_svc.name) == 0) svc = &(priv->quotad_svc); #ifdef BUILD_GNFS else if (strcmp(server, priv->nfs_svc.name) == 0) svc = &(priv->nfs_svc); #endif else if (strcmp(server, priv->bitd_svc.name) == 0) svc = &(priv->bitd_svc); else if (strcmp(server, priv->scrub_svc.name) == 0) svc = &(priv->scrub_svc); else { ret = 0; goto out; } // Consider service to be running only when glusterd sees it Online if (svc->online) running = gf_is_service_running(pidfile, &pid); /* For nfs-servers/self-heal-daemon setting * brick.hostname = "NFS Server" / "Self-heal Daemon" * brick.path = uuid * brick.port = 0 * * This might be confusing, but cli displays the name of * the brick as hostname+path, so this will make more sense * when output. */ keylen = snprintf(key, sizeof(key), "brick%d.hostname", count); if (!strcmp(server, priv->quotad_svc.name)) ret = dict_set_nstrn(dict, key, keylen, "Quota Daemon", SLEN("Quota Daemon")); #ifdef BUILD_GNFS else if (!strcmp(server, priv->nfs_svc.name)) ret = dict_set_nstrn(dict, key, keylen, "NFS Server", SLEN("NFS Server")); #endif else if (!strcmp(server, priv->bitd_svc.name)) ret = dict_set_nstrn(dict, key, keylen, "Bitrot Daemon", SLEN("Bitrot Daemon")); else if (!strcmp(server, priv->scrub_svc.name)) ret = dict_set_nstrn(dict, key, keylen, "Scrubber Daemon", SLEN("Scrubber Daemon")); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } keylen = snprintf(key, sizeof(key), "brick%d.path", count); ret = dict_set_dynstrn(dict, key, keylen, gf_strdup(uuid_utoa(MY_UUID))); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } #ifdef BUILD_GNFS /* Port is available only for the NFS server. * Self-heal daemon doesn't provide any port for access * by entities other than gluster. */ if (!strcmp(server, priv->nfs_svc.name)) { if (dict_get_sizen(vol_opts, "nfs.port")) { ret = dict_get_int32(vol_opts, "nfs.port", &port); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=nfs.port", NULL); goto out; } } else port = GF_NFS3_PORT; } #endif keylen = snprintf(key, sizeof(key), "brick%d.port", count); ret = dict_set_int32n(dict, key, keylen, port); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } keylen = snprintf(key, sizeof(key), "brick%d.pid", count); ret = dict_set_int32n(dict, key, keylen, pid); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } keylen = snprintf(key, sizeof(key), "brick%d.status", count); ret = dict_set_int32n(dict, key, keylen, running); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int32_t glusterd_get_all_volnames(dict_t *dict) { int ret = -1; int32_t vol_count = 0; char key[64] = ""; int keylen; glusterd_volinfo_t *entry = NULL; glusterd_conf_t *priv = NULL; priv = THIS->private; GF_ASSERT(priv); cds_list_for_each_entry(entry, &priv->volumes, vol_list) { keylen = snprintf(key, sizeof(key), "vol%d", vol_count); ret = dict_set_strn(dict, key, keylen, entry->volname); if (ret) goto out; vol_count++; } ret = dict_set_int32_sizen(dict, "vol_count", vol_count); out: if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to get all " "volume names for status"); return ret; } static int32_t glusterd_add_shd_to_dict(glusterd_volinfo_t *volinfo, dict_t *dict, int32_t count) { int ret = -1; int32_t pid = -1; int32_t brick_online = -1; char key[64] = {0}; int keylen; char *pidfile = NULL; xlator_t *this = THIS; char *uuid_str = NULL; GF_VALIDATE_OR_GOTO(this->name, volinfo, out); GF_VALIDATE_OR_GOTO(this->name, dict, out); keylen = snprintf(key, sizeof(key), "brick%d.hostname", count); ret = dict_set_nstrn(dict, key, keylen, "Self-heal Daemon", SLEN("Self-heal Daemon")); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } keylen = snprintf(key, sizeof(key), "brick%d.path", count); uuid_str = gf_strdup(uuid_utoa(MY_UUID)); if (!uuid_str) { ret = -1; goto out; } ret = dict_set_dynstrn(dict, key, keylen, uuid_str); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } uuid_str = NULL; /* shd doesn't have a port. but the cli needs a port key with * a zero value to parse. * */ keylen = snprintf(key, sizeof(key), "brick%d.port", count); ret = dict_set_int32n(dict, key, keylen, 0); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } pidfile = volinfo->shd.svc.proc.pidfile; brick_online = gf_is_service_running(pidfile, &pid); /* If shd is not running, then don't print the pid */ if (!brick_online) pid = -1; keylen = snprintf(key, sizeof(key), "brick%d.pid", count); ret = dict_set_int32n(dict, key, keylen, pid); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } keylen = snprintf(key, sizeof(key), "brick%d.status", count); ret = dict_set_int32n(dict, key, keylen, brick_online); out: if (uuid_str) GF_FREE(uuid_str); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Returning %d. adding values to dict failed", ret); return ret; } static int glusterd_op_status_volume(dict_t *dict, char **op_errstr, dict_t *rsp_dict) { int ret = -1; int node_count = 0; int brick_index = -1; int other_count = 0; int other_index = 0; uint32_t cmd = 0; char *volname = NULL; char *brick = NULL; xlator_t *this = THIS; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; glusterd_conf_t *priv = NULL; dict_t *vol_opts = NULL; #ifdef BUILD_GNFS gf_boolean_t nfs_disabled = _gf_false; #endif gf_boolean_t shd_enabled = _gf_false; gf_boolean_t origin_glusterd = _gf_false; int snapd_enabled, bitrot_enabled, volume_quota_enabled; priv = this->private; GF_ASSERT(priv); GF_ASSERT(dict); origin_glusterd = is_origin_glusterd(dict); ret = dict_get_uint32(dict, "cmd", &cmd); if (ret) goto out; if (origin_glusterd) { ret = 0; if ((cmd & GF_CLI_STATUS_ALL)) { ret = glusterd_get_all_volnames(rsp_dict); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLNAMES_GET_FAIL, "failed to get all volume " "names for status"); } } ret = dict_set_uint32(rsp_dict, "cmd", cmd); if (ret) goto out; if (cmd & GF_CLI_STATUS_ALL) goto out; ret = dict_get_str(dict, "volname", &volname); if (ret) goto out; ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "Volume with name: %s " "does not exist", volname); goto out; } vol_opts = volinfo->dict; if ((cmd & GF_CLI_STATUS_QUOTAD) != 0) { ret = glusterd_add_node_to_dict(priv->quotad_svc.name, rsp_dict, 0, vol_opts); if (ret) goto out; other_count++; node_count++; #ifdef BUILD_GNFS } else if ((cmd & GF_CLI_STATUS_NFS) != 0) { ret = glusterd_add_node_to_dict(priv->nfs_svc.name, rsp_dict, 0, vol_opts); if (ret) goto out; other_count++; node_count++; #endif } else if ((cmd & GF_CLI_STATUS_BITD) != 0) { ret = glusterd_add_node_to_dict(priv->bitd_svc.name, rsp_dict, 0, vol_opts); if (ret) goto out; other_count++; node_count++; } else if ((cmd & GF_CLI_STATUS_SCRUB) != 0) { ret = glusterd_add_node_to_dict(priv->scrub_svc.name, rsp_dict, 0, vol_opts); if (ret) goto out; other_count++; node_count++; } else if ((cmd & GF_CLI_STATUS_SNAPD) != 0) { ret = glusterd_add_snapd_to_dict(volinfo, rsp_dict, other_index); if (ret) goto out; other_count++; node_count++; } else if ((cmd & GF_CLI_STATUS_SHD) != 0) { ret = glusterd_add_shd_to_dict(volinfo, rsp_dict, other_index); if (ret) goto out; other_count++; node_count++; } else if ((cmd & GF_CLI_STATUS_BRICK) != 0) { ret = dict_get_str(dict, "brick", &brick); if (ret) goto out; ret = glusterd_volume_brickinfo_get_by_brick(brick, volinfo, &brickinfo, _gf_false); if (ret) goto out; if (gf_uuid_compare(brickinfo->uuid, MY_UUID)) goto out; glusterd_add_brick_to_dict(volinfo, brickinfo, rsp_dict, ++brick_index); if (cmd & GF_CLI_STATUS_DETAIL) glusterd_add_brick_detail_to_dict(volinfo, brickinfo, rsp_dict, brick_index); node_count++; } else if ((cmd & GF_CLI_STATUS_TASKS) != 0) { ret = glusterd_aggregate_task_status(rsp_dict, volinfo); goto out; } else { snapd_enabled = glusterd_is_snapd_enabled(volinfo); shd_enabled = gd_is_self_heal_enabled(volinfo, vol_opts); #ifdef BUILD_GNFS nfs_disabled = dict_get_str_boolean(vol_opts, NFS_DISABLE_MAP_KEY, _gf_false); #endif volume_quota_enabled = glusterd_is_volume_quota_enabled(volinfo); bitrot_enabled = glusterd_is_bitrot_enabled(volinfo); cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { brick_index++; if (gf_uuid_compare(brickinfo->uuid, MY_UUID)) continue; glusterd_add_brick_to_dict(volinfo, brickinfo, rsp_dict, brick_index); if (cmd & GF_CLI_STATUS_DETAIL) { glusterd_add_brick_detail_to_dict(volinfo, brickinfo, rsp_dict, brick_index); } node_count++; } if ((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE) { other_index = brick_index + 1; if (snapd_enabled) { ret = glusterd_add_snapd_to_dict(volinfo, rsp_dict, other_index); if (ret) goto out; other_count++; other_index++; node_count++; } if (glusterd_is_shd_compatible_volume(volinfo)) { if (shd_enabled) { ret = glusterd_add_shd_to_dict(volinfo, rsp_dict, other_index); if (ret) goto out; other_count++; other_index++; node_count++; } } #ifdef BUILD_GNFS if (!nfs_disabled) { ret = glusterd_add_node_to_dict(priv->nfs_svc.name, rsp_dict, other_index, vol_opts); if (ret) goto out; other_index++; other_count++; node_count++; } #endif if (volume_quota_enabled) { ret = glusterd_add_node_to_dict(priv->quotad_svc.name, rsp_dict, other_index, vol_opts); if (ret) goto out; other_count++; node_count++; other_index++; } if (bitrot_enabled) { ret = glusterd_add_node_to_dict(priv->bitd_svc.name, rsp_dict, other_index, vol_opts); if (ret) goto out; other_count++; node_count++; other_index++; /* For handling scrub status. Scrub daemon will be * running automatically when bitrot is enable */ ret = glusterd_add_node_to_dict(priv->scrub_svc.name, rsp_dict, other_index, vol_opts); if (ret) goto out; other_count++; node_count++; } } } ret = dict_set_int32_sizen(rsp_dict, "type", volinfo->type); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=type", NULL); goto out; } ret = dict_set_int32_sizen(rsp_dict, "brick-index-max", brick_index); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=brick-index-max", NULL); goto out; } ret = dict_set_int32_sizen(rsp_dict, "other-count", other_count); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=other-count", NULL); goto out; } ret = dict_set_int32_sizen(rsp_dict, "count", node_count); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=count", NULL); goto out; } /* Active tasks */ /* Tasks are added only for normal volume status request for either a * single volume or all volumes */ if (!glusterd_status_has_tasks(cmd)) goto out; ret = glusterd_aggregate_task_status(rsp_dict, volinfo); if (ret) goto out; ret = 0; out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_ac_none(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; gf_msg_debug(THIS->name, 0, "Returning with %d", ret); return ret; } static int glusterd_op_sm_locking_failed(uuid_t *txn_id) { int ret = -1; opinfo.op_ret = -1; opinfo.op_errstr = gf_strdup("locking failed for one of the peer."); ret = glusterd_set_txn_opinfo(txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); /* Inject a reject event such that unlocking gets triggered right away*/ ret = glusterd_op_sm_inject_event(GD_OP_EVENT_RCVD_RJT, txn_id, NULL); return ret; } static int glusterd_op_ac_send_lock(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; rpc_clnt_procedure_t *proc = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; glusterd_peerinfo_t *peerinfo = NULL; uint32_t pending_count = 0; dict_t *dict = NULL; priv = this->private; GF_ASSERT(priv); RCU_READ_LOCK; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { /* Only send requests to peers who were available before the * transaction started */ if (peerinfo->generation > opinfo.txn_generation) continue; if (!peerinfo->connected || !peerinfo->mgmt) continue; if ((peerinfo->state != GD_FRIEND_STATE_BEFRIENDED) && (glusterd_op_get_op() != GD_OP_SYNC_VOLUME)) continue; /* Based on the op_version, acquire a cluster or mgmt_v3 lock */ if (priv->op_version < GD_OP_VERSION_3_6_0) { proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_CLUSTER_LOCK]; if (proc->fn) { ret = proc->fn(NULL, this, peerinfo); if (ret) { RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_LOCK_REQ_SEND_FAIL, "Failed to send lock request " "for operation 'Volume %s' to " "peer %s", gd_op_list[opinfo.op], peerinfo->hostname); goto out; } /* Mark the peer as locked*/ peerinfo->locked = _gf_true; pending_count++; } } else { dict = glusterd_op_get_ctx(); dict_ref(dict); proc = &peerinfo->mgmt_v3->proctable[GLUSTERD_MGMT_V3_LOCK]; if (proc->fn) { ret = dict_set_static_ptr(dict, "peerinfo", peerinfo); if (ret) { RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); dict_unref(dict); goto out; } ret = proc->fn(NULL, this, dict); if (ret) { RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_MGMTV3_LOCK_REQ_SEND_FAIL, "Failed to send mgmt_v3 lock " "request for operation " "'Volume %s' to peer %s", gd_op_list[opinfo.op], peerinfo->hostname); dict_unref(dict); goto out; } /* Mark the peer as locked*/ peerinfo->locked = _gf_true; pending_count++; } } } RCU_READ_UNLOCK; opinfo.pending_count = pending_count; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (!opinfo.pending_count) ret = glusterd_op_sm_inject_all_acc(&event->txn_id); out: if (ret) ret = glusterd_op_sm_locking_failed(&event->txn_id); gf_msg_debug(this->name, 0, "Returning with %d", ret); return ret; } static int glusterd_op_ac_send_unlock(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; rpc_clnt_procedure_t *proc = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; glusterd_peerinfo_t *peerinfo = NULL; uint32_t pending_count = 0; dict_t *dict = NULL; priv = this->private; GF_ASSERT(priv); RCU_READ_LOCK; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { /* Only send requests to peers who were available before the * transaction started */ if (peerinfo->generation > opinfo.txn_generation) continue; if (!peerinfo->connected || !peerinfo->mgmt || !peerinfo->locked) continue; if ((peerinfo->state != GD_FRIEND_STATE_BEFRIENDED) && (glusterd_op_get_op() != GD_OP_SYNC_VOLUME)) continue; /* Based on the op_version, * release the cluster or mgmt_v3 lock */ if (priv->op_version < GD_OP_VERSION_3_6_0) { proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_CLUSTER_UNLOCK]; if (proc->fn) { ret = proc->fn(NULL, this, peerinfo); if (ret) { opinfo.op_errstr = gf_strdup( "Unlocking failed for one of " "the peer."); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_CLUSTER_UNLOCK_FAILED, "Unlocking failed for operation" " volume %s on peer %s", gd_op_list[opinfo.op], peerinfo->hostname); continue; } pending_count++; peerinfo->locked = _gf_false; } } else { dict = glusterd_op_get_ctx(); dict_ref(dict); proc = &peerinfo->mgmt_v3->proctable[GLUSTERD_MGMT_V3_UNLOCK]; if (proc->fn) { ret = dict_set_static_ptr(dict, "peerinfo", peerinfo); if (ret) { opinfo.op_errstr = gf_strdup( "Unlocking failed for one of the " "peer."); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_CLUSTER_UNLOCK_FAILED, "Unlocking failed for operation" " volume %s on peer %s", gd_op_list[opinfo.op], peerinfo->hostname); dict_unref(dict); continue; } ret = proc->fn(NULL, this, dict); if (ret) { opinfo.op_errstr = gf_strdup( "Unlocking failed for one of the " "peer."); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_CLUSTER_UNLOCK_FAILED, "Unlocking failed for operation" " volume %s on peer %s", gd_op_list[opinfo.op], peerinfo->hostname); dict_unref(dict); continue; } pending_count++; peerinfo->locked = _gf_false; } } } RCU_READ_UNLOCK; opinfo.pending_count = pending_count; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (!opinfo.pending_count) ret = glusterd_op_sm_inject_all_acc(&event->txn_id); gf_msg_debug(this->name, 0, "Returning with %d", ret); return ret; } static int glusterd_op_ac_ack_drain(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; if (opinfo.pending_count > 0) opinfo.pending_count--; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (!opinfo.pending_count) ret = glusterd_op_sm_inject_event(GD_OP_EVENT_ALL_ACK, &event->txn_id, NULL); gf_msg_debug(THIS->name, 0, "Returning with %d", ret); return ret; } static int glusterd_op_ac_send_unlock_drain(glusterd_op_sm_event_t *event, void *ctx) { return glusterd_op_ac_ack_drain(event, ctx); } static int glusterd_op_ac_lock(glusterd_op_sm_event_t *event, void *ctx) { int32_t ret = 0; char *volname = NULL; char *globalname = NULL; glusterd_op_lock_ctx_t *lock_ctx = NULL; xlator_t *this = THIS; uint32_t op_errno = 0; glusterd_conf_t *conf = NULL; time_t timeout = 0; GF_ASSERT(event); GF_ASSERT(ctx); conf = this->private; GF_ASSERT(conf); lock_ctx = (glusterd_op_lock_ctx_t *)ctx; /* If the req came from a node running on older op_version * the dict won't be present. Based on it acquiring a cluster * or mgmt_v3 lock */ if (lock_ctx->dict == NULL) { ret = glusterd_lock(lock_ctx->uuid); glusterd_op_lock_send_resp(lock_ctx->req, ret); } else { /* Cli will add timeout key to dict if the default timeout is * other than 2 minutes. Here we use this value to check whether * mgmt_v3_lock_timeout should be set to default value or we * need to change the value according to timeout value * i.e, timeout + 120 seconds. */ ret = dict_get_time(lock_ctx->dict, "timeout", &timeout); if (!ret) conf->mgmt_v3_lock_timeout = timeout + 120; ret = dict_get_str(lock_ctx->dict, "volname", &volname); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to acquire volname"); else { ret = glusterd_mgmt_v3_lock(volname, lock_ctx->uuid, &op_errno, "vol"); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_LOCK_GET_FAIL, "Unable to acquire lock for %s", volname); goto out; } ret = dict_get_str(lock_ctx->dict, "globalname", &globalname); if (!ret) { ret = glusterd_mgmt_v3_lock(globalname, lock_ctx->uuid, &op_errno, "global"); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_LOCK_GET_FAIL, "Unable to acquire lock for %s", globalname); } out: glusterd_op_mgmt_v3_lock_send_resp(lock_ctx->req, &event->txn_id, ret); dict_unref(lock_ctx->dict); } gf_msg_debug(THIS->name, 0, "Lock Returned %d", ret); return ret; } static int glusterd_op_ac_unlock(glusterd_op_sm_event_t *event, void *ctx) { int32_t ret = 0; char *volname = NULL; char *globalname = NULL; glusterd_op_lock_ctx_t *lock_ctx = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; GF_ASSERT(event); GF_ASSERT(ctx); priv = this->private; lock_ctx = (glusterd_op_lock_ctx_t *)ctx; /* If the req came from a node running on older op_version * the dict won't be present. Based on it releasing the cluster * or mgmt_v3 lock */ if (lock_ctx->dict == NULL) { ret = glusterd_unlock(lock_ctx->uuid); glusterd_op_unlock_send_resp(lock_ctx->req, ret); } else { ret = dict_get_str(lock_ctx->dict, "volname", &volname); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to acquire volname"); else { ret = glusterd_mgmt_v3_unlock(volname, lock_ctx->uuid, "vol"); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Unable to release lock for %s", volname); goto out; } ret = dict_get_str(lock_ctx->dict, "globalname", &globalname); if (!ret) { ret = glusterd_mgmt_v3_unlock(globalname, lock_ctx->uuid, "global"); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Unable to release lock for %s", globalname); } out: glusterd_op_mgmt_v3_unlock_send_resp(lock_ctx->req, &event->txn_id, ret); dict_unref(lock_ctx->dict); } gf_msg_debug(this->name, 0, "Unlock Returned %d", ret); if (priv->pending_quorum_action) glusterd_do_quorum_action(); return ret; } static int glusterd_op_ac_local_unlock(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; uuid_t *originator = NULL; GF_ASSERT(event); GF_ASSERT(ctx); originator = (uuid_t *)ctx; ret = glusterd_unlock(*originator); gf_msg_debug(THIS->name, 0, "Unlock Returned %d", ret); return ret; } static int glusterd_op_ac_rcvd_lock_acc(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; GF_ASSERT(event); if (opinfo.pending_count > 0) opinfo.pending_count--; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (opinfo.pending_count > 0) goto out; ret = glusterd_op_sm_inject_event(GD_OP_EVENT_ALL_ACC, &event->txn_id, NULL); gf_msg_debug(THIS->name, 0, "Returning %d", ret); out: return ret; } int glusterd_dict_set_volid(dict_t *dict, char *volname, char **op_errstr) { int ret = -1; glusterd_volinfo_t *volinfo = NULL; char *volid = NULL; char msg[1024] = { 0, }; xlator_t *this = THIS; if (!dict || !volname) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_INVALID_ARGUMENT, NULL); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), FMTSTR_CHECK_VOL_EXISTS, volname); goto out; } volid = gf_strdup(uuid_utoa(volinfo->volume_id)); if (!volid) { ret = -1; goto out; } ret = dict_set_dynstr_sizen(dict, "vol-id", volid); if (ret) { snprintf(msg, sizeof(msg), "Failed to set volume id of volume" " %s", volname); GF_FREE(volid); goto out; } out: if (msg[0] != '\0') { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_ID_SET_FAIL, "%s", msg); *op_errstr = gf_strdup(msg); } return ret; } int gd_set_commit_hash(dict_t *dict) { struct timeval tv; uint32_t hash; /* * We need a commit hash that won't conflict with others we might have * set, or zero which is the implicit value if we never have. Using * seconds<<3 like this ensures that we'll only get a collision if two * consecutive rebalances are separated by exactly 2^29 seconds - about * 17 years - and even then there's only a 1/8 chance of a collision in * the low order bits. It's far more likely that this code will have * changed completely by then. If not, call me in 2031. * * P.S. Time zone changes? Yeah, right. */ gettimeofday(&tv, NULL); hash = tv.tv_sec << 3; /* * Make sure at least one of those low-order bits is set. The extra * shifting is because not all machines have sub-millisecond time * resolution. */ hash |= 1 << ((tv.tv_usec >> 10) % 3); return dict_set_uint32(dict, "commit-hash", hash); } int glusterd_op_build_payload(dict_t **req, char **op_errstr, dict_t *op_ctx) { int ret = -1; void *ctx = NULL; dict_t *dict = NULL; dict_t *req_dict = NULL; glusterd_op_t op = GD_OP_NONE; char *volname = NULL; uint32_t status_cmd = GF_CLI_STATUS_NONE; xlator_t *this = THIS; gf_boolean_t do_common = _gf_false; GF_ASSERT(req); req_dict = dict_new(); if (!req_dict) goto out; if (!op_ctx) { op = glusterd_op_get_op(); ctx = (void *)glusterd_op_get_ctx(); if (!ctx) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_NO_OPTIONS_GIVEN, "Null Context for " "op %d", op); ret = -1; goto out; } } else { #define GD_SYNC_OPCODE_KEY "sync-mgmt-operation" ret = dict_get_int32(op_ctx, GD_SYNC_OPCODE_KEY, (int32_t *)&op); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Failed to get volume" " operation"); goto out; } ctx = op_ctx; #undef GD_SYNC_OPCODE_KEY } dict = ctx; switch (op) { case GD_OP_CREATE_VOLUME: { ++glusterfs_port; ret = dict_set_int32_sizen(dict, "port", glusterfs_port); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to set port in " "dictionary"); goto out; } dict_copy(dict, req_dict); } break; case GD_OP_GSYNC_CREATE: case GD_OP_GSYNC_SET: { ret = glusterd_op_gsync_args_get(dict, op_errstr, &volname, NULL, NULL); if (ret == 0) { ret = glusterd_dict_set_volid(dict, volname, op_errstr); if (ret) goto out; } dict_copy(dict, req_dict); } break; case GD_OP_SET_VOLUME: { ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_CRITICAL, 0, GD_MSG_DICT_GET_FAILED, "volname is not present in " "operation ctx"); goto out; } if (strcmp(volname, "help") && strcmp(volname, "help-xml") && strcasecmp(volname, "all")) { ret = glusterd_dict_set_volid(dict, volname, op_errstr); if (ret) goto out; } dict_unref(req_dict); req_dict = dict_ref(dict); } break; case GD_OP_REMOVE_BRICK: { dict_t *dict = ctx; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_CRITICAL, 0, GD_MSG_DICT_GET_FAILED, "volname is not present in " "operation ctx"); goto out; } ret = glusterd_dict_set_volid(dict, volname, op_errstr); if (ret) goto out; if (gd_set_commit_hash(dict) != 0) { goto out; } dict_unref(req_dict); req_dict = dict_ref(dict); } break; case GD_OP_STATUS_VOLUME: { ret = dict_get_uint32(dict, "cmd", &status_cmd); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Status command not present " "in op ctx"); goto out; } if (GF_CLI_STATUS_ALL & status_cmd) { dict_copy(dict, req_dict); break; } do_common = _gf_true; } break; case GD_OP_DELETE_VOLUME: case GD_OP_START_VOLUME: case GD_OP_STOP_VOLUME: case GD_OP_ADD_BRICK: case GD_OP_REPLACE_BRICK: case GD_OP_RESET_VOLUME: case GD_OP_LOG_ROTATE: case GD_OP_QUOTA: case GD_OP_PROFILE_VOLUME: case GD_OP_HEAL_VOLUME: case GD_OP_STATEDUMP_VOLUME: case GD_OP_CLEARLOCKS_VOLUME: case GD_OP_DEFRAG_BRICK_VOLUME: case GD_OP_BARRIER: case GD_OP_BITROT: case GD_OP_SCRUB_STATUS: case GD_OP_SCRUB_ONDEMAND: case GD_OP_RESET_BRICK: { do_common = _gf_true; } break; case GD_OP_REBALANCE: { if (gd_set_commit_hash(dict) != 0) { goto out; } do_common = _gf_true; } break; case GD_OP_SYNC_VOLUME: case GD_OP_COPY_FILE: case GD_OP_SYS_EXEC: case GD_OP_GANESHA: { dict_copy(dict, req_dict); } break; default: break; } /* * This has been moved out of the switch so that multiple ops with * other special needs can all "fall through" to it. */ if (do_common) { ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_CRITICAL, -ret, GD_MSG_DICT_GET_FAILED, "volname is not present in " "operation ctx"); goto out; } if (strcasecmp(volname, "all")) { ret = glusterd_dict_set_volid(dict, volname, op_errstr); if (ret) goto out; } dict_copy(dict, req_dict); } *req = req_dict; ret = 0; out: if (ret && req_dict) dict_unref(req_dict); return ret; } static int glusterd_op_ac_send_stage_op(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; int ret1 = 0; rpc_clnt_procedure_t *proc = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; glusterd_peerinfo_t *peerinfo = NULL; dict_t *dict = NULL; dict_t *rsp_dict = NULL; char *op_errstr = NULL; glusterd_op_t op = GD_OP_NONE; uint32_t pending_count = 0; priv = this->private; GF_ASSERT(priv); op = glusterd_op_get_op(); rsp_dict = dict_new(); if (!rsp_dict) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_DICT_CREATE_FAIL, "Failed to create rsp_dict"); ret = -1; goto out; } ret = glusterd_op_build_payload(&dict, &op_errstr, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_OP_PAYLOAD_BUILD_FAIL, LOGSTR_BUILD_PAYLOAD, gd_op_list[op]); if (op_errstr == NULL) gf_asprintf(&op_errstr, OPERRSTR_BUILD_PAYLOAD); opinfo.op_errstr = op_errstr; goto out; } ret = glusterd_validate_quorum(this, op, dict, &op_errstr); if (ret) { gf_msg(this->name, GF_LOG_CRITICAL, 0, GD_MSG_SERVER_QUORUM_NOT_MET, "Server quorum not met. Rejecting operation."); opinfo.op_errstr = op_errstr; goto out; } ret = glusterd_op_stage_validate(op, dict, &op_errstr, rsp_dict); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VALIDATE_FAILED, LOGSTR_STAGE_FAIL, gd_op_list[op], "localhost", (op_errstr) ? ":" : " ", (op_errstr) ? op_errstr : " "); if (op_errstr == NULL) gf_asprintf(&op_errstr, OPERRSTR_STAGE_FAIL, "localhost"); opinfo.op_errstr = op_errstr; goto out; } RCU_READ_LOCK; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { /* Only send requests to peers who were available before the * transaction started */ if (peerinfo->generation > opinfo.txn_generation) continue; if (!peerinfo->connected || !peerinfo->mgmt) continue; if ((peerinfo->state != GD_FRIEND_STATE_BEFRIENDED) && (glusterd_op_get_op() != GD_OP_SYNC_VOLUME)) continue; proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_STAGE_OP]; GF_ASSERT(proc); if (proc->fn) { ret = dict_set_static_ptr(dict, "peerinfo", peerinfo); if (ret) { RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to " "set peerinfo"); goto out; } ret = proc->fn(NULL, this, dict); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_STAGE_REQ_SEND_FAIL, "Failed to " "send stage request for operation " "'Volume %s' to peer %s", gd_op_list[op], peerinfo->hostname); continue; } pending_count++; } } RCU_READ_UNLOCK; opinfo.pending_count = pending_count; out: if (ret) opinfo.op_ret = ret; ret1 = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret1) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (rsp_dict) dict_unref(rsp_dict); if (dict) dict_unref(dict); if (ret) { glusterd_op_sm_inject_event(GD_OP_EVENT_RCVD_RJT, &event->txn_id, NULL); opinfo.op_ret = ret; } gf_msg_debug(this->name, 0, "Sent stage op request for " "'Volume %s' to %d peers", gd_op_list[op], opinfo.pending_count); if (!opinfo.pending_count) ret = glusterd_op_sm_inject_all_acc(&event->txn_id); gf_msg_debug(this->name, 0, "Returning with %d", ret); return ret; } /* This function takes a dict and converts the uuid values of key specified * into hostnames */ static int glusterd_op_volume_dict_uuid_to_hostname(dict_t *dict, const char *key_fmt, int idx_min, int idx_max) { int ret = -1; int i = 0; char key[128]; int keylen; char *uuid_str = NULL; uuid_t uuid = { 0, }; char *hostname = NULL; xlator_t *this = THIS; GF_ASSERT(dict); GF_ASSERT(key_fmt); for (i = idx_min; i < idx_max; i++) { keylen = snprintf(key, sizeof(key), key_fmt, i); ret = dict_get_strn(dict, key, keylen, &uuid_str); if (ret) { ret = 0; continue; } gf_msg_debug(this->name, 0, "Got uuid %s", uuid_str); ret = gf_uuid_parse(uuid_str, uuid); /* if parsing fails don't error out * let the original value be retained */ if (ret) { ret = 0; continue; } hostname = glusterd_uuid_to_hostname(uuid); if (hostname) { gf_msg_debug(this->name, 0, "%s -> %s", uuid_str, hostname); ret = dict_set_dynstrn(dict, key, keylen, hostname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Error setting hostname %s to dict", hostname); GF_FREE(hostname); goto out; } } } out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int reassign_defrag_status(dict_t *dict, char *key, int keylen, gf_defrag_status_t *status) { int ret = 0; if (!*status) return ret; switch (*status) { case GF_DEFRAG_STATUS_STARTED: *status = GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED; break; case GF_DEFRAG_STATUS_STOPPED: *status = GF_DEFRAG_STATUS_LAYOUT_FIX_STOPPED; break; case GF_DEFRAG_STATUS_COMPLETE: *status = GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE; break; case GF_DEFRAG_STATUS_FAILED: *status = GF_DEFRAG_STATUS_LAYOUT_FIX_FAILED; break; default: break; } ret = dict_set_int32n(dict, key, keylen, *status); if (ret) gf_msg(THIS->name, GF_LOG_WARNING, 0, GD_MSG_DICT_SET_FAILED, "failed to reset defrag %s in dict", key); return ret; } /* Check and reassign the defrag_status enum got from the rebalance process * of all peers so that the rebalance-status CLI command can display if a * full-rebalance or just a fix-layout was carried out. */ static int glusterd_op_check_peer_defrag_status(dict_t *dict, int count) { glusterd_volinfo_t *volinfo = NULL; gf_defrag_status_t status = GF_DEFRAG_STATUS_NOT_STARTED; char key[64] = { 0, }; int keylen; char *volname = NULL; int ret = -1; int i = 1; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(THIS->name, GF_LOG_WARNING, 0, GD_MSG_DICT_GET_FAILED, "Unable to get volume name"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { gf_msg(THIS->name, GF_LOG_WARNING, 0, GD_MSG_VOL_NOT_FOUND, FMTSTR_CHECK_VOL_EXISTS, volname); goto out; } if (volinfo->rebal.defrag_cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX) { /* Fix layout was not issued; we don't need to reassign the status */ ret = 0; goto out; } do { keylen = snprintf(key, sizeof(key), "status-%d", i); ret = dict_get_int32n(dict, key, keylen, (int32_t *)&status); if (ret) { gf_msg(THIS->name, GF_LOG_WARNING, 0, GD_MSG_DICT_GET_FAILED, "failed to get defrag %s", key); goto out; } ret = reassign_defrag_status(dict, key, keylen, &status); if (ret) goto out; i++; } while (i <= count); ret = 0; out: return ret; } /* This function is used to verify if op_ctx indeed requires modification. This is necessary since the dictionary for certain commands might not have the necessary keys required for the op_ctx modification to succeed. Special Cases: - volume status all - volume status Regular Cases: - volume status - volume status mem - volume status clients - volume status inode - volume status fd - volume status callpool - volume status tasks */ static gf_boolean_t glusterd_is_volume_status_modify_op_ctx(uint32_t cmd) { if ((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE) { if (cmd & GF_CLI_STATUS_BRICK) return _gf_false; if (cmd & GF_CLI_STATUS_ALL) return _gf_false; return _gf_true; } return _gf_false; } int glusterd_op_modify_port_key(dict_t *op_ctx, int brick_index_max) { char *port = NULL; int i = 0; int ret = -1; char key[64] = {0}; int keylen; char old_key[64] = {0}; int old_keylen; for (i = 0; i <= brick_index_max; i++) { keylen = snprintf(key, sizeof(key), "brick%d.rdma_port", i); ret = dict_get_strn(op_ctx, key, keylen, &port); if (ret) { old_keylen = snprintf(old_key, sizeof(old_key), "brick%d.port", i); ret = dict_get_strn(op_ctx, old_key, old_keylen, &port); if (ret) goto out; ret = dict_set_strn(op_ctx, key, keylen, port); if (ret) goto out; ret = dict_set_nstrn(op_ctx, old_key, old_keylen, "\0", SLEN("\0")); if (ret) goto out; } } out: return ret; } /* This function is used to modify the op_ctx dict before sending it back * to cli. This is useful in situations like changing the peer uuids to * hostnames etc. */ void glusterd_op_modify_op_ctx(glusterd_op_t op, void *ctx) { int ret = -1; dict_t *op_ctx = NULL; int brick_index_max = -1; int other_count = 0; int count = 0; uint32_t cmd = GF_CLI_STATUS_NONE; xlator_t *this = THIS; glusterd_conf_t *conf = NULL; char *volname = NULL; glusterd_volinfo_t *volinfo = NULL; char *port = 0; int i = 0; char key[64] = { 0, }; int keylen; conf = this->private; if (ctx) op_ctx = ctx; else op_ctx = glusterd_op_get_ctx(); if (!op_ctx) { gf_msg(this->name, GF_LOG_CRITICAL, 0, GD_MSG_OPCTX_NULL, "Operation context is not present."); goto out; } switch (op) { case GD_OP_STATUS_VOLUME: ret = dict_get_uint32(op_ctx, "cmd", &cmd); if (ret) { gf_msg_debug(this->name, 0, "Failed to get status cmd"); goto out; } if (!glusterd_is_volume_status_modify_op_ctx(cmd)) { gf_msg_debug(this->name, 0, "op_ctx modification not required for status " "operation being performed"); goto out; } ret = dict_get_int32(op_ctx, "brick-index-max", &brick_index_max); if (ret) { gf_msg_debug(this->name, 0, "Failed to get brick-index-max"); goto out; } ret = dict_get_int32(op_ctx, "other-count", &other_count); if (ret) { gf_msg_debug(this->name, 0, "Failed to get other-count"); goto out; } count = brick_index_max + other_count + 1; /* * a glusterd lesser than version 3.7 will be sending the * rdma port in older key. Changing that value from here * to support backward compatibility */ ret = dict_get_str(op_ctx, "volname", &volname); if (ret) goto out; for (i = 0; i <= brick_index_max; i++) { keylen = snprintf(key, sizeof(key), "brick%d.rdma_port", i); ret = dict_get_strn(op_ctx, key, keylen, &port); if (ret) { ret = dict_set_nstrn(op_ctx, key, keylen, "\0", SLEN("\0")); if (ret) goto out; } } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) goto out; if (conf->op_version < GD_OP_VERSION_3_7_0 && volinfo->transport_type == GF_TRANSPORT_RDMA) { ret = glusterd_op_modify_port_key(op_ctx, brick_index_max); if (ret) goto out; } /* add 'brick%d.peerid' into op_ctx with value of 'brick%d.path'. nfs/sshd like services have this additional uuid */ { char *uuid_str = NULL; char *uuid = NULL; int i; for (i = brick_index_max + 1; i < count; i++) { keylen = snprintf(key, sizeof(key), "brick%d.path", i); ret = dict_get_strn(op_ctx, key, keylen, &uuid_str); if (!ret) { keylen = snprintf(key, sizeof(key), "brick%d.peerid", i); uuid = gf_strdup(uuid_str); if (!uuid) { gf_msg_debug(this->name, 0, "unable to create dup of" " uuid_str"); continue; } ret = dict_set_dynstrn(op_ctx, key, keylen, uuid); if (ret != 0) { GF_FREE(uuid); } } } } ret = glusterd_op_volume_dict_uuid_to_hostname( op_ctx, "brick%d.path", 0, count); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_CONVERSION_FAILED, "Failed uuid to hostname conversion"); break; case GD_OP_PROFILE_VOLUME: ret = dict_get_str_boolean(op_ctx, "nfs", _gf_false); if (!ret) goto out; ret = dict_get_int32(op_ctx, "count", &count); if (ret) { gf_msg_debug(this->name, 0, "Failed to get brick count"); goto out; } ret = glusterd_op_volume_dict_uuid_to_hostname(op_ctx, "%d-brick", 1, (count + 1)); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_CONVERSION_FAILED, "Failed uuid to hostname conversion"); break; /* For both rebalance and remove-brick status, the glusterd op is the * same */ case GD_OP_DEFRAG_BRICK_VOLUME: case GD_OP_SCRUB_STATUS: case GD_OP_SCRUB_ONDEMAND: ret = dict_get_int32(op_ctx, "count", &count); if (ret) { gf_msg_debug(this->name, 0, "Failed to get count"); goto out; } /* add 'node-name-%d' into op_ctx with value uuid_str. this will be used to convert to hostname later */ { char *uuid_str = NULL; char *uuid = NULL; int i; for (i = 1; i <= count; i++) { keylen = snprintf(key, sizeof(key), "node-uuid-%d", i); ret = dict_get_strn(op_ctx, key, keylen, &uuid_str); if (!ret) { keylen = snprintf(key, sizeof(key), "node-name-%d", i); uuid = gf_strdup(uuid_str); if (!uuid) { gf_msg_debug(this->name, 0, "unable to create dup of" " uuid_str"); continue; } ret = dict_set_dynstrn(op_ctx, key, keylen, uuid); if (ret != 0) { GF_FREE(uuid); } } } } ret = glusterd_op_volume_dict_uuid_to_hostname( op_ctx, "node-name-%d", 1, (count + 1)); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_CONVERSION_FAILED, "Failed uuid to hostname conversion"); /* Since Both rebalance and bitrot scrub status/ondemand * are going to use same code path till here, we should * break in case of scrub status. */ if (op == GD_OP_SCRUB_STATUS || op == GD_OP_SCRUB_ONDEMAND) { break; } ret = glusterd_op_check_peer_defrag_status(op_ctx, count); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DEFRAG_STATUS_UPDATE_FAIL, "Failed to reset defrag status for fix-layout"); break; default: ret = 0; gf_msg_debug(this->name, 0, "op_ctx modification not required"); break; } out: if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_OPCTX_UPDATE_FAIL, "op_ctx modification failed"); return; } int glusterd_op_commit_hook(glusterd_op_t op, dict_t *op_ctx, glusterd_commit_hook_type_t type) { glusterd_conf_t *priv = NULL; char hookdir[PATH_MAX] = { 0, }; char scriptdir[PATH_MAX] = { 0, }; char *type_subdir = ""; char *cmd_subdir = NULL; int ret = -1; int32_t len = 0; priv = THIS->private; switch (type) { case GD_COMMIT_HOOK_NONE: case GD_COMMIT_HOOK_MAX: /*Won't be called*/ break; case GD_COMMIT_HOOK_PRE: type_subdir = "pre"; break; case GD_COMMIT_HOOK_POST: type_subdir = "post"; break; } cmd_subdir = glusterd_hooks_get_hooks_cmd_subdir(op); if (strlen(cmd_subdir) == 0) return -1; GLUSTERD_GET_HOOKS_DIR(hookdir, GLUSTERD_HOOK_VER, priv); len = snprintf(scriptdir, sizeof(scriptdir), "%s/%s/%s", hookdir, cmd_subdir, type_subdir); if ((len < 0) || (len >= sizeof(scriptdir))) { return -1; } switch (type) { case GD_COMMIT_HOOK_NONE: case GD_COMMIT_HOOK_MAX: /*Won't be called*/ break; case GD_COMMIT_HOOK_PRE: ret = glusterd_hooks_run_hooks(scriptdir, op, op_ctx, type); break; case GD_COMMIT_HOOK_POST: ret = glusterd_hooks_post_stub_enqueue(scriptdir, op, op_ctx); break; } return ret; } static int glusterd_op_ac_send_commit_op(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; int ret1 = 0; rpc_clnt_procedure_t *proc = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; dict_t *dict = NULL; glusterd_peerinfo_t *peerinfo = NULL; char *op_errstr = NULL; glusterd_op_t op = GD_OP_NONE; uint32_t pending_count = 0; priv = this->private; GF_ASSERT(priv); op = glusterd_op_get_op(); ret = glusterd_op_build_payload(&dict, &op_errstr, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_OP_PAYLOAD_BUILD_FAIL, LOGSTR_BUILD_PAYLOAD, gd_op_list[op]); if (op_errstr == NULL) gf_asprintf(&op_errstr, OPERRSTR_BUILD_PAYLOAD); opinfo.op_errstr = op_errstr; goto out; } ret = glusterd_op_commit_perform(op, dict, &op_errstr, NULL); // rsp_dict invalid for source if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_COMMIT_OP_FAIL, LOGSTR_COMMIT_FAIL, gd_op_list[op], "localhost", (op_errstr) ? ":" : " ", (op_errstr) ? op_errstr : " "); if (op_errstr == NULL) gf_asprintf(&op_errstr, OPERRSTR_COMMIT_FAIL, "localhost"); opinfo.op_errstr = op_errstr; goto out; } RCU_READ_LOCK; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { /* Only send requests to peers who were available before the * transaction started */ if (peerinfo->generation > opinfo.txn_generation) continue; if (!peerinfo->connected || !peerinfo->mgmt) continue; if ((peerinfo->state != GD_FRIEND_STATE_BEFRIENDED) && (glusterd_op_get_op() != GD_OP_SYNC_VOLUME)) continue; proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_COMMIT_OP]; GF_ASSERT(proc); if (proc->fn) { ret = dict_set_static_ptr(dict, "peerinfo", peerinfo); if (ret) { RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); goto out; } ret = proc->fn(NULL, this, dict); if (ret) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_COMMIT_REQ_SEND_FAIL, "Failed to " "send commit request for operation " "'Volume %s' to peer %s", gd_op_list[op], peerinfo->hostname); continue; } pending_count++; } } RCU_READ_UNLOCK; opinfo.pending_count = pending_count; gf_msg_debug(this->name, 0, "Sent commit op req for 'Volume %s' " "to %d peers", gd_op_list[op], opinfo.pending_count); out: if (dict) dict_unref(dict); if (ret) opinfo.op_ret = ret; ret1 = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret1) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (ret) { glusterd_op_sm_inject_event(GD_OP_EVENT_RCVD_RJT, &event->txn_id, NULL); opinfo.op_ret = ret; } if (!opinfo.pending_count) { if (op == GD_OP_REPLACE_BRICK) { ret = glusterd_op_sm_inject_all_acc(&event->txn_id); } else { glusterd_op_modify_op_ctx(op, NULL); ret = glusterd_op_sm_inject_all_acc(&event->txn_id); } goto err; } err: gf_msg_debug(this->name, 0, "Returning with %d", ret); return ret; } static int glusterd_op_ac_rcvd_stage_op_acc(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; GF_ASSERT(event); if (opinfo.pending_count > 0) opinfo.pending_count--; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (opinfo.pending_count > 0) goto out; ret = glusterd_op_sm_inject_event(GD_OP_EVENT_STAGE_ACC, &event->txn_id, NULL); out: gf_msg_debug(THIS->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_ac_stage_op_failed(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; GF_ASSERT(event); if (opinfo.pending_count > 0) opinfo.pending_count--; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (opinfo.pending_count > 0) goto out; ret = glusterd_op_sm_inject_event(GD_OP_EVENT_ALL_ACK, &event->txn_id, NULL); out: gf_msg_debug(THIS->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_ac_commit_op_failed(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; GF_ASSERT(event); if (opinfo.pending_count > 0) opinfo.pending_count--; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (opinfo.pending_count > 0) goto out; ret = glusterd_op_sm_inject_event(GD_OP_EVENT_ALL_ACK, &event->txn_id, NULL); out: gf_msg_debug(THIS->name, 0, "Returning %d", ret); return ret; } static int glusterd_remove_pending_entry(struct cds_list_head *list, void *elem) { glusterd_pending_node_t *pending_node = NULL; glusterd_pending_node_t *tmp = NULL; int ret = 0; cds_list_for_each_entry_safe(pending_node, tmp, list, list) { if (elem == pending_node->node) { cds_list_del_init(&pending_node->list); GF_FREE(pending_node); ret = 0; goto out; } } out: gf_msg_debug(THIS->name, 0, "returning %d", ret); return ret; } static int glusterd_op_ac_brick_op_failed(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL; gf_boolean_t free_errstr = _gf_false; xlator_t *this = THIS; GF_ASSERT(event); GF_ASSERT(ctx); ev_ctx = ctx; ret = glusterd_remove_pending_entry(&opinfo.pending_bricks, ev_ctx->pending_node->node); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_UNKNOWN_RESPONSE, "unknown response received "); ret = -1; free_errstr = _gf_true; goto out; } if (opinfo.brick_pending_count > 0) opinfo.brick_pending_count--; if (opinfo.op_ret == 0) opinfo.op_ret = ev_ctx->op_ret; if (opinfo.op_errstr == NULL) opinfo.op_errstr = ev_ctx->op_errstr; else free_errstr = _gf_true; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (opinfo.brick_pending_count > 0) goto out; ret = glusterd_op_sm_inject_event(GD_OP_EVENT_ALL_ACK, &event->txn_id, ev_ctx->commit_ctx); out: if (ev_ctx->rsp_dict) dict_unref(ev_ctx->rsp_dict); if (free_errstr && ev_ctx->op_errstr) GF_FREE(ev_ctx->op_errstr); GF_FREE(ctx); gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_ac_rcvd_commit_op_acc(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; gf_boolean_t commit_ack_inject = _gf_true; glusterd_op_t op = GD_OP_NONE; xlator_t *this = THIS; op = glusterd_op_get_op(); GF_ASSERT(event); if (opinfo.pending_count > 0) opinfo.pending_count--; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (opinfo.pending_count > 0) goto out; if (op == GD_OP_REPLACE_BRICK) { ret = glusterd_op_sm_inject_all_acc(&event->txn_id); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_RBOP_START_FAIL, "Couldn't start " "replace-brick operation."); goto out; } commit_ack_inject = _gf_false; goto out; } out: if (commit_ack_inject) { if (ret) ret = glusterd_op_sm_inject_event(GD_OP_EVENT_RCVD_RJT, &event->txn_id, NULL); else if (!opinfo.pending_count) { glusterd_op_modify_op_ctx(op, NULL); ret = glusterd_op_sm_inject_event(GD_OP_EVENT_COMMIT_ACC, &event->txn_id, NULL); } /*else do nothing*/ } return ret; } static int glusterd_op_ac_rcvd_unlock_acc(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; GF_ASSERT(event); if (opinfo.pending_count > 0) opinfo.pending_count--; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); if (opinfo.pending_count > 0) goto out; ret = glusterd_op_sm_inject_event(GD_OP_EVENT_ALL_ACC, &event->txn_id, NULL); gf_msg_debug(THIS->name, 0, "Returning %d", ret); out: return ret; } int32_t glusterd_op_clear_errstr(void) { opinfo.op_errstr = NULL; return 0; } int32_t glusterd_op_set_ctx(void *ctx) { opinfo.op_ctx = ctx; return 0; } int32_t glusterd_op_reset_ctx(void) { glusterd_op_set_ctx(NULL); return 0; } int32_t glusterd_op_txn_complete(uuid_t *txn_id) { int32_t ret = -1; glusterd_conf_t *priv = NULL; int32_t op = -1; int32_t op_ret = 0; int32_t op_errno = 0; rpcsvc_request_t *req = NULL; void *ctx = NULL; char *op_errstr = NULL; char *volname = NULL; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); op = glusterd_op_get_op(); ctx = glusterd_op_get_ctx(); op_ret = opinfo.op_ret; op_errno = opinfo.op_errno; req = opinfo.req; if (opinfo.op_errstr) op_errstr = opinfo.op_errstr; opinfo.op_ret = 0; opinfo.op_errno = 0; /* Based on the op-version, we release the cluster or mgmt_v3 lock */ if (priv->op_version < GD_OP_VERSION_3_6_0) { ret = glusterd_unlock(MY_UUID); /* unlock can't/shouldn't fail here!! */ if (ret) gf_msg(this->name, GF_LOG_CRITICAL, 0, GD_MSG_GLUSTERD_UNLOCK_FAIL, "Unable to clear local lock, ret: %d", ret); else gf_msg_debug(this->name, 0, "Cleared local lock"); } else { ret = dict_get_str(ctx, "volname", &volname); if (ret) gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_DICT_GET_FAILED, "No Volume name present. " "Locks have not been held."); if (volname) { ret = glusterd_mgmt_v3_unlock(volname, MY_UUID, "vol"); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Unable to release lock for %s", volname); } } ret = glusterd_op_send_cli_response(op, op_ret, op_errno, req, ctx, op_errstr); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_NO_CLI_RESP, "Responding to cli failed, " "ret: %d", ret); // Ignore this error, else state machine blocks ret = 0; } if (op_errstr && (strcmp(op_errstr, ""))) GF_FREE(op_errstr); if (priv->pending_quorum_action) glusterd_do_quorum_action(); /* Clearing the transaction opinfo */ ret = glusterd_clear_txn_opinfo(txn_id); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_CLEAR_FAIL, "Unable to clear transaction's opinfo"); gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_ac_unlocked_all(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; GF_ASSERT(event); ret = glusterd_op_txn_complete(&event->txn_id); gf_msg_debug(THIS->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_ac_stage_op(glusterd_op_sm_event_t *event, void *ctx) { int ret = -1; glusterd_req_ctx_t *req_ctx = NULL; int32_t status = 0; dict_t *rsp_dict = NULL; char *op_errstr = NULL; dict_t *dict = NULL; xlator_t *this = THIS; uuid_t *txn_id = NULL; glusterd_op_info_t txn_op_info = { GD_OP_STATE_DEFAULT, }; glusterd_conf_t *priv = NULL; priv = this->private; GF_ASSERT(priv); GF_ASSERT(ctx); req_ctx = ctx; dict = req_ctx->dict; rsp_dict = dict_new(); if (!rsp_dict) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_DICT_CREATE_FAIL, "Failed to get new dictionary"); return -1; } status = glusterd_op_stage_validate(req_ctx->op, dict, &op_errstr, rsp_dict); if (status) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VALIDATE_FAILED, "Stage failed on operation" " 'Volume %s', Status : %d", gd_op_list[req_ctx->op], status); } txn_id = GF_MALLOC(sizeof(uuid_t), gf_common_mt_uuid_t); if (txn_id) gf_uuid_copy(*txn_id, event->txn_id); else { ret = -1; goto out; } ret = glusterd_get_txn_opinfo(&event->txn_id, &txn_op_info); ret = dict_set_bin(rsp_dict, "transaction_id", txn_id, sizeof(*txn_id)); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to set transaction id."); GF_FREE(txn_id); txn_id = NULL; goto out; } ret = glusterd_op_stage_send_resp(req_ctx->req, req_ctx->op, status, op_errstr, rsp_dict); out: if (op_errstr && (strcmp(op_errstr, ""))) GF_FREE(op_errstr); gf_msg_debug(this->name, 0, "Returning with %d", ret); /* for no volname transactions, the txn_opinfo needs to be cleaned up * as there's no unlock event triggered. However if the originator node of * this transaction is still running with a version lower than 60000, * txn_opinfo can't be cleared as that'll lead to a race of referring op_ctx * after it's being freed. */ if (txn_op_info.skip_locking && priv->op_version >= GD_OP_VERSION_6_0 && txn_id) ret = glusterd_clear_txn_opinfo(txn_id); if (rsp_dict) dict_unref(rsp_dict); return ret; } static gf_boolean_t glusterd_need_brick_op(glusterd_op_t op) { gf_boolean_t ret = _gf_false; GF_ASSERT(GD_OP_NONE < op && op < GD_OP_MAX); switch (op) { case GD_OP_PROFILE_VOLUME: case GD_OP_STATUS_VOLUME: case GD_OP_DEFRAG_BRICK_VOLUME: case GD_OP_HEAL_VOLUME: case GD_OP_SCRUB_STATUS: case GD_OP_SCRUB_ONDEMAND: ret = _gf_true; break; default: ret = _gf_false; } return ret; } dict_t * glusterd_op_init_commit_rsp_dict(glusterd_op_t op) { dict_t *rsp_dict = NULL; dict_t *op_ctx = NULL; GF_ASSERT(GD_OP_NONE < op && op < GD_OP_MAX); if (glusterd_need_brick_op(op)) { op_ctx = glusterd_op_get_ctx(); GF_ASSERT(op_ctx); rsp_dict = dict_ref(op_ctx); } else { rsp_dict = dict_new(); } return rsp_dict; } static int glusterd_op_ac_commit_op(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; glusterd_req_ctx_t *req_ctx = NULL; int32_t status = 0; char *op_errstr = NULL; dict_t *dict = NULL; dict_t *rsp_dict = NULL; xlator_t *this = THIS; uuid_t *txn_id = NULL; glusterd_op_info_t txn_op_info = { GD_OP_STATE_DEFAULT, }; gf_boolean_t need_cleanup = _gf_true; GF_ASSERT(ctx); req_ctx = ctx; dict = req_ctx->dict; rsp_dict = glusterd_op_init_commit_rsp_dict(req_ctx->op); if (NULL == rsp_dict) return -1; if (GD_OP_CLEARLOCKS_VOLUME == req_ctx->op) { /*clear locks should be run only on * originator glusterd*/ status = 0; } else { status = glusterd_op_commit_perform(req_ctx->op, dict, &op_errstr, rsp_dict); } if (status) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_COMMIT_OP_FAIL, "Commit of operation " "'Volume %s' failed: %d", gd_op_list[req_ctx->op], status); txn_id = GF_MALLOC(sizeof(uuid_t), gf_common_mt_uuid_t); if (txn_id) gf_uuid_copy(*txn_id, event->txn_id); else { ret = -1; goto out; } ret = glusterd_get_txn_opinfo(&event->txn_id, &txn_op_info); if (ret) { gf_msg_callingfn(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_GET_FAIL, "Unable to get transaction opinfo " "for transaction ID : %s", uuid_utoa(event->txn_id)); goto out; } ret = dict_set_bin(rsp_dict, "transaction_id", txn_id, sizeof(*txn_id)); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to set transaction id."); if (txn_op_info.skip_locking) ret = glusterd_clear_txn_opinfo(txn_id); need_cleanup = _gf_false; GF_FREE(txn_id); goto out; } ret = glusterd_op_commit_send_resp(req_ctx->req, req_ctx->op, status, op_errstr, rsp_dict); out: if (op_errstr && (strcmp(op_errstr, ""))) GF_FREE(op_errstr); if (rsp_dict) dict_unref(rsp_dict); /* for no volname transactions, the txn_opinfo needs to be cleaned up * as there's no unlock event triggered */ if (need_cleanup && txn_id && txn_op_info.skip_locking) ret = glusterd_clear_txn_opinfo(txn_id); gf_msg_debug(this->name, 0, "Returning with %d", ret); return ret; } static int glusterd_op_ac_send_commit_failed(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; glusterd_req_ctx_t *req_ctx = NULL; dict_t *op_ctx = NULL; GF_ASSERT(ctx); req_ctx = ctx; op_ctx = glusterd_op_get_ctx(); ret = glusterd_op_commit_send_resp(req_ctx->req, req_ctx->op, opinfo.op_ret, opinfo.op_errstr, op_ctx); if (opinfo.op_errstr && (strcmp(opinfo.op_errstr, ""))) { GF_FREE(opinfo.op_errstr); opinfo.op_errstr = NULL; } ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); gf_msg_debug(THIS->name, 0, "Returning with %d", ret); return ret; } static int glusterd_op_sm_transition_state(glusterd_op_info_t *opinfo, glusterd_op_sm_t *state, glusterd_op_sm_event_type_t event_type) { glusterd_conf_t *conf = NULL; GF_ASSERT(state); GF_ASSERT(opinfo); conf = THIS->private; GF_ASSERT(conf); (void)glusterd_sm_tr_log_transition_add(&conf->op_sm_log, opinfo->state, state[event_type].next_state, event_type); opinfo->state = state[event_type].next_state; return 0; } int32_t glusterd_op_stage_validate(glusterd_op_t op, dict_t *dict, char **op_errstr, dict_t *rsp_dict) { int ret = -1; xlator_t *this = THIS; switch (op) { case GD_OP_CREATE_VOLUME: ret = glusterd_op_stage_create_volume(dict, op_errstr, rsp_dict); break; case GD_OP_START_VOLUME: ret = glusterd_op_stage_start_volume(dict, op_errstr, rsp_dict); break; case GD_OP_STOP_VOLUME: ret = glusterd_op_stage_stop_volume(dict, op_errstr); break; case GD_OP_DELETE_VOLUME: ret = glusterd_op_stage_delete_volume(dict, op_errstr); break; case GD_OP_ADD_BRICK: ret = glusterd_op_stage_add_brick(dict, op_errstr, rsp_dict); break; case GD_OP_REPLACE_BRICK: ret = glusterd_op_stage_replace_brick(dict, op_errstr, rsp_dict); break; case GD_OP_SET_VOLUME: ret = glusterd_op_stage_set_volume(dict, op_errstr); break; case GD_OP_GANESHA: ret = glusterd_op_stage_set_ganesha(dict, op_errstr); break; case GD_OP_RESET_VOLUME: ret = glusterd_op_stage_reset_volume(dict, op_errstr); break; case GD_OP_REMOVE_BRICK: ret = glusterd_op_stage_remove_brick(dict, op_errstr); break; case GD_OP_LOG_ROTATE: ret = glusterd_op_stage_log_rotate(dict, op_errstr); break; case GD_OP_SYNC_VOLUME: ret = glusterd_op_stage_sync_volume(dict, op_errstr); break; case GD_OP_GSYNC_CREATE: ret = glusterd_op_stage_gsync_create(dict, op_errstr); break; case GD_OP_GSYNC_SET: ret = glusterd_op_stage_gsync_set(dict, op_errstr); break; case GD_OP_PROFILE_VOLUME: ret = glusterd_op_stage_stats_volume(dict, op_errstr); break; case GD_OP_QUOTA: ret = glusterd_op_stage_quota(dict, op_errstr, rsp_dict); break; case GD_OP_STATUS_VOLUME: ret = glusterd_op_stage_status_volume(dict, op_errstr); break; case GD_OP_REBALANCE: case GD_OP_DEFRAG_BRICK_VOLUME: ret = glusterd_op_stage_rebalance(dict, op_errstr); break; case GD_OP_HEAL_VOLUME: ret = glusterd_op_stage_heal_volume(dict, op_errstr); break; case GD_OP_STATEDUMP_VOLUME: ret = glusterd_op_stage_statedump_volume(dict, op_errstr); break; case GD_OP_CLEARLOCKS_VOLUME: ret = glusterd_op_stage_clearlocks_volume(dict, op_errstr); break; case GD_OP_COPY_FILE: ret = glusterd_op_stage_copy_file(dict, op_errstr); break; case GD_OP_SYS_EXEC: ret = glusterd_op_stage_sys_exec(dict, op_errstr); break; case GD_OP_BARRIER: ret = glusterd_op_stage_barrier(dict, op_errstr); break; case GD_OP_BITROT: case GD_OP_SCRUB_STATUS: case GD_OP_SCRUB_ONDEMAND: ret = glusterd_op_stage_bitrot(dict, op_errstr, rsp_dict); break; default: gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "Unknown op %s", gd_op_list[op]); } gf_msg_debug(this->name, 0, "OP = %d. Returning %d", op, ret); return ret; } static void glusterd_wait_for_blockers(glusterd_conf_t *priv) { while (GF_ATOMIC_GET(priv->blockers)) { synccond_wait(&priv->cond_blockers, &priv->big_lock); } } int32_t glusterd_op_commit_perform(glusterd_op_t op, dict_t *dict, char **op_errstr, dict_t *rsp_dict) { int ret = -1; xlator_t *this = THIS; glusterd_op_commit_hook(op, dict, GD_COMMIT_HOOK_PRE); switch (op) { case GD_OP_CREATE_VOLUME: ret = glusterd_op_create_volume(dict, op_errstr); break; case GD_OP_START_VOLUME: ret = glusterd_op_start_volume(dict, op_errstr); break; case GD_OP_STOP_VOLUME: ret = glusterd_op_stop_volume(dict); break; case GD_OP_DELETE_VOLUME: glusterd_wait_for_blockers(this->private); ret = glusterd_op_delete_volume(dict); break; case GD_OP_ADD_BRICK: glusterd_wait_for_blockers(this->private); ret = glusterd_op_add_brick(dict, op_errstr); break; case GD_OP_REPLACE_BRICK: glusterd_wait_for_blockers(this->private); ret = glusterd_op_replace_brick(dict, rsp_dict); break; case GD_OP_SET_VOLUME: ret = glusterd_op_set_volume(dict, op_errstr); break; case GD_OP_GANESHA: ret = glusterd_op_set_ganesha(dict, op_errstr); break; case GD_OP_RESET_VOLUME: ret = glusterd_op_reset_volume(dict, op_errstr); break; case GD_OP_REMOVE_BRICK: glusterd_wait_for_blockers(this->private); ret = glusterd_op_remove_brick(dict, op_errstr); break; case GD_OP_LOG_ROTATE: ret = glusterd_op_log_rotate(dict); break; case GD_OP_SYNC_VOLUME: ret = glusterd_op_sync_volume(dict, op_errstr, rsp_dict); break; case GD_OP_GSYNC_CREATE: ret = glusterd_op_gsync_create(dict, op_errstr, rsp_dict); break; case GD_OP_GSYNC_SET: ret = glusterd_op_gsync_set(dict, op_errstr, rsp_dict); break; case GD_OP_PROFILE_VOLUME: ret = glusterd_op_stats_volume(dict, op_errstr, rsp_dict); break; case GD_OP_QUOTA: ret = glusterd_op_quota(dict, op_errstr, rsp_dict); break; case GD_OP_STATUS_VOLUME: ret = glusterd_op_status_volume(dict, op_errstr, rsp_dict); break; case GD_OP_REBALANCE: case GD_OP_DEFRAG_BRICK_VOLUME: ret = glusterd_op_rebalance(dict, op_errstr, rsp_dict); break; case GD_OP_HEAL_VOLUME: ret = glusterd_op_heal_volume(dict, op_errstr); break; case GD_OP_STATEDUMP_VOLUME: ret = glusterd_op_statedump_volume(dict, op_errstr); break; case GD_OP_CLEARLOCKS_VOLUME: ret = glusterd_op_clearlocks_volume(dict, op_errstr, rsp_dict); break; case GD_OP_COPY_FILE: ret = glusterd_op_copy_file(dict, op_errstr); break; case GD_OP_SYS_EXEC: ret = glusterd_op_sys_exec(dict, op_errstr, rsp_dict); break; case GD_OP_BARRIER: ret = glusterd_op_barrier(dict, op_errstr); break; case GD_OP_BITROT: case GD_OP_SCRUB_STATUS: case GD_OP_SCRUB_ONDEMAND: ret = glusterd_op_bitrot(dict, op_errstr, rsp_dict); break; default: gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "Unknown op %s", gd_op_list[op]); break; } if (ret == 0) glusterd_op_commit_hook(op, dict, GD_COMMIT_HOOK_POST); gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_bricks_select_stop_volume(dict_t *dict, char **op_errstr, struct cds_list_head *selected) { int ret = 0; int flags = 0; char *volname = NULL; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; glusterd_pending_node_t *pending_node = NULL; ret = glusterd_op_stop_volume_args_get(dict, &volname, &flags); if (ret) goto out; ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, FMTSTR_CHECK_VOL_EXISTS, volname); gf_asprintf(op_errstr, FMTSTR_CHECK_VOL_EXISTS, volname); goto out; } cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (glusterd_is_brick_started(brickinfo)) { pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } else { pending_node->node = brickinfo; pending_node->type = GD_NODE_BRICK; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; } /* * This is not really the right place to do it, but * it's the most convenient. * TBD: move this to *after* the RPC */ brickinfo->status = GF_BRICK_STOPPED; } } out: return ret; } static int glusterd_bricks_select_remove_brick(dict_t *dict, char **op_errstr, struct cds_list_head *selected) { int ret = -1; char *volname = NULL; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; char *brick = NULL; int32_t count = 0; int32_t i = 1; char key[64] = { 0, }; int keylen; glusterd_pending_node_t *pending_node = NULL; int32_t command = 0; int32_t force = 0; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get volume name"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "Unable to allocate memory"); goto out; } ret = dict_get_int32(dict, "count", &count); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Unable to get count"); goto out; } ret = dict_get_int32(dict, "command", &command); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Unable to get command"); goto out; } ret = dict_get_int32(dict, "force", &force); if (ret) { gf_msg(THIS->name, GF_LOG_INFO, 0, GD_MSG_DICT_GET_FAILED, "force flag is not set"); ret = 0; goto out; } while (i <= count) { keylen = snprintf(key, sizeof(key), "brick%d", i); ret = dict_get_strn(dict, key, keylen, &brick); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get brick"); goto out; } ret = glusterd_volume_brickinfo_get_by_brick(brick, volinfo, &brickinfo, _gf_false); if (ret) goto out; if (glusterd_is_brick_started(brickinfo)) { pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } else { pending_node->node = brickinfo; pending_node->type = GD_NODE_BRICK; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; } /* * This is not really the right place to do it, but * it's the most convenient. * TBD: move this to *after* the RPC */ brickinfo->status = GF_BRICK_STOPPED; } i++; } out: return ret; } static int glusterd_bricks_select_profile_volume(dict_t *dict, char **op_errstr, struct cds_list_head *selected) { int ret = -1; char *volname = NULL; char msg[2048] = { 0, }; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; xlator_t *this = THIS; int32_t stats_op = GF_CLI_STATS_NONE; glusterd_brickinfo_t *brickinfo = NULL; glusterd_pending_node_t *pending_node = NULL; char *brick = NULL; int32_t pid = -1; char pidfile[PATH_MAX] = {0}; priv = this->private; GF_ASSERT(priv); ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "volume name get failed"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), "Volume %s does not exists", volname); *op_errstr = gf_strdup(msg); gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "%s", msg); goto out; } ret = dict_get_int32(dict, "op", &stats_op); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "volume profile op get failed"); goto out; } switch (stats_op) { case GF_CLI_STATS_START: case GF_CLI_STATS_STOP: goto out; break; case GF_CLI_STATS_INFO: #ifdef BUILD_GNFS ret = dict_get_str_boolean(dict, "nfs", _gf_false); if (ret) { if (!priv->nfs_svc.online) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_NFS_SERVER_NOT_RUNNING, "NFS server" " is not running"); goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = &(priv->nfs_svc); pending_node->type = GD_NODE_NFS; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; ret = 0; goto out; } #endif cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (glusterd_is_brick_started(brickinfo)) { /* * In normal use, glusterd_is_brick_started * will give us the answer we need. However, * in our tests the brick gets detached behind * our back, so we need to double-check this * way. */ GLUSTERD_GET_BRICK_PIDFILE(pidfile, volinfo, brickinfo, priv); if (!gf_is_service_running(pidfile, &pid)) { continue; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } else { pending_node->node = brickinfo; pending_node->type = GD_NODE_BRICK; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; } } } break; case GF_CLI_STATS_TOP: #ifdef BUILD_GNFS ret = dict_get_str_boolean(dict, "nfs", _gf_false); if (ret) { if (!priv->nfs_svc.online) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_NFS_SERVER_NOT_RUNNING, "NFS server" " is not running"); goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = &(priv->nfs_svc); pending_node->type = GD_NODE_NFS; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; ret = 0; goto out; } #endif ret = dict_get_str(dict, "brick", &brick); if (!ret) { ret = glusterd_volume_brickinfo_get_by_brick( brick, volinfo, &brickinfo, _gf_true); if (ret) goto out; if (!glusterd_is_brick_started(brickinfo)) goto out; pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } else { pending_node->node = brickinfo; pending_node->type = GD_NODE_BRICK; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; goto out; } } ret = 0; cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (glusterd_is_brick_started(brickinfo)) { pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } else { pending_node->node = brickinfo; pending_node->type = GD_NODE_BRICK; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; } } } break; default: GF_ASSERT(0); gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "Invalid profile op: %d", stats_op); ret = -1; goto out; break; } out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } int _get_hxl_children_count(glusterd_volinfo_t *volinfo) { if (volinfo->type == GF_CLUSTER_TYPE_DISPERSE) { return volinfo->disperse_count; } else { return volinfo->replica_count; } } static int _add_hxlator_to_dict(dict_t *dict, glusterd_volinfo_t *volinfo, int index, int count) { int ret = -1; char key[64] = { 0, }; int keylen; char *xname = NULL; char *xl_type = 0; if (volinfo->type == GF_CLUSTER_TYPE_DISPERSE) { xl_type = "disperse"; } else { xl_type = "replicate"; } keylen = snprintf(key, sizeof(key), "xl-%d", count); ret = gf_asprintf(&xname, "%s-%s-%d", volinfo->volname, xl_type, index); if (ret == -1) goto out; ret = dict_set_dynstrn(dict, key, keylen, xname); if (ret) goto out; ret = dict_set_int32(dict, xname, index); out: return ret; } int get_replica_index_for_per_replica_cmd(glusterd_volinfo_t *volinfo, dict_t *dict) { int ret = 0; char *hostname = NULL; char *path = NULL; int index = 0; glusterd_brickinfo_t *brickinfo = NULL; int cmd_replica_index = -1; int replica_count = -1; if (!dict) { ret = -1; goto out; } ret = dict_get_str(dict, "per-replica-cmd-hostname", &hostname); if (ret) goto out; ret = dict_get_str(dict, "per-replica-cmd-path", &path); if (ret) goto out; replica_count = volinfo->replica_count; cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (gf_uuid_is_null(brickinfo->uuid)) (void)glusterd_resolve_brick(brickinfo); if (!strcmp(brickinfo->path, path) && !strcmp(brickinfo->hostname, hostname)) { cmd_replica_index = index / (replica_count); goto out; } index++; } out: if (ret) cmd_replica_index = -1; return cmd_replica_index; } int _select_hxlator_with_matching_brick(xlator_t *this, glusterd_volinfo_t *volinfo, dict_t *dict, int *index) { char *path = NULL; glusterd_brickinfo_t *brickinfo = NULL; int hxl_children = 0; if (!dict || dict_get_str(dict, "per-replica-cmd-path", &path)) return -1; hxl_children = _get_hxl_children_count(volinfo); if ((*index) == 0) (*index)++; cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (gf_uuid_is_null(brickinfo->uuid)) (void)glusterd_resolve_brick(brickinfo); if ((!gf_uuid_compare(MY_UUID, brickinfo->uuid)) && (!strncmp(brickinfo->path, path, strlen(path)))) { _add_hxlator_to_dict(dict, volinfo, ((*index) - 1) / hxl_children, 0); return 1; } (*index)++; } return 0; } void _select_hxlators_with_local_bricks(xlator_t *this, glusterd_volinfo_t *volinfo, dict_t *dict, int *index, int *hxlator_count) { glusterd_brickinfo_t *brickinfo = NULL; int hxl_children = 0; gf_boolean_t add = _gf_false; hxl_children = _get_hxl_children_count(volinfo); if ((*index) == 0) (*index)++; cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (gf_uuid_is_null(brickinfo->uuid)) (void)glusterd_resolve_brick(brickinfo); if (!gf_uuid_compare(MY_UUID, brickinfo->uuid)) add = _gf_true; if ((*index) % hxl_children == 0) { if (add) { _add_hxlator_to_dict(dict, volinfo, ((*index) - 1) / hxl_children, (*hxlator_count)); (*hxlator_count)++; } add = _gf_false; } (*index)++; } } int _select_hxlators_for_full_self_heal(xlator_t *this, glusterd_volinfo_t *volinfo, dict_t *dict, int *index, int *hxlator_count) { glusterd_brickinfo_t *brickinfo = NULL; int hxl_children = 0; uuid_t candidate = {0}; int brick_index = 0; glusterd_peerinfo_t *peerinfo = NULL; int delta = 0; uuid_t candidate_max = {0}; if ((*index) == 0) (*index)++; if (volinfo->type == GF_CLUSTER_TYPE_DISPERSE) { hxl_children = volinfo->disperse_count; } else { hxl_children = volinfo->replica_count; } cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (gf_uuid_compare(brickinfo->uuid, candidate_max) > 0) { if (!gf_uuid_compare(MY_UUID, brickinfo->uuid)) { gf_uuid_copy(candidate_max, brickinfo->uuid); } else { peerinfo = glusterd_peerinfo_find(brickinfo->uuid, NULL); if (peerinfo && peerinfo->connected) { gf_uuid_copy(candidate_max, brickinfo->uuid); } } } } cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (gf_uuid_is_null(brickinfo->uuid)) (void)glusterd_resolve_brick(brickinfo); delta %= hxl_children; if ((*index + delta) == (brick_index + hxl_children)) { if (!gf_uuid_compare(MY_UUID, brickinfo->uuid)) { gf_uuid_copy(candidate, brickinfo->uuid); } else { peerinfo = glusterd_peerinfo_find(brickinfo->uuid, NULL); if (peerinfo && peerinfo->connected) { gf_uuid_copy(candidate, brickinfo->uuid); } else if (peerinfo && (!gf_uuid_compare(candidate_max, MY_UUID))) { _add_hxlator_to_dict(dict, volinfo, ((*index) - 1) / hxl_children, (*hxlator_count)); (*hxlator_count)++; } } if (!gf_uuid_compare(MY_UUID, candidate)) { _add_hxlator_to_dict(dict, volinfo, ((*index) - 1) / hxl_children, (*hxlator_count)); (*hxlator_count)++; } gf_uuid_clear(candidate); brick_index += hxl_children; delta++; } (*index)++; } return *hxlator_count; } static int glusterd_bricks_select_snap(dict_t *dict, char **op_errstr, struct cds_list_head *selected) { int ret = -1; xlator_t *this = THIS; glusterd_pending_node_t *pending_node = NULL; glusterd_volinfo_t *volinfo = NULL; char *volname = NULL; glusterd_brickinfo_t *brickinfo = NULL; int brick_index = -1; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get" " volname"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) goto out; cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { brick_index++; if (gf_uuid_compare(brickinfo->uuid, MY_UUID) || !glusterd_is_brick_started(brickinfo)) { continue; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = brickinfo; pending_node->type = GD_NODE_BRICK; pending_node->index = brick_index; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; } ret = 0; out: gf_msg_debug(this->name, 0, "Returning ret %d", ret); return ret; } static int fill_shd_status_for_local_bricks(dict_t *dict, glusterd_volinfo_t *volinfo, cli_cmd_type type, int *index, dict_t *req_dict) { glusterd_brickinfo_t *brickinfo = NULL; static char *msg = "self-heal-daemon is not running on"; char key[32] = { 0, }; int keylen; char value[128] = { 0, }; int ret = 0; xlator_t *this = THIS; int cmd_replica_index = -1; if (type == PER_HEAL_XL) { cmd_replica_index = get_replica_index_for_per_replica_cmd(volinfo, req_dict); if (cmd_replica_index == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_REPLICA_INDEX_GET_FAIL, "Could not find the " "replica index for per replica type command"); ret = -1; goto out; } } cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (gf_uuid_is_null(brickinfo->uuid)) (void)glusterd_resolve_brick(brickinfo); if (gf_uuid_compare(MY_UUID, brickinfo->uuid)) { (*index)++; continue; } if (type == PER_HEAL_XL) { if (cmd_replica_index != ((*index) / volinfo->replica_count)) { (*index)++; continue; } } keylen = snprintf(key, sizeof(key), "%d-status", (*index)); snprintf(value, sizeof(value), "%s %s", msg, uuid_utoa(MY_UUID)); ret = dict_set_dynstrn(dict, key, keylen, gf_strdup(value)); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Unable to" "set the dictionary for shd status msg"); goto out; } keylen = snprintf(key, sizeof(key), "%d-shd-status", (*index)); ret = dict_set_nstrn(dict, key, keylen, "off", SLEN("off")); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Unable to" " set dictionary for shd status msg"); goto out; } (*index)++; } out: return ret; } int glusterd_shd_select_brick_xlator(dict_t *dict, gf_xl_afr_op_t heal_op, glusterd_volinfo_t *volinfo, int *index, int *hxlator_count, dict_t *rsp_dict) { int ret = -1; xlator_t *this = THIS; glusterd_svc_t *svc = NULL; svc = &(volinfo->shd.svc); switch (heal_op) { case GF_SHD_OP_INDEX_SUMMARY: case GF_SHD_OP_STATISTICS_HEAL_COUNT: if (!svc->online) { if (!rsp_dict) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OPCTX_NULL, "Received " "empty ctx."); goto out; } ret = fill_shd_status_for_local_bricks( rsp_dict, volinfo, ALL_HEAL_XL, index, dict); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SHD_STATUS_SET_FAIL, "Unable to " "fill the shd status for the local " "bricks"); goto out; } break; case GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA: if (!svc->online) { if (!rsp_dict) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OPCTX_NULL, "Received " "empty ctx."); goto out; } ret = fill_shd_status_for_local_bricks( rsp_dict, volinfo, PER_HEAL_XL, index, dict); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SHD_STATUS_SET_FAIL, "Unable to " "fill the shd status for the local" " bricks."); goto out; } break; default: break; } switch (heal_op) { case GF_SHD_OP_HEAL_FULL: _select_hxlators_for_full_self_heal(this, volinfo, dict, index, hxlator_count); break; case GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA: (*hxlator_count) += _select_hxlator_with_matching_brick( this, volinfo, dict, index); break; default: _select_hxlators_with_local_bricks(this, volinfo, dict, index, hxlator_count); break; } ret = (*hxlator_count); out: return ret; } static int glusterd_bricks_select_heal_volume(dict_t *dict, char **op_errstr, struct cds_list_head *selected, dict_t *rsp_dict) { int ret = -1; char *volname = NULL; glusterd_volinfo_t *volinfo = NULL; xlator_t *this = THIS; char msg[2048] = { 0, }; glusterd_pending_node_t *pending_node = NULL; gf_xl_afr_op_t heal_op = GF_SHD_OP_INVALID; int hxlator_count = 0; int index = 0; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "volume name get failed"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), "Volume %s does not exist", volname); *op_errstr = gf_strdup(msg); gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "%s", msg); goto out; } ret = dict_get_int32(dict, "heal-op", (int32_t *)&heal_op); if (ret || (heal_op == GF_SHD_OP_INVALID)) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "heal op invalid"); goto out; } ret = glusterd_shd_select_brick_xlator(dict, heal_op, volinfo, &index, &hxlator_count, rsp_dict); if (ret < 0) { goto out; } if (!hxlator_count) goto out; if (hxlator_count == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_XLATOR_COUNT_GET_FAIL, "Could not determine the" "translator count"); ret = -1; goto out; } ret = dict_set_int32_sizen(dict, "count", hxlator_count); if (ret) goto out; pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } else { pending_node->node = &(volinfo->shd.svc); pending_node->type = GD_NODE_SHD; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; } out: gf_msg_debug(this->name, 0, "Returning ret %d", ret); return ret; } static int glusterd_bricks_select_rebalance_volume(dict_t *dict, char **op_errstr, struct cds_list_head *selected) { int ret = -1; char *volname = NULL; glusterd_volinfo_t *volinfo = NULL; char msg[2048] = { 0, }; glusterd_pending_node_t *pending_node = NULL; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "volume name get failed"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), "Volume %s does not exist", volname); *op_errstr = gf_strdup(msg); gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "%s", msg); goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } else { pending_node->node = volinfo; pending_node->type = GD_NODE_REBALANCE; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; } out: return ret; } static int glusterd_bricks_select_status_volume(dict_t *dict, char **op_errstr, struct cds_list_head *selected) { int ret = -1; int cmd = 0; int brick_index = -1; char *volname = NULL; char *brickname = NULL; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; glusterd_pending_node_t *pending_node = NULL; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; glusterd_svc_t *svc = NULL; GF_ASSERT(dict); priv = this->private; GF_ASSERT(priv); ret = dict_get_int32(dict, "cmd", &cmd); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get status type"); goto out; } if (cmd & GF_CLI_STATUS_ALL) goto out; switch (cmd & GF_CLI_STATUS_MASK) { case GF_CLI_STATUS_MEM: case GF_CLI_STATUS_CLIENTS: case GF_CLI_STATUS_INODE: case GF_CLI_STATUS_FD: case GF_CLI_STATUS_CALLPOOL: case GF_CLI_STATUS_NFS: case GF_CLI_STATUS_SHD: case GF_CLI_STATUS_QUOTAD: case GF_CLI_STATUS_SNAPD: case GF_CLI_STATUS_BITD: case GF_CLI_STATUS_SCRUB: case GF_CLI_STATUS_CLIENT_LIST: break; default: goto out; } ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get volname"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { goto out; } if ((cmd & GF_CLI_STATUS_BRICK) != 0) { ret = dict_get_str(dict, "brick", &brickname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get brick"); goto out; } ret = glusterd_volume_brickinfo_get_by_brick(brickname, volinfo, &brickinfo, _gf_false); if (ret) goto out; if (gf_uuid_compare(brickinfo->uuid, MY_UUID) || !glusterd_is_brick_started(brickinfo)) goto out; pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = brickinfo; pending_node->type = GD_NODE_BRICK; pending_node->index = 0; cds_list_add_tail(&pending_node->list, selected); ret = 0; #ifdef BUILD_GNFS } else if ((cmd & GF_CLI_STATUS_NFS) != 0) { if (!priv->nfs_svc.online) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_NFS_SERVER_NOT_RUNNING, "NFS server is not running"); goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = &(priv->nfs_svc); pending_node->type = GD_NODE_NFS; pending_node->index = 0; cds_list_add_tail(&pending_node->list, selected); ret = 0; #endif } else if ((cmd & GF_CLI_STATUS_SHD) != 0) { svc = &(volinfo->shd.svc); if (!svc->online) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SELF_HEALD_DISABLED, "Self-heal daemon is not running"); goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = svc; pending_node->type = GD_NODE_SHD; pending_node->index = 0; cds_list_add_tail(&pending_node->list, selected); ret = 0; } else if ((cmd & GF_CLI_STATUS_QUOTAD) != 0) { if (!priv->quotad_svc.online) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_QUOTAD_NOT_RUNNING, "Quotad is not " "running"); ret = -1; goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = &(priv->quotad_svc); pending_node->type = GD_NODE_QUOTAD; pending_node->index = 0; cds_list_add_tail(&pending_node->list, selected); ret = 0; } else if ((cmd & GF_CLI_STATUS_BITD) != 0) { if (!priv->bitd_svc.online) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BITROT_NOT_RUNNING, "Bitrot is not " "running"); ret = -1; goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = &(priv->bitd_svc); pending_node->type = GD_NODE_BITD; pending_node->index = 0; cds_list_add_tail(&pending_node->list, selected); ret = 0; } else if ((cmd & GF_CLI_STATUS_SCRUB) != 0) { if (!priv->scrub_svc.online) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SCRUBBER_NOT_RUNNING, "Scrubber is not " "running"); ret = -1; goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = &(priv->scrub_svc); pending_node->type = GD_NODE_SCRUB; pending_node->index = 0; cds_list_add_tail(&pending_node->list, selected); ret = 0; } else if ((cmd & GF_CLI_STATUS_SNAPD) != 0) { if (!volinfo->snapd.svc.online) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_NOT_RUNNING, "snapd is not " "running"); ret = -1; goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY, "failed to allocate " "memory for pending node"); ret = -1; goto out; } pending_node->node = (void *)(&volinfo->snapd); pending_node->type = GD_NODE_SNAPD; pending_node->index = 0; cds_list_add_tail(&pending_node->list, selected); ret = 0; } else { cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { brick_index++; if (gf_uuid_compare(brickinfo->uuid, MY_UUID) || !glusterd_is_brick_started(brickinfo)) { continue; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY, "Unable to allocate memory"); goto out; } pending_node->node = brickinfo; pending_node->type = GD_NODE_BRICK; pending_node->index = brick_index; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; } } out: return ret; } static int glusterd_bricks_select_scrub(dict_t *dict, char **op_errstr, struct cds_list_head *selected) { int ret = -1; char *volname = NULL; char msg[2048] = { 0, }; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; glusterd_pending_node_t *pending_node = NULL; priv = this->private; GF_ASSERT(priv); GF_ASSERT(dict); ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get" " volname"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { snprintf(msg, sizeof(msg), "Volume %s does not exist", volname); *op_errstr = gf_strdup(msg); gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_VOL_NOT_FOUND, "%s", msg); goto out; } if (!priv->scrub_svc.online) { ret = 0; snprintf(msg, sizeof(msg), "Scrubber daemon is not running"); gf_msg_debug(this->name, 0, "%s", msg); goto out; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = &(priv->scrub_svc); pending_node->type = GD_NODE_SCRUB; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } /* Select the bricks to send the barrier request to. * This selects the bricks of the given volume which are present on this peer * and are running */ static int glusterd_bricks_select_barrier(dict_t *dict, struct cds_list_head *selected) { int ret = -1; char *volname = NULL; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; glusterd_pending_node_t *pending_node = NULL; GF_ASSERT(dict); ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Failed to get volname"); goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "Failed to find volume %s", volname); goto out; } cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (gf_uuid_compare(brickinfo->uuid, MY_UUID) || !glusterd_is_brick_started(brickinfo)) { continue; } pending_node = GF_CALLOC(1, sizeof(*pending_node), gf_gld_mt_pending_node_t); if (!pending_node) { ret = -1; goto out; } pending_node->node = brickinfo; pending_node->type = GD_NODE_BRICK; cds_list_add_tail(&pending_node->list, selected); pending_node = NULL; } out: gf_msg_debug(THIS->name, 0, "Returning %d", ret); return ret; } static int glusterd_clear_pending_nodes(struct cds_list_head *list) { glusterd_pending_node_t *pending_node = NULL; glusterd_pending_node_t *tmp = NULL; cds_list_for_each_entry_safe(pending_node, tmp, list, list) { cds_list_del_init(&pending_node->list); GF_FREE(pending_node); } return 0; } static int glusterd_op_ac_send_brick_op(glusterd_op_sm_event_t *event, void *ctx) { int ret = 0; rpc_clnt_procedure_t *proc = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; glusterd_op_t op = GD_OP_NONE; glusterd_req_ctx_t *req_ctx = NULL; char *op_errstr = NULL; gf_boolean_t free_req_ctx = _gf_false; priv = this->private; if (ctx) { req_ctx = ctx; } else { req_ctx = GF_CALLOC(1, sizeof(*req_ctx), gf_gld_mt_op_allack_ctx_t); if (!req_ctx) goto out; free_req_ctx = _gf_true; op = glusterd_op_get_op(); req_ctx->op = op; gf_uuid_copy(req_ctx->uuid, MY_UUID); ret = glusterd_op_build_payload(&req_ctx->dict, &op_errstr, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_OP_PAYLOAD_BUILD_FAIL, LOGSTR_BUILD_PAYLOAD, gd_op_list[op]); if (op_errstr == NULL) gf_asprintf(&op_errstr, OPERRSTR_BUILD_PAYLOAD); opinfo.op_errstr = op_errstr; goto out; } } proc = &priv->gfs_mgmt->proctable[GLUSTERD_BRICK_OP]; if (proc->fn) { ret = proc->fn(NULL, this, req_ctx); if (ret) goto out; } if (!opinfo.pending_count && !opinfo.brick_pending_count) { glusterd_clear_pending_nodes(&opinfo.pending_bricks); ret = glusterd_op_sm_inject_event(GD_OP_EVENT_ALL_ACK, &event->txn_id, req_ctx); } out: if (ret && free_req_ctx) GF_FREE(req_ctx); gf_msg_debug(this->name, 0, "Returning with %d", ret); return ret; } static int glusterd_op_ac_rcvd_brick_op_acc(glusterd_op_sm_event_t *event, void *ctx) { int ret = -1; glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL; char *op_errstr = NULL; glusterd_op_t op = GD_OP_NONE; gd_node_type type = GD_NODE_NONE; dict_t *op_ctx = NULL; glusterd_req_ctx_t *req_ctx = NULL; void *pending_entry = NULL; xlator_t *this = THIS; GF_VALIDATE_OR_GOTO(this->name, event, out); GF_VALIDATE_OR_GOTO(this->name, ctx, out); ev_ctx = ctx; GF_VALIDATE_OR_GOTO(this->name, ev_ctx, out); req_ctx = ev_ctx->commit_ctx; GF_VALIDATE_OR_GOTO(this->name, req_ctx, out); op = req_ctx->op; op_ctx = glusterd_op_get_ctx(); pending_entry = ev_ctx->pending_node->node; type = ev_ctx->pending_node->type; ret = glusterd_remove_pending_entry(&opinfo.pending_bricks, pending_entry); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_UNKNOWN_RESPONSE, "unknown response received "); ret = -1; goto out; } if (opinfo.brick_pending_count > 0) opinfo.brick_pending_count--; ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); glusterd_handle_node_rsp(req_ctx->dict, pending_entry, op, ev_ctx->rsp_dict, op_ctx, &op_errstr, type); if (opinfo.brick_pending_count > 0) goto out; ret = glusterd_op_sm_inject_event(GD_OP_EVENT_ALL_ACK, &event->txn_id, ev_ctx->commit_ctx); out: if (ev_ctx && ev_ctx->rsp_dict) dict_unref(ev_ctx->rsp_dict); GF_FREE(ev_ctx); gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } int32_t glusterd_op_bricks_select(glusterd_op_t op, dict_t *dict, char **op_errstr, struct cds_list_head *selected, dict_t *rsp_dict) { int ret = 0; GF_ASSERT(dict); GF_ASSERT(op_errstr); GF_ASSERT(op > GD_OP_NONE); GF_ASSERT(op < GD_OP_MAX); switch (op) { case GD_OP_STOP_VOLUME: ret = glusterd_bricks_select_stop_volume(dict, op_errstr, selected); break; case GD_OP_REMOVE_BRICK: ret = glusterd_bricks_select_remove_brick(dict, op_errstr, selected); break; case GD_OP_PROFILE_VOLUME: ret = glusterd_bricks_select_profile_volume(dict, op_errstr, selected); break; case GD_OP_HEAL_VOLUME: ret = glusterd_bricks_select_heal_volume(dict, op_errstr, selected, rsp_dict); break; case GD_OP_STATUS_VOLUME: ret = glusterd_bricks_select_status_volume(dict, op_errstr, selected); break; case GD_OP_DEFRAG_BRICK_VOLUME: ret = glusterd_bricks_select_rebalance_volume(dict, op_errstr, selected); break; case GD_OP_BARRIER: ret = glusterd_bricks_select_barrier(dict, selected); break; case GD_OP_SNAP: ret = glusterd_bricks_select_snap(dict, op_errstr, selected); break; case GD_OP_SCRUB_STATUS: case GD_OP_SCRUB_ONDEMAND: ret = glusterd_bricks_select_scrub(dict, op_errstr, selected); break; default: break; } gf_msg_debug(THIS->name, 0, "Returning %d", ret); return ret; } glusterd_op_sm_t glusterd_op_state_default[] = { {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_send_lock}, // EVENT_START_LOCK {GD_OP_STATE_LOCKED, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_RCVD_ACC {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_RCVD_RJT {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_ALL_ACK {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_lock_sent[] = { {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_rcvd_lock_acc}, // EVENT_RCVD_ACC {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_send_stage_op}, // EVENT_ALL_ACC {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_send_unlock_drain}, // EVENT_RCVD_RJT {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, // EVENT_ALL_ACK {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_locked[] = { {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_LOCKED, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_RCVD_ACC {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_RCVD_RJT {GD_OP_STATE_STAGED, glusterd_op_ac_stage_op}, // EVENT_STAGE_OP {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_ALL_ACK {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_stage_op_sent[] = { {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_rcvd_stage_op_acc}, // EVENT_RCVD_ACC {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_send_brick_op}, // EVENT_ALL_ACC {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_send_brick_op}, // EVENT_STAGE_ACC {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_stage_op_failed}, // EVENT_RCVD_RJT {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, // EVENT_ALL_ACK {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_stage_op_failed[] = { {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_stage_op_failed}, // EVENT_RCVD_ACC {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_stage_op_failed}, // EVENT_RCVD_RJT {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, // EVENT_ALL_ACK {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_staged[] = { {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_STAGED, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_RCVD_ACC {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_RCVD_RJT {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_send_brick_op}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_ALL_ACK {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_STAGED, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_brick_op_sent[] = { {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_rcvd_brick_op_acc}, // EVENT_RCVD_ACC {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_brick_op_failed}, // EVENT_RCVD_RJT {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, // EVENT_BRICK_OP {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_send_commit_op}, // EVENT_ALL_ACK {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_brick_op_failed[] = { {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_brick_op_failed}, // EVENT_RCVD_ACC {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_brick_op_failed}, // EVENT_RCVD_RJT {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, // EVENT_BRICK_OP {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, // EVENT_ALL_ACK {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_brick_committed[] = { {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_rcvd_brick_op_acc}, // EVENT_RCVD_ACC {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_brick_op_failed}, // EVENT_RCVD_RJT {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_COMMITED, glusterd_op_ac_commit_op}, // EVENT_ALL_ACK {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_brick_commit_failed[] = { {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_brick_op_failed}, // EVENT_RCVD_ACC {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_brick_op_failed}, // EVENT_RCVD_RJT {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_send_commit_failed}, // EVENT_ALL_ACK {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_commit_op_failed[] = { {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_commit_op_failed}, // EVENT_RCVD_ACC {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_commit_op_failed}, // EVENT_RCVD_RJT {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, // EVENT_ALL_ACK {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_commit_op_sent[] = { {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_rcvd_commit_op_acc}, // EVENT_RCVD_ACC {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, // EVENT_ALL_ACC {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, // EVENT_COMMIT_ACC {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_commit_op_failed}, // EVENT_RCVD_RJT {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, // EVENT_ALL_ACK {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_committed[] = { {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_COMMITED, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_RCVD_ACC {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_RCVD_RJT {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_ALL_ACK {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_unlock_sent[] = { {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_rcvd_unlock_acc}, // EVENT_RCVD_ACC {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlocked_all}, // EVENT_ALL_ACC {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_rcvd_unlock_acc}, // EVENT_RCVD_RJT {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, // EVENT_ALL_ACK {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t glusterd_op_state_ack_drain[] = { {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_NONE {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_LOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_lock}, // EVENT_LOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_send_unlock_drain}, // EVENT_RCVD_ACC {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_ALL_ACC {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_STAGE_ACC {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_COMMIT_ACC {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_send_unlock_drain}, // EVENT_RCVD_RJT {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_STAGE_OP {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_COMMIT_OP {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, // EVENT_UNLOCK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_START_UNLOCK {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, // EVENT_ALL_ACK {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_LOCAL_UNLOCK_NO_RESP {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, // EVENT_MAX }; glusterd_op_sm_t *glusterd_op_state_table[] = { glusterd_op_state_default, glusterd_op_state_lock_sent, glusterd_op_state_locked, glusterd_op_state_stage_op_sent, glusterd_op_state_staged, glusterd_op_state_commit_op_sent, glusterd_op_state_committed, glusterd_op_state_unlock_sent, glusterd_op_state_stage_op_failed, glusterd_op_state_commit_op_failed, glusterd_op_state_brick_op_sent, glusterd_op_state_brick_op_failed, glusterd_op_state_brick_committed, glusterd_op_state_brick_commit_failed, glusterd_op_state_ack_drain}; int glusterd_op_sm_new_event(glusterd_op_sm_event_type_t event_type, glusterd_op_sm_event_t **new_event) { glusterd_op_sm_event_t *event = NULL; GF_ASSERT(new_event); GF_ASSERT(GD_OP_EVENT_NONE <= event_type && GD_OP_EVENT_MAX > event_type); event = GF_CALLOC(1, sizeof(*event), gf_gld_mt_op_sm_event_t); if (!event) return -1; *new_event = event; event->event = event_type; CDS_INIT_LIST_HEAD(&event->list); return 0; } int glusterd_op_sm_inject_event(glusterd_op_sm_event_type_t event_type, uuid_t *txn_id, void *ctx) { int32_t ret = -1; glusterd_op_sm_event_t *event = NULL; GF_ASSERT(event_type < GD_OP_EVENT_MAX && event_type >= GD_OP_EVENT_NONE); ret = glusterd_op_sm_new_event(event_type, &event); if (ret) goto out; event->ctx = ctx; if (txn_id) gf_uuid_copy(event->txn_id, *txn_id); gf_msg_debug(THIS->name, 0, "Enqueue event: '%s'", glusterd_op_sm_event_name_get(event->event)); cds_list_add_tail(&event->list, &gd_op_sm_queue); out: return ret; } void glusterd_destroy_req_ctx(glusterd_req_ctx_t *ctx) { if (!ctx) return; if (ctx->dict) dict_unref(ctx->dict); GF_FREE(ctx); } void glusterd_destroy_local_unlock_ctx(uuid_t *ctx) { if (!ctx) return; GF_FREE(ctx); } void glusterd_destroy_op_event_ctx(glusterd_op_sm_event_t *event) { if (!event) return; switch (event->event) { case GD_OP_EVENT_LOCK: case GD_OP_EVENT_UNLOCK: glusterd_destroy_lock_ctx(event->ctx); break; case GD_OP_EVENT_STAGE_OP: case GD_OP_EVENT_ALL_ACK: glusterd_destroy_req_ctx(event->ctx); break; case GD_OP_EVENT_LOCAL_UNLOCK_NO_RESP: glusterd_destroy_local_unlock_ctx(event->ctx); break; default: break; } } int glusterd_op_sm(void) { glusterd_op_sm_event_t *event = NULL; glusterd_op_sm_event_t *tmp = NULL; int ret = -1; int lock_err = 0; glusterd_op_sm_ac_fn handler = NULL; glusterd_op_sm_t *state = NULL; glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE; xlator_t *this = THIS; glusterd_op_info_t txn_op_info; glusterd_conf_t *priv = NULL; priv = this->private; GF_ASSERT(priv); ret = synclock_trylock(&gd_op_sm_lock); if (ret) { lock_err = errno; gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_LOCK_FAIL, "lock failed due to %s", strerror(lock_err)); goto lock_failed; } while (!cds_list_empty(&gd_op_sm_queue)) { cds_list_for_each_entry_safe(event, tmp, &gd_op_sm_queue, list) { cds_list_del_init(&event->list); event_type = event->event; gf_msg_debug(this->name, 0, "Dequeued event of " "type: '%s'", glusterd_op_sm_event_name_get(event_type)); gf_msg_debug(this->name, 0, "transaction ID = %s", uuid_utoa(event->txn_id)); ret = glusterd_get_txn_opinfo(&event->txn_id, &txn_op_info); if (ret) { gf_msg_callingfn(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_GET_FAIL, "Unable to get transaction " "opinfo for transaction ID :" "%s", uuid_utoa(event->txn_id)); glusterd_destroy_op_event_ctx(event); GF_FREE(event); continue; } else opinfo = txn_op_info; state = glusterd_op_state_table[opinfo.state]; GF_ASSERT(state); handler = state[event_type].handler; GF_ASSERT(handler); ret = handler(event, event->ctx); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_HANDLER_RETURNED, "handler returned: %d", ret); glusterd_destroy_op_event_ctx(event); GF_FREE(event); continue; } ret = glusterd_op_sm_transition_state(&opinfo, state, event_type); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_EVENT_STATE_TRANSITION_FAIL, "Unable to transition" "state from '%s' to '%s'", glusterd_op_sm_state_name_get(opinfo.state), glusterd_op_sm_state_name_get( state[event_type].next_state)); (void)synclock_unlock(&gd_op_sm_lock); return ret; } if ((state[event_type].next_state == GD_OP_STATE_DEFAULT) && (event_type == GD_OP_EVENT_UNLOCK)) { /* Clearing the transaction opinfo */ ret = glusterd_clear_txn_opinfo(&event->txn_id); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_CLEAR_FAIL, "Unable to clear " "transaction's opinfo"); } else { if ((priv->op_version < GD_OP_VERSION_6_0) || !(event_type == GD_OP_EVENT_STAGE_OP && opinfo.state == GD_OP_STATE_STAGED && opinfo.skip_locking)) { ret = glusterd_set_txn_opinfo(&event->txn_id, &opinfo); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TRANS_OPINFO_SET_FAIL, "Unable to set " "transaction's opinfo"); } } glusterd_destroy_op_event_ctx(event); GF_FREE(event); } } (void)synclock_unlock(&gd_op_sm_lock); ret = 0; lock_failed: return ret; } int32_t glusterd_op_set_op(glusterd_op_t op) { GF_ASSERT(op < GD_OP_MAX); GF_ASSERT(op > GD_OP_NONE); opinfo.op = op; return 0; } int32_t glusterd_op_get_op(void) { return opinfo.op; } int32_t glusterd_op_set_req(rpcsvc_request_t *req) { GF_ASSERT(req); opinfo.req = req; return 0; } int32_t glusterd_op_clear_op(void) { opinfo.op = GD_OP_NONE; return 0; } int32_t glusterd_op_free_ctx(glusterd_op_t op, void *ctx) { if (ctx) { switch (op) { case GD_OP_CREATE_VOLUME: case GD_OP_DELETE_VOLUME: case GD_OP_STOP_VOLUME: case GD_OP_ADD_BRICK: case GD_OP_REMOVE_BRICK: case GD_OP_REPLACE_BRICK: case GD_OP_LOG_ROTATE: case GD_OP_SYNC_VOLUME: case GD_OP_SET_VOLUME: case GD_OP_START_VOLUME: case GD_OP_RESET_VOLUME: case GD_OP_GSYNC_SET: case GD_OP_QUOTA: case GD_OP_PROFILE_VOLUME: case GD_OP_STATUS_VOLUME: case GD_OP_REBALANCE: case GD_OP_HEAL_VOLUME: case GD_OP_STATEDUMP_VOLUME: case GD_OP_CLEARLOCKS_VOLUME: case GD_OP_DEFRAG_BRICK_VOLUME: case GD_OP_MAX_OPVERSION: dict_unref(ctx); break; default: GF_ASSERT(0); break; } } glusterd_op_reset_ctx(); return 0; } void * glusterd_op_get_ctx(void) { return opinfo.op_ctx; } int glusterd_op_sm_init(void) { CDS_INIT_LIST_HEAD(&gd_op_sm_queue); synclock_init(&gd_op_sm_lock, SYNC_LOCK_DEFAULT); return 0; } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-mountbroker.c0000644000000000000000000000013214522202451026002 xustar000000000000000030 mtime=1699284265.718027585 30 atime=1699284265.718027585 30 ctime=1699284306.620150781 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-mountbroker.c0000664000175100017510000004311014522202451026260 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2011-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "glusterd-mem-types.h" #include "glusterd-utils.h" #include #include "glusterd-mountbroker.h" #include "glusterd-op-sm.h" #include "glusterd-messages.h" static int seq_dict_foreach(dict_t *dict, int (*fn)(char *str, void *data), void *data) { char index[] = "4294967296"; // 1<<32 int i = 0; char *val = NULL; int ret = 0; for (;; i++) { snprintf(index, sizeof(index), "%d", i); ret = dict_get_str(dict, index, &val); if (ret != 0) return ret == -ENOENT ? 0 : ret; ret = fn(val, data); if (ret != 0) return ret; } } int parse_mount_pattern_desc(gf_mount_spec_t *mspec, char *pdesc) #define SYNTAX_ERR -2 { char *curs = NULL; char *c2 = NULL; char sc = '\0'; char **cc = NULL; gf_mount_pattern_t *pat = NULL; int pnum = 0; int ret = 0; int lastsup = -1; int incl = -1; char **pcc = NULL; int pnc = 0; skipwhite(&pdesc); /* a bow to theory */ if (!*pdesc) return 0; /* count number of components, separated by '&' */ mspec->len = 0; for (curs = pdesc; *curs; curs++) { if (*curs == ')') mspec->len++; } mspec->patterns = GF_CALLOC(mspec->len, sizeof(*mspec->patterns), gf_gld_mt_mount_pattern); if (!mspec->patterns) { gf_smsg("glusterd", GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); ret = -1; goto out; } pat = mspec->patterns; curs = pdesc; skipwhite(&curs); for (;;) { incl = -1; /* check for pattern signedness modifier */ if (*curs == '-') { pat->negative = _gf_true; curs++; } /* now should come condition specifier, * then opening paren */ c2 = nwstrtail(curs, "SUB("); if (c2) { pat->condition = SET_SUB; goto got_cond; } c2 = nwstrtail(curs, "SUP("); if (c2) { pat->condition = SET_SUPER; lastsup = pat - mspec->patterns; goto got_cond; } c2 = nwstrtail(curs, "EQL("); if (c2) { pat->condition = SET_EQUAL; goto got_cond; } c2 = nwstrtail(curs, "MEET("); if (c2) { pat->condition = SET_INTERSECT; goto got_cond; } c2 = nwstrtail(curs, "SUB+("); if (c2) { pat->condition = SET_SUB; incl = lastsup; goto got_cond; } ret = SYNTAX_ERR; goto out; got_cond: curs = c2; skipwhite(&curs); /* count the number of components for pattern */ pnum = *curs == ')' ? 0 : 1; for (c2 = curs; *c2 != ')';) { if (strchr("&|", *c2)) { ret = SYNTAX_ERR; goto out; } while (!strchr("|&)", *c2) && !isspace(*c2)) c2++; skipwhite(&c2); switch (*c2) { case ')': break; case '\0': case '&': ret = SYNTAX_ERR; goto out; case '|': *c2 = ' '; skipwhite(&c2); /* fall through */ default: pnum++; } } if (incl >= 0) { pnc = 0; for (pcc = mspec->patterns[incl].components; *pcc; pcc++) pnc++; pnum += pnc; } pat->components = GF_CALLOC(pnum + 1, sizeof(*pat->components), gf_gld_mt_mount_comp_container); if (!pat->components) { ret = -1; goto out; } cc = pat->components; /* copy over included component set */ if (incl >= 0) { memcpy(pat->components, mspec->patterns[incl].components, pnc * sizeof(*pat->components)); cc += pnc; } /* parse and add components */ c2 = ""; /* reset c2 */ while (*c2 != ')') { c2 = curs; while (!isspace(*c2) && *c2 != ')') c2++; sc = *c2; *c2 = '\0'; ; *cc = gf_strdup(curs); if (!*cc) { ret = -1; goto out; } *c2 = sc; skipwhite(&c2); curs = c2; cc++; } curs++; skipwhite(&curs); if (*curs == '&') { curs++; skipwhite(&curs); } if (!*curs) break; pat++; } out: if (ret == SYNTAX_ERR) { gf_msg("glusterd", GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "cannot parse mount patterns %s", pdesc); } /* We've allocted a lotta stuff here but don't bother with freeing * on error, in that case we'll terminate anyway */ return ret ? -1 : 0; } #undef SYNTAX_ERR const char *georep_mnt_desc_template = "SUP(" "aux-gfid-mount " "acl " "volfile-server=localhost " "client-pid=%d " "user-map-root=%s " ")" "SUB+(" "log-file=%s/" GEOREP "*/* " "log-level=* " "volfile-id=* " ")" "MEET(" "%s" ")"; int make_georep_mountspec(gf_mount_spec_t *mspec, const char *volnames, char *user, char *logdir) { char *georep_mnt_desc = NULL; char *meetspec = NULL; char *vols = NULL; char *vol = NULL; char *p = NULL; char *savetok = NULL; char *fa[3] = { 0, }; size_t siz = 0; int vc = 0; int i = 0; int ret = 0; vols = gf_strdup((char *)volnames); if (!vols) { gf_smsg(THIS->name, GF_LOG_ERROR, errno, GD_MSG_STRDUP_FAILED, "Volume name=%s", volnames, NULL); goto out; } for (vc = 1, p = vols; *p; p++) { if (*p == ',') vc++; } siz = strlen(volnames) + vc * SLEN("volfile-id="); meetspec = GF_CALLOC(1, siz + 1, gf_gld_mt_georep_meet_spec); if (!meetspec) { gf_smsg(THIS->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); goto out; } for (p = vols;;) { vol = strtok_r(p, ",", &savetok); if (!vol) { GF_ASSERT(vc == 0); break; } p = NULL; strcat(meetspec, "volfile-id="); strcat(meetspec, vol); if (--vc > 0) strcat(meetspec, " "); } ret = gf_asprintf(&georep_mnt_desc, georep_mnt_desc_template, GF_CLIENT_PID_GSYNCD, user, logdir, meetspec); if (ret == -1) { georep_mnt_desc = NULL; goto out; } ret = parse_mount_pattern_desc(mspec, georep_mnt_desc); out: fa[0] = meetspec; fa[1] = vols; fa[2] = georep_mnt_desc; for (i = 0; i < 3; i++) { if (fa[i] == NULL) ret = -1; else GF_FREE(fa[i]); } return ret; } static gf_boolean_t match_comp(char *str, char *patcomp) { char *c1 = patcomp; char *c2 = str; GF_ASSERT(c1); GF_ASSERT(c2); while (*c1 == *c2) { if (!*c1) return _gf_true; c1++; c2++; if (c1[-1] == '=') break; } return fnmatch(c1, c2, 0) == 0 ? _gf_true : _gf_false; } struct gf_set_descriptor { gf_boolean_t priv[2]; gf_boolean_t common; }; static int _gf_set_dict_iter1(char *val, void *data) { void **dataa = data; struct gf_set_descriptor *sd = dataa[0]; char **curs = dataa[1]; gf_boolean_t priv = _gf_true; while (*curs) { if (match_comp(val, *curs)) { priv = _gf_false; sd->common = _gf_true; } curs++; } if (priv) sd->priv[0] = _gf_true; return 0; } static int _gf_set_dict_iter2(char *val, void *data) { void **dataa = data; gf_boolean_t *boo = dataa[0]; char *comp = dataa[1]; if (match_comp(val, comp)) *boo = _gf_true; return 0; } static void relate_sets(struct gf_set_descriptor *sd, dict_t *argdict, char **complist) { void *dataa[] = {NULL, NULL}; gf_boolean_t boo = _gf_false; memset(sd, 0, sizeof(*sd)); dataa[0] = sd; dataa[1] = complist; seq_dict_foreach(argdict, _gf_set_dict_iter1, dataa); while (*complist) { boo = _gf_false; dataa[0] = &boo; dataa[1] = *complist; seq_dict_foreach(argdict, _gf_set_dict_iter2, dataa); if (boo) sd->common = _gf_true; else sd->priv[1] = _gf_true; complist++; } } static int _arg_parse_uid(char *val, void *data) { char *user = strtail(val, "user-map-root="); struct passwd *pw = NULL; if (!user) return 0; pw = getpwnam(user); if (!pw) return -EINVAL; if (*(int *)data >= 0) /* uid ambiguity, already found */ return -EINVAL; *(int *)data = pw->pw_uid; return 0; } static int evaluate_mount_request(xlator_t *this, gf_mount_spec_t *mspec, dict_t *argdict) { struct gf_set_descriptor sd = { { 0, }, }; int i = 0; int uid = -1; int ret = 0; gf_boolean_t match = _gf_false; for (i = 0; i < mspec->len; i++) { relate_sets(&sd, argdict, mspec->patterns[i].components); switch (mspec->patterns[i].condition) { case SET_SUB: match = !sd.priv[0]; break; case SET_SUPER: match = !sd.priv[1]; break; case SET_EQUAL: match = (!sd.priv[0] && !sd.priv[1]); break; case SET_INTERSECT: match = sd.common; break; default: GF_ASSERT(!"unreached"); } if (mspec->patterns[i].negative) match = !match; if (!match) { gf_msg(this->name, GF_LOG_ERROR, EPERM, GD_MSG_MNTBROKER_SPEC_MISMATCH, "Mountbroker spec mismatch!!! SET: %d " "COMPONENT: %d. Review the mount args passed", mspec->patterns[i].condition, i); return -EPERM; } } ret = seq_dict_foreach(argdict, _arg_parse_uid, &uid); if (ret != 0) return ret; return uid; } static int _volname_get(char *val, void *data) { char **volname = data; *volname = strtail(val, "volfile-id="); return *volname ? 1 : 0; } static int _runner_add(char *val, void *data) { runner_t *runner = data; runner_argprintf(runner, "--%s", val); return 0; } int glusterd_do_mount(char *label, dict_t *argdict, char **path, int *op_errno) { glusterd_conf_t *priv = NULL; char *mountbroker_root = NULL; gf_mount_spec_t *mspec = NULL; int uid = -ENOENT; char *volname = NULL; glusterd_volinfo_t *vol = NULL; char *mtptemp = NULL; char *mntlink = NULL; char *cookieswitch = NULL; char *cookie = NULL; char *sla = NULL; struct stat st = { 0, }; runner_t runner = { 0, }; int ret = 0; xlator_t *this = THIS; mode_t orig_umask = 0; gf_boolean_t found_label = _gf_false; priv = this->private; GF_ASSERT(priv); GF_ASSERT(op_errno); *op_errno = 0; if (dict_get_str(this->options, "mountbroker-root", &mountbroker_root) != 0) { *op_errno = ENOENT; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "'option mountbroker-root' " "missing in glusterd vol file"); goto out; } GF_ASSERT(label); if (!*label) { *op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, *op_errno, GD_MSG_MNTBROKER_LABEL_NULL, "label is NULL (%s)", strerror(*op_errno)); goto out; } /* look up spec for label */ cds_list_for_each_entry(mspec, &priv->mount_specs, speclist) { if (strcmp(mspec->label, label) != 0) continue; found_label = _gf_true; uid = evaluate_mount_request(this, mspec, argdict); break; } if (uid < 0) { *op_errno = -uid; if (!found_label) { gf_msg(this->name, GF_LOG_ERROR, *op_errno, GD_MSG_MNTBROKER_LABEL_MISS, "Missing mspec: Check the corresponding option " "in glusterd vol file for mountbroker user: %s", label); } goto out; } /* some sanity check on arguments */ seq_dict_foreach(argdict, _volname_get, &volname); if (!volname) { *op_errno = EINVAL; gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_DICT_GET_FAILED, "Dict get failed for the key 'volname'"); goto out; } if (glusterd_volinfo_find(volname, &vol) != 0 || !glusterd_is_volume_started(vol)) { *op_errno = ENOENT; gf_msg(this->name, GF_LOG_ERROR, *op_errno, GD_MSG_MOUNT_REQ_FAIL, "Either volume is not started or volinfo not found"); goto out; } /* go do mount */ /** create actual mount dir */ /*** "overload" string name to be possible to used for cookie creation, see below */ ret = gf_asprintf(&mtptemp, "%s/user%d/mtpt-%s-XXXXXX/cookie", mountbroker_root, uid, label); if (ret == -1) { mtptemp = NULL; *op_errno = ENOMEM; goto out; } /*** hide cookie part */ cookieswitch = strrchr(mtptemp, '/'); *cookieswitch = '\0'; sla = strrchr(mtptemp, '/'); *sla = '\0'; ret = sys_mkdir(mtptemp, 0700); if (ret == 0) ret = sys_chown(mtptemp, uid, 0); else if (errno == EEXIST) ret = 0; if (ret == -1) { *op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, *op_errno, GD_MSG_SYSCALL_FAIL, "Mountbroker User directory creation failed"); goto out; } ret = sys_lstat(mtptemp, &st); if (ret == -1) { *op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, *op_errno, GD_MSG_SYSCALL_FAIL, "stat on mountbroker user directory failed"); goto out; } if (!(S_ISDIR(st.st_mode) && (st.st_mode & ~S_IFMT) == 0700 && st.st_uid == uid && st.st_gid == 0)) { *op_errno = EACCES; gf_msg(this->name, GF_LOG_ERROR, *op_errno, GD_MSG_MOUNT_REQ_FAIL, "Incorrect mountbroker user directory attributes"); goto out; } *sla = '/'; if (!mkdtemp(mtptemp)) { *op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, *op_errno, GD_MSG_SYSCALL_FAIL, "Mountbroker mount directory creation failed"); goto out; } /** create private "cookie" symlink */ /*** occupy an entry in the hive dir via mkstemp */ ret = gf_asprintf(&cookie, "%s/" MB_HIVE "/mntXXXXXX", mountbroker_root); if (ret == -1) { cookie = NULL; *op_errno = ENOMEM; goto out; } orig_umask = umask(S_IRWXG | S_IRWXO); ret = mkstemp(cookie); umask(orig_umask); if (ret == -1) { *op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, *op_errno, GD_MSG_SYSCALL_FAIL, "Mountbroker cookie file creation failed"); goto out; } sys_close(ret); /*** assembly the path from cookie to mountpoint */ sla = strchr(sla - 1, '/'); GF_ASSERT(sla); ret = gf_asprintf(&mntlink, "../user%d%s", uid, sla); if (ret == -1) { *op_errno = ENOMEM; goto out; } /*** create cookie link in (to-be) mountpoint, move it over to the final place */ *cookieswitch = '/'; ret = sys_symlink(mntlink, mtptemp); if (ret != -1) ret = sys_rename(mtptemp, cookie); *cookieswitch = '\0'; if (ret == -1) { *op_errno = errno; gf_msg(this->name, GF_LOG_ERROR, *op_errno, GD_MSG_SYSCALL_FAIL, "symlink or rename failed"); goto out; } /** invoke glusterfs on the mountpoint */ runinit(&runner); runner_add_arg(&runner, SBIN_DIR "/glusterfs"); seq_dict_foreach(argdict, _runner_add, &runner); runner_add_arg(&runner, mtptemp); ret = runner_run_reuse(&runner); if (ret == -1) { *op_errno = EIO; /* XXX hacky fake */ runner_log(&runner, "", GF_LOG_ERROR, "command failed"); } runner_end(&runner); out: if (*op_errno) { ret = -1; gf_msg(this->name, GF_LOG_WARNING, *op_errno, GD_MSG_MOUNT_REQ_FAIL, "unsuccessful mount request"); if (mtptemp) { *cookieswitch = '/'; sys_unlink(mtptemp); *cookieswitch = '\0'; sys_rmdir(mtptemp); } if (cookie) { sys_unlink(cookie); GF_FREE(cookie); } } else { ret = 0; *path = cookie; } if (mtptemp) GF_FREE(mtptemp); if (mntlink) GF_FREE(mntlink); return ret; } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-utils.h0000644000000000000000000000013014522202451024576 xustar000000000000000029 mtime=1699284265.73602764 29 atime=1699284265.73602764 30 ctime=1699284306.543150549 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-utils.h0000664000175100017510000005664614522202451025100 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GLUSTERD_UTILS_H #define _GLUSTERD_UTILS_H #include #include "glusterd-peer-utils.h" typedef struct glusterd_add_dict_args { xlator_t *this; dict_t *voldict; int start; int end; } glusterd_add_dict_args_t; typedef struct glusterd_friend_synctask_args { dict_t *peer_data; dict_t *peer_ver_data; // Dictionary to save peer version data /* This status_arr[1] is not a real size, real size of the array is dynamically allocated */ uint64_t status_arr[1]; } glusterd_friend_synctask_args_t; enum glusterd_vol_comp_status_ { GLUSTERD_VOL_COMP_NONE = 0, GLUSTERD_VOL_COMP_SCS = 1, GLUSTERD_VOL_COMP_UPDATE_REQ, GLUSTERD_VOL_COMP_RJT, }; typedef struct addrinfo_list { struct cds_list_head list; struct addrinfo *info; } addrinfo_list_t; typedef enum { GF_AI_COMPARE_NO_MATCH = 0, GF_AI_COMPARE_MATCH = 1, GF_AI_COMPARE_ERROR = 2 } gf_ai_compare_t; #define GLUSTERD_CKSUM_FILE "cksum" #define GLUSTERD_SOCK_DIR "/var/run/gluster" #define GLUSTERD_ASSIGN_BRICKID_TO_BRICKINFO(brickinfo, volinfo, brickid) \ do { \ sprintf(brickinfo->brick_id, "%s-client-%d", volinfo->volname, \ brickid); \ } while (0) #define GLUSTERD_ASSIGN_BRICKID_TO_TA_BRICKINFO(ta_brickinfo, volinfo, \ brickid) \ do { \ sprintf(ta_brickinfo->brick_id, "%s-ta-%d", volinfo->volname, \ brickid); \ } while (0) #define ALL_VOLUME_OPTION_CHECK(volname, get_opt, key, ret, op_errstr, label) \ do { \ gf_boolean_t _all = !strcmp("all", volname); \ gf_boolean_t _key_all = !strcmp(key, "all"); \ gf_boolean_t _is_valid_opt = _gf_false; \ int32_t i = 0; \ \ if (!get_opt && \ (_key_all || !strcmp(key, GLUSTERD_MAX_OP_VERSION_KEY))) { \ ret = -1; \ *op_errstr = gf_strdup("Not a valid option to set"); \ goto out; \ } \ if (_key_all) { \ _is_valid_opt = _gf_true; \ } else { \ for (i = 0; valid_all_vol_opts[i].option; i++) { \ if (!strcmp(key, valid_all_vol_opts[i].option)) { \ _is_valid_opt = _gf_true; \ break; \ } \ } \ } \ if (_all && !_is_valid_opt) { \ ret = -1; \ *op_errstr = gf_strdup("Not a valid option for all volumes"); \ goto label; \ } else if (!_all && _is_valid_opt) { \ ret = -1; \ *op_errstr = gf_strdup("Not a valid option for single volume"); \ goto label; \ } \ } while (0) struct glusterd_lock_ { uuid_t owner; time_t timestamp; }; typedef struct glusterd_dict_ctx_ { dict_t *dict; int opt_count; char *key_name; char *val_name; char *prefix; } glusterd_dict_ctx_t; typedef struct glusterd_hostname_ { char *hostname; struct list_head hostname_list; } glusterd_hostname_t; struct glusterd_snap_ops { const char *name; gf_boolean_t (*const probe)(char *brick_path); int (*const details)(dict_t *rsp_dict, glusterd_brickinfo_t *snap_brickinfo, char *snapname, char *snap_volume_id, int32_t brick_num, char *key_prefix); int32_t (*const create)(glusterd_brickinfo_t *snap_brickinfo, char *snapname, char *snap_volume_id, int32_t brick_num); int32_t (*const clone)(glusterd_brickinfo_t *snap_brickinfo, char *snapname, char *snap_volume_id, char *clonename, char *clone_volume_id, int32_t brick_num); int32_t (*const remove)(glusterd_brickinfo_t *snap_brickinfo, char *snapname, char *snap_volume_id, int32_t brick_num); int32_t (*const activate)(glusterd_brickinfo_t *snap_brickinfo, char *snapname, char *snap_volume_id, int32_t brick_num); int32_t (*const deactivate)(glusterd_brickinfo_t *snap_brickinfo, char *snapname, char *snap_volume_id, int32_t brick_num); int32_t (*const restore)(glusterd_brickinfo_t *snap_brickinfo, char *snapname, char *snap_volume_id, int32_t brick_num, gf_boolean_t *retain_origin_path); int32_t (*const brick_path)(char *snap_mount_dir, char *origin_brick_path, int clone, char *snap_clone_name, char *snap_clone_volume_id, char *snap_brick_dir, int brick_num, glusterd_brickinfo_t *brickinfo, int restore); }; extern struct glusterd_snap_ops lvm_snap_ops; extern struct glusterd_snap_ops zfs_snap_ops; gf_boolean_t glusterd_mntopts_exists(const char *str, const char *opts); gf_boolean_t is_brick_mx_enabled(void); int glusterd_compare_lines(const void *a, const void *b); typedef int (*glusterd_condition_func)(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, void *ctx); typedef struct glusterd_lock_ glusterd_lock_t; int32_t glusterd_get_lock_owner(uuid_t *cur_owner); int32_t glusterd_lock(uuid_t new_owner); int32_t glusterd_unlock(uuid_t owner); int32_t glusterd_get_uuid(uuid_t *uuid); int glusterd_submit_reply(rpcsvc_request_t *req, void *arg, struct iovec *payload, int payloadcount, struct iobref *iobref, xdrproc_t xdrproc); int glusterd_to_cli(rpcsvc_request_t *req, gf_cli_rsp *arg, struct iovec *payload, int payloadcount, struct iobref *iobref, xdrproc_t xdrproc, dict_t *dict); int glusterd_submit_request(struct rpc_clnt *rpc, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref, xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc); int32_t glusterd_volinfo_new(glusterd_volinfo_t **volinfo); char * glusterd_auth_get_username(glusterd_volinfo_t *volinfo); char * glusterd_auth_get_password(glusterd_volinfo_t *volinfo); int32_t glusterd_auth_set_username(glusterd_volinfo_t *volinfo, char *username); int32_t glusterd_auth_set_password(glusterd_volinfo_t *volinfo, char *password); int32_t glusterd_brickinfo_new(glusterd_brickinfo_t **brickinfo); int32_t glusterd_brickinfo_new_from_brick(char *brick, glusterd_brickinfo_t **brickinfo, gf_boolean_t construct_real_path, char **op_errstr); int32_t glusterd_volinfo_find(const char *volname, glusterd_volinfo_t **volinfo); int glusterd_get_next_available_brickid(glusterd_volinfo_t *volinfo); int32_t glusterd_resolve_brick(glusterd_brickinfo_t *brickinfo); int glusterd_brick_process_remove_brick(glusterd_brickinfo_t *brickinfo, int *last_brick); int32_t glusterd_volume_stop_glusterfs(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, gf_boolean_t del_brick); int send_attach_req(xlator_t *this, struct rpc_clnt *rpc, char *path, glusterd_brickinfo_t *brick, glusterd_brickinfo_t *other_brick, int op, gf_boolean_t graceful_cleanup); glusterd_volinfo_t * glusterd_volinfo_ref(glusterd_volinfo_t *volinfo); glusterd_volinfo_t * glusterd_volinfo_unref(glusterd_volinfo_t *volinfo); int32_t glusterd_brickinfo_delete(glusterd_brickinfo_t *brickinfo); int32_t glusterd_volume_brickinfo_get_by_brick(char *brick, glusterd_volinfo_t *volinfo, glusterd_brickinfo_t **brickinfo, gf_boolean_t construct_real_path); int32_t glusterd_add_volumes_to_export_dict(dict_t *peer_data, char **buf, u_int *length); int32_t glusterd_compare_friend_data(dict_t *peer_data, dict_t *cmp, int32_t *status, char *hostname); int glusterd_compute_cksum(glusterd_volinfo_t *volinfo, gf_boolean_t is_quota_conf); void glusterd_set_socket_filepath(char *sock_filepath, char *sockpath, size_t len); struct rpc_clnt * glusterd_pending_node_get_rpc(glusterd_pending_node_t *pending_node); void glusterd_pending_node_put_rpc(glusterd_pending_node_t *pending_node); int glusterd_remote_hostname_get(rpcsvc_request_t *req, char *remote_host, int len); void glusterd_set_volume_status(glusterd_volinfo_t *volinfo, glusterd_volume_status status); int32_t glusterd_add_volume_to_dict(glusterd_volinfo_t *volinfo, dict_t *dict, int32_t count, char *prefix); void glusterd_set_brick_status(glusterd_brickinfo_t *brickinfo, gf_brick_status_t status); gf_boolean_t glusterd_is_brick_started(glusterd_brickinfo_t *brickinfo); int glusterd_brick_start(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, gf_boolean_t wait, gf_boolean_t only_connect); int glusterd_brick_stop(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, gf_boolean_t del_brick); int glusterd_is_defrag_on(glusterd_volinfo_t *volinfo); int glusterd_new_brick_validate(char *brick, glusterd_brickinfo_t *brickinfo, char *op_errstr, size_t len, char *op); int glusterd_validate_and_create_brickpath(glusterd_brickinfo_t *brickinfo, uuid_t volume_id, char *volname, char **op_errstr, gf_boolean_t is_force, gf_boolean_t ignore_partition); int glusterd_sm_tr_log_transition_add(glusterd_sm_tr_log_t *log, int old_state, int new_state, int event); int glusterd_sm_tr_log_init(glusterd_sm_tr_log_t *log, char *(*state_name_get)(int), char *(*event_name_get)(int), size_t size); void glusterd_sm_tr_log_delete(glusterd_sm_tr_log_t *log); int32_t glusterd_delete_volume(glusterd_volinfo_t *volinfo); int32_t glusterd_delete_brick(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo); int glusterd_spawn_daemons(void *opaque); int glusterd_start_gsync(glusterd_volinfo_t *primary_vol, char *secondary, char *path_list, char *conf_path, char *glusterd_uuid_str, char **op_errstr, gf_boolean_t is_pause); int glusterd_get_local_brickpaths(glusterd_volinfo_t *volinfo, char **pathlist); int glusterd_add_brick_detail_to_dict(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, dict_t *dict, int32_t count); int32_t glusterd_add_brick_to_dict(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, dict_t *dict, int32_t count); gf_boolean_t glusterd_is_fuse_available(void); int glusterd_brick_statedump(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, char *options, int option_cnt, char **op_errstr); #ifdef BUILD_GNFS int glusterd_nfs_statedump(char *options, int option_cnt, char **op_errstr); #endif int glusterd_quotad_statedump(char *options, int option_cnt, char **op_errstr); gf_boolean_t glusterd_is_volume_replicate(glusterd_volinfo_t *volinfo); gf_boolean_t glusterd_is_brick_decommissioned(glusterd_volinfo_t *volinfo, char *hostname, char *path); int glusterd_friend_contains_vol_bricks(glusterd_volinfo_t *volinfo, uuid_t friend_uuid); int glusterd_friend_remove_cleanup_vols(uuid_t uuid); int glusterd_get_trusted_client_filepath(char *filepath, glusterd_volinfo_t *volinfo, gf_transport_type type); int glusterd_restart_rebalance_for_volume(glusterd_volinfo_t *volinfo); int glusterd_get_dist_leaf_count(glusterd_volinfo_t *volinfo); gf_boolean_t glusterd_is_local_brick(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo); int glusterd_validate_volume_id(dict_t *op_dict, glusterd_volinfo_t *volinfo); int glusterd_defrag_volume_status_update(glusterd_volinfo_t *volinfo, dict_t *rsp_dict, int32_t cmd); int glusterd_check_files_identical(char *filename1, char *filename2, gf_boolean_t *identical); int glusterd_check_topology_identical(const char *filename1, const char *filename2, gf_boolean_t *identical); void glusterd_volinfo_reset_defrag_stats(glusterd_volinfo_t *volinfo); int glusterd_volset_help(dict_t *dict, char **op_errstr); int32_t glusterd_sync_use_rsp_dict(dict_t *aggr, dict_t *rsp_dict); int32_t glusterd_rb_use_rsp_dict(dict_t *aggr, dict_t *rsp_dict); int glusterd_profile_volume_use_rsp_dict(dict_t *aggr, dict_t *rsp_dict); int glusterd_volume_status_copy_to_op_ctx_dict(dict_t *aggr, dict_t *rsp_dict); int glusterd_volume_rebalance_use_rsp_dict(dict_t *aggr, dict_t *rsp_dict); int32_t glusterd_handle_node_rsp(dict_t *req_ctx, void *pending_entry, glusterd_op_t op, dict_t *rsp_dict, dict_t *op_ctx, char **op_errstr, gd_node_type type); int32_t glusterd_check_if_quota_trans_enabled(glusterd_volinfo_t *volinfo); int32_t glusterd_set_originator_uuid(dict_t *dict); /* Should be used only when an operation is in progress, as that is the only * time a lock_owner is set */ gf_boolean_t is_origin_glusterd(dict_t *dict); int glusterd_get_next_global_opt_version_str(dict_t *opts, char **version_str); int glusterd_generate_and_set_task_id(dict_t *dict, char *key, const int keylen); int glusterd_copy_uuid_to_dict(uuid_t uuid, dict_t *dict, char *key, const int keylen); void gd_update_volume_op_versions(glusterd_volinfo_t *volinfo); gf_boolean_t gd_is_remove_brick_committed(glusterd_volinfo_t *volinfo); int glusterd_remove_brick_validate_bricks(gf1_op_commands cmd, int32_t brick_count, dict_t *dict, glusterd_volinfo_t *volinfo, char **errstr, gf_defrag_type_t type); int glusterd_get_secondary_details_confpath(glusterd_volinfo_t *volinfo, dict_t *dict, char **secondary_url, char **secondary_host, char **secondary_vol, char **conf_path, char **op_errstr); int glusterd_get_secondary_info(char *secondary, char **secondary_url, char **hostname, char **secondary_vol, char **op_errstr); int glusterd_get_statefile_name(glusterd_volinfo_t *volinfo, char *secondary, char *conf_path, char **statefile, gf_boolean_t *is_template_in_use); int glusterd_gsync_read_frm_status(char *path, char *buf, size_t blen); int glusterd_create_status_file(char *primary, char *secondary, char *secondary_url, char *secondary_vol, char *status); int glusterd_check_restart_gsync_session(glusterd_volinfo_t *volinfo, char *secondary, dict_t *resp_dict, char *path_list, char *conf_path, gf_boolean_t is_force); int glusterd_check_gsync_running_local(char *primary, char *secondary, char *conf_path, gf_boolean_t *is_run); gf_boolean_t gd_should_i_start_rebalance(glusterd_volinfo_t *volinfo); int glusterd_is_volume_quota_enabled(glusterd_volinfo_t *volinfo); int glusterd_is_bitrot_enabled(glusterd_volinfo_t *volinfo); gf_boolean_t glusterd_all_volumes_with_quota_stopped(void); void glusterd_clean_up_quota_store(glusterd_volinfo_t *volinfo); gf_boolean_t glusterd_status_has_tasks(int cmd); rpc_clnt_t * glusterd_rpc_clnt_unref(glusterd_conf_t *conf, rpc_clnt_t *rpc); int32_t glusterd_compare_volume_name(struct cds_list_head *, struct cds_list_head *); char * glusterd_get_brick_mount_device(char *brick_path); struct mntent * glusterd_get_mnt_entry_info(char *mnt_pt, char *buff, int buflen, struct mntent *entry_ptr); int glusterd_get_brick_root(char *path, char **mount_point); int32_t glusterd_get_brick_mount_dir(char *brickpath, char *hostname, char *mount_dir); int32_t glusterd_aggr_brick_mount_dirs(dict_t *aggr, dict_t *rsp_dict); int glusterd_launch_synctask(synctask_fn_t fn, void *opaque); int glusterd_enable_default_options(glusterd_volinfo_t *volinfo, char *option); int32_t glusterd_find_brick_mount_path(char *brick_path, char **brick_mount_path); /* * Function to retrieve list of snap volnames and their uuids */ int glusterd_snapshot_get_volnames_uuids(dict_t *dict, char *volname, gf_getsnap_name_uuid_rsp *snap_info_rsp); int glusterd_update_mntopts(char *brick_path, glusterd_brickinfo_t *brickinfo); int glusterd_update_fs_label(char *brick_path, char *fstype, char *device_path); int glusterd_get_global_max_op_version(rpcsvc_request_t *req, dict_t *ctx, int count); int glusterd_get_global_options_for_all_vols(rpcsvc_request_t *req, dict_t *dict, char **op_errstr); int glusterd_get_default_val_for_volopt(dict_t *dict, gf_boolean_t all_opts, char *key, char *orig_key, glusterd_volinfo_t *volinfo, char **err_str); int glusterd_check_client_op_version_support(char *volname, uint32_t op_version, char **op_errstr); void glusterd_get_rebalance_volfile(glusterd_volinfo_t *volinfo, char *path, int path_len); void glusterd_get_gfproxy_client_volfile(glusterd_volinfo_t *volinfo, char *path, int path_len); int glusterd_vol_add_quota_conf_to_dict(glusterd_volinfo_t *volinfo, dict_t *load, int vol_idx, char *prefix); int32_t glusterd_import_volinfo(dict_t *peer_data, int count, glusterd_volinfo_t **volinfo, char *prefix); int glusterd_import_quota_conf(dict_t *peer_data, int vol_idx, glusterd_volinfo_t *new_volinfo, char *prefix); gf_boolean_t glusterd_is_shd_compatible_volume(glusterd_volinfo_t *volinfo); gf_boolean_t glusterd_are_all_volumes_stopped(void); #ifdef BUILD_GNFS void glusterd_nfs_pmap_deregister(void); #endif gf_boolean_t glusterd_is_volume_started(glusterd_volinfo_t *volinfo); void glusterd_list_add_order(struct cds_list_head *new, struct cds_list_head *head, int (*compare)(struct cds_list_head *, struct cds_list_head *)); struct rpc_clnt * glusterd_defrag_rpc_get(glusterd_defrag_info_t *defrag); struct rpc_clnt * glusterd_defrag_rpc_put(glusterd_defrag_info_t *defrag); int glusterd_get_dummy_client_filepath(char *filepath, glusterd_volinfo_t *volinfo, gf_transport_type type); int glusterd_handle_replicate_brick_ops(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, glusterd_op_t op); void assign_brick_groups(glusterd_volinfo_t *volinfo); glusterd_brickinfo_t * get_last_brick_of_brick_group(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo); int glusterd_get_rb_dst_brickinfo(glusterd_volinfo_t *volinfo, glusterd_brickinfo_t **brickinfo); int rb_update_dstbrick_port(glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict, dict_t *req_dict); int glusterd_op_perform_replace_brick(glusterd_volinfo_t *volinfo, char *old_brick, char *new_brick, dict_t *dict); char * gd_rb_op_to_str(char *op); glusterd_op_t gd_cli_to_gd_op(char *cli_op); int glusterd_get_dst_brick_info(char **dst_brick, char *volname, char **op_errstr, glusterd_brickinfo_t **dst_brickinfo, char **host, dict_t *dict, char **dup_dstbrick); int glusterd_brick_op_prerequisites(dict_t *dict, char **op, glusterd_op_t *gd_op, char **volname, glusterd_volinfo_t **volinfo, char **src_brick, glusterd_brickinfo_t **src_brickinfo, char *pidfile, char **op_errstr, dict_t *rsp_dict); int glusterd_get_volinfo_from_brick(char *brick, glusterd_volinfo_t **volinfo); gf_boolean_t glusterd_is_profile_on(glusterd_volinfo_t *volinfo); char * search_brick_path_from_proc(pid_t brick_pid, char *brickpath); int32_t glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type, char **volname, char **bricks, int32_t *brick_count, int32_t sub_count, int flag); gf_boolean_t glusterd_gf_is_local_addr(char *hostname); int glusterd_defrag_ref(glusterd_defrag_info_t *defrag); int glusterd_defrag_unref(glusterd_defrag_info_t *defrag); #endif glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-nfs-svc.h0000644000000000000000000000013114522202451025016 xustar000000000000000030 mtime=1699284265.718027585 30 atime=1699284265.718027585 29 ctime=1699284306.57315064 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-nfs-svc.h0000664000175100017510000000112514522202451025275 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GLUSTERD_NFS_SVC_H_ #define _GLUSTERD_NFS_SVC_H_ #include "glusterd-svc-mgmt.h" #ifdef BUILD_GNFS void glusterd_nfssvc_build(glusterd_svc_t *svc); int glusterd_nfssvc_reconfigure(void); #endif /* BUILD_GNFS */ #endif glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-svc-helper.c0000644000000000000000000000013214522202451025503 xustar000000000000000030 mtime=1699284265.731027625 30 atime=1699284265.731027625 30 ctime=1699284306.643150851 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-svc-helper.c0000664000175100017510000007243214522202451025772 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include "glusterd.h" #include #include "glusterd-utils.h" #include "glusterd-svc-mgmt.h" #include "glusterd-shd-svc.h" #include "glusterd-quotad-svc.h" #ifdef BUILD_GNFS #include "glusterd-nfs-svc.h" #endif #include "glusterd-bitd-svc.h" #include "glusterd-shd-svc-helper.h" #include "glusterd-scrub-svc.h" #include "glusterd-svc-helper.h" #include #include "glusterd-snapshot-utils.h" int glusterd_svcs_reconfigure(glusterd_volinfo_t *volinfo) { int ret = 0; xlator_t *this = THIS; glusterd_conf_t *conf = NULL; char *svc_name = NULL; conf = this->private; GF_ASSERT(conf); #ifdef BUILD_GNFS svc_name = "nfs"; ret = glusterd_nfssvc_reconfigure(); if (ret) goto out; #endif svc_name = "self-heald"; if (volinfo) { ret = glusterd_shdsvc_reconfigure(volinfo); if (ret) goto out; } if (conf->op_version == GD_OP_VERSION_MIN) goto out; svc_name = "quotad"; ret = glusterd_quotadsvc_reconfigure(); if (ret) goto out; svc_name = "bitd"; ret = glusterd_bitdsvc_reconfigure(); if (ret) goto out; svc_name = "scrubber"; ret = glusterd_scrubsvc_reconfigure(); out: if (ret && svc_name) gf_event(EVENT_SVC_RECONFIGURE_FAILED, "svc_name=%s", svc_name); return ret; } int glusterd_svcs_stop(glusterd_volinfo_t *volinfo) { int ret = 0; glusterd_conf_t *priv = NULL; priv = THIS->private; GF_ASSERT(priv); #ifdef BUILD_GNFS ret = priv->nfs_svc.stop(&(priv->nfs_svc), SIGKILL); if (ret) goto out; #endif ret = priv->quotad_svc.stop(&(priv->quotad_svc), SIGTERM); if (ret) goto out; if (volinfo) { ret = volinfo->shd.svc.stop(&(volinfo->shd.svc), SIGTERM); if (ret) goto out; } ret = priv->bitd_svc.stop(&(priv->bitd_svc), SIGTERM); if (ret) goto out; ret = priv->scrub_svc.stop(&(priv->scrub_svc), SIGTERM); out: return ret; } int glusterd_svcs_manager(glusterd_volinfo_t *volinfo) { int ret = 0; glusterd_conf_t *conf = NULL; conf = THIS->private; GF_ASSERT(conf); if (volinfo && volinfo->is_snap_volume) return 0; #if BUILD_GNFS ret = conf->nfs_svc.manager(&(conf->nfs_svc), NULL, PROC_START_NO_WAIT); if (ret) goto out; #endif if (conf->op_version == GD_OP_VERSION_MIN) goto out; ret = conf->quotad_svc.manager(&(conf->quotad_svc), volinfo, PROC_START_NO_WAIT); if (ret == -EINVAL) ret = 0; if (ret) goto out; ret = conf->bitd_svc.manager(&(conf->bitd_svc), NULL, PROC_START_NO_WAIT); if (ret == -EINVAL) ret = 0; if (ret) goto out; if (volinfo) { ret = volinfo->shd.svc.manager(&(volinfo->shd.svc), volinfo, PROC_START_NO_WAIT); if (ret == -EINVAL) ret = 0; if (ret) goto out; } ret = conf->scrub_svc.manager(&(conf->scrub_svc), NULL, PROC_START_NO_WAIT); if (ret == -EINVAL) ret = 0; out: return ret; } int glusterd_svc_check_volfile_identical(char *svc_name, glusterd_graph_builder_t builder, gf_boolean_t *identical) { char orgvol[PATH_MAX] = { 0, }; char *tmpvol = NULL; glusterd_conf_t *conf = NULL; xlator_t *this = THIS; int ret = -1; int need_unlink = 0; int tmp_fd = -1; GF_ASSERT(identical); conf = this->private; glusterd_svc_build_volfile_path(svc_name, conf->workdir, orgvol, sizeof(orgvol)); ret = gf_asprintf(&tmpvol, "/tmp/g%s-XXXXXX", svc_name); if (ret < 0) { goto out; } /* coverity[SECURE_TEMP] mkstemp uses 0600 as the mode and is safe */ tmp_fd = mkstemp(tmpvol); if (tmp_fd < 0) { gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED, "Unable to create temp file" " %s:(%s)", tmpvol, strerror(errno)); ret = -1; goto out; } need_unlink = 1; ret = glusterd_create_global_volfile(builder, tmpvol, NULL); if (ret) goto out; ret = glusterd_check_files_identical(orgvol, tmpvol, identical); out: if (need_unlink) sys_unlink(tmpvol); if (tmpvol != NULL) GF_FREE(tmpvol); if (tmp_fd >= 0) sys_close(tmp_fd); return ret; } int glusterd_svc_check_topology_identical(char *svc_name, glusterd_graph_builder_t builder, gf_boolean_t *identical) { char orgvol[PATH_MAX] = { 0, }; char *tmpvol = NULL; glusterd_conf_t *conf = NULL; xlator_t *this = THIS; int ret = -1; int tmpclean = 0; int tmpfd = -1; if ((!identical) || (!this->private)) { gf_smsg(THIS->name, GF_LOG_ERROR, errno, GD_MSG_INVALID_ARGUMENT, NULL); goto out; } conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); /* Fetch the original volfile */ glusterd_svc_build_volfile_path(svc_name, conf->workdir, orgvol, sizeof(orgvol)); /* Create the temporary volfile */ ret = gf_asprintf(&tmpvol, "/tmp/g%s-XXXXXX", svc_name); if (ret < 0) { goto out; } /* coverity[SECURE_TEMP] mkstemp uses 0600 as the mode and is safe */ tmpfd = mkstemp(tmpvol); if (tmpfd < 0) { gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED, "Unable to create temp file" " %s:(%s)", tmpvol, strerror(errno)); ret = -1; goto out; } tmpclean = 1; /* SET the flag to unlink() tmpfile */ ret = glusterd_create_global_volfile(builder, tmpvol, NULL); if (ret) goto out; /* Compare the topology of volfiles */ ret = glusterd_check_topology_identical(orgvol, tmpvol, identical); out: if (tmpfd >= 0) sys_close(tmpfd); if (tmpclean) sys_unlink(tmpvol); if (tmpvol != NULL) GF_FREE(tmpvol); return ret; } int glusterd_volume_svc_check_volfile_identical( char *svc_name, dict_t *mode_dict, glusterd_volinfo_t *volinfo, glusterd_vol_graph_builder_t builder, gf_boolean_t *identical) { char orgvol[PATH_MAX] = { 0, }; char *tmpvol = NULL; xlator_t *this = THIS; int ret = -1; int need_unlink = 0; int tmp_fd = -1; GF_VALIDATE_OR_GOTO(this->name, identical, out); /* This builds volfile for volume level dameons */ glusterd_volume_svc_build_volfile_path(svc_name, volinfo, orgvol, sizeof(orgvol)); ret = gf_asprintf(&tmpvol, "/tmp/g%s-XXXXXX", svc_name); if (ret < 0) { goto out; } /* coverity[SECURE_TEMP] mkstemp uses 0600 as the mode and is safe */ tmp_fd = mkstemp(tmpvol); if (tmp_fd < 0) { gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED, "Unable to create temp file" " %s:(%s)", tmpvol, strerror(errno)); ret = -1; goto out; } need_unlink = 1; ret = builder(volinfo, tmpvol, mode_dict); if (ret) goto out; ret = glusterd_check_files_identical(orgvol, tmpvol, identical); out: if (need_unlink) sys_unlink(tmpvol); if (tmpvol != NULL) GF_FREE(tmpvol); if (tmp_fd >= 0) sys_close(tmp_fd); return ret; } int glusterd_volume_svc_check_topology_identical( char *svc_name, dict_t *mode_dict, glusterd_volinfo_t *volinfo, glusterd_vol_graph_builder_t builder, gf_boolean_t *identical) { char orgvol[PATH_MAX] = { 0, }; char *tmpvol = NULL; glusterd_conf_t *conf = NULL; xlator_t *this = THIS; int ret = -1; int tmpclean = 0; int tmpfd = -1; if ((!identical) || (!this->private)) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_INVALID_ARGUMENT, NULL); goto out; } conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); /* This builds volfile for volume level dameons */ glusterd_volume_svc_build_volfile_path(svc_name, volinfo, orgvol, sizeof(orgvol)); /* Create the temporary volfile */ ret = gf_asprintf(&tmpvol, "/tmp/g%s-XXXXXX", svc_name); if (ret < 0) { goto out; } /* coverity[SECURE_TEMP] mkstemp uses 0600 as the mode and is safe */ tmpfd = mkstemp(tmpvol); if (tmpfd < 0) { gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED, "Unable to create temp file" " %s:(%s)", tmpvol, strerror(errno)); ret = -1; goto out; } tmpclean = 1; /* SET the flag to unlink() tmpfile */ ret = builder(volinfo, tmpvol, mode_dict); if (ret) goto out; /* Compare the topology of volfiles */ ret = glusterd_check_topology_identical(orgvol, tmpvol, identical); out: if (tmpfd >= 0) sys_close(tmpfd); if (tmpclean) sys_unlink(tmpvol); if (tmpvol != NULL) GF_FREE(tmpvol); return ret; } gf_boolean_t glusterd_is_svcproc_attachable(glusterd_svc_proc_t *svc_proc) { int pid = -1; glusterd_svc_t *parent_svc = NULL; if (!svc_proc) return _gf_false; if (svc_proc->status == GF_SVC_STARTING) return _gf_true; if (svc_proc->status == GF_SVC_STARTED || svc_proc->status == GF_SVC_DISCONNECTED) { parent_svc = cds_list_entry(svc_proc->svcs.next, glusterd_svc_t, mux_svc); if (parent_svc && gf_is_service_running(parent_svc->proc.pidfile, &pid)) return _gf_true; } if (svc_proc->status == GF_SVC_DIED || svc_proc->status == GF_SVC_STOPPING) return _gf_false; return _gf_false; } void * __gf_find_compatible_svc(gd_node_type daemon) { glusterd_svc_proc_t *svc_proc = NULL; struct cds_list_head *svc_procs = NULL; glusterd_conf_t *conf = NULL; conf = THIS->private; GF_VALIDATE_OR_GOTO("glusterd", conf, out); switch (daemon) { case GD_NODE_SHD: { svc_procs = &conf->shd_procs; if (!svc_procs) goto out; } break; default: /* Add support for other client daemons here */ goto out; } cds_list_for_each_entry(svc_proc, svc_procs, svc_proc_list) { if (glusterd_is_svcproc_attachable(svc_proc)) return (void *)svc_proc; /* * Logic to select one process goes here. Currently there is only one * shd_proc. So selecting the first one; */ } out: return NULL; } glusterd_svc_proc_t * glusterd_svcprocess_new(void) { glusterd_svc_proc_t *new_svcprocess = NULL; new_svcprocess = GF_CALLOC(1, sizeof(*new_svcprocess), gf_gld_mt_glusterd_svc_proc_t); if (!new_svcprocess) return NULL; CDS_INIT_LIST_HEAD(&new_svcprocess->svc_proc_list); CDS_INIT_LIST_HEAD(&new_svcprocess->svcs); new_svcprocess->notify = glusterd_muxsvc_common_rpc_notify; new_svcprocess->status = GF_SVC_STARTING; return new_svcprocess; } int glusterd_shd_svc_mux_init(glusterd_volinfo_t *volinfo, glusterd_svc_t *svc) { int ret = -1; glusterd_svc_proc_t *mux_proc = NULL; glusterd_conn_t *mux_conn = NULL; glusterd_conf_t *conf = NULL; glusterd_svc_t *parent_svc = NULL; int pid = -1; gf_boolean_t stop_daemon = _gf_false; char pidfile[PATH_MAX] = { 0, }; GF_VALIDATE_OR_GOTO("glusterd", svc, out); GF_VALIDATE_OR_GOTO("glusterd", volinfo, out); conf = THIS->private; GF_VALIDATE_OR_GOTO("glusterd", conf, out); GF_VALIDATE_OR_GOTO("glusterd", svc, out); pthread_mutex_lock(&conf->attach_lock); { if (svc->inited && !glusterd_proc_is_running(&(svc->proc))) { /* This is the case when shd process was abnormally killed */ pthread_mutex_unlock(&conf->attach_lock); glusterd_shd_svcproc_cleanup(&volinfo->shd); pthread_mutex_lock(&conf->attach_lock); } if (!svc->inited) { glusterd_svc_build_shd_pidfile(volinfo, pidfile, sizeof(pidfile)); ret = snprintf(svc->proc.name, sizeof(svc->proc.name), "%s", "glustershd"); if (ret < 0) goto unlock; ret = snprintf(svc->proc.pidfile, sizeof(svc->proc.pidfile), "%s", pidfile); if (ret < 0) goto unlock; if (gf_is_service_running(pidfile, &pid)) { /* Just connect is required, but we don't know what happens * during the disconnect. So better to reattach. */ mux_proc = __gf_find_compatible_svc_from_pid(GD_NODE_SHD, pid); } if (!mux_proc) { if (pid != -1 && sys_access(pidfile, R_OK) == 0) { /* stale pid file, stop and unlink it. This has to be * done outside the attach_lock. */ stop_daemon = _gf_true; } mux_proc = __gf_find_compatible_svc(GD_NODE_SHD); } if (mux_proc) { /* Take first entry from the process */ parent_svc = cds_list_entry(mux_proc->svcs.next, glusterd_svc_t, mux_svc); mux_conn = &parent_svc->conn; if (volinfo) volinfo->shd.attached = _gf_true; } else { mux_proc = glusterd_svcprocess_new(); if (!mux_proc) { ret = -1; goto unlock; } cds_list_add_tail(&mux_proc->svc_proc_list, &conf->shd_procs); } svc->svc_proc = mux_proc; cds_list_del_init(&svc->mux_svc); cds_list_add_tail(&svc->mux_svc, &mux_proc->svcs); ret = glusterd_shdsvc_init(volinfo, mux_conn, mux_proc); if (ret) { pthread_mutex_unlock(&conf->attach_lock); gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_FAILED_INIT_SHDSVC, "Failed to init shd " "service"); goto out; } gf_msg_debug(THIS->name, 0, "shd service initialized"); svc->inited = _gf_true; } ret = 0; } unlock: pthread_mutex_unlock(&conf->attach_lock); out: if (stop_daemon) { glusterd_proc_stop(&svc->proc, SIGTERM, PROC_STOP_FORCE); gf_unlink(pidfile); } return ret; } void * __gf_find_compatible_svc_from_pid(gd_node_type daemon, pid_t pid) { glusterd_svc_proc_t *svc_proc = NULL; struct cds_list_head *svc_procs = NULL; glusterd_svc_t *svc = NULL; pid_t mux_pid = -1; glusterd_conf_t *conf = NULL; conf = THIS->private; if (!conf) return NULL; switch (daemon) { case GD_NODE_SHD: { svc_procs = &conf->shd_procs; if (!svc_procs) return NULL; } break; default: /* Add support for other client daemons here */ return NULL; } cds_list_for_each_entry(svc_proc, svc_procs, svc_proc_list) { cds_list_for_each_entry(svc, &svc_proc->svcs, mux_svc) { if (gf_is_service_running(svc->proc.pidfile, &mux_pid)) { if (mux_pid == pid && glusterd_is_svcproc_attachable(svc_proc)) { /*TODO * inefficient loop, but at the moment, there is only * one shd. */ return svc_proc; } } } } return NULL; } static int32_t my_callback(struct rpc_req *req, struct iovec *iov, int count, void *v_frame) { call_frame_t *frame = v_frame; xlator_t *this = NULL; glusterd_conf_t *conf = NULL; GF_VALIDATE_OR_GOTO("glusterd", frame, out); this = frame->this; GF_VALIDATE_OR_GOTO("glusterd", this, out); conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); if (GF_ATOMIC_DEC(conf->blockers) == 0) { synccond_broadcast(&conf->cond_blockers); } STACK_DESTROY(frame->root); out: return 0; } static int32_t glusterd_svc_attach_cbk(struct rpc_req *req, struct iovec *iov, int count, void *v_frame) { call_frame_t *frame = v_frame; glusterd_volinfo_t *volinfo = NULL; glusterd_shdsvc_t *shd = NULL; glusterd_svc_t *svc = frame->cookie; glusterd_conf_t *conf = NULL; int *flag = (int *)frame->local; xlator_t *this = THIS; int ret = -1; gf_getspec_rsp rsp = { 0, }; conf = this->private; GF_VALIDATE_OR_GOTO("glusterd", conf, out); GF_VALIDATE_OR_GOTO("glusterd", frame, out); GF_VALIDATE_OR_GOTO("glusterd", svc, out); frame->local = NULL; frame->cookie = NULL; if (!strcmp(svc->name, "glustershd")) { /* Get volinfo->shd from svc object */ shd = cds_list_entry(svc, glusterd_shdsvc_t, svc); if (!shd) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_SHD_OBJ_GET_FAIL, "Failed to get shd object " "from shd service"); goto out; } /* Get volinfo from shd */ volinfo = cds_list_entry(shd, glusterd_volinfo_t, shd); if (!volinfo) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL, "Failed to get volinfo from " "from shd"); goto out; } } if (!iov) { gf_msg(frame->this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "iov is NULL"); ret = -1; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp); if (ret < 0) { gf_msg(frame->this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "XDR decoding error"); ret = -1; goto out; } if (rsp.op_ret == 0) { svc->online = _gf_true; gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_SVC_ATTACH_FAIL, "svc %s of volume %s attached successfully to pid %d", svc->name, volinfo->volname, glusterd_proc_get_pid(&svc->proc)); } else { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_ATTACH_FAIL, "svc %s of volume %s failed to attach to pid %d", svc->name, volinfo->volname, glusterd_proc_get_pid(&svc->proc)); if (!strcmp(svc->name, "glustershd")) { glusterd_shd_svcproc_cleanup(&volinfo->shd); } } out: if (flag) { GF_FREE(flag); } if (volinfo) glusterd_volinfo_unref(volinfo); if (GF_ATOMIC_DEC(conf->blockers) == 0) { synccond_broadcast(&conf->cond_blockers); } STACK_DESTROY(frame->root); return 0; } extern size_t build_volfile_path(char *volume_id, char *path, size_t path_len, char *trusted_str, dict_t *dict); int __glusterd_send_svc_configure_req(glusterd_svc_t *svc, int flags, struct rpc_clnt *rpc, char *volfile_id, int op) { int ret = -1; struct iobuf *iobuf = NULL; struct iobref *iobref = NULL; struct iovec iov = { 0, }; char path[PATH_MAX] = { '\0', }; struct stat stbuf = { 0, }; int32_t spec_fd = -1; size_t file_len = -1; char *volfile_content = NULL; ssize_t req_size = 0; call_frame_t *frame = NULL; gd1_mgmt_brick_op_req brick_req; dict_t *dict = NULL; void *req = &brick_req; struct rpc_clnt_connection *conn; xlator_t *this = THIS; glusterd_conf_t *conf = THIS->private; extern struct rpc_clnt_program gd_brick_prog; fop_cbk_fn_t cbkfn = my_callback; if (!rpc) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_PARAM_NULL, "called with null rpc"); return -1; } conn = &rpc->conn; if (rpc_clnt_connection_status(conn) != RPC_STATUS_CONNECTED) { gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_CONNECT_RETURNED, "not connected yet"); return -1; } brick_req.op = op; brick_req.name = volfile_id; brick_req.input.input_val = NULL; brick_req.input.input_len = 0; brick_req.dict.dict_val = NULL; brick_req.dict.dict_len = 0; frame = create_frame(this, this->ctx->pool); if (!frame) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_FRAME_CREATE_FAIL, NULL); goto err; } if (op == GLUSTERD_SVC_ATTACH) { dict = dict_new(); if (!dict) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); ret = -ENOMEM; goto err; } (void)build_volfile_path(volfile_id, path, sizeof(path), NULL, dict); ret = sys_stat(path, &stbuf); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_ATTACH_FAIL, "Unable to stat %s (%s)", path, strerror(errno)); ret = -EINVAL; goto err; } file_len = stbuf.st_size; volfile_content = GF_MALLOC(file_len + 1, gf_common_mt_char); if (!volfile_content) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); ret = -ENOMEM; goto err; } spec_fd = open(path, O_RDONLY); if (spec_fd < 0) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_SVC_ATTACH_FAIL, "failed to read volfile %s", path); ret = -EIO; goto err; } ret = sys_read(spec_fd, volfile_content, file_len); if (ret == file_len) { brick_req.input.input_val = volfile_content; brick_req.input.input_len = file_len; } else { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_ATTACH_FAIL, "read failed on path %s. File size=%" GF_PRI_SIZET "read size=%d", path, file_len, ret); ret = -EIO; goto err; } if (dict->count > 0) { ret = dict_allocate_and_serialize(dict, &brick_req.dict.dict_val, &brick_req.dict.dict_len); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_ALLOC_AND_SERL_LENGTH_GET_FAIL, NULL); goto err; } } frame->cookie = svc; frame->local = GF_CALLOC(1, sizeof(int), gf_gld_mt_int); *((int *)frame->local) = flags; cbkfn = glusterd_svc_attach_cbk; } req_size = xdr_sizeof((xdrproc_t)xdr_gd1_mgmt_brick_op_req, req); iobuf = iobuf_get2(rpc->ctx->iobuf_pool, req_size); if (!iobuf) { goto err; } iov.iov_base = iobuf->ptr; iov.iov_len = iobuf_pagesize(iobuf); iobref = iobref_new(); if (!iobref) { goto err; } iobref_add(iobref, iobuf); /* Create the xdr payload */ ret = xdr_serialize_generic(iov, req, (xdrproc_t)xdr_gd1_mgmt_brick_op_req); if (ret == -1) { goto err; } iov.iov_len = ret; /* Send the msg */ GF_ATOMIC_INC(conf->blockers); ret = rpc_clnt_submit(rpc, &gd_brick_prog, op, cbkfn, &iov, 1, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL); frame = NULL; err: if (iobuf) { iobuf_unref(iobuf); } if (iobref) { iobref_unref(iobref); } if (dict) dict_unref(dict); if (brick_req.dict.dict_val) GF_FREE(brick_req.dict.dict_val); GF_FREE(volfile_content); if (spec_fd >= 0) sys_close(spec_fd); if (frame && ret) STACK_DESTROY(frame->root); return ret; } static gf_boolean_t glusterd_volume_exists(const char *volname) { glusterd_volinfo_t *tmp_volinfo = NULL; gf_boolean_t volume_found = _gf_false; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; GF_ASSERT(volname); priv = this->private; GF_ASSERT(priv); cds_list_for_each_entry(tmp_volinfo, &priv->volumes, vol_list) { if (!strcmp(tmp_volinfo->volname, volname)) { gf_msg_debug(this->name, 0, "Volume %s found", volname); volume_found = _gf_true; break; } } return volume_found; } int glusterd_attach_svc(glusterd_svc_t *svc, glusterd_volinfo_t *volinfo, int flags) { glusterd_conf_t *conf = THIS->private; int ret = -1; int tries; rpc_clnt_t *rpc = NULL; GF_VALIDATE_OR_GOTO("glusterd", conf, out); GF_VALIDATE_OR_GOTO("glusterd", svc, out); GF_VALIDATE_OR_GOTO("glusterd", volinfo, out); gf_msg("glusterd", GF_LOG_INFO, 0, GD_MSG_ATTACH_INFO, "adding svc %s (volume=%s) to existing " "process with pid %d", svc->name, volinfo->volname, glusterd_proc_get_pid(&svc->proc)); rpc = rpc_clnt_ref(svc->conn.rpc); for (tries = 15; tries > 0; --tries) { /* There might be a case that the volume for which we're attempting to * attach a shd svc might become stale and in the process of deletion. * Given that the volinfo object is being already passed here before * that sequence of operation has happened we might be operating on a * stale volume. At every sync task switch we should check for existance * of the volume now */ if (!glusterd_volume_exists(volinfo->volname)) { gf_msg(THIS->name, GF_LOG_INFO, 0, GD_MSG_SVC_ATTACH_FAIL, "Volume %s " " is marked as stale, not attempting further shd svc attach " "attempts", volinfo->volname); ret = 0; goto out; } if (rpc) { pthread_mutex_lock(&conf->attach_lock); { ret = __glusterd_send_svc_configure_req( svc, flags, rpc, svc->proc.volfileid, GLUSTERD_SVC_ATTACH); } pthread_mutex_unlock(&conf->attach_lock); if (!ret) { volinfo->shd.attached = _gf_true; goto out; } } /* * It might not actually be safe to manipulate the lock * like this, but if we don't then the connection can * never actually complete and retries are useless. * Unfortunately, all of the alternatives (e.g. doing * all of this in a separate thread) are much more * complicated and risky. * TBD: see if there's a better way */ synclock_unlock(&conf->big_lock); synctask_sleep(1); synclock_lock(&conf->big_lock); } ret = -1; gf_msg("glusterd", GF_LOG_WARNING, 0, GD_MSG_SVC_ATTACH_FAIL, "attach failed for %s(volume=%s)", svc->name, volinfo->volname); out: if (rpc) rpc_clnt_unref(rpc); return ret; } int glusterd_detach_svc(glusterd_svc_t *svc, glusterd_volinfo_t *volinfo, int sig) { glusterd_conf_t *conf = THIS->private; int ret = -1; int tries; rpc_clnt_t *rpc = NULL; GF_VALIDATE_OR_GOTO(THIS->name, conf, out); GF_VALIDATE_OR_GOTO(THIS->name, svc, out); GF_VALIDATE_OR_GOTO(THIS->name, volinfo, out); gf_msg(THIS->name, GF_LOG_INFO, 0, GD_MSG_DETACH_INFO, "removing svc %s (volume=%s) from existing " "process with pid %d", svc->name, volinfo->volname, glusterd_proc_get_pid(&svc->proc)); rpc = rpc_clnt_ref(svc->conn.rpc); for (tries = 15; tries > 0; --tries) { if (rpc) { /*For detach there is no flags, and we are not using sig.*/ pthread_mutex_lock(&conf->attach_lock); { ret = __glusterd_send_svc_configure_req(svc, 0, svc->conn.rpc, svc->proc.volfileid, GLUSTERD_SVC_DETACH); } pthread_mutex_unlock(&conf->attach_lock); if (!ret) { goto out; } } /* * It might not actually be safe to manipulate the lock * like this, but if we don't then the connection can * never actually complete and retries are useless. * Unfortunately, all of the alternatives (e.g. doing * all of this in a separate thread) are much more * complicated and risky. * TBD: see if there's a better way */ synclock_unlock(&conf->big_lock); synctask_sleep(1); synclock_lock(&conf->big_lock); } ret = -1; gf_msg("glusterd", GF_LOG_WARNING, 0, GD_MSG_SVC_DETACH_FAIL, "detach failed for %s(volume=%s)", svc->name, volinfo->volname); out: if (rpc) rpc_clnt_unref(rpc); return ret; } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-locks.c0000644000000000000000000000013214522202451024546 xustar000000000000000030 mtime=1699284265.715027576 30 atime=1699284265.715027576 30 ctime=1699284306.626150799 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-locks.c0000664000175100017510000005767214522202451025046 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013-2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "glusterd-op-sm.h" #include "glusterd-store.h" #include "glusterd-utils.h" #include "glusterd-volgen.h" #include "glusterd-locks.h" #include "glusterd-errno.h" #include #include #include "glusterd-messages.h" #include #define GF_MAX_LOCKING_ENTITIES 3 /* Valid entities that the mgmt_v3 lock can hold locks upon * * To add newer entities to be locked, we can just add more * * entries to this table along with the type and default value */ glusterd_valid_entities valid_types[] = { {"vol", _gf_true}, {"snap", _gf_false}, {"global", _gf_false}, {NULL}, }; /* Checks if the lock request is for a valid entity */ static gf_boolean_t glusterd_mgmt_v3_is_type_valid(char *type) { int i = 0; GF_ASSERT(type); for (i = 0; valid_types[i].type; i++) { if (!strcmp(type, valid_types[i].type)) { return _gf_true; } } return _gf_false; } /* Initialize the global mgmt_v3 lock list(dict) when * glusterd is spawned */ int32_t glusterd_mgmt_v3_lock_init(void) { int32_t ret = -1; glusterd_conf_t *priv = NULL; priv = THIS->private; GF_ASSERT(priv); priv->mgmt_v3_lock = dict_new(); if (!priv->mgmt_v3_lock) goto out; ret = 0; out: return ret; } /* Destroy the global mgmt_v3 lock list(dict) when * glusterd cleanup is performed */ void glusterd_mgmt_v3_lock_fini(void) { glusterd_conf_t *priv = NULL; priv = THIS->private; GF_ASSERT(priv); if (priv->mgmt_v3_lock) dict_unref(priv->mgmt_v3_lock); } /* Initialize the global mgmt_v3_timer lock list(dict) when * glusterd is spawned */ int32_t glusterd_mgmt_v3_lock_timer_init(void) { int32_t ret = -1; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); priv->mgmt_v3_lock_timer = dict_new(); if (!priv->mgmt_v3_lock_timer) goto out; ret = 0; out: return ret; } /* Destroy the global mgmt_v3_timer lock list(dict) when * glusterd cleanup is performed */ void glusterd_mgmt_v3_lock_timer_fini(void) { xlator_t *this = THIS; glusterd_conf_t *priv = NULL; priv = this->private; GF_VALIDATE_OR_GOTO(this->name, priv, out); if (priv->mgmt_v3_lock_timer) dict_unref(priv->mgmt_v3_lock_timer); out: return; } static int32_t glusterd_get_mgmt_v3_lock_owner(char *key, uuid_t *uuid) { int32_t ret = -1; glusterd_mgmt_v3_lock_obj *lock_obj = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); if (!key || !uuid) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "key or uuid is null."); ret = -1; goto out; } ret = dict_get_bin(priv->mgmt_v3_lock, key, (void **)&lock_obj); if (!ret) gf_uuid_copy(*uuid, lock_obj->lock_owner); ret = 0; out: gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } /* This function is called with the locked_count and type, to * * release all the acquired locks. */ static int32_t glusterd_release_multiple_locks_per_entity(dict_t *dict, uuid_t uuid, int32_t locked_count, char *type) { char name_buf[PATH_MAX] = ""; char *name = NULL; int32_t i = -1; int32_t op_ret = 0; int32_t ret = -1; xlator_t *this = THIS; GF_ASSERT(dict); GF_ASSERT(type); if (locked_count == 0) { gf_msg_debug(this->name, 0, "No %s locked as part of this transaction", type); goto out; } /* Release all the locks held */ for (i = 0; i < locked_count; i++) { ret = snprintf(name_buf, sizeof(name_buf), "%sname%d", type, i + 1); /* Looking for volname1, volname2 or snapname1, * * as key in the dict snapname2 */ ret = dict_get_strn(dict, name_buf, ret, &name); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get %s locked_count = %d", name_buf, locked_count); op_ret = ret; continue; } ret = glusterd_mgmt_v3_unlock(name, uuid, type); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Failed to release lock for %s.", name); op_ret = ret; } } out: gf_msg_trace(this->name, 0, "Returning %d", op_ret); return op_ret; } /* Given the count and type of the entity this function acquires * * locks on multiple elements of the same entity. For example: * * If type is "vol" this function tries to acquire locks on multiple * * volumes */ static int32_t glusterd_acquire_multiple_locks_per_entity(dict_t *dict, uuid_t uuid, uint32_t *op_errno, int32_t count, char *type) { char name_buf[PATH_MAX] = ""; char *name = NULL; int32_t i = -1; int32_t ret = -1; int32_t locked_count = 0; xlator_t *this = THIS; GF_ASSERT(dict); GF_ASSERT(type); /* Locking one element after other */ for (i = 0; i < count; i++) { ret = snprintf(name_buf, sizeof(name_buf), "%sname%d", type, i + 1); /* Looking for volname1, volname2 or snapname1, * * as key in the dict snapname2 */ ret = dict_get_strn(dict, name_buf, ret, &name); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to get %s count = %d", name_buf, count); break; } ret = glusterd_mgmt_v3_lock(name, uuid, op_errno, type); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_LOCK_GET_FAIL, "Failed to acquire lock for %s %s " "on behalf of %s. Reversing " "this transaction", type, name, uuid_utoa(uuid)); break; } locked_count++; } if (count == locked_count) { /* If all locking ops went successfully, return as success */ ret = 0; goto out; } /* If we failed to lock one element, unlock others and return failure */ ret = glusterd_release_multiple_locks_per_entity(dict, uuid, locked_count, type); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MULTIPLE_LOCK_RELEASE_FAIL, "Failed to release multiple %s locks", type); } ret = -1; out: gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } /* Given the type of entity, this function figures out if it should unlock a * * single element of multiple elements of the said entity. For example: * * if the type is "vol", this function will accordingly unlock a single volume * * or multiple volumes */ static int32_t glusterd_mgmt_v3_unlock_entity(dict_t *dict, uuid_t uuid, char *type, gf_boolean_t default_value) { char name_buf[PATH_MAX] = ""; char *name = NULL; int32_t count = -1; int32_t ret = -1; gf_boolean_t hold_locks = _gf_false; xlator_t *this = THIS; GF_ASSERT(dict); GF_ASSERT(type); snprintf(name_buf, sizeof(name_buf), "hold_%s_locks", type); hold_locks = dict_get_str_boolean(dict, name_buf, default_value); if (hold_locks == _gf_false) { /* Locks were not held for this particular entity * * Hence nothing to release */ ret = 0; goto out; } /* Looking for volcount or snapcount in the dict */ ret = snprintf(name_buf, sizeof(name_buf), "%scount", type); ret = dict_get_int32n(dict, name_buf, ret, &count); if (ret) { /* count is not present. Only one * * element name needs to be unlocked */ ret = snprintf(name_buf, sizeof(name_buf), "%sname", type); ret = dict_get_strn(dict, name_buf, ret, &name); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to fetch %sname", type); goto out; } ret = glusterd_mgmt_v3_unlock(name, uuid, type); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Failed to release lock for %s %s " "on behalf of %s.", type, name, uuid_utoa(uuid)); goto out; } } else { /* Unlocking one element name after another */ ret = glusterd_release_multiple_locks_per_entity(dict, uuid, count, type); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MULTIPLE_LOCK_RELEASE_FAIL, "Failed to release all %s locks", type); goto out; } } ret = 0; out: gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } /* Given the type of entity, this function figures out if it should lock a * * single element or multiple elements of the said entity. For example: * * if the type is "vol", this function will accordingly lock a single volume * * or multiple volumes */ static int32_t glusterd_mgmt_v3_lock_entity(dict_t *dict, uuid_t uuid, uint32_t *op_errno, char *type, gf_boolean_t default_value) { char name_buf[PATH_MAX] = ""; char *name = NULL; int32_t count = -1; int32_t ret = -1; gf_boolean_t hold_locks = _gf_false; xlator_t *this = THIS; GF_ASSERT(dict); GF_ASSERT(type); snprintf(name_buf, sizeof(name_buf), "hold_%s_locks", type); hold_locks = dict_get_str_boolean(dict, name_buf, default_value); if (hold_locks == _gf_false) { /* Not holding locks for this particular entity */ ret = 0; goto out; } /* Looking for volcount or snapcount in the dict */ ret = snprintf(name_buf, sizeof(name_buf), "%scount", type); ret = dict_get_int32n(dict, name_buf, ret, &count); if (ret) { /* count is not present. Only one * * element name needs to be locked */ ret = snprintf(name_buf, sizeof(name_buf), "%sname", type); ret = dict_get_strn(dict, name_buf, ret, &name); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "Unable to fetch %sname", type); goto out; } ret = glusterd_mgmt_v3_lock(name, uuid, op_errno, type); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_LOCK_GET_FAIL, "Failed to acquire lock for %s %s " "on behalf of %s.", type, name, uuid_utoa(uuid)); goto out; } } else { /* Locking one element name after another */ ret = glusterd_acquire_multiple_locks_per_entity(dict, uuid, op_errno, count, type); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MULTIPLE_LOCK_ACQUIRE_FAIL, "Failed to acquire all %s locks", type); goto out; } } ret = 0; out: gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } /* Try to release locks of multiple entities like * * volume, snaps etc. */ int32_t glusterd_multiple_mgmt_v3_unlock(dict_t *dict, uuid_t uuid) { int32_t i = -1; int32_t ret = -1; int32_t op_ret = 0; xlator_t *this = THIS; if (!dict) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_EMPTY, "dict is null."); ret = -1; goto out; } for (i = 0; valid_types[i].type; i++) { ret = glusterd_mgmt_v3_unlock_entity(dict, uuid, valid_types[i].type, valid_types[i].default_value); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MULTIPLE_LOCK_RELEASE_FAIL, "Unable to unlock all %s", valid_types[i].type); op_ret = ret; } } ret = op_ret; out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } /* Try to acquire locks on multiple entities like * * volume, snaps etc. */ int32_t glusterd_multiple_mgmt_v3_lock(dict_t *dict, uuid_t uuid, uint32_t *op_errno) { int32_t i = -1; int32_t ret = -1; int32_t locked_count = 0; xlator_t *this = THIS; if (!dict) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_EMPTY, "dict is null."); ret = -1; goto out; } /* Locking one entity after other */ for (i = 0; valid_types[i].type; i++) { ret = glusterd_mgmt_v3_lock_entity(dict, uuid, op_errno, valid_types[i].type, valid_types[i].default_value); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MULTIPLE_LOCK_ACQUIRE_FAIL, "Unable to lock all %s", valid_types[i].type); break; } locked_count++; } if (locked_count == GF_MAX_LOCKING_ENTITIES) { /* If all locking ops went successfully, return as success */ ret = 0; goto out; } /* If we failed to lock one entity, unlock others and return failure */ for (i = 0; i < locked_count; i++) { ret = glusterd_mgmt_v3_unlock_entity(dict, uuid, valid_types[i].type, valid_types[i].default_value); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MULTIPLE_LOCK_RELEASE_FAIL, "Unable to unlock all %s", valid_types[i].type); } } ret = -1; out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } int32_t glusterd_mgmt_v3_lock(const char *name, uuid_t uuid, uint32_t *op_errno, char *type) { char key[PATH_MAX] = ""; int32_t ret = -1; glusterd_mgmt_v3_lock_obj *lock_obj = NULL; gf_timer_t *mgmt_lock_timer = NULL; glusterd_conf_t *priv = NULL; gf_boolean_t is_valid = _gf_true; uuid_t owner = {0}; xlator_t *this = THIS; struct timespec delay = {0}; char *key_dup = NULL; priv = this->private; GF_ASSERT(priv); if (!name || !type) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "name or type is null."); ret = -1; goto out; } is_valid = glusterd_mgmt_v3_is_type_valid(type); if (is_valid != _gf_true) { gf_msg_callingfn(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "Invalid entity. Cannot perform locking " "operation on %s types", type); ret = -1; goto out; } ret = snprintf(key, sizeof(key), "%s_%s", name, type); if (ret != strlen(name) + 1 + strlen(type)) { ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_CREATE_KEY_FAIL, "Unable to create key"); goto out; } gf_msg_debug(this->name, 0, "Trying to acquire lock of %s for %s", key, uuid_utoa(uuid)); ret = glusterd_get_mgmt_v3_lock_owner(key, &owner); if (ret) { gf_msg_debug(this->name, 0, "Unable to get mgmt_v3 lock owner"); goto out; } /* If the lock has already been held for the given volume * we fail */ if (!gf_uuid_is_null(owner)) { gf_msg_callingfn(this->name, GF_LOG_WARNING, 0, GD_MSG_LOCK_ALREADY_HELD, "Lock for %s held by %s", name, uuid_utoa(owner)); ret = -1; *op_errno = EG_ANOTRANS; goto out; } lock_obj = GF_MALLOC(sizeof(glusterd_mgmt_v3_lock_obj), gf_common_mt_mgmt_v3_lock_obj_t); if (!lock_obj) { ret = -1; goto out; } gf_uuid_copy(lock_obj->lock_owner, uuid); ret = dict_set_bin(priv->mgmt_v3_lock, key, lock_obj, sizeof(glusterd_mgmt_v3_lock_obj)); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Unable to set lock owner in mgmt_v3 lock"); GF_FREE(lock_obj); goto out; } key_dup = gf_strdup(key); delay.tv_sec = priv->mgmt_v3_lock_timeout; delay.tv_nsec = 0; /* Changing to default timeout value. */ priv->mgmt_v3_lock_timeout = GF_LOCK_TIMER; mgmt_lock_timer = gf_timer_call_after(this->ctx, delay, gd_mgmt_v3_unlock_timer_cbk, key_dup); /* Timer object is allocated dynamically but freed with gf_timer_call_cancel(). So it should not be managed by dict to avoid double free and treated as static here. Also note that just the pointer to timer is stored in the dict, not the timer object as a whole (the latter causes copying and most likely a crash in timer code). */ /* coverity[SUSPICIOUS_SIZEOF] */ ret = dict_set_static_bin(priv->mgmt_v3_lock_timer, key, mgmt_lock_timer, sizeof(mgmt_lock_timer)); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Unable to set timer in mgmt_v3 lock"); GF_FREE(key_dup); GF_FREE(mgmt_lock_timer); goto out; } #ifdef DEBUG char *bt = NULL; /* Saving the backtrace into the pre-allocated buffer, ctx->btbuf*/ if ((bt = gf_backtrace_save(NULL))) { snprintf(key, sizeof(key), "debug.last-success-bt-%s", key_dup); ret = dict_set_dynstr_with_alloc(priv->mgmt_v3_lock, key, bt); if (ret) gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_SET_FAILED, "Failed to save " "the back trace for lock %s granted to %s", key_dup, uuid_utoa(uuid)); ret = 0; } #endif gf_msg_debug(this->name, 0, "Lock for %s successfully held by %s", key_dup, uuid_utoa(uuid)); ret = 0; out: gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } /* * This call back will ensure to unlock the lock_obj, in case we hit a situation * where unlocking failed and stale lock exist*/ void gd_mgmt_v3_unlock_timer_cbk(void *data) { xlator_t *this = THIS; glusterd_conf_t *conf = NULL; gf_timer_t *mgmt_lock_timer = NULL; char *key = NULL; int keylen; int32_t ret = -1; conf = this->private; GF_VALIDATE_OR_GOTO(this->name, conf, out); GF_ASSERT(NULL != data); key = (char *)data; keylen = strlen(key); dict_deln(conf->mgmt_v3_lock, key, keylen); #ifdef DEBUG char bt_key[PATH_MAX] = ""; int bt_key_len = 0; bt_key_len = snprintf(bt_key, PATH_MAX, "debug.last-success-bt-%s", key); if (bt_key_len != SLEN("debug.last-success-bt-") + keylen) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_CREATE_KEY_FAIL, "Unable to create backtrace " "key"); goto out; } dict_deln(conf->mgmt_v3_lock, bt_key, bt_key_len); #endif ret = dict_get_bin(conf->mgmt_v3_lock_timer, key, (void **)&mgmt_lock_timer); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Unable to get lock owner in mgmt_v3 lock"); } out: if (mgmt_lock_timer) { GF_ASSERT(mgmt_lock_timer->xl && mgmt_lock_timer->xl->ctx); GF_FREE(mgmt_lock_timer->data); gf_timer_call_cancel(mgmt_lock_timer->xl->ctx, mgmt_lock_timer); #ifdef DEBUG dict_deln(conf->mgmt_v3_lock_timer, bt_key, bt_key_len); #endif gf_log(this->name, GF_LOG_INFO, "unlock timer is cancelled for volume_type" " %s", key); } } int32_t glusterd_mgmt_v3_unlock(const char *name, uuid_t uuid, char *type) { char key[PATH_MAX] = ""; char key_dup[PATH_MAX] = ""; int keylen; int32_t ret = -1; gf_boolean_t is_valid = _gf_true; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; gf_timer_t *mgmt_lock_timer = NULL; uuid_t owner = {0}; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); if (!name || !type) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "name is null."); ret = -1; goto out; } is_valid = glusterd_mgmt_v3_is_type_valid(type); if (is_valid != _gf_true) { gf_msg_callingfn(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "Invalid entity. Cannot perform unlocking " "operation on %s types", type); ret = -1; goto out; } keylen = snprintf(key, sizeof(key), "%s_%s", name, type); if (keylen != strlen(name) + 1 + strlen(type)) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_CREATE_KEY_FAIL, "Unable to create key"); ret = -1; goto out; } gf_msg_debug(this->name, 0, "Trying to release lock of %s %s for %s as %s", type, name, uuid_utoa(uuid), key); ret = glusterd_get_mgmt_v3_lock_owner(key, &owner); if (ret) { gf_msg_debug(this->name, 0, "Unable to get mgmt_v3 lock owner"); goto out; } if (gf_uuid_is_null(owner)) { gf_msg_callingfn(this->name, GF_LOG_WARNING, 0, GD_MSG_LOCK_NOT_HELD, "Lock for %s %s not held", type, name); ret = -1; goto out; } ret = gf_uuid_compare(uuid, owner); if (ret) { gf_msg_callingfn(this->name, GF_LOG_WARNING, 0, GD_MSG_LOCK_OWNER_MISMATCH, "Lock owner mismatch. " "Lock for %s %s held by %s", type, name, uuid_utoa(owner)); goto out; } /* Removing the mgmt_v3 lock from the global list */ dict_deln(priv->mgmt_v3_lock, key, keylen); ret = dict_get_bin(priv->mgmt_v3_lock_timer, key, (void **)&mgmt_lock_timer); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Unable to get mgmt lock key in mgmt_v3 lock"); goto out; } (void)snprintf(key_dup, sizeof(key_dup), "%s", key); #ifdef DEBUG /* Remove the backtrace key as well */ ret = snprintf(key, sizeof(key), "debug.last-success-bt-%s", key_dup); if (ret != SLEN("debug.last-success-bt-") + keylen) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_CREATE_KEY_FAIL, "Unable to create backtrace " "key"); ret = -1; goto out; } dict_deln(priv->mgmt_v3_lock, key, ret); #endif gf_msg_debug(this->name, 0, "Lock for %s %s successfully released", type, name); /* Release owner reference which was held during lock. */ if (mgmt_lock_timer) { GF_ASSERT(mgmt_lock_timer->xl && mgmt_lock_timer->xl->ctx); GF_FREE(mgmt_lock_timer->data); gf_timer_call_cancel(mgmt_lock_timer->xl->ctx, mgmt_lock_timer); dict_deln(priv->mgmt_v3_lock_timer, key_dup, keylen); } ret = glusterd_volinfo_find(name, &volinfo); if (volinfo && volinfo->stage_deleted) { /* this indicates a volume still exists and the volume delete * operation has failed in some of the phases, need to ensure * stage_deleted flag is set back to false */ volinfo->stage_deleted = _gf_false; gf_log(this->name, GF_LOG_INFO, "Volume %s still exist, setting " "stage deleted flag to false for the volume", volinfo->volname); } ret = 0; out: gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-bitd-svc.h0000644000000000000000000000013214522202451025153 xustar000000000000000030 mtime=1699284265.705027546 30 atime=1699284265.705027546 30 ctime=1699284306.581150664 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-bitd-svc.h0000664000175100017510000000140214522202451025427 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GLUSTERD_BITD_SVC_H_ #define _GLUSTERD_BITD_SVC_H_ #include "glusterd-svc-mgmt.h" #define bitd_svc_name "bitd" void glusterd_bitdsvc_build(glusterd_svc_t *svc); int glusterd_bitdsvc_init(glusterd_svc_t *svc); int glusterd_bitdsvc_manager(glusterd_svc_t *svc, void *data, int flags); int glusterd_bitdsvc_stop(glusterd_svc_t *svc, int sig); int glusterd_bitdsvc_reconfigure(void); #endif glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-conn-helper.c0000644000000000000000000000013214522202451025645 xustar000000000000000030 mtime=1699284265.707027552 30 atime=1699284265.707027552 30 ctime=1699284306.645150857 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-conn-helper.c0000664000175100017510000000113714522202451026126 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "glusterd-conn-mgmt.h" #include "glusterd-svc-mgmt.h" #define _LGPL_SOURCE #include glusterd_svc_t * glusterd_conn_get_svc_object(glusterd_conn_t *conn) { return cds_list_entry(conn, glusterd_svc_t, conn); } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-sm.c0000644000000000000000000000013214522202451024052 xustar000000000000000030 mtime=1699284265.725027606 30 atime=1699284265.725027606 30 ctime=1699284306.597150712 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-sm.c0000664000175100017510000015053414522202451024341 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include #include #include "fnmatch.h" #include #include #include "glusterd-messages.h" #include #include #include #include "glusterd-sm.h" #include "glusterd-op-sm.h" #include "glusterd-utils.h" #include "glusterd-store.h" #include "glusterd-svc-helper.h" #include "glusterd-snapshot-utils.h" #include "glusterd-server-quorum.h" #include "glusterd-gfproxyd-svc-helper.h" char local_node_hostname[PATH_MAX] = { 0, }; static struct cds_list_head gd_friend_sm_queue; static char *glusterd_friend_sm_state_names[] = { "Establishing Connection", "Probe Sent to Peer", "Probe Received from Peer", "Peer in Cluster", "Accepted peer request", "Sent and Received peer request", "Peer Rejected", "Peer detach in progress", "Probe Received from peer", "Connected to Peer", "Peer is connected and Accepted", "Invalid State"}; static char *glusterd_friend_sm_event_names[] = { "GD_FRIEND_EVENT_NONE", "GD_FRIEND_EVENT_PROBE", "GD_FRIEND_EVENT_INIT_FRIEND_REQ", "GD_FRIEND_EVENT_RCVD_ACC", "GD_FRIEND_EVENT_LOCAL_ACC", "GD_FRIEND_EVENT_RCVD_RJT", "GD_FRIEND_EVENT_LOCAL_RJT", "GD_FRIEND_EVENT_RCVD_FRIEND_REQ", "GD_FRIEND_EVENT_INIT_REMOVE_FRIEND", "GD_FRIEND_EVENT_RCVD_REMOVE_FRIEND", "GD_FRIEND_EVENT_REMOVE_FRIEND", "GD_FRIEND_EVENT_CONNECTED", "GD_FRIEND_EVENT_NEW_NAME", "GD_FRIEND_EVENT_MAX"}; char * glusterd_friend_sm_state_name_get(int state) { if (state < 0 || state >= GD_FRIEND_STATE_MAX) return glusterd_friend_sm_state_names[GD_FRIEND_STATE_MAX]; return glusterd_friend_sm_state_names[state]; } char * glusterd_friend_sm_event_name_get(int event) { if (event < 0 || event >= GD_FRIEND_EVENT_MAX) return glusterd_friend_sm_event_names[GD_FRIEND_EVENT_MAX]; return glusterd_friend_sm_event_names[event]; } void glusterd_destroy_probe_ctx(glusterd_probe_ctx_t *ctx) { if (!ctx) return; GF_FREE(ctx->hostname); GF_FREE(ctx); } void glusterd_destroy_friend_req_ctx(glusterd_friend_req_ctx_t *ctx) { if (!ctx) return; if (ctx->vols) dict_unref(ctx->vols); if (ctx->peer_ver) dict_unref(ctx->peer_ver); GF_FREE(ctx->hostname); GF_FREE(ctx); } void glusterd_destroy_friend_update_ctx(glusterd_friend_update_ctx_t *ctx) { if (!ctx) return; GF_FREE(ctx->hostname); GF_FREE(ctx); } int glusterd_broadcast_friend_delete(char *hostname, uuid_t uuid) { int ret = 0; rpc_clnt_procedure_t *proc = NULL; xlator_t *this = THIS; glusterd_friend_update_ctx_t ctx = { {0}, }; glusterd_peerinfo_t *peerinfo = NULL; glusterd_conf_t *priv = NULL; dict_t *friends = NULL; char key[64] = { 0, }; int keylen; int32_t count = 0; priv = this->private; GF_ASSERT(priv); ctx.hostname = hostname; ctx.op = GD_FRIEND_UPDATE_DEL; friends = dict_new(); if (!friends) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } keylen = snprintf(key, sizeof(key), "op"); ret = dict_set_int32n(friends, key, keylen, ctx.op); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } keylen = snprintf(key, sizeof(key), "hostname"); ret = dict_set_strn(friends, key, keylen, hostname); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } ret = dict_set_int32_sizen(friends, "count", count); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto out; } RCU_READ_LOCK; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { if (!peerinfo->connected || !peerinfo->peer) continue; /* Setting a direct reference to peerinfo in the dict is okay as * it is only going to be used within this read critical section * (in glusterd_rpc_friend_update) */ ret = dict_set_static_ptr(friends, "peerinfo", peerinfo); if (ret) { RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); goto out; } proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_UPDATE]; if (proc->fn) { ret = proc->fn(NULL, this, friends); } } RCU_READ_UNLOCK; out: if (friends) dict_unref(friends); gf_msg_debug("glusterd", 0, "Returning with %d", ret); return ret; } static int glusterd_ac_none(glusterd_friend_sm_event_t *event, void *ctx) { int ret = 0; gf_msg_debug("glusterd", 0, "Returning with %d", ret); return ret; } static int glusterd_ac_error(glusterd_friend_sm_event_t *event, void *ctx) { int ret = 0; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_AC_ERROR, "Received event %d ", event->event); return ret; } static int glusterd_ac_reverse_probe_begin(glusterd_friend_sm_event_t *event, void *ctx) { int ret = 0; glusterd_peerinfo_t *peerinfo = NULL; glusterd_friend_sm_event_t *new_event = NULL; glusterd_probe_ctx_t *new_ev_ctx = NULL; GF_ASSERT(event); GF_ASSERT(ctx); new_ev_ctx = GF_CALLOC(1, sizeof(*new_ev_ctx), gf_gld_mt_probe_ctx_t); RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { RCU_READ_UNLOCK; ret = -1; gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); goto out; } ret = glusterd_friend_sm_new_event(GD_FRIEND_EVENT_PROBE, &new_event); if (ret) { RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_EVENT_NEW_GET_FAIL, "Unable to get new new_event"); ret = -1; goto out; } if (!new_ev_ctx) { RCU_READ_UNLOCK; ret = -1; goto out; } new_ev_ctx->hostname = gf_strdup(peerinfo->hostname); new_ev_ctx->port = peerinfo->port; new_ev_ctx->req = NULL; new_event->peername = gf_strdup(peerinfo->hostname); gf_uuid_copy(new_event->peerid, peerinfo->uuid); new_event->ctx = new_ev_ctx; ret = glusterd_friend_sm_inject_event(new_event); RCU_READ_UNLOCK; if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_EVENT_INJECT_FAIL, "Unable to inject new_event %d, " "ret = %d", new_event->event, ret); } out: if (ret) { if (new_event) GF_FREE(new_event->peername); GF_FREE(new_event); if (new_ev_ctx) GF_FREE(new_ev_ctx->hostname); GF_FREE(new_ev_ctx); } gf_msg_debug("glusterd", 0, "returning with %d", ret); return ret; } static int glusterd_ac_friend_add(glusterd_friend_sm_event_t *event, void *ctx) { int ret = 0; glusterd_peerinfo_t *peerinfo = NULL; rpc_clnt_procedure_t *proc = NULL; call_frame_t *frame = NULL; glusterd_conf_t *conf = NULL; xlator_t *this = THIS; GF_ASSERT(event); conf = this->private; GF_ASSERT(conf); RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); goto out; } if (!peerinfo->peer) { RCU_READ_UNLOCK; goto out; } proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_ADD]; if (proc->fn) { frame = create_frame(this, this->ctx->pool); if (!frame) { RCU_READ_UNLOCK; goto out; } frame->local = ctx; ret = proc->fn(frame, this, event); } RCU_READ_UNLOCK; out: if (ret && frame) STACK_DESTROY(frame->root); gf_msg_debug("glusterd", 0, "Returning with %d", ret); return ret; } static int glusterd_ac_friend_probe(glusterd_friend_sm_event_t *event, void *ctx) { int ret = -1; rpc_clnt_procedure_t *proc = NULL; call_frame_t *frame = NULL; glusterd_conf_t *conf = NULL; xlator_t *this = THIS; glusterd_probe_ctx_t *probe_ctx = NULL; glusterd_peerinfo_t *peerinfo = NULL; dict_t *dict = NULL; GF_ASSERT(ctx); probe_ctx = ctx; conf = this->private; GF_ASSERT(conf); RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(NULL, probe_ctx->hostname); if (peerinfo == NULL) { // We should not reach this state ideally gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_PEER_NOT_FOUND, NULL); ret = -1; goto unlock; } if (!peerinfo->peer) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_PEER_ADDRESS_GET_FAIL, NULL); goto unlock; } proc = &peerinfo->peer->proctable[GLUSTERD_PROBE_QUERY]; if (proc->fn) { frame = create_frame(this, this->ctx->pool); if (!frame) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_FRAME_CREATE_FAIL, NULL); goto unlock; } frame->local = ctx; dict = dict_new(); if (!dict) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); goto unlock; } ret = dict_set_str_sizen(dict, "hostname", probe_ctx->hostname); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=hostname", NULL); goto unlock; } ret = dict_set_int32_sizen(dict, "port", probe_ctx->port); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=port", NULL); goto unlock; } /* The peerinfo reference being set here is going to be used * only within this critical section, in glusterd_rpc_probe * (ie. proc->fn). */ ret = dict_set_static_ptr(dict, "peerinfo", peerinfo); if (ret) { RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); goto out; } ret = proc->fn(frame, this, dict); if (ret) goto unlock; } unlock: RCU_READ_UNLOCK; out: if (dict) dict_unref(dict); gf_msg_debug("glusterd", 0, "Returning with %d", ret); if (ret && frame) STACK_DESTROY(frame->root); return ret; } static int glusterd_ac_send_friend_remove_req(glusterd_friend_sm_event_t *event, void *data) { int ret = 0; glusterd_peerinfo_t *peerinfo = NULL; rpc_clnt_procedure_t *proc = NULL; call_frame_t *frame = NULL; glusterd_conf_t *conf = NULL; xlator_t *this = THIS; glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE; glusterd_probe_ctx_t *ctx = NULL; glusterd_friend_sm_event_t *new_event = NULL; GF_ASSERT(event); conf = this->private; GF_ASSERT(conf); RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { RCU_READ_UNLOCK; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); goto out; } ctx = event->ctx; if (!peerinfo->connected) { event_type = GD_FRIEND_EVENT_REMOVE_FRIEND; ret = glusterd_friend_sm_new_event(event_type, &new_event); if (!ret) { new_event->peername = peerinfo->hostname; gf_uuid_copy(new_event->peerid, peerinfo->uuid); ret = glusterd_friend_sm_inject_event(new_event); } else { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_EVENT_NEW_GET_FAIL, "Unable to get event"); } if (ctx) { ret = glusterd_xfer_cli_deprobe_resp(ctx->req, ret, 0, NULL, ctx->hostname, ctx->dict); glusterd_broadcast_friend_delete(ctx->hostname, NULL); glusterd_destroy_probe_ctx(ctx); } goto unlock; } if (!peerinfo->peer) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_PEER_ADDRESS_GET_FAIL, NULL); goto unlock; } proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_REMOVE]; if (proc->fn) { frame = create_frame(this, this->ctx->pool); if (!frame) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_FRAME_CREATE_FAIL, NULL); goto unlock; } frame->local = data; ret = proc->fn(frame, this, event); } unlock: RCU_READ_UNLOCK; out: gf_msg_debug("glusterd", 0, "Returning with %d", ret); if (ret && frame) STACK_DESTROY(frame->root); return ret; } static gf_boolean_t glusterd_should_update_peer(glusterd_peerinfo_t *peerinfo, glusterd_peerinfo_t *cur_peerinfo) { if ((peerinfo == cur_peerinfo) || (peerinfo->state == GD_FRIEND_STATE_BEFRIENDED)) return _gf_true; return _gf_false; } static int glusterd_ac_send_friend_update(glusterd_friend_sm_event_t *event, void *ctx) { int ret = 0; glusterd_peerinfo_t *cur_peerinfo = NULL; glusterd_peerinfo_t *peerinfo = NULL; rpc_clnt_procedure_t *proc = NULL; xlator_t *this = THIS; glusterd_friend_update_ctx_t ev_ctx = {{0}}; glusterd_conf_t *priv = NULL; dict_t *friends = NULL; char key[64] = { 0, }; int keylen; int32_t count = 0; GF_ASSERT(event); priv = this->private; GF_ASSERT(priv); keylen = snprintf(key, sizeof(key), "op"); friends = dict_new(); RCU_READ_LOCK; cur_peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!cur_peerinfo) { RCU_READ_UNLOCK; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); goto out; } if (!friends) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); goto unlock; } ev_ctx.op = GD_FRIEND_UPDATE_ADD; ret = dict_set_int32n(friends, key, keylen, ev_ctx.op); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto unlock; } cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { if (!glusterd_should_update_peer(peerinfo, cur_peerinfo)) continue; count++; snprintf(key, sizeof(key), "friend%d", count); ret = gd_add_friend_to_dict(peerinfo, friends, key); if (ret) goto unlock; } ret = dict_set_int32_sizen(friends, "count", count); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=count", NULL); goto unlock; } cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { if (!peerinfo->connected || !peerinfo->peer) continue; if (!glusterd_should_update_peer(peerinfo, cur_peerinfo)) continue; ret = dict_set_static_ptr(friends, "peerinfo", peerinfo); if (ret) { RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); goto out; } proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_UPDATE]; if (proc->fn) { ret = proc->fn(NULL, this, friends); } } unlock: RCU_READ_UNLOCK; out: if (friends) dict_unref(friends); gf_msg_debug("glusterd", 0, "Returning with %d", ret); return ret; } /* ac_update_friend only sends friend update to the friend that caused this * event to happen */ static int glusterd_ac_update_friend(glusterd_friend_sm_event_t *event, void *ctx) { int ret = 0; glusterd_peerinfo_t *cur_peerinfo = NULL; glusterd_peerinfo_t *peerinfo = NULL; rpc_clnt_procedure_t *proc = NULL; xlator_t *this = THIS; glusterd_friend_update_ctx_t ev_ctx = {{0}}; glusterd_conf_t *priv = NULL; dict_t *friends = NULL; char key[64] = { 0, }; int keylen; int32_t count = 0; GF_ASSERT(event); priv = this->private; GF_ASSERT(priv); friends = dict_new(); keylen = snprintf(key, sizeof(key), "op"); RCU_READ_LOCK; cur_peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!cur_peerinfo) { RCU_READ_UNLOCK; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); goto out; } /* Bail out early if peer is not connected. * We cannot send requests to the peer until we have established our * client connection to it. */ if (!cur_peerinfo->connected || !cur_peerinfo->peer) { ret = 0; goto unlock; } if (!friends) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } ev_ctx.op = GD_FRIEND_UPDATE_ADD; ret = dict_set_int32n(friends, key, keylen, ev_ctx.op); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=%s", key, NULL); goto unlock; } cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { if (!glusterd_should_update_peer(peerinfo, cur_peerinfo)) continue; count++; snprintf(key, sizeof(key), "friend%d", count); ret = gd_add_friend_to_dict(peerinfo, friends, key); if (ret) goto unlock; } ret = dict_set_int32_sizen(friends, "count", count); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED, "Key=count", NULL); goto unlock; } ret = dict_set_static_ptr(friends, "peerinfo", cur_peerinfo); if (ret) { RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); goto out; } proc = &cur_peerinfo->peer->proctable[GLUSTERD_FRIEND_UPDATE]; if (proc->fn) ret = proc->fn(NULL, this, friends); gf_msg_debug(this->name, 0, "Returning with %d", ret); unlock: RCU_READ_UNLOCK; out: if (friends) dict_unref(friends); return ret; } /* Clean up stale volumes on the peer being detached. The volumes which have * bricks on other peers are stale with respect to the detached peer. */ static void glusterd_peer_detach_cleanup(glusterd_conf_t *priv) { int ret = -1; glusterd_volinfo_t *volinfo = NULL; glusterd_volinfo_t *tmp_volinfo = NULL; glusterd_svc_t *svc = NULL; GF_ASSERT(priv); cds_list_for_each_entry_safe(volinfo, tmp_volinfo, &priv->volumes, vol_list) { /* The peer detach checks make sure that, at this point in the * detach process, there are only volumes contained completely * within or completely outside the detached peer. * The only stale volumes at this point are the ones * completely outside the peer and can be safely deleted. */ if (!glusterd_friend_contains_vol_bricks(volinfo, MY_UUID)) { gf_msg(THIS->name, GF_LOG_INFO, 0, GD_MSG_STALE_VOL_DELETE_INFO, "Deleting stale volume %s", volinfo->volname); /*Stop snapd daemon service if snapd daemon is running*/ if (!volinfo->is_snap_volume) { svc = &(volinfo->snapd.svc); ret = svc->stop(svc, SIGTERM); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_SVC_STOP_FAIL, "Failed " "to stop snapd daemon service"); } } if (glusterd_is_shd_compatible_volume(volinfo)) { svc = &(volinfo->shd.svc); ret = svc->stop(svc, SIGTERM); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_SVC_STOP_FAIL, "Failed " "to stop shd daemon service"); } } if (glusterd_is_gfproxyd_enabled(volinfo)) { svc = &(volinfo->gfproxyd.svc); ret = svc->stop(svc, SIGTERM); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_SVC_STOP_FAIL, "Failed " "to stop gfproxyd daemon service"); } } ret = glusterd_cleanup_snaps_for_volume(volinfo); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_VOL_DELETE_FAIL, "Error deleting snapshots for volume %s", volinfo->volname); } ret = glusterd_delete_volume(volinfo); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_STALE_VOL_REMOVE_FAIL, "Error deleting stale volume"); } } } /*Reconfigure all daemon services upon peer detach*/ ret = glusterd_svcs_reconfigure(NULL); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_SVC_STOP_FAIL, "Failed to reconfigure all daemon services."); } } static int glusterd_ac_handle_friend_remove_req(glusterd_friend_sm_event_t *event, void *ctx) { int ret = 0; glusterd_peerinfo_t *peerinfo = NULL; glusterd_friend_req_ctx_t *ev_ctx = NULL; glusterd_friend_sm_event_t *new_event = NULL; glusterd_conf_t *priv = NULL; GF_ASSERT(ctx); ev_ctx = ctx; priv = THIS->private; GF_ASSERT(priv); ret = glusterd_xfer_friend_remove_resp(ev_ctx->req, ev_ctx->hostname, ev_ctx->port); RCU_READ_LOCK; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { ret = glusterd_friend_sm_new_event(GD_FRIEND_EVENT_REMOVE_FRIEND, &new_event); if (ret) { RCU_READ_UNLOCK; goto out; } new_event->peername = gf_strdup(peerinfo->hostname); gf_uuid_copy(new_event->peerid, peerinfo->uuid); ret = glusterd_friend_sm_inject_event(new_event); if (ret) { RCU_READ_UNLOCK; goto out; } new_event = NULL; } RCU_READ_UNLOCK; glusterd_peer_detach_cleanup(priv); out: if (new_event) GF_FREE(new_event->peername); GF_FREE(new_event); gf_msg_debug(THIS->name, 0, "Returning with %d", ret); return ret; } static int glusterd_ac_friend_remove(glusterd_friend_sm_event_t *event, void *ctx) { int ret = -1; glusterd_peerinfo_t *peerinfo = NULL; GF_ASSERT(event); RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { RCU_READ_UNLOCK; gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); goto out; } ret = glusterd_friend_remove_cleanup_vols(peerinfo->uuid); RCU_READ_UNLOCK; if (ret) gf_msg(THIS->name, GF_LOG_WARNING, 0, GD_MSG_VOL_CLEANUP_FAIL, "Volumes cleanup failed"); /* Exiting read critical section as glusterd_peerinfo_cleanup calls * synchronize_rcu before freeing the peerinfo */ ret = glusterd_peerinfo_cleanup(peerinfo); if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_PEER_DETACH_CLEANUP_FAIL, "Cleanup returned: %d", ret); } out: return 0; } /*static int glusterd_ac_none (void *ctx) { int ret = 0; gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); return ret; }*/ static int glusterd_ac_handle_friend_add_req(glusterd_friend_sm_event_t *event, void *ctx) { int ret = 0; uuid_t uuid; glusterd_peerinfo_t *peerinfo = NULL; glusterd_friend_req_ctx_t *ev_ctx = NULL; glusterd_friend_update_ctx_t *new_ev_ctx = NULL; glusterd_friend_sm_event_t *new_event = NULL; glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE; glusterd_conf_t *conf = NULL; int status = 0; int32_t op_ret = -1; int32_t op_errno = 0; xlator_t *this = THIS; char *hostname = NULL; GF_ASSERT(ctx); ev_ctx = ctx; gf_uuid_copy(uuid, ev_ctx->uuid); RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { RCU_READ_UNLOCK; ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); goto out; } /* TODO: How do you do an atomic copy of uuid_t */ /* TODO: Updating within a read-critical section is also invalid * Update properly with updater synchronization */ gf_uuid_copy(peerinfo->uuid, ev_ctx->uuid); RCU_READ_UNLOCK; conf = this->private; GF_ASSERT(conf); /* Passing the peername from the event. glusterd_compare_friend_data * updates volumes and will use synchronize_rcu. If we were to pass * peerinfo->hostname, we would have to do it under a read critical * section which would lead to a deadlock */ // Build comparison logic here. pthread_mutex_lock(&conf->import_volumes); { ret = glusterd_compare_friend_data(ev_ctx->vols, ev_ctx->peer_ver, &status, event->peername); if (ret) { pthread_mutex_unlock(&conf->import_volumes); goto out; } if (GLUSTERD_VOL_COMP_RJT != status) { event_type = GD_FRIEND_EVENT_LOCAL_ACC; op_ret = 0; } else { event_type = GD_FRIEND_EVENT_LOCAL_RJT; op_errno = GF_PROBE_VOLUME_CONFLICT; op_ret = -1; } /* Compare missed_snapshot list with the peer * * if volume comparison is successful */ if ((op_ret == 0) && (conf->op_version >= GD_OP_VERSION_3_6_0)) { ret = glusterd_import_friend_missed_snap_list(ev_ctx->vols); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MISSED_SNAP_LIST_STORE_FAIL, "Failed to import peer's " "missed_snaps_list."); event_type = GD_FRIEND_EVENT_LOCAL_RJT; op_errno = GF_PROBE_MISSED_SNAP_CONFLICT; op_ret = -1; } /* glusterd_compare_friend_snapshots and functions only require * a peers hostname and uuid. It also does updates, which * require use of synchronize_rcu. So we pass the hostname and * id from the event instead of the peerinfo object to prevent * deadlocks as above. */ ret = glusterd_compare_friend_snapshots( ev_ctx->vols, event->peername, event->peerid); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_COMPARE_CONFLICT, "Conflict in comparing peer's snapshots"); event_type = GD_FRIEND_EVENT_LOCAL_RJT; op_errno = GF_PROBE_SNAP_CONFLICT; op_ret = -1; } } } pthread_mutex_unlock(&conf->import_volumes); ret = glusterd_friend_sm_new_event(event_type, &new_event); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY, "Out of Memory"); goto out; } new_event->peername = gf_strdup(event->peername); gf_uuid_copy(new_event->peerid, event->peerid); new_ev_ctx = GF_CALLOC(1, sizeof(*new_ev_ctx), gf_gld_mt_friend_update_ctx_t); if (!new_ev_ctx) { ret = -1; goto out; } gf_uuid_copy(new_ev_ctx->uuid, ev_ctx->uuid); new_ev_ctx->hostname = gf_strdup(ev_ctx->hostname); new_ev_ctx->op = GD_FRIEND_UPDATE_ADD; new_event->ctx = new_ev_ctx; ret = dict_get_str(ev_ctx->vols, "hostname_in_cluster", &hostname); if (ret || !hostname) { gf_msg_debug(this->name, 0, "Unable to fetch local hostname from peer"); } else if (snprintf(local_node_hostname, sizeof(local_node_hostname), "%s", hostname) >= sizeof(local_node_hostname)) { gf_msg_debug(this->name, 0, "local_node_hostname truncated"); ret = -1; goto out; } glusterd_friend_sm_inject_event(new_event); new_event = NULL; ret = glusterd_xfer_friend_add_resp(ev_ctx->req, ev_ctx->hostname, event->peername, ev_ctx->port, op_ret, op_errno); out: if (new_event) GF_FREE(new_event->peername); GF_FREE(new_event); gf_msg_debug("glusterd", 0, "Returning with %d", ret); return ret; } static int glusterd_friend_sm_transition_state(uuid_t peerid, char *peername, glusterd_sm_t *state, glusterd_friend_sm_event_type_t event_type) { int ret = -1; glusterd_peerinfo_t *peerinfo = NULL; GF_ASSERT(state); GF_ASSERT(peername); RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(peerid, peername); if (!peerinfo) { gf_smsg(THIS->name, GF_LOG_ERROR, errno, GD_MSG_PEER_NOT_FOUND, NULL); goto out; } (void)glusterd_sm_tr_log_transition_add(&peerinfo->sm_log, peerinfo->state, state[event_type].next_state, event_type); uatomic_set(&peerinfo->state, state[event_type].next_state); ret = 0; out: RCU_READ_UNLOCK; return ret; } glusterd_sm_t glusterd_state_default[] = { {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_probe}, // EV_PROBE {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_friend_add}, // EV_INIT_FRIEND_REQ {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_handle_friend_add_req}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, // EV_INIT_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_probe}, // EVENT_CONNECTED {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_probe_rcvd[] = { {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, // EV_PROBE {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, // EV_INIT_FRIEND_REQ {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_handle_friend_add_req}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, // EV_INIT_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EVENT_CONNECTED {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_connected_rcvd[] = { {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EV_PROBE {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EV_INIT_FRIEND_REQ {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_reverse_probe_begin}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_handle_friend_add_req}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, // EV_INIT_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EVENT_CONNECTED {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_connected_accepted[] = { {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_friend_probe}, // EV_PROBE {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_friend_add}, // EV_INIT_FRIEND_REQ {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, // EV_INIT_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, // EVENT_CONNECTED {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_req_sent[] = { {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_NONE, {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_PROBE, {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_INIT_FRIEND_REQ, {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_handle_friend_add_req}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_send_friend_remove_req}, // EVENT_INIT_REMOVE_FRIEND, {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_CONNECTED {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_req_rcvd[] = { {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, // EVENT_NONE, {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, // EVENT_PROBE, {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_INIT_FRIEND_REQ, {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, // EVENT_INIT_REMOVE_FRIEND, {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EVENT_CONNECTED {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_befriended[] = { {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, // EVENT_NONE, {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, // EVENT_PROBE, {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, // EVENT_INIT_FRIEND_REQ, {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_update_friend}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_update_friend}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_handle_friend_add_req}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_send_friend_remove_req}, // EVENT_INIT_REMOVE_FRIEND, {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_friend_add}, // EVENT_CONNECTED {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, // EVENT_NEW_NAME {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_req_sent_rcvd[] = { {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_NONE, {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_PROBE, {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_INIT_FRIEND_REQ, {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_send_friend_remove_req}, // EVENT_INIT_REMOVE_FRIEND, {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_CONNECTED {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_rejected[] = { {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_NONE, {GD_FRIEND_STATE_REJECTED, glusterd_ac_friend_probe}, // EVENT_PROBE, {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_friend_add}, // EVENT_INIT_FRIEND_REQ, {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_handle_friend_add_req}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, // EVENT_INIT_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_REJECTED, glusterd_ac_friend_add}, // EVENT_CONNECTED {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_req_accepted[] = { {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, // EVENT_NONE, {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, // EVENT_PROBE, {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, // EVENT_INIT_FRIEND_REQ, {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_handle_friend_add_req}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_send_friend_remove_req}, // EVENT_INIT_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_reverse_probe_begin}, // EVENT_CONNECTED {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t glusterd_state_unfriend_sent[] = { {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, // EVENT_NONE, {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_error}, // EVENT_PROBE, {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, // EVENT_INIT_FRIEND_REQ, {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, // EVENT_RCVD_ACC {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, // EVENT_RCVD_LOCAL_ACC {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_error}, // EVENT_RCVD_RJT {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_error}, // EVENT_RCVD_LOCAL_RJT {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_error}, // EVENT_RCV_FRIEND_REQ {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, // EVENT_INIT_REMOVE_FRIEND {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, // EVENT_RCVD_REMOVE_FRIEND {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, // EVENT_REMOVE_FRIEND {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, // EVENT_CONNECTED {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, // EVENT_NEW_NAME {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, // EVENT_MAX }; glusterd_sm_t *glusterd_friend_state_table[] = { glusterd_state_default, glusterd_state_req_sent, glusterd_state_req_rcvd, glusterd_state_befriended, glusterd_state_req_accepted, glusterd_state_req_sent_rcvd, glusterd_state_rejected, glusterd_state_unfriend_sent, glusterd_state_probe_rcvd, glusterd_state_connected_rcvd, glusterd_state_connected_accepted}; int glusterd_friend_sm_new_event(glusterd_friend_sm_event_type_t event_type, glusterd_friend_sm_event_t **new_event) { glusterd_friend_sm_event_t *event = NULL; GF_ASSERT(new_event); GF_ASSERT(GD_FRIEND_EVENT_NONE <= event_type && GD_FRIEND_EVENT_MAX > event_type); event = GF_CALLOC(1, sizeof(*event), gf_gld_mt_friend_sm_event_t); if (!event) return -1; *new_event = event; event->event = event_type; CDS_INIT_LIST_HEAD(&event->list); return 0; } int glusterd_friend_sm_inject_event(glusterd_friend_sm_event_t *event) { GF_ASSERT(event); gf_msg_debug("glusterd", 0, "Enqueue event: '%s'", glusterd_friend_sm_event_name_get(event->event)); cds_list_add_tail(&event->list, &gd_friend_sm_queue); return 0; } void glusterd_destroy_friend_event_context(glusterd_friend_sm_event_t *event) { if (!event) return; switch (event->event) { case GD_FRIEND_EVENT_RCVD_FRIEND_REQ: case GD_FRIEND_EVENT_RCVD_REMOVE_FRIEND: glusterd_destroy_friend_req_ctx(event->ctx); break; case GD_FRIEND_EVENT_LOCAL_ACC: case GD_FRIEND_EVENT_LOCAL_RJT: case GD_FRIEND_EVENT_RCVD_ACC: case GD_FRIEND_EVENT_RCVD_RJT: glusterd_destroy_friend_update_ctx(event->ctx); break; default: break; } } gf_boolean_t gd_does_peer_affect_quorum(glusterd_friend_sm_state_t old_state, glusterd_friend_sm_event_type_t event_type, glusterd_peerinfo_t *peerinfo) { gf_boolean_t affects = _gf_false; // When glusterd comes up with friends in BEFRIENDED state in store, // wait until compare-data happens. if ((old_state == GD_FRIEND_STATE_BEFRIENDED) && (event_type != GD_FRIEND_EVENT_RCVD_ACC) && (event_type != GD_FRIEND_EVENT_LOCAL_ACC)) goto out; if ((peerinfo->state == GD_FRIEND_STATE_BEFRIENDED) && peerinfo->connected) { affects = _gf_true; } out: return affects; } int glusterd_friend_sm(void) { glusterd_friend_sm_event_t *event = NULL; glusterd_friend_sm_event_t *tmp = NULL; int ret = -1; glusterd_friend_sm_ac_fn handler = NULL; glusterd_sm_t *state = NULL; glusterd_peerinfo_t *peerinfo = NULL; glusterd_friend_sm_event_type_t event_type = 0; gf_boolean_t is_await_conn = _gf_false; gf_boolean_t quorum_action = _gf_false; glusterd_friend_sm_state_t old_state = GD_FRIEND_STATE_DEFAULT; xlator_t *this = THIS; glusterd_conf_t *priv = NULL; priv = this->private; GF_ASSERT(priv); while (!cds_list_empty(&gd_friend_sm_queue)) { cds_list_for_each_entry_safe(event, tmp, &gd_friend_sm_queue, list) { cds_list_del_init(&event->list); event_type = event->event; RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_CRITICAL, 0, GD_MSG_PEER_NOT_FOUND, "Received" " event %s with empty peer info", glusterd_friend_sm_event_name_get(event_type)); GF_FREE(event); continue; } old_state = peerinfo->state; RCU_READ_UNLOCK; gf_msg_debug("glusterd", 0, "Dequeued event of type: '%s'", glusterd_friend_sm_event_name_get(event_type)); /* Giving up read-critical section here as we only need * the current state to call the handler. * * We cannot continue into the handler in a read * critical section as there are handlers who do * updates, and could cause deadlocks. */ state = glusterd_friend_state_table[old_state]; GF_ASSERT(state); handler = state[event_type].handler; GF_ASSERT(handler); ret = handler(event, event->ctx); if (ret == GLUSTERD_CONNECTION_AWAITED) { is_await_conn = _gf_true; ret = 0; } if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_HANDLER_RETURNED, "handler returned: " "%d", ret); glusterd_destroy_friend_event_context(event); GF_FREE(event); continue; } if ((GD_FRIEND_EVENT_REMOVE_FRIEND == event_type) || (GD_FRIEND_EVENT_INIT_REMOVE_FRIEND == event_type)) { glusterd_destroy_friend_event_context(event); GF_FREE(event); continue; } ret = glusterd_friend_sm_transition_state( event->peerid, event->peername, state, event_type); if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_EVENT_STATE_TRANSITION_FAIL, "Unable to transition" " state from '%s' to '%s' for event '%s'", glusterd_friend_sm_state_name_get(old_state), glusterd_friend_sm_state_name_get( state[event_type].next_state), glusterd_friend_sm_event_name_get(event_type)); goto out; } peerinfo = NULL; /* We need to obtain peerinfo reference once again as we * had exited the read critical section above. */ RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { RCU_READ_UNLOCK; /* A peer can only be deleted as a effect of * this state machine, and two such state * machines can never run at the same time. * So if we cannot find the peerinfo here, * something has gone terribly wrong. */ ret = -1; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Cannot find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); goto out; } if (gd_does_peer_affect_quorum(old_state, event_type, peerinfo)) { peerinfo->quorum_contrib = QUORUM_UP; if (peerinfo->quorum_action) { peerinfo->quorum_action = _gf_false; quorum_action = _gf_true; } } ret = glusterd_store_peerinfo(peerinfo); RCU_READ_UNLOCK; if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEERINFO_CREATE_FAIL, "Failed to store peerinfo"); } glusterd_destroy_friend_event_context(event); GF_FREE(event); if (is_await_conn) break; } if (is_await_conn) break; } ret = 0; out: if (quorum_action) { /* When glusterd is restarted, it needs to wait until the 'friends' view * of the volumes settle, before it starts any of the internal daemons. * * Every friend that was part of the cluster, would send its * cluster-view, 'our' way. For every friend, who belongs to * a partition which has a different cluster-view from our * partition, we may update our cluster-view. For subsequent * friends from that partition would agree with us, if the first * friend wasn't rejected. For every first friend, whom we agreed with, * we would need to start internal daemons/bricks belonging to the * new volumes. * glusterd_spawn_daemons calls functions that are idempotent. ie, * the functions spawn process(es) only if they are not started yet. * * */ synclock_unlock(&priv->big_lock); glusterd_launch_synctask(glusterd_spawn_daemons, NULL); synclock_lock(&priv->big_lock); glusterd_do_quorum_action(); } return ret; } int glusterd_friend_sm_init(void) { CDS_INIT_LIST_HEAD(&gd_friend_sm_queue); return 0; } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-store.h0000644000000000000000000000013214522202451024574 xustar000000000000000030 mtime=1699284265.731027625 30 atime=1699284265.731027625 30 ctime=1699284306.547150561 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-store.h0000664000175100017510000002007014522202451025052 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2006-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GLUSTERD_HA_H_ #define _GLUSTERD_HA_H_ #include #include #include "glusterd.h" typedef enum glusterd_store_ver_ac_ { GLUSTERD_VOLINFO_VER_AC_NONE = 0, GLUSTERD_VOLINFO_VER_AC_INCREMENT = 1, GLUSTERD_VOLINFO_VER_AC_DECREMENT = 2, } glusterd_volinfo_ver_ac_t; #define GLUSTERD_UPGRADE_FILE \ "glusterd.upgrade" /* zero byte file to detect a need for regenerating \ volfiles in container mode */ #define GLUSTERD_VOLUME_DIR_PREFIX "vols" #define GLUSTERD_PEER_DIR_PREFIX "peers" #define GLUSTERD_VOLUME_SNAPD_INFO_FILE "snapd.info" #define GLUSTERD_SNAP_INFO_FILE "info" #define GLUSTERD_BRICK_INFO_DIR "bricks" #define GLUSTERD_NODE_STATE_FILE "node_state.info" #define GLUSTERD_MISSED_SNAPS_LIST_FILE "missed_snaps_list" #define VOLINFO_BUFFER_SIZE 4093 #define GLUSTERD_STORE_UUID_KEY "UUID" #define GLUSTERD_STORE_KEY_VOL_TYPE "type" #define GLUSTERD_STORE_KEY_VOL_COUNT "count" #define GLUSTERD_STORE_KEY_VOL_STATUS "status" #define GLUSTERD_STORE_KEY_VOL_PORT "port" #define GLUSTERD_STORE_KEY_VOL_SUB_COUNT "sub_count" #define GLUSTERD_STORE_KEY_VOL_STRIPE_CNT "stripe_count" #define GLUSTERD_STORE_KEY_VOL_REPLICA_CNT "replica_count" #define GLUSTERD_STORE_KEY_VOL_DISPERSE_CNT "disperse_count" #define GLUSTERD_STORE_KEY_VOL_REDUNDANCY_CNT "redundancy_count" #define GLUSTERD_STORE_KEY_VOL_ARBITER_CNT "arbiter_count" #define GLUSTERD_STORE_KEY_VOL_THIN_ARBITER_CNT "thin_arbiter_count" #define GLUSTERD_STORE_KEY_VOL_BRICK "brick" #define GLUSTERD_STORE_KEY_VOL_TA_BRICK "ta-brick" #define GLUSTERD_STORE_KEY_VOL_VERSION "version" #define GLUSTERD_STORE_KEY_VOL_TRANSPORT "transport-type" #define GLUSTERD_STORE_KEY_VOL_ID "volume-id" #define GLUSTERD_STORE_KEY_VOL_RESTORED_SNAP "restored_from_snap" #define GLUSTERD_STORE_KEY_VOL_RESTORED_SNAPNAME_ID "restored_from_snapname_id" #define GLUSTERD_STORE_KEY_VOL_RESTORED_SNAPNAME "restored_from_snapname" #define GLUSTERD_STORE_KEY_RB_STATUS "rb_status" #define GLUSTERD_STORE_KEY_RB_SRC_BRICK "rb_src" #define GLUSTERD_STORE_KEY_RB_DST_BRICK "rb_dst" #define GLUSTERD_STORE_KEY_RB_DST_PORT "rb_port" #define GLUSTERD_STORE_KEY_VOL_DEFRAG "rebalance_status" #define GLUSTERD_STORE_KEY_VOL_DEFRAG_STATUS "status" #define GLUSTERD_STORE_KEY_DEFRAG_OP "rebalance_op" #define GLUSTERD_STORE_KEY_USERNAME "username" #define GLUSTERD_STORE_KEY_PASSWORD "password" #define GLUSTERD_STORE_KEY_PARENT_VOLNAME "parent_volname" #define GLUSTERD_STORE_KEY_VOL_OP_VERSION "op-version" #define GLUSTERD_STORE_KEY_VOL_CLIENT_OP_VERSION "client-op-version" #define GLUSTERD_STORE_KEY_VOL_QUOTA_VERSION "quota-version" #define GLUSTERD_STORE_KEY_VOL_SNAP_PLUGIN "snap_plugin" #define GLUSTERD_STORE_KEY_SNAP_NAME "name" #define GLUSTERD_STORE_KEY_SNAP_ID "snap-id" #define GLUSTERD_STORE_KEY_SNAP_DESC "desc" #define GLUSTERD_STORE_KEY_SNAP_TIMESTAMP "time-stamp" #define GLUSTERD_STORE_KEY_SNAP_STATUS "status" #define GLUSTERD_STORE_KEY_SNAP_RESTORED "snap-restored" #define GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT "snap-max-hard-limit" #define GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE "auto-delete" #define GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT "snap-max-soft-limit" #define GLUSTERD_STORE_KEY_SNAPD_PORT "snapd-port" #define GLUSTERD_STORE_KEY_SNAP_ACTIVATE "snap-activate-on-create" #define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname" #define GLUSTERD_STORE_KEY_BRICK_PATH "path" #define GLUSTERD_STORE_KEY_BRICK_REAL_PATH "real_path" #define GLUSTERD_STORE_KEY_BRICK_ORIGIN_PATH "origin_path" #define GLUSTERD_STORE_KEY_BRICK_PORT "listen-port" #define GLUSTERD_STORE_KEY_BRICK_RDMA_PORT "rdma.listen-port" #define GLUSTERD_STORE_KEY_BRICK_DECOMMISSIONED "decommissioned" #define GLUSTERD_STORE_KEY_BRICK_VGNAME "vg" #define GLUSTERD_STORE_KEY_BRICK_DEVICE_PATH "device_path" #define GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR "mount_dir" #define GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS "snap-status" #define GLUSTERD_STORE_KEY_BRICK_FSTYPE "fs-type" #define GLUSTERD_STORE_KEY_BRICK_SNAPTYPE "snap-type" #define GLUSTERD_STORE_KEY_BRICK_MNTOPTS "mnt-opts" #define GLUSTERD_STORE_KEY_BRICK_ID "brick-id" #define GLUSTERD_STORE_KEY_BRICK_FSID "brick-fsid" #define GLUSTERD_STORE_KEY_BRICK_UUID "uuid" #define GLUSTERD_STORE_KEY_PEER_UUID "uuid" #define GLUSTERD_STORE_KEY_PEER_HOSTNAME "hostname" #define GLUSTERD_STORE_KEY_PEER_STATE "state" #define GLUSTERD_STORE_KEY_VOL_CAPS "caps" /* left just for backward compat */ #define GLUSTERD_STORE_KEY_VOL_DEFRAG_REB_FILES "rebalanced-files" #define GLUSTERD_STORE_KEY_VOL_DEFRAG_SIZE "size" #define GLUSTERD_STORE_KEY_VOL_DEFRAG_SCANNED "scanned" #define GLUSTERD_STORE_KEY_VOL_DEFRAG_FAILURES "failures" #define GLUSTERD_STORE_KEY_VOL_DEFRAG_SKIPPED "skipped" #define GLUSTERD_STORE_KEY_VOL_DEFRAG_RUN_TIME "run-time" #define GLUSTERD_STORE_KEY_VOL_MIGRATED_FILES "migrated-files" #define GLUSTERD_STORE_KEY_VOL_MIGRATED_SIZE "migration-size" #define GLUSTERD_STORE_KEY_VOL_MIGRATIONS_SCANNED "migration-scanned" #define GLUSTERD_STORE_KEY_VOL_MIGRATIONS_FAILURES "migration-failures" #define GLUSTERD_STORE_KEY_VOL_MIGRATIONS_SKIPPED "migration-skipped" #define GLUSTERD_STORE_KEY_VOL_MIGRATION_RUN_TIME "migration-run-time" #define GLUSTERD_STORE_KEY_GANESHA_GLOBAL "nfs-ganesha" /* * The structure is responsible for handling the parameter for writes into * the buffer before it is finally written to the file. The writes will be * of the form of key-value pairs. */ struct glusterd_volinfo_data_store_ { gf_store_handle_t *shandle; /*Contains fd and path of the file */ int16_t buffer_len; char key_check; /* flag to check if key is to be validated before write*/ char buffer[VOLINFO_BUFFER_SIZE]; }; typedef struct glusterd_volinfo_data_store_ glusterd_volinfo_data_store_t; int32_t glusterd_store_volinfo(glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac); int32_t glusterd_store_delete_volume(glusterd_volinfo_t *volinfo); int32_t glusterd_store_delete_snap(glusterd_snap_t *snap); int32_t glusterd_retrieve_uuid(void); int32_t glusterd_store_peerinfo(glusterd_peerinfo_t *peerinfo); int32_t glusterd_store_delete_peerinfo(glusterd_peerinfo_t *peerinfo); int32_t glusterd_store_delete_brick(glusterd_brickinfo_t *brickinfo, char *delete_path); int32_t glusterd_restore(void); void glusterd_perform_volinfo_version_action(glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac); gf_boolean_t glusterd_store_is_valid_brickpath(char *volname, char *brick); int32_t glusterd_store_perform_node_state_store(glusterd_volinfo_t *volinfo); int glusterd_retrieve_op_version(xlator_t *this, int *op_version); int glusterd_retrieve_max_op_version(xlator_t *this, int *op_version); int glusterd_store_max_op_version(xlator_t *this); int glusterd_store_global_info(xlator_t *this); int32_t glusterd_store_retrieve_options(xlator_t *this); int32_t glusterd_store_retrieve_bricks(glusterd_volinfo_t *volinfo); int32_t glusterd_store_options(xlator_t *this, dict_t *opts); void glusterd_replace_slash_with_hyphen(char *str); int32_t glusterd_store_create_quota_conf_sh_on_absence(glusterd_volinfo_t *volinfo); int glusterd_store_retrieve_quota_version(glusterd_volinfo_t *volinfo); int glusterd_store_save_quota_version_and_cksum(glusterd_volinfo_t *volinfo); int32_t glusterd_store_snap(glusterd_snap_t *snap); int32_t glusterd_store_update_missed_snaps(void); glusterd_volinfo_t * glusterd_store_retrieve_volume(char *volname, glusterd_snap_t *snap); int glusterd_restore_op_version(xlator_t *this); int32_t glusterd_quota_conf_write_header(int fd); int32_t glusterd_quota_conf_write_gfid(int fd, void *buf, char type); int32_t glusterd_recreate_vol_brick_mounts(xlator_t *this, glusterd_volinfo_t *volinfo); #endif glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-server-quorum.c0000644000000000000000000000013214522202451026267 xustar000000000000000030 mtime=1699284265.724027603 30 atime=1699284265.724027603 30 ctime=1699284306.651150875 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-server-quorum.c0000664000175100017510000003324014522202451026550 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "glusterd-utils.h" #include "glusterd-messages.h" #include "glusterd-server-quorum.h" #include "glusterd-store.h" #include "glusterd-syncop.h" #include "glusterd-op-sm.h" #define CEILING_POS(X) (((X) - (int)(X)) > 0 ? (int)((X) + 1) : (int)(X)) static gf_boolean_t glusterd_is_get_op(xlator_t *this, glusterd_op_t op, dict_t *dict) { char *key = NULL; char *volname = NULL; int ret = 0; if (op == GD_OP_STATUS_VOLUME) return _gf_true; if (op == GD_OP_SET_VOLUME) { /*check for set volume help*/ ret = dict_get_str(dict, "volname", &volname); if (volname && ((strcmp(volname, "help") == 0) || (strcmp(volname, "help-xml") == 0))) { ret = dict_get_str(dict, "key1", &key); if (ret < 0) return _gf_true; } } return _gf_false; } gf_boolean_t glusterd_is_quorum_validation_required(xlator_t *this, glusterd_op_t op, dict_t *dict) { gf_boolean_t required = _gf_true; char *key = NULL; char *key_fixed = NULL; int ret = -1; if (glusterd_is_get_op(this, op, dict)) { required = _gf_false; goto out; } if ((op != GD_OP_SET_VOLUME) && (op != GD_OP_RESET_VOLUME)) goto out; if (op == GD_OP_SET_VOLUME) ret = dict_get_str(dict, "key1", &key); else if (op == GD_OP_RESET_VOLUME) ret = dict_get_str(dict, "key", &key); if (ret) goto out; ret = glusterd_check_option_exists(key, &key_fixed); if (ret <= 0) goto out; if (key_fixed) key = key_fixed; if (glusterd_is_quorum_option(key)) required = _gf_false; out: GF_FREE(key_fixed); return required; } int glusterd_validate_quorum(xlator_t *this, glusterd_op_t op, dict_t *dict, char **op_errstr) { int ret = 0; char *volname = NULL; glusterd_volinfo_t *volinfo = NULL; char *errstr = NULL; errstr = "Quorum not met. Volume operation not allowed."; if (!glusterd_is_quorum_validation_required(this, op, dict)) goto out; ret = dict_get_str(dict, "volname", &volname); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED, "Key=volname", NULL); ret = 0; goto out; } ret = glusterd_volinfo_find(volname, &volinfo); if (ret) { ret = 0; goto out; } if (!glusterd_is_volume_in_server_quorum(volinfo)) { ret = 0; goto out; } if (does_gd_meet_server_quorum(this)) { ret = 0; goto out; } ret = -1; *op_errstr = gf_strdup(errstr); out: return ret; } gf_boolean_t glusterd_is_quorum_option(char *option) { gf_boolean_t res = _gf_false; int i = 0; static const char *const keys[] = {GLUSTERD_QUORUM_TYPE_KEY, GLUSTERD_QUORUM_RATIO_KEY, NULL}; for (i = 0; keys[i]; i++) { if (strcmp(option, keys[i]) == 0) { res = _gf_true; break; } } return res; } gf_boolean_t glusterd_is_quorum_changed(dict_t *options, char *option, char *value) { int ret = 0; gf_boolean_t reconfigured = _gf_false; gf_boolean_t all = _gf_false; char *oldquorum = NULL; char *newquorum = NULL; char *oldratio = NULL; char *newratio = NULL; xlator_t *this = THIS; if ((strcmp("all", option) != 0) && !glusterd_is_quorum_option(option)) goto out; if (strcmp("all", option) == 0) all = _gf_true; if (all || (strcmp(GLUSTERD_QUORUM_TYPE_KEY, option) == 0)) { newquorum = value; ret = dict_get_str(options, GLUSTERD_QUORUM_TYPE_KEY, &oldquorum); if (ret) gf_msg(this->name, GF_LOG_DEBUG, 0, GD_MSG_DICT_GET_FAILED, "dict_get_str failed on %s", GLUSTERD_QUORUM_TYPE_KEY); } if (all || (strcmp(GLUSTERD_QUORUM_RATIO_KEY, option) == 0)) { newratio = value; ret = dict_get_str(options, GLUSTERD_QUORUM_RATIO_KEY, &oldratio); if (ret) gf_msg(this->name, GF_LOG_DEBUG, 0, GD_MSG_DICT_GET_FAILED, "dict_get_str failed on %s", GLUSTERD_QUORUM_RATIO_KEY); } reconfigured = _gf_true; if (oldquorum && newquorum && (strcmp(oldquorum, newquorum) == 0)) reconfigured = _gf_false; if (oldratio && newratio && (strcmp(oldratio, newratio) == 0)) reconfigured = _gf_false; if ((oldratio == NULL) && (newratio == NULL) && (oldquorum == NULL) && (newquorum == NULL)) reconfigured = _gf_false; out: return reconfigured; } static gf_boolean_t _is_contributing_to_quorum(gd_quorum_contrib_t contrib) { if ((contrib == QUORUM_UP) || (contrib == QUORUM_DOWN)) return _gf_true; return _gf_false; } gf_boolean_t does_quorum_meet(int active_count, int quorum_count) { return (active_count >= quorum_count); } int glusterd_get_quorum_cluster_counts(xlator_t *this, int *active_count, int *quorum_count) { glusterd_peerinfo_t *peerinfo = NULL; glusterd_conf_t *conf = NULL; int ret = -1; int inquorum_count = 0; char *val = NULL; double quorum_percentage = 0.0; gf_boolean_t ratio = _gf_false; int count = 0; conf = this->private; /* Start with counting self */ inquorum_count = 1; if (active_count) *active_count = 1; RCU_READ_LOCK; cds_list_for_each_entry_rcu(peerinfo, &conf->peers, uuid_list) { if (_is_contributing_to_quorum(peerinfo->quorum_contrib)) inquorum_count = inquorum_count + 1; if (active_count && (peerinfo->quorum_contrib == QUORUM_UP)) *active_count = *active_count + 1; } RCU_READ_UNLOCK; ret = dict_get_str(conf->opts, GLUSTERD_QUORUM_RATIO_KEY, &val); if (ret == 0) { ret = gf_string2percent(val, &quorum_percentage); if (ret == 0) ratio = _gf_true; } if (ratio) count = CEILING_POS(inquorum_count * quorum_percentage / 100.0); else count = (inquorum_count * 50 / 100) + 1; *quorum_count = count; ret = 0; return ret; } gf_boolean_t glusterd_is_volume_in_server_quorum(glusterd_volinfo_t *volinfo) { gf_boolean_t res = _gf_false; char *quorum_type = NULL; int ret = 0; ret = dict_get_str(volinfo->dict, GLUSTERD_QUORUM_TYPE_KEY, &quorum_type); if (ret) { gf_smsg(THIS->name, GF_LOG_DEBUG, -ret, GD_MSG_DICT_GET_FAILED, "Key=%s", GLUSTERD_QUORUM_TYPE_KEY, NULL); goto out; } if (strcmp(quorum_type, GLUSTERD_SERVER_QUORUM) == 0) res = _gf_true; out: return res; } gf_boolean_t glusterd_is_any_volume_in_server_quorum(xlator_t *this) { glusterd_conf_t *conf = NULL; glusterd_volinfo_t *volinfo = NULL; conf = this->private; list_for_each_entry(volinfo, &conf->volumes, vol_list) { if (glusterd_is_volume_in_server_quorum(volinfo)) { return _gf_true; } } return _gf_false; } gf_boolean_t does_gd_meet_server_quorum(xlator_t *this) { int quorum_count = 0; int active_count = 0; gf_boolean_t in = _gf_false; int ret = -1; ret = glusterd_get_quorum_cluster_counts(this, &active_count, &quorum_count); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_QUORUM_CLUSTER_COUNT_GET_FAIL, NULL); goto out; } if (!does_quorum_meet(active_count, quorum_count)) { goto out; } in = _gf_true; out: return in; } void glusterd_do_volume_quorum_action(xlator_t *this, glusterd_volinfo_t *volinfo, gf_boolean_t meets_quorum) { int ret = -1; glusterd_brickinfo_t *brickinfo = NULL; gd_quorum_status_t quorum_status = NOT_APPLICABLE_QUORUM; gf_boolean_t follows_quorum = _gf_false; gf_boolean_t quorum_status_unchanged = _gf_false; if (volinfo->status != GLUSTERD_STATUS_STARTED) { volinfo->quorum_status = NOT_APPLICABLE_QUORUM; goto out; } follows_quorum = glusterd_is_volume_in_server_quorum(volinfo); if (follows_quorum) { if (meets_quorum) quorum_status = MEETS_QUORUM; else quorum_status = DOESNT_MEET_QUORUM; } else { quorum_status = NOT_APPLICABLE_QUORUM; } /* * The following check is added to prevent spurious brick starts when * events occur that affect quorum. * Example: * There is a cluster of 10 peers. Volume is in quorum. User * takes down one brick from the volume to perform maintenance. * Suddenly one of the peers go down. Cluster is still in quorum. But * because of this 'peer going down' event, quorum is calculated and * the bricks that are down are brought up again. In this process it * also brings up the brick that is purposefully taken down. */ if (volinfo->quorum_status == quorum_status) { quorum_status_unchanged = _gf_true; goto out; } if (quorum_status == MEETS_QUORUM) { gf_msg(this->name, GF_LOG_CRITICAL, 0, GD_MSG_SERVER_QUORUM_MET_STARTING_BRICKS, "Server quorum regained for volume %s. Starting local " "bricks.", volinfo->volname); gf_event(EVENT_QUORUM_REGAINED, "volume=%s", volinfo->volname); } else if (quorum_status == DOESNT_MEET_QUORUM) { gf_msg(this->name, GF_LOG_CRITICAL, 0, GD_MSG_SERVER_QUORUM_LOST_STOPPING_BRICKS, "Server quorum lost for volume %s. Stopping local " "bricks.", volinfo->volname); gf_event(EVENT_QUORUM_LOST, "volume=%s", volinfo->volname); } list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (!glusterd_is_local_brick(volinfo, brickinfo)) continue; if (quorum_status == DOESNT_MEET_QUORUM) { ret = glusterd_brick_stop(volinfo, brickinfo, _gf_false); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_STOP_FAIL, "Failed to " "stop brick %s:%s", brickinfo->hostname, brickinfo->path); } } else { if (!brickinfo->start_triggered) { pthread_mutex_lock(&brickinfo->restart_mutex); { /* coverity[SLEEP] */ ret = glusterd_brick_start(volinfo, brickinfo, _gf_false, _gf_false); } pthread_mutex_unlock(&brickinfo->restart_mutex); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_DISCONNECTED, "Failed to start %s:%s", brickinfo->hostname, brickinfo->path); } } } } volinfo->quorum_status = quorum_status; if (quorum_status == MEETS_QUORUM) { /* bricks might have been restarted and so as the port change * might have happened */ ret = glusterd_store_volinfo(volinfo, GLUSTERD_VOLINFO_VER_AC_NONE); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_STORE_FAIL, "Failed to write volinfo for volume %s", volinfo->volname); goto out; } } out: if (quorum_status_unchanged) { list_for_each_entry(brickinfo, &volinfo->bricks, brick_list) { if (!glusterd_is_local_brick(volinfo, brickinfo)) continue; ret = glusterd_brick_start(volinfo, brickinfo, _gf_false, _gf_true); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_DISCONNECTED, "Failed to " "connect to %s:%s", brickinfo->hostname, brickinfo->path); } } } return; } int glusterd_do_quorum_action(void) { xlator_t *this = THIS; glusterd_conf_t *conf = NULL; glusterd_volinfo_t *volinfo = NULL; int ret = 0; int active_count = 0; int quorum_count = 0; gf_boolean_t meets = _gf_false; conf = this->private; conf->pending_quorum_action = _gf_true; ret = glusterd_lock(conf->uuid); if (ret) goto out; { ret = glusterd_get_quorum_cluster_counts(this, &active_count, &quorum_count); if (ret) goto unlock; if (does_quorum_meet(active_count, quorum_count)) meets = _gf_true; list_for_each_entry(volinfo, &conf->volumes, vol_list) { glusterd_do_volume_quorum_action(this, volinfo, meets); } } unlock: (void)glusterd_unlock(conf->uuid); conf->pending_quorum_action = _gf_false; out: return ret; } /* ret = 0 represents quorum is not met * ret = 1 represents quorum is met * ret = 2 represents quorum not applicable */ int check_quorum_for_brick_start(glusterd_volinfo_t *volinfo, gf_boolean_t node_quorum) { gf_boolean_t volume_quorum = _gf_false; int ret = 0; volume_quorum = glusterd_is_volume_in_server_quorum(volinfo); if (volume_quorum) { if (node_quorum) ret = 1; } else { ret = 2; } return ret; } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-rcu.h0000644000000000000000000000013214522202451024231 xustar000000000000000030 mtime=1699284265.722027598 30 atime=1699284265.722027598 30 ctime=1699284306.580150661 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-rcu.h0000664000175100017510000000173214522202451024513 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GLUSTERD_RCU_H #define _GLUSTERD_RCU_H #include #include #include #include #include #ifdef URCU_OLD #include "rculist-extra.h" #endif #include /* gd_rcu_head is a composite struct, composed of struct rcu_head and a this * pointer, which is used to pass the THIS pointer to call_rcu callbacks. * * Use this in place of struct rcu_head when embedding into another struct */ typedef struct glusterd_rcu_head_ { struct rcu_head head; xlator_t *this; } gd_rcu_head; #endif /* _GLUSTERD_RCU_H */ glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-server-quorum.h0000644000000000000000000000013214522202451026274 xustar000000000000000030 mtime=1699284265.724027603 30 atime=1699284265.724027603 30 ctime=1699284306.584150673 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-server-quorum.h0000664000175100017510000000247614522202451026564 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GLUSTERD_SERVER_QUORUM_H #define _GLUSTERD_SERVER_QUORUM_H #define GLUSTERD_SERVER_QUORUM "server" int glusterd_validate_quorum(xlator_t *this, glusterd_op_t op, dict_t *dict, char **op_errstr); gf_boolean_t glusterd_is_quorum_changed(dict_t *options, char *option, char *value); int glusterd_do_quorum_action(void); int glusterd_get_quorum_cluster_counts(xlator_t *this, int *active_count, int *quorum_count); gf_boolean_t glusterd_is_quorum_option(char *option); gf_boolean_t glusterd_is_volume_in_server_quorum(glusterd_volinfo_t *volinfo); gf_boolean_t glusterd_is_any_volume_in_server_quorum(xlator_t *this); gf_boolean_t does_gd_meet_server_quorum(xlator_t *this); int check_quorum_for_brick_start(glusterd_volinfo_t *volinfo, gf_boolean_t node_quorum); gf_boolean_t does_quorum_meet(int active_count, int quorum_count); #endif /* _GLUSTERD_SERVER_QUORUM_H */ glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-shd-svc-helper.c0000644000000000000000000000013114522202451026256 xustar000000000000000030 mtime=1699284265.724027603 30 atime=1699284265.724027603 29 ctime=1699284306.65615089 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c0000664000175100017510000000773714522202451026554 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2016 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "glusterd-utils.h" #include "glusterd-shd-svc-helper.h" #include "glusterd-messages.h" #include "glusterd-volgen.h" void glusterd_svc_build_shd_socket_filepath(glusterd_volinfo_t *volinfo, char *path, int path_len) { char sockfilepath[PATH_MAX] = { 0, }; char rundir[PATH_MAX] = { 0, }; int32_t len = 0; glusterd_conf_t *priv = THIS->private; if (!priv) return; GLUSTERD_GET_SHD_RUNDIR(rundir, volinfo, priv); len = snprintf(sockfilepath, sizeof(sockfilepath), "%s/run-%s", rundir, uuid_utoa(MY_UUID)); if ((len < 0) || (len >= sizeof(sockfilepath))) { sockfilepath[0] = 0; } glusterd_set_socket_filepath(sockfilepath, path, path_len); } void glusterd_svc_build_shd_pidfile(glusterd_volinfo_t *volinfo, char *path, int path_len) { char rundir[PATH_MAX] = { 0, }; glusterd_conf_t *priv = THIS->private; if (!priv) return; GLUSTERD_GET_SHD_RUNDIR(rundir, volinfo, priv); snprintf(path, path_len, "%s/%s-shd.pid", rundir, volinfo->volname); } void glusterd_svc_build_shd_volfile_path(glusterd_volinfo_t *volinfo, char *path, int path_len) { char workdir[PATH_MAX] = { 0, }; glusterd_conf_t *priv = THIS->private; if (!priv) return; GLUSTERD_GET_VOLUME_DIR(workdir, volinfo, priv); snprintf(path, path_len, "%s/%s-shd.vol", workdir, volinfo->volname); } void glusterd_shd_svcproc_cleanup(glusterd_shdsvc_t *shd) { glusterd_svc_proc_t *svc_proc = NULL; glusterd_svc_t *svc = NULL; glusterd_conf_t *conf = NULL; gf_boolean_t need_unref = _gf_false; rpc_clnt_t *rpc = NULL; xlator_t *this = THIS; conf = this->private; if (!conf) return; GF_VALIDATE_OR_GOTO(this->name, conf, out); GF_VALIDATE_OR_GOTO(this->name, shd, out); svc = &shd->svc; shd->attached = _gf_false; if (svc->conn.rpc) { rpc_clnt_unref(svc->conn.rpc); svc->conn.rpc = NULL; } pthread_mutex_lock(&conf->attach_lock); { svc_proc = svc->svc_proc; svc->svc_proc = NULL; svc->inited = _gf_false; cds_list_del_init(&svc->mux_svc); gf_unlink(svc->proc.pidfile); if (svc_proc && cds_list_empty(&svc_proc->svcs)) { cds_list_del_init(&svc_proc->svc_proc_list); /* We cannot free svc_proc list from here. Because * if there are pending events on the rpc, it will * try to access the corresponding svc_proc, so unrefing * rpc request and then cleaning up the memory is carried * from the notify function upon RPC_CLNT_DESTROY destroy. */ need_unref = _gf_true; rpc = svc_proc->rpc; svc_proc->rpc = NULL; } } pthread_mutex_unlock(&conf->attach_lock); /*rpc unref has to be performed outside the lock*/ if (need_unref && rpc) rpc_clnt_unref(rpc); out: return; } int glusterd_svc_set_shd_pidfile(glusterd_volinfo_t *volinfo, dict_t *dict) { int ret = -1; glusterd_svc_t *svc = NULL; xlator_t *this = THIS; GF_VALIDATE_OR_GOTO(this->name, volinfo, out); GF_VALIDATE_OR_GOTO(this->name, dict, out); svc = &(volinfo->shd.svc); ret = dict_set_dynstr_with_alloc(dict, "pidfile", svc->proc.pidfile); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Failed to set pidfile %s in dict", svc->proc.pidfile); goto out; } ret = 0; out: return ret; } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-snapshot-utils.h0000644000000000000000000000013214522202451026435 xustar000000000000000030 mtime=1699284265.727027613 30 atime=1699284265.727027613 30 ctime=1699284306.565150616 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h0000664000175100017510000001663114522202451026723 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2015 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _GLUSTERD_SNAP_UTILS_H #define _GLUSTERD_SNAP_UTILS_H #define GLUSTERD_SNAPS_MAX_HARD_LIMIT 256 #define GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT 90 #define GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT 100 #define GLUSTERD_GET_SNAP_DIR(path, snap, priv) \ do { \ int32_t _snap_dir_len; \ _snap_dir_len = snprintf(path, PATH_MAX, "%s/snaps/%s", priv->workdir, \ snap->snapname); \ if ((_snap_dir_len < 0) || (_snap_dir_len >= PATH_MAX)) { \ path[0] = 0; \ } \ } while (0) #define GLUSTERD_GET_UUID_NOHYPHEN(ret_string, uuid) \ do { \ char *snap_volname_ptr = ret_string; \ char tmp_uuid[64]; \ char *snap_volid_ptr = uuid_utoa_r(uuid, tmp_uuid); \ while (*snap_volid_ptr) { \ if (*snap_volid_ptr == '-') { \ snap_volid_ptr++; \ } else { \ (*snap_volname_ptr++) = (*snap_volid_ptr++); \ } \ } \ *snap_volname_ptr = '\0'; \ } while (0) void glusterd_snapshot_plugin_by_name(char *name, struct glusterd_snap_ops **snap_ops); int32_t glusterd_snap_volinfo_find(char *volname, glusterd_snap_t *snap, glusterd_volinfo_t **volinfo); int32_t glusterd_snap_volinfo_find_from_parent_volname(char *origin_volname, glusterd_snap_t *snap, glusterd_volinfo_t **volinfo); gf_boolean_t glusterd_is_cmd_available(char *cmd); int glusterd_is_path_mounted(const char *path); int32_t glusterd_snapshot_remove(dict_t *rsp_dict, glusterd_volinfo_t *snap_vol, glusterd_brickinfo_t *brickinfo, int32_t brick_count); int32_t glusterd_bricks_snapshot_restore(dict_t *rsp_dict, glusterd_volinfo_t *snap_vol, gf_boolean_t *retain_origin_path); gf_boolean_t glusterd_snapshot_probe(char *path, glusterd_brickinfo_t *brickinfo); int glusterd_snapshot_umount(glusterd_volinfo_t *snap_vol, glusterd_brickinfo_t *brickinfo, int32_t brick_count); int glusterd_remove_trashpath(char *volname); int glusterd_snap_volinfo_find_by_volume_id(uuid_t volume_id, glusterd_volinfo_t **volinfo); int32_t glusterd_add_snapd_to_dict(glusterd_volinfo_t *volinfo, dict_t *dict, int32_t count); int glusterd_compare_snap_time(struct cds_list_head *, struct cds_list_head *); int glusterd_compare_snap_vol_time(struct cds_list_head *, struct cds_list_head *); int32_t glusterd_snap_volinfo_restore(dict_t *dict, dict_t *rsp_dict, glusterd_volinfo_t *new_volinfo, glusterd_volinfo_t *snap_volinfo, int32_t volcount, gf_boolean_t retain_origin_path, char *snap_mount_dir); int32_t glusterd_snapobject_delete(glusterd_snap_t *snap); int32_t glusterd_cleanup_snaps_for_volume(glusterd_volinfo_t *volinfo); int32_t glusterd_missed_snapinfo_new(glusterd_missed_snap_info **missed_snapinfo); int32_t glusterd_missed_snap_op_new(glusterd_snap_op_t **snap_op); int32_t glusterd_add_missed_snaps_to_dict(dict_t *rsp_dict, glusterd_volinfo_t *snap_vol, glusterd_brickinfo_t *brickinfo, int32_t brick_number, int32_t op); int32_t glusterd_add_missed_snaps_to_export_dict(dict_t *peer_data); int32_t glusterd_import_friend_missed_snap_list(dict_t *peer_data); int gd_restore_snap_volume(dict_t *dict, dict_t *rsp_dict, glusterd_volinfo_t *orig_vol, glusterd_volinfo_t *snap_vol, int32_t volcount, gf_boolean_t retain_origin_path); int32_t glusterd_snap_unmount(xlator_t *this, glusterd_volinfo_t *volinfo); int32_t glusterd_add_snapshots_to_export_dict(dict_t *peer_data); int32_t glusterd_compare_friend_snapshots(dict_t *peer_data, char *peername, uuid_t peerid); int32_t glusterd_store_create_snap_dir(glusterd_snap_t *snap); int32_t glusterd_copy_file(const char *source, const char *destination); int32_t glusterd_copy_folder(const char *source, const char *destination); int32_t glusterd_get_geo_rep_session(char *secondary_key, char *origin_volname, dict_t *gsync_secondaries_dict, char *session, char *secondary); int32_t glusterd_restore_geo_rep_files(glusterd_volinfo_t *snap_vol); int32_t glusterd_copy_quota_files(glusterd_volinfo_t *src_vol, glusterd_volinfo_t *dest_vol, gf_boolean_t *conf_present); int glusterd_snap_use_rsp_dict(dict_t *aggr, dict_t *rsp_dict); int gd_add_vol_snap_details_to_dict(dict_t *dict, char *prefix, glusterd_volinfo_t *volinfo); int gd_add_brick_snap_details_to_dict(dict_t *dict, char *prefix, glusterd_brickinfo_t *brickinfo); int gd_import_new_brick_snap_details(dict_t *dict, char *prefix, glusterd_brickinfo_t *brickinfo); int gd_import_volume_snap_details(dict_t *dict, glusterd_volinfo_t *volinfo, char *prefix, char *volname); int32_t glusterd_snap_quorum_check(dict_t *dict, gf_boolean_t snap_volume, char **op_errstr, uint32_t *op_errno); int32_t glusterd_snap_brick_create(glusterd_volinfo_t *snap_volinfo, glusterd_brickinfo_t *brickinfo, int32_t brick_count, int32_t clone, struct glusterd_snap_ops *snap_ops); int glusterd_snapshot_restore_cleanup(dict_t *rsp_dict, char *volname, glusterd_snap_t *snap); int glusterd_is_snapd_enabled(glusterd_volinfo_t *volinfo); int32_t glusterd_is_snap_soft_limit_reached(glusterd_volinfo_t *volinfo, dict_t *dict); void gd_get_snap_conf_values_if_present(dict_t *opts, uint64_t *sys_hard_limit, uint64_t *sys_soft_limit); int glusterd_get_snap_status_str(glusterd_snap_t *snapinfo, char *snap_status_str); #endif glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-mgmt-handler.c0000644000000000000000000000013214522202451026012 xustar000000000000000030 mtime=1699284265.717027582 30 atime=1699284265.717027582 30 ctime=1699284306.629150808 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c0000664000175100017510000007640114522202451026301 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013-2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "glusterd-utils.h" #include "glusterd-locks.h" #include "glusterd-mgmt.h" #include "glusterd-op-sm.h" #include "glusterd-messages.h" static int glusterd_mgmt_v3_null(rpcsvc_request_t *req) { return 0; } static int glusterd_mgmt_v3_lock_send_resp(rpcsvc_request_t *req, int32_t status, uint32_t op_errno) { gd1_mgmt_v3_lock_rsp rsp = { {0}, }; int ret = -1; GF_ASSERT(req); rsp.op_ret = status; if (rsp.op_ret) rsp.op_errno = op_errno; glusterd_get_uuid(&rsp.uuid); ret = glusterd_submit_reply(req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gd1_mgmt_v3_lock_rsp); gf_msg_debug(THIS->name, 0, "Responded to mgmt_v3 lock, ret: %d", ret); return ret; } static int glusterd_synctasked_mgmt_v3_lock(rpcsvc_request_t *req, gd1_mgmt_v3_lock_req *lock_req, glusterd_op_lock_ctx_t *ctx) { int32_t ret = -1; xlator_t *this = THIS; uint32_t op_errno = 0; GF_ASSERT(req); GF_ASSERT(ctx); GF_ASSERT(ctx->dict); /* Trying to acquire multiple mgmt_v3 locks */ ret = glusterd_multiple_mgmt_v3_lock(ctx->dict, ctx->uuid, &op_errno); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_LOCK_GET_FAIL, "Failed to acquire mgmt_v3 locks for %s", uuid_utoa(ctx->uuid)); ret = glusterd_mgmt_v3_lock_send_resp(req, ret, op_errno); gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_state_machine_mgmt_v3_lock(rpcsvc_request_t *req, gd1_mgmt_v3_lock_req *lock_req, glusterd_op_lock_ctx_t *ctx) { int32_t ret = -1; xlator_t *this = THIS; glusterd_op_info_t txn_op_info = { GD_OP_STATE_DEFAULT, }; GF_ASSERT(req); glusterd_txn_opinfo_init(&txn_op_info, 0, &lock_req->op, ctx->dict, req); ret = glusterd_set_txn_opinfo(&lock_req->txn_id, &txn_op_info); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OPINFO_SET_FAIL, "Unable to set transaction's opinfo"); goto out; } ret = glusterd_op_sm_inject_event(GD_OP_EVENT_LOCK, &lock_req->txn_id, ctx); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_EVENT_LOCK_FAIL, "Failed to inject event GD_OP_EVENT_LOCK"); out: glusterd_friend_sm(); glusterd_op_sm(); gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_handle_mgmt_v3_lock_fn(rpcsvc_request_t *req) { gd1_mgmt_v3_lock_req lock_req = { {0}, }; int32_t ret = -1; glusterd_op_lock_ctx_t *ctx = NULL; xlator_t *this = THIS; gf_boolean_t is_synctasked = _gf_false; gf_boolean_t free_ctx = _gf_false; glusterd_conf_t *conf = NULL; time_t timeout = 0; conf = this->private; GF_ASSERT(conf); GF_ASSERT(req); ret = xdr_to_generic(req->msg[0], &lock_req, (xdrproc_t)xdr_gd1_mgmt_v3_lock_req); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "Failed to decode lock " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } gf_msg_debug(this->name, 0, "Received mgmt_v3 lock req " "from uuid: %s", uuid_utoa(lock_req.uuid)); if (glusterd_peerinfo_find_by_uuid(lock_req.uuid) == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_PEER_NOT_FOUND, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa(lock_req.uuid)); ret = -1; goto out; } ctx = GF_CALLOC(1, sizeof(*ctx), gf_gld_mt_op_lock_ctx_t); if (!ctx) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); ret = -1; goto out; } gf_uuid_copy(ctx->uuid, lock_req.uuid); ctx->req = req; ctx->dict = dict_new(); if (!ctx->dict) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); ret = -1; goto out; } ret = dict_unserialize(lock_req.dict.dict_val, lock_req.dict.dict_len, &ctx->dict); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, NULL); goto out; } /* Cli will add timeout key to dict if the default timeout is * other than 2 minutes. Here we use this value to check whether * mgmt_v3_lock_timeout should be set to default value or we * need to change the value according to timeout value * i.e, timeout + 120 seconds. */ ret = dict_get_time(ctx->dict, "timeout", &timeout); if (!ret) conf->mgmt_v3_lock_timeout = timeout + 120; is_synctasked = dict_get_str_boolean(ctx->dict, "is_synctasked", _gf_false); if (is_synctasked) { ret = glusterd_synctasked_mgmt_v3_lock(req, &lock_req, ctx); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_LOCK_GET_FAIL, "Failed to acquire mgmt_v3_locks"); /* Ignore the return code, as it shouldn't be propagated * from the handler function so as to avoid double * deletion of the req */ ret = 0; } /* The above function does not take ownership of ctx. * Therefore we need to free the ctx explicitly. */ free_ctx = _gf_true; } else { /* Shouldn't ignore the return code here, and it should * be propagated from the handler function as in failure * case it doesn't delete the req object */ ret = glusterd_op_state_machine_mgmt_v3_lock(req, &lock_req, ctx); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_LOCK_GET_FAIL, "Failed to acquire mgmt_v3_locks"); } out: if (ctx && (ret || free_ctx)) { if (ctx->dict) dict_unref(ctx->dict); GF_FREE(ctx); } free(lock_req.dict.dict_val); gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_mgmt_v3_pre_validate_send_resp(rpcsvc_request_t *req, int32_t op, int32_t status, char *op_errstr, dict_t *rsp_dict, uint32_t op_errno) { gd1_mgmt_v3_pre_val_rsp rsp = { {0}, }; int ret = -1; xlator_t *this = THIS; GF_ASSERT(req); rsp.op_ret = status; glusterd_get_uuid(&rsp.uuid); rsp.op = op; rsp.op_errno = op_errno; if (op_errstr) rsp.op_errstr = op_errstr; else rsp.op_errstr = ""; ret = dict_allocate_and_serialize(rsp_dict, &rsp.dict.dict_val, &rsp.dict.dict_len); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_ALLOC_AND_SERL_LENGTH_GET_FAIL, NULL); goto out; } ret = glusterd_submit_reply(req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gd1_mgmt_v3_pre_val_rsp); GF_FREE(rsp.dict.dict_val); out: gf_msg_debug(this->name, 0, "Responded to pre validation, ret: %d", ret); return ret; } static int glusterd_handle_pre_validate_fn(rpcsvc_request_t *req) { int32_t ret = -1; gd1_mgmt_v3_pre_val_req op_req = { {0}, }; xlator_t *this = THIS; char *op_errstr = NULL; dict_t *dict = NULL; dict_t *rsp_dict = NULL; uint32_t op_errno = 0; GF_ASSERT(req); ret = xdr_to_generic(req->msg[0], &op_req, (xdrproc_t)xdr_gd1_mgmt_v3_pre_val_req); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "Failed to decode pre validation " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } if (glusterd_peerinfo_find_by_uuid(op_req.uuid) == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_PEER_NOT_FOUND, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa(op_req.uuid)); ret = -1; goto out; } dict = dict_new(); if (!dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } ret = dict_unserialize(op_req.dict.dict_val, op_req.dict.dict_len, &dict); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, NULL); goto out; } rsp_dict = dict_new(); if (!rsp_dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); return -1; } ret = gd_mgmt_v3_pre_validate_fn(op_req.op, dict, &op_errstr, rsp_dict, &op_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PRE_VALIDATION_FAIL, "Pre Validation failed on operation %s", gd_op_list[op_req.op]); } ret = glusterd_mgmt_v3_pre_validate_send_resp( req, op_req.op, ret, op_errstr, rsp_dict, op_errno); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_OP_RESP_FAIL, "Failed to send Pre Validation " "response for operation %s", gd_op_list[op_req.op]); goto out; } out: if (op_errstr && (strcmp(op_errstr, ""))) GF_FREE(op_errstr); free(op_req.dict.dict_val); if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); /* Return 0 from handler to avoid double deletion of req obj */ return 0; } static int glusterd_mgmt_v3_brick_op_send_resp(rpcsvc_request_t *req, int32_t op, int32_t status, char *op_errstr, dict_t *rsp_dict) { gd1_mgmt_v3_brick_op_rsp rsp = { {0}, }; int ret = -1; xlator_t *this = THIS; GF_ASSERT(req); rsp.op_ret = status; glusterd_get_uuid(&rsp.uuid); rsp.op = op; if (op_errstr) rsp.op_errstr = op_errstr; else rsp.op_errstr = ""; ret = dict_allocate_and_serialize(rsp_dict, &rsp.dict.dict_val, &rsp.dict.dict_len); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_ALLOC_AND_SERL_LENGTH_GET_FAIL, NULL); goto out; } ret = glusterd_submit_reply(req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gd1_mgmt_v3_brick_op_rsp); GF_FREE(rsp.dict.dict_val); out: gf_msg_debug(this->name, 0, "Responded to brick op, ret: %d", ret); return ret; } static int glusterd_handle_brick_op_fn(rpcsvc_request_t *req) { int32_t ret = -1; gd1_mgmt_v3_brick_op_req op_req = { {0}, }; xlator_t *this = THIS; char *op_errstr = NULL; dict_t *dict = NULL; dict_t *rsp_dict = NULL; GF_ASSERT(req); ret = xdr_to_generic(req->msg[0], &op_req, (xdrproc_t)xdr_gd1_mgmt_v3_brick_op_req); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "Failed to decode brick op " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } if (glusterd_peerinfo_find_by_uuid(op_req.uuid) == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_PEER_NOT_FOUND, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa(op_req.uuid)); ret = -1; goto out; } dict = dict_new(); if (!dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } ret = dict_unserialize(op_req.dict.dict_val, op_req.dict.dict_len, &dict); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, NULL); goto out; } rsp_dict = dict_new(); if (!rsp_dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); return -1; } ret = gd_mgmt_v3_brick_op_fn(op_req.op, dict, &op_errstr, rsp_dict); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_OP_FAIL, "Brick Op failed on operation %s", gd_op_list[op_req.op]); } ret = glusterd_mgmt_v3_brick_op_send_resp(req, op_req.op, ret, op_errstr, rsp_dict); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PRE_VALD_RESP_FAIL, "Failed to send brick op " "response for operation %s", gd_op_list[op_req.op]); goto out; } out: if (op_errstr && (strcmp(op_errstr, ""))) GF_FREE(op_errstr); free(op_req.dict.dict_val); if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); /* Return 0 from handler to avoid double deletion of req obj */ return 0; } static int glusterd_mgmt_v3_commit_send_resp(rpcsvc_request_t *req, int32_t op, int32_t status, char *op_errstr, uint32_t op_errno, dict_t *rsp_dict) { gd1_mgmt_v3_commit_rsp rsp = { {0}, }; int ret = -1; xlator_t *this = THIS; GF_ASSERT(req); rsp.op_ret = status; glusterd_get_uuid(&rsp.uuid); rsp.op = op; rsp.op_errno = op_errno; if (op_errstr) rsp.op_errstr = op_errstr; else rsp.op_errstr = ""; ret = dict_allocate_and_serialize(rsp_dict, &rsp.dict.dict_val, &rsp.dict.dict_len); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_ALLOC_AND_SERL_LENGTH_GET_FAIL, NULL); goto out; } ret = glusterd_submit_reply(req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gd1_mgmt_v3_commit_rsp); GF_FREE(rsp.dict.dict_val); out: gf_msg_debug(this->name, 0, "Responded to commit, ret: %d", ret); return ret; } static int glusterd_handle_commit_fn(rpcsvc_request_t *req) { int32_t ret = -1; gd1_mgmt_v3_commit_req op_req = { {0}, }; xlator_t *this = THIS; char *op_errstr = NULL; dict_t *dict = NULL; dict_t *rsp_dict = NULL; uint32_t op_errno = 0; GF_ASSERT(req); ret = xdr_to_generic(req->msg[0], &op_req, (xdrproc_t)xdr_gd1_mgmt_v3_commit_req); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "Failed to decode commit " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } if (glusterd_peerinfo_find_by_uuid(op_req.uuid) == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_PEER_NOT_FOUND, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa(op_req.uuid)); ret = -1; goto out; } dict = dict_new(); if (!dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } ret = dict_unserialize(op_req.dict.dict_val, op_req.dict.dict_len, &dict); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, NULL); goto out; } rsp_dict = dict_new(); if (!rsp_dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); return -1; } ret = gd_mgmt_v3_commit_fn(op_req.op, dict, &op_errstr, &op_errno, rsp_dict); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_COMMIT_OP_FAIL, "commit failed on operation %s", gd_op_list[op_req.op]); } ret = glusterd_mgmt_v3_commit_send_resp(req, op_req.op, ret, op_errstr, op_errno, rsp_dict); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_OP_RESP_FAIL, "Failed to send commit " "response for operation %s", gd_op_list[op_req.op]); goto out; } out: if (op_errstr && (strcmp(op_errstr, ""))) GF_FREE(op_errstr); free(op_req.dict.dict_val); if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); /* Return 0 from handler to avoid double deletion of req obj */ return 0; } static int glusterd_mgmt_v3_post_commit_send_resp(rpcsvc_request_t *req, int32_t op, int32_t status, char *op_errstr, uint32_t op_errno, dict_t *rsp_dict) { gd1_mgmt_v3_post_commit_rsp rsp = { {0}, }; int ret = -1; xlator_t *this = THIS; GF_ASSERT(req); rsp.op_ret = status; glusterd_get_uuid(&rsp.uuid); rsp.op = op; rsp.op_errno = op_errno; if (op_errstr) rsp.op_errstr = op_errstr; else rsp.op_errstr = ""; ret = dict_allocate_and_serialize(rsp_dict, &rsp.dict.dict_val, &rsp.dict.dict_len); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_ALLOC_AND_SERL_LENGTH_GET_FAIL, NULL); goto out; } ret = glusterd_submit_reply(req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gd1_mgmt_v3_post_commit_rsp); GF_FREE(rsp.dict.dict_val); out: gf_msg_debug(this->name, 0, "Responded to post commit, ret: %d", ret); return ret; } static int glusterd_handle_post_commit_fn(rpcsvc_request_t *req) { int32_t ret = -1; gd1_mgmt_v3_post_commit_req op_req = { {0}, }; xlator_t *this = THIS; char *op_errstr = NULL; dict_t *dict = NULL; dict_t *rsp_dict = NULL; uint32_t op_errno = 0; GF_ASSERT(req); ret = xdr_to_generic(req->msg[0], &op_req, (xdrproc_t)xdr_gd1_mgmt_v3_post_commit_req); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "Failed to decode post commit " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } if (glusterd_peerinfo_find_by_uuid(op_req.uuid) == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_PEER_NOT_FOUND, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa(op_req.uuid)); ret = -1; goto out; } dict = dict_new(); if (!dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } ret = dict_unserialize(op_req.dict.dict_val, op_req.dict.dict_len, &dict); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, NULL); goto out; } rsp_dict = dict_new(); if (!rsp_dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); return -1; } ret = gd_mgmt_v3_post_commit_fn(op_req.op, dict, &op_errstr, &op_errno, rsp_dict); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_POST_COMMIT_OP_FAIL, "post commit failed on operation %s", gd_op_list[op_req.op]); } ret = glusterd_mgmt_v3_post_commit_send_resp(req, op_req.op, ret, op_errstr, op_errno, rsp_dict); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_OP_RESP_FAIL, "Failed to send post commit " "response for operation %s", gd_op_list[op_req.op]); goto out; } out: if (op_errstr && (strcmp(op_errstr, ""))) GF_FREE(op_errstr); free(op_req.dict.dict_val); if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); /* Return 0 from handler to avoid double deletion of req obj */ return 0; } static int glusterd_mgmt_v3_post_validate_send_resp(rpcsvc_request_t *req, int32_t op, int32_t status, char *op_errstr, dict_t *rsp_dict) { gd1_mgmt_v3_post_val_rsp rsp = { {0}, }; int ret = -1; xlator_t *this = THIS; GF_ASSERT(req); rsp.op_ret = status; glusterd_get_uuid(&rsp.uuid); rsp.op = op; if (op_errstr) rsp.op_errstr = op_errstr; else rsp.op_errstr = ""; ret = dict_allocate_and_serialize(rsp_dict, &rsp.dict.dict_val, &rsp.dict.dict_len); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_ALLOC_AND_SERL_LENGTH_GET_FAIL, NULL); goto out; } ret = glusterd_submit_reply(req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gd1_mgmt_v3_post_val_rsp); GF_FREE(rsp.dict.dict_val); out: gf_msg_debug(this->name, 0, "Responded to post validation, ret: %d", ret); return ret; } static int glusterd_handle_post_validate_fn(rpcsvc_request_t *req) { int32_t ret = -1; gd1_mgmt_v3_post_val_req op_req = { {0}, }; xlator_t *this = THIS; char *op_errstr = NULL; dict_t *dict = NULL; dict_t *rsp_dict = NULL; GF_ASSERT(req); ret = xdr_to_generic(req->msg[0], &op_req, (xdrproc_t)xdr_gd1_mgmt_v3_post_val_req); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "Failed to decode post validation " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } if (glusterd_peerinfo_find_by_uuid(op_req.uuid) == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_PEER_NOT_FOUND, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa(op_req.uuid)); ret = -1; goto out; } dict = dict_new(); if (!dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); goto out; } ret = dict_unserialize(op_req.dict.dict_val, op_req.dict.dict_len, &dict); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, NULL); goto out; } rsp_dict = dict_new(); if (!rsp_dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); return -1; } ret = gd_mgmt_v3_post_validate_fn(op_req.op, op_req.op_ret, dict, &op_errstr, rsp_dict); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_POST_VALIDATION_FAIL, "Post Validation failed on operation %s", gd_op_list[op_req.op]); } ret = glusterd_mgmt_v3_post_validate_send_resp(req, op_req.op, ret, op_errstr, rsp_dict); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_OP_RESP_FAIL, "Failed to send Post Validation " "response for operation %s", gd_op_list[op_req.op]); goto out; } out: if (op_errstr && (strcmp(op_errstr, ""))) GF_FREE(op_errstr); free(op_req.dict.dict_val); if (dict) dict_unref(dict); if (rsp_dict) dict_unref(rsp_dict); /* Return 0 from handler to avoid double deletion of req obj */ return 0; } static int glusterd_mgmt_v3_unlock_send_resp(rpcsvc_request_t *req, int32_t status) { gd1_mgmt_v3_unlock_rsp rsp = { {0}, }; int ret = -1; GF_ASSERT(req); rsp.op_ret = status; if (rsp.op_ret) rsp.op_errno = errno; glusterd_get_uuid(&rsp.uuid); ret = glusterd_submit_reply(req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gd1_mgmt_v3_unlock_rsp); gf_msg_debug(THIS->name, 0, "Responded to mgmt_v3 unlock, ret: %d", ret); return ret; } static int glusterd_syctasked_mgmt_v3_unlock(rpcsvc_request_t *req, gd1_mgmt_v3_unlock_req *unlock_req, glusterd_op_lock_ctx_t *ctx) { int32_t ret = -1; xlator_t *this = THIS; GF_ASSERT(req); GF_ASSERT(ctx); /* Trying to release multiple mgmt_v3 locks */ ret = glusterd_multiple_mgmt_v3_unlock(ctx->dict, ctx->uuid); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Failed to release mgmt_v3 locks for %s", uuid_utoa(ctx->uuid)); } ret = glusterd_mgmt_v3_unlock_send_resp(req, ret); gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_op_state_machine_mgmt_v3_unlock(rpcsvc_request_t *req, gd1_mgmt_v3_unlock_req *lock_req, glusterd_op_lock_ctx_t *ctx) { int32_t ret = -1; xlator_t *this = THIS; GF_ASSERT(req); ret = glusterd_op_sm_inject_event(GD_OP_EVENT_UNLOCK, &lock_req->txn_id, ctx); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_EVENT_UNLOCK_FAIL, "Failed to inject event GD_OP_EVENT_UNLOCK"); glusterd_friend_sm(); glusterd_op_sm(); gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } static int glusterd_handle_mgmt_v3_unlock_fn(rpcsvc_request_t *req) { gd1_mgmt_v3_unlock_req lock_req = { {0}, }; int32_t ret = -1; glusterd_op_lock_ctx_t *ctx = NULL; xlator_t *this = THIS; gf_boolean_t is_synctasked = _gf_false; gf_boolean_t free_ctx = _gf_false; GF_ASSERT(req); ret = xdr_to_generic(req->msg[0], &lock_req, (xdrproc_t)xdr_gd1_mgmt_v3_unlock_req); if (ret < 0) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "Failed to decode unlock " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } gf_msg_debug(this->name, 0, "Received volume unlock req " "from uuid: %s", uuid_utoa(lock_req.uuid)); if (glusterd_peerinfo_find_by_uuid(lock_req.uuid) == NULL) { gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_PEER_NOT_FOUND, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa(lock_req.uuid)); ret = -1; goto out; } ctx = GF_CALLOC(1, sizeof(*ctx), gf_gld_mt_op_lock_ctx_t); if (!ctx) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_NO_MEMORY, NULL); ret = -1; goto out; } gf_uuid_copy(ctx->uuid, lock_req.uuid); ctx->req = req; ctx->dict = dict_new(); if (!ctx->dict) { gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, NULL); ret = -1; goto out; } ret = dict_unserialize(lock_req.dict.dict_val, lock_req.dict.dict_len, &ctx->dict); if (ret) { gf_smsg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, NULL); goto out; } is_synctasked = dict_get_str_boolean(ctx->dict, "is_synctasked", _gf_false); if (is_synctasked) { ret = glusterd_syctasked_mgmt_v3_unlock(req, &lock_req, ctx); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Failed to release mgmt_v3_locks"); /* Ignore the return code, as it shouldn't be propagated * from the handler function so as to avoid double * deletion of the req */ ret = 0; } /* The above function does not take ownership of ctx. * Therefore we need to free the ctx explicitly. */ free_ctx = _gf_true; } else { /* Shouldn't ignore the return code here, and it should * be propagated from the handler function as in failure * case it doesn't delete the req object */ ret = glusterd_op_state_machine_mgmt_v3_unlock(req, &lock_req, ctx); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Failed to release mgmt_v3_locks"); } out: if (ctx && (ret || free_ctx)) { if (ctx->dict) dict_unref(ctx->dict); GF_FREE(ctx); } free(lock_req.dict.dict_val); gf_msg_trace(this->name, 0, "Returning %d", ret); return ret; } int glusterd_handle_mgmt_v3_lock(rpcsvc_request_t *req) { return glusterd_big_locked_handler(req, glusterd_handle_mgmt_v3_lock_fn); } static int glusterd_handle_pre_validate(rpcsvc_request_t *req) { return glusterd_big_locked_handler(req, glusterd_handle_pre_validate_fn); } static int glusterd_handle_brick_op(rpcsvc_request_t *req) { return glusterd_big_locked_handler(req, glusterd_handle_brick_op_fn); } static int glusterd_handle_commit(rpcsvc_request_t *req) { return glusterd_big_locked_handler(req, glusterd_handle_commit_fn); } static int glusterd_handle_post_commit(rpcsvc_request_t *req) { return glusterd_big_locked_handler(req, glusterd_handle_post_commit_fn); } static int glusterd_handle_post_validate(rpcsvc_request_t *req) { return glusterd_big_locked_handler(req, glusterd_handle_post_validate_fn); } int glusterd_handle_mgmt_v3_unlock(rpcsvc_request_t *req) { return glusterd_big_locked_handler(req, glusterd_handle_mgmt_v3_unlock_fn); } static rpcsvc_actor_t gd_svc_mgmt_v3_actors[GLUSTERD_MGMT_V3_MAXVALUE] = { [GLUSTERD_MGMT_V3_NULL] = {"NULL", glusterd_mgmt_v3_null, NULL, GLUSTERD_MGMT_V3_NULL, DRC_NA, 0}, [GLUSTERD_MGMT_V3_LOCK] = {"MGMT_V3_LOCK", glusterd_handle_mgmt_v3_lock, NULL, GLUSTERD_MGMT_V3_LOCK, DRC_NA, 0}, [GLUSTERD_MGMT_V3_PRE_VALIDATE] = {"PRE_VAL", glusterd_handle_pre_validate, NULL, GLUSTERD_MGMT_V3_PRE_VALIDATE, DRC_NA, 0}, [GLUSTERD_MGMT_V3_BRICK_OP] = {"BRCK_OP", glusterd_handle_brick_op, NULL, GLUSTERD_MGMT_V3_BRICK_OP, DRC_NA, 0}, [GLUSTERD_MGMT_V3_COMMIT] = {"COMMIT", glusterd_handle_commit, NULL, GLUSTERD_MGMT_V3_COMMIT, DRC_NA, 0}, [GLUSTERD_MGMT_V3_POST_VALIDATE] = {"POST_VAL", glusterd_handle_post_validate, NULL, GLUSTERD_MGMT_V3_POST_VALIDATE, DRC_NA, 0}, [GLUSTERD_MGMT_V3_UNLOCK] = {"MGMT_V3_UNLOCK", glusterd_handle_mgmt_v3_unlock, NULL, GLUSTERD_MGMT_V3_UNLOCK, DRC_NA, 0}, [GLUSTERD_MGMT_V3_POST_COMMIT] = {"POST_COMMIT", glusterd_handle_post_commit, NULL, GLUSTERD_MGMT_V3_POST_COMMIT, DRC_NA, 0}, }; struct rpcsvc_program gd_svc_mgmt_v3_prog = { .progname = "GlusterD svc mgmt v3", .prognum = GD_MGMT_PROGRAM, .progver = GD_MGMT_V3_VERSION, .numactors = GLUSTERD_MGMT_V3_MAXVALUE, .actors = gd_svc_mgmt_v3_actors, .synctask = _gf_true, }; glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-snapd-svc-helper.c0000644000000000000000000000013214522202451026606 xustar000000000000000030 mtime=1699284265.725027606 30 atime=1699284265.725027606 30 ctime=1699284306.647150863 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-snapd-svc-helper.c0000664000175100017510000000402714522202451027070 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "glusterd.h" #include "glusterd-utils.h" #include "glusterd-snapd-svc-helper.h" void glusterd_svc_build_snapd_rundir(glusterd_volinfo_t *volinfo, char *path, int path_len) { char workdir[PATH_MAX] = { 0, }; glusterd_conf_t *priv = THIS->private; GLUSTERD_GET_VOLUME_PID_DIR(workdir, volinfo, priv); snprintf(path, path_len, "%s", workdir); } void glusterd_svc_build_snapd_socket_filepath(glusterd_volinfo_t *volinfo, char *path, int path_len) { char sockfilepath[PATH_MAX] = { 0, }; char rundir[PATH_MAX] = { 0, }; int32_t len = 0; glusterd_svc_build_snapd_rundir(volinfo, rundir, sizeof(rundir)); len = snprintf(sockfilepath, sizeof(sockfilepath), "%s/run-%s", rundir, uuid_utoa(MY_UUID)); if ((len < 0) || (len >= sizeof(sockfilepath))) { sockfilepath[0] = 0; } glusterd_set_socket_filepath(sockfilepath, path, path_len); } void glusterd_svc_build_snapd_pidfile(glusterd_volinfo_t *volinfo, char *path, int path_len) { char rundir[PATH_MAX] = { 0, }; glusterd_svc_build_snapd_rundir(volinfo, rundir, sizeof(rundir)); snprintf(path, path_len, "%s/%s-snapd.pid", rundir, volinfo->volname); } void glusterd_svc_build_snapd_volfile(glusterd_volinfo_t *volinfo, char *path, int path_len) { char workdir[PATH_MAX] = { 0, }; glusterd_conf_t *priv = THIS->private; GLUSTERD_GET_VOLUME_DIR(workdir, volinfo, priv); snprintf(path, path_len, "%s/%s-snapd.vol", workdir, volinfo->volname); } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-snapd-svc.c0000644000000000000000000000012714522202451025335 xustar000000000000000029 mtime=1699284265.72602761 29 atime=1699284265.72602761 29 ctime=1699284306.64615086 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c0000664000175100017510000003420414522202451025613 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include #include "glusterd-utils.h" #include "glusterd-volgen.h" #include "glusterd-messages.h" #include "glusterd-svc-mgmt.h" #include "glusterd-svc-helper.h" #include "glusterd-conn-mgmt.h" #include "glusterd-proc-mgmt.h" #include "glusterd-snapd-svc.h" #include "glusterd-snapd-svc-helper.h" #include "glusterd-snapshot-utils.h" #include char *snapd_svc_name = "snapd"; static void glusterd_svc_build_snapd_logdir(char *logdir, char *volname, size_t len) { glusterd_conf_t *priv = THIS->private; snprintf(logdir, len, "%s/snaps/%s", priv->logdir, volname); } void glusterd_snapdsvc_build(glusterd_svc_t *svc) { svc->manager = glusterd_snapdsvc_manager; svc->start = glusterd_snapdsvc_start; svc->stop = glusterd_svc_stop; } int glusterd_snapdsvc_init(void *data) { int ret = -1; char rundir[PATH_MAX] = { 0, }; char sockpath[PATH_MAX] = { 0, }; char pidfile[PATH_MAX] = { 0, }; char volfile[PATH_MAX] = { 0, }; char logdir[PATH_MAX] = { 0, }; char logfile[PATH_MAX] = { 0, }; char volfileid[256] = {0}; glusterd_svc_t *svc = NULL; glusterd_volinfo_t *volinfo = NULL; glusterd_conf_t *priv = NULL; glusterd_conn_notify_t notify = NULL; xlator_t *this = THIS; char *volfileserver = NULL; int32_t len = 0; priv = this->private; GF_ASSERT(priv); volinfo = data; svc = &(volinfo->snapd.svc); ret = snprintf(svc->name, sizeof(svc->name), "%s", snapd_svc_name); if (ret < 0) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL); goto out; } notify = glusterd_snapdsvc_rpc_notify; glusterd_svc_build_snapd_rundir(volinfo, rundir, sizeof(rundir)); glusterd_svc_create_rundir(rundir); /* Initialize the connection mgmt */ glusterd_svc_build_snapd_socket_filepath(volinfo, sockpath, sizeof(sockpath)); ret = glusterd_conn_init(&(svc->conn), sockpath, 600, notify); if (ret) goto out; /* Initialize the process mgmt */ glusterd_svc_build_snapd_pidfile(volinfo, pidfile, sizeof(pidfile)); glusterd_svc_build_snapd_volfile(volinfo, volfile, sizeof(volfile)); glusterd_svc_build_snapd_logdir(logdir, volinfo->volname, sizeof(logdir)); ret = mkdir_p(logdir, 0755, _gf_true); if ((ret == -1) && (EEXIST != errno)) { gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_CREATE_DIR_FAILED, "Unable to create logdir %s", logdir); goto out; } len = snprintf(logfile, sizeof(logfile), "%s/snapd.log", logdir); if ((len < 0) || (len >= sizeof(logfile))) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL); ret = -1; goto out; } len = snprintf(volfileid, sizeof(volfileid), "snapd/%s", volinfo->volname); if ((len < 0) || (len >= sizeof(volfileid))) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL); ret = -1; goto out; } if (dict_get_str(this->options, "transport.socket.bind-address", &volfileserver) != 0) { volfileserver = "localhost"; } ret = glusterd_proc_init(&(svc->proc), snapd_svc_name, pidfile, logdir, logfile, volfile, volfileid, volfileserver); if (ret) goto out; out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } int glusterd_snapdsvc_manager(glusterd_svc_t *svc, void *data, int flags) { int ret = 0; xlator_t *this = THIS; glusterd_volinfo_t *volinfo = NULL; volinfo = data; if (!svc->inited) { ret = glusterd_snapdsvc_init(volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_INIT_FAIL, "Failed to initialize " "snapd service for volume %s", volinfo->volname); goto out; } else { svc->inited = _gf_true; gf_msg_debug(this->name, 0, "snapd service " "initialized"); } } ret = glusterd_is_snapd_enabled(volinfo); if (ret == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL, "Failed to read volume " "options"); goto out; } if (ret) { if (!glusterd_is_volume_started(volinfo)) { if (glusterd_proc_is_running(&svc->proc)) { ret = svc->stop(svc, SIGTERM); if (ret) gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_STOP_FAIL, "Couldn't stop snapd for " "volume: %s", volinfo->volname); } else { /* Since snapd is not running set ret to 0 */ ret = 0; } goto out; } ret = glusterd_snapdsvc_create_volfile(volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_CREATE_FAIL, "Couldn't create " "snapd volfile for volume: %s", volinfo->volname); goto out; } ret = svc->start(svc, flags); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_START_FAIL, "Couldn't start " "snapd for volume: %s", volinfo->volname); goto out; } glusterd_volinfo_ref(volinfo); ret = glusterd_conn_connect(&(svc->conn)); if (ret) { glusterd_volinfo_unref(volinfo); goto out; } } else if (glusterd_proc_is_running(&svc->proc)) { ret = svc->stop(svc, SIGTERM); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_STOP_FAIL, "Couldn't stop snapd for volume: %s", volinfo->volname); goto out; } volinfo->snapd.port = 0; } out: if (ret) { gf_event(EVENT_SVC_MANAGER_FAILED, "volume=%s;svc_name=%s", volinfo->volname, svc->name); } gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } int32_t glusterd_snapdsvc_start(glusterd_svc_t *svc, int flags) { int ret = -1; runner_t runner = { 0, }; glusterd_conf_t *priv = NULL; xlator_t *this = THIS; char valgrind_logfile[PATH_MAX] = {0}; int snapd_port = 0; char msg[1024] = { 0, }; char snapd_id[PATH_MAX] = { 0, }; glusterd_volinfo_t *volinfo = NULL; glusterd_snapdsvc_t *snapd = NULL; char *localtime_logging = NULL; int32_t len = 0; priv = this->private; GF_ASSERT(priv); if (glusterd_proc_is_running(&svc->proc)) { ret = 0; goto out; } /* Get volinfo->snapd from svc object */ snapd = cds_list_entry(svc, glusterd_snapdsvc_t, svc); if (!snapd) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_OBJ_GET_FAIL, "Failed to get snapd object " "from snapd service"); goto out; } /* Get volinfo from snapd */ volinfo = cds_list_entry(snapd, glusterd_volinfo_t, snapd); if (!volinfo) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL, "Failed to get volinfo from " "from snapd"); goto out; } ret = sys_access(svc->proc.volfile, F_OK); if (ret) { gf_msg(this->name, GF_LOG_DEBUG, 0, GD_MSG_VOLINFO_GET_FAIL, "snapd Volfile %s is not present", svc->proc.volfile); /* If glusterd is down on one of the nodes and during * that time "USS is enabled" for the first time. After some * time when the glusterd which was down comes back it tries * to look for the snapd volfile and it does not find snapd * volfile and because of this starting of snapd fails. * Therefore, if volfile is not present then create a fresh * volfile. */ ret = glusterd_snapdsvc_create_volfile(volinfo); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL, "Couldn't create " "snapd volfile for volume: %s", volinfo->volname); goto out; } } runinit(&runner); if (this->ctx->cmd_args.vgtool != _gf_none) { len = snprintf(valgrind_logfile, PATH_MAX, "%s/valgrind-snapd.log", svc->proc.logdir); if ((len < 0) || (len >= PATH_MAX)) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL); ret = -1; goto out; } if (this->ctx->cmd_args.vgtool == _gf_memcheck) runner_add_args(&runner, "valgrind", "--leak-check=full", "--trace-children=yes", "--track-origins=yes", NULL); else runner_add_args(&runner, "valgrind", "--tool=drd", NULL); runner_argprintf(&runner, "--log-file=%s", valgrind_logfile); } snprintf(snapd_id, sizeof(snapd_id), "snapd-%s", volinfo->volname); runner_add_args(&runner, SBIN_DIR "/glusterfsd", "-s", svc->proc.volfileserver, "--volfile-id", svc->proc.volfileid, "-p", svc->proc.pidfile, "-l", svc->proc.logfile, "--brick-name", snapd_id, "-S", svc->conn.sockpath, "--process-name", svc->name, NULL); if (dict_get_str(priv->opts, GLUSTERD_LOCALTIME_LOGGING_KEY, &localtime_logging) == 0) { if (strcmp(localtime_logging, "enable") == 0) runner_add_arg(&runner, "--localtime-logging"); } snapd_port = pmap_assign_port(this, volinfo->snapd.port, snapd_id); if (!snapd_port) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PORTS_EXHAUSTED, "All the ports in the range are exhausted, can't start " "snapd for volume %s", volinfo->volname); ret = -1; goto out; } volinfo->snapd.port = snapd_port; runner_add_arg(&runner, "--brick-port"); runner_argprintf(&runner, "%d", snapd_port); runner_add_arg(&runner, "--xlator-option"); runner_argprintf(&runner, "%s-server.listen-port=%d", volinfo->volname, snapd_port); runner_add_arg(&runner, "--no-mem-accounting"); snprintf(msg, sizeof(msg), "Starting the snapd service for volume %s", volinfo->volname); runner_log(&runner, this->name, GF_LOG_DEBUG, msg); if (flags == PROC_START_NO_WAIT) { ret = runner_run_nowait(&runner); } else { synclock_unlock(&priv->big_lock); { ret = runner_run(&runner); } synclock_lock(&priv->big_lock); } out: return ret; } int glusterd_snapdsvc_restart(void) { glusterd_volinfo_t *volinfo = NULL; glusterd_volinfo_t *tmp = NULL; int ret = 0; xlator_t *this = THIS; glusterd_conf_t *conf = NULL; glusterd_svc_t *svc = NULL; conf = this->private; GF_ASSERT(conf); cds_list_for_each_entry_safe(volinfo, tmp, &conf->volumes, vol_list) { /* Start per volume snapd svc */ if (volinfo->status == GLUSTERD_STATUS_STARTED) { svc = &(volinfo->snapd.svc); ret = svc->manager(svc, volinfo, PROC_START_NO_WAIT); if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_START_FAIL, "Couldn't resolve snapd for " "vol: %s on restart", volinfo->volname); gf_event(EVENT_SVC_MANAGER_FAILED, "volume=%s;svc_name=%s", volinfo->volname, svc->name); goto out; } } } out: return ret; } int glusterd_snapdsvc_rpc_notify(glusterd_conn_t *conn, rpc_clnt_event_t event) { int ret = 0; glusterd_svc_t *svc = NULL; xlator_t *this = THIS; glusterd_volinfo_t *volinfo = NULL; glusterd_snapdsvc_t *snapd = NULL; svc = cds_list_entry(conn, glusterd_svc_t, conn); if (!svc) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_GET_FAIL, "Failed to get the service"); return -1; } snapd = cds_list_entry(svc, glusterd_snapdsvc_t, svc); if (!snapd) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_OBJ_GET_FAIL, "Failed to get the " "snapd object"); return -1; } volinfo = cds_list_entry(snapd, glusterd_volinfo_t, snapd); if (!volinfo) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL, "Failed to get the " "volinfo object"); return -1; } switch (event) { case RPC_CLNT_CONNECT: gf_msg_debug(this->name, 0, "%s has connected with " "glusterd.", svc->name); gf_event(EVENT_SVC_CONNECTED, "volume=%s;svc_name=%s", volinfo->volname, svc->name); svc->online = _gf_true; break; case RPC_CLNT_DISCONNECT: if (svc->online) { gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_NODE_DISCONNECTED, "%s has disconnected " "from glusterd.", svc->name); gf_event(EVENT_SVC_DISCONNECTED, "volume=%s;svc_name=%s", volinfo->volname, svc->name); svc->online = _gf_false; } break; case RPC_CLNT_DESTROY: glusterd_volinfo_unref(volinfo); break; default: gf_msg_trace(this->name, 0, "got some other RPC event %d", event); break; } return ret; } glusterfs-11.1/xlators/mgmt/glusterd/src/PaxHeaders.9031/glusterd-volume-set.c0000644000000000000000000000013214522202451025533 xustar000000000000000030 mtime=1699284265.740027652 30 atime=1699284265.739027649 30 ctime=1699284306.625150796 glusterfs-11.1/xlators/mgmt/glusterd/src/glusterd-volume-set.c0000664000175100017510000030604414522202451026021 0ustar00jenkinsjenkins00000000000000/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include #include "glusterd.h" #include "glusterd-volgen.h" #include "glusterd-utils.h" static int validate_cache_max_min_size(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char *current_max_value = NULL; char *current_min_value = NULL; char errstr[2048] = ""; glusterd_conf_t *priv = NULL; int ret = 0; uint64_t max_value = 0; uint64_t min_value = 0; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); if ((!strcmp(key, "performance.cache-min-file-size")) || (!strcmp(key, "cache-min-file-size"))) { glusterd_volinfo_get(volinfo, "performance.cache-max-file-size", ¤t_max_value); if (current_max_value) { gf_string2bytesize_uint64(current_max_value, &max_value); gf_string2bytesize_uint64(value, &min_value); current_min_value = value; } } else if ((!strcmp(key, "performance.cache-max-file-size")) || (!strcmp(key, "cache-max-file-size"))) { glusterd_volinfo_get(volinfo, "performance.cache-min-file-size", ¤t_min_value); if (current_min_value) { gf_string2bytesize_uint64(current_min_value, &min_value); gf_string2bytesize_uint64(value, &max_value); current_max_value = value; } } if (min_value > max_value) { snprintf(errstr, sizeof(errstr), "cache-min-file-size (%s) is greater than " "cache-max-file-size (%s)", current_min_value, current_max_value); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_CACHE_MINMAX_SIZE_INVALID, "%s", errstr); *op_errstr = gf_strdup(errstr); ret = -1; goto out; } out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int validate_defrag_throttle_option(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { int ret = 0; if (gf_rebalance_thread_count(value, op_errstr) < 1) { gf_msg(THIS->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "%s", *op_errstr ? *op_errstr : ""); ret = -1; } return ret; } static int validate_quota(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; glusterd_conf_t *priv = NULL; int ret = 0; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); ret = glusterd_volinfo_get_boolean(volinfo, VKEY_FEATURES_QUOTA); if (ret == -1) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_QUOTA_GET_STAT_FAIL, "failed to get the quota status"); goto out; } if (ret == _gf_false) { snprintf(errstr, sizeof(errstr), "Cannot set %s. Enable quota first.", key); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_QUOTA_DISABLED, "%s", errstr); *op_errstr = gf_strdup(errstr); ret = -1; goto out; } ret = 0; out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int validate_uss(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; int ret = 0; xlator_t *this = THIS; gf_boolean_t b = _gf_false; ret = gf_string2boolean(value, &b); if (ret) { snprintf(errstr, sizeof(errstr), "%s is not a valid boolean " "value. %s expects a valid boolean value.", value, key); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", errstr); *op_errstr = gf_strdup(errstr); goto out; } out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int validate_uss_dir(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; int ret = -1; int i = 0; xlator_t *this = THIS; i = strlen(value); if (i > NAME_MAX) { snprintf(errstr, sizeof(errstr), "value of %s exceedes %d " "characters", key, NAME_MAX); goto out; } else if (i < 2) { snprintf(errstr, sizeof(errstr), "value of %s too short, " "expects at least two characters", key); goto out; } if (value[0] != '.') { snprintf(errstr, sizeof(errstr), "%s expects value starting " "with '.' ", key); goto out; } for (i = 1; value[i]; i++) { if (isalnum(value[i]) || value[i] == '_' || value[i] == '-') continue; snprintf(errstr, sizeof(errstr), "%s expects value to" " contain only '0-9a-z-_'", key); goto out; } ret = 0; out: if (ret) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "%s", errstr); *op_errstr = gf_strdup(errstr); } gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int validate_server_options(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; xlator_t *this = THIS; int ret = -1; int origin_val = 0; if (volinfo->status == GLUSTERD_STATUS_STARTED) { gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_VOL_SET_VALIDATION_INFO, "Please note that " "volume %s is started. This option will only get " "effected after a brick restart.", volinfo->volname); } ret = gf_string2int(value, &origin_val); if (ret) { snprintf(errstr, sizeof(errstr), "%s is not a compatible " "value. %s expects an integer value.", value, key); ret = -1; goto out; } if (origin_val < 0) { snprintf(errstr, sizeof(errstr), "%s is not a " "compatible value. %s expects a positive" "integer value.", value, key); ret = -1; goto out; } ret = 0; out: if (ret) { gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INCOMPATIBLE_VALUE, "%s", errstr); *op_errstr = gf_strdup(errstr); } return ret; } static int validate_disperse(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; int ret = -1; if (volinfo->type != GF_CLUSTER_TYPE_DISPERSE) { snprintf(errstr, sizeof(errstr), "Cannot set %s for a non-disperse volume.", key); gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_DISPERSE, "%s", errstr); *op_errstr = gf_strdup(errstr); ret = -1; goto out; } ret = 0; out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int validate_replica(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; int ret = 0; xlator_t *this = THIS; if (volinfo->replica_count == 1) { snprintf(errstr, sizeof(errstr), "Cannot set %s for a non-replicate volume.", key); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_REPLICA, "%s", errstr); *op_errstr = gf_strdup(errstr); ret = -1; goto out; } out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int validate_quorum_count(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { int ret = 0; xlator_t *this = THIS; int q_count = 0; ret = gf_string2int(value, &q_count); if (ret) { gf_asprintf(op_errstr, "%s is not an integer. %s expects a " "valid integer value.", value, key); goto out; } if (q_count < 1 || q_count > volinfo->replica_count) { gf_asprintf(op_errstr, "%d in %s %d is out of range [1 - %d]", q_count, key, q_count, volinfo->replica_count); ret = -1; } out: if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", *op_errstr); } gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int validate_subvols_per_directory(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; glusterd_conf_t *priv = NULL; int ret = 0; int subvols = 0; xlator_t *this = THIS; priv = this->private; GF_ASSERT(priv); subvols = atoi(value); /* Checking if the subvols-per-directory exceed the total number of subvolumes. */ if (subvols > volinfo->subvol_count) { snprintf(errstr, sizeof(errstr), "subvols-per-directory(%d) is greater " "than the number of subvolumes(%d).", subvols, volinfo->subvol_count); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SUBVOLUMES_EXCEED, "%s.", errstr); *op_errstr = gf_strdup(errstr); ret = -1; goto out; } out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int validate_replica_heal_enable_disable(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { int ret = 0; if (!glusterd_is_volume_replicate(volinfo)) { gf_asprintf(op_errstr, "Volume %s is not of replicate type", volinfo->volname); ret = -1; } return ret; } static int validate_mandatory_locking(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; int ret = 0; xlator_t *this = THIS; if (strcmp(value, "off") != 0 && strcmp(value, "file") != 0 && strcmp(value, "forced") != 0 && strcmp(value, "optimal") != 0) { snprintf(errstr, sizeof(errstr), "Invalid option value '%s':" " Available options are 'off', 'file', " "'forced' or 'optimal'", value); gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", errstr); *op_errstr = gf_strdup(errstr); ret = -1; goto out; } out: gf_msg_debug(this->name, 0, "Returning %d", ret); return ret; } static int validate_disperse_heal_enable_disable(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { int ret = 0; if (volinfo->type != GF_CLUSTER_TYPE_DISPERSE) { gf_asprintf(op_errstr, "Volume %s is not of disperse type", volinfo->volname); ret = -1; } return ret; } static int validate_lock_migration_option(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; int ret = 0; xlator_t *this = THIS; gf_boolean_t b = _gf_false; if (volinfo->replica_count > 1 || volinfo->disperse_count) { snprintf(errstr, sizeof(errstr), "Lock migration is " "a experimental feature. Currently works with" " pure distribute volume only"); ret = -1; gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "%s", errstr); *op_errstr = gf_strdup(errstr); goto out; } ret = gf_string2boolean(value, &b); if (ret) { snprintf(errstr, sizeof(errstr), "Invalid value" " for volume set command. Use on/off only."); ret = -1; gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "%s", errstr); *op_errstr = gf_strdup(errstr); goto out; } gf_msg_debug(this->name, 0, "Returning %d", ret); out: return ret; } static int validate_mux_limit(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { uint val = 0; int ret = -1; if (!is_brick_mx_enabled()) { gf_asprintf(op_errstr, "Brick-multiplexing is not enabled. " "Please enable brick multiplexing before trying " "to set this option."); gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_WRONG_OPTS_SETTING, "%s", *op_errstr); goto out; } ret = gf_string2uint(value, &val); if (ret) { gf_asprintf(op_errstr, "%s is not a valid count. " "%s expects an unsigned integer.", value, key); gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", *op_errstr); } if (val == 1) { gf_asprintf(op_errstr, "Brick-multiplexing is enabled. " "Please set this option to a value other than 1 " "to make use of the brick-multiplexing feature."); ret = -1; goto out; } out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int validate_volume_per_thread_limit(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { uint val = 0; int ret = -1; if (!is_brick_mx_enabled()) { gf_asprintf(op_errstr, "Brick-multiplexing is not enabled. " "Please enable brick multiplexing before trying " "to set this option."); gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_WRONG_OPTS_SETTING, "%s", *op_errstr); goto out; } ret = gf_string2uint(value, &val); if (ret) { gf_asprintf(op_errstr, "%s is not a valid count. " "%s expects an unsigned integer.", value, key); gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", *op_errstr); } if ((val < 5) || (val > 200)) { gf_asprintf( op_errstr, "Please set this option to a value between 5 and 200 to" "optimize processing large numbers of volumes in parallel."); ret = -1; goto out; } out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int validate_boolean(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { gf_boolean_t b = _gf_false; int ret = -1; ret = gf_string2boolean(value, &b); if (ret) { gf_asprintf(op_errstr, "%s is not a valid boolean value. %s " "expects a valid boolean value.", value, key); gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", *op_errstr); } gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int validate_disperse_quorum_count(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { int ret = -1; int quorum_count = 0; int data_count = 0; ret = gf_string2int(value, &quorum_count); if (ret) { gf_asprintf(op_errstr, "%s is not an integer. %s expects a " "valid integer value.", value, key); goto out; } if (volinfo->type != GF_CLUSTER_TYPE_DISPERSE) { gf_asprintf(op_errstr, "Cannot set %s for a non-disperse volume.", key); ret = -1; goto out; } data_count = volinfo->disperse_count - volinfo->redundancy_count; if (quorum_count < data_count || quorum_count > volinfo->disperse_count) { gf_asprintf(op_errstr, "%d for %s is out of range [%d - %d]", quorum_count, key, data_count, volinfo->disperse_count); ret = -1; goto out; } ret = 0; out: return ret; } static int validate_parallel_readdir(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { int ret = -1; ret = validate_boolean(volinfo, dict, key, value, op_errstr); if (ret) goto out; ret = glusterd_is_defrag_on(volinfo); if (ret) { gf_asprintf(op_errstr, "%s option should be set " "after rebalance is complete", key); gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", *op_errstr); } out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int validate_rda_cache_limit(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { int ret = 0; uint64_t rda_cache_size = 0; ret = gf_string2bytesize_uint64(value, &rda_cache_size); if (ret < 0) goto out; if (rda_cache_size <= (1 * GF_UNIT_GB)) goto out; /* With release 3.11 the max value of rda_cache_limit is changed from * 1GB to INFINITY. If there are clients older than 3.11 and the value * of rda-cache-limit is set to > 1GB, the older clients will stop * working. Hence if a user is setting rda-cache-limit to > 1GB * ensure that all the clients are 3.11 or greater. */ ret = glusterd_check_client_op_version_support( volinfo->volname, GD_OP_VERSION_3_11_0, op_errstr); out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int validate_worm_period(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { uint64_t period = -1; int ret = -1; ret = gf_string2uint64(value, &period); if (ret) { gf_asprintf(op_errstr, "%s is not a valid uint64_t value." " %s expects a valid uint64_t value.", value, key); gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", *op_errstr); } gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int validate_reten_mode(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { int ret = -1; if ((strcmp(value, "relax") && strcmp(value, "enterprise"))) { gf_asprintf(op_errstr, "The value of retention mode should be " "either relax or enterprise. But the value" " of %s is %s", key, value); gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", *op_errstr); ret = -1; goto out; } ret = 0; out: gf_msg_debug("glusterd", 0, "Returning %d", ret); return ret; } static int is_directory(const char *path) { struct stat statbuf; if (sys_stat(path, &statbuf) != 0) return 0; return S_ISDIR(statbuf.st_mode); } static int validate_statedump_path(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, char **op_errstr) { int ret = 0; if (!is_directory(value)) { gf_asprintf(op_errstr, "Failed: %s is not a directory", value); ret = -1; gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", *op_errstr); } return ret; } /* dispatch table for VOLUME SET * ----------------------------- * * Format of entries: * * First field is the , for the purpose of looking it up * in volume dictionary. Each is of the format ".". * * Second field is . * * Third field is