diff options
| author | Kaushik BV <kaushikbv@gluster.com> | 2011-01-27 05:23:30 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2011-01-27 03:16:51 -0800 | 
| commit | 73bce15b61755509de23d32646135254d369a2f6 (patch) | |
| tree | 921b92f6d3e549b1e6dd68bc886cc727caec5429 | |
| parent | 11dd59b788334fe2de1653ae85395986ba531606 (diff) | |
adding libxlator, to ensure proper client side aggregation of marks by clustering translators
Signed-off-by: Kaushik BV <kaushikbv@gluster.com>
Signed-off-by: Csaba Henk <csaba@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 2310 (georeplication)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2310
| -rw-r--r-- | libglusterfs/src/mem-types.h | 3 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/Makefile.am | 7 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-inode-read.c | 74 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 10 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/Makefile.am | 10 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 71 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 5 | ||||
| -rw-r--r-- | xlators/cluster/stripe/src/Makefile.am | 7 | ||||
| -rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 108 | ||||
| -rw-r--r-- | xlators/cluster/stripe/src/stripe.h | 5 | ||||
| -rw-r--r-- | xlators/lib/src/libxlator.c | 371 | ||||
| -rw-r--r-- | xlators/lib/src/libxlator.h | 86 | 
12 files changed, 737 insertions, 20 deletions
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h index 9e857901b..3a55bdc7c 100644 --- a/libglusterfs/src/mem-types.h +++ b/libglusterfs/src/mem-types.h @@ -97,6 +97,7 @@ enum gf_common_mem_types_ {          gf_common_mt_rdma_context_t     =       72,          gf_common_mt_sge                =       73,          gf_common_mt_rpcclnt_cb_program_t =     74, -        gf_common_mt_end                =       75 +        gf_common_mt_libxl_marker_local =       75, +        gf_common_mt_end                =       76  };  #endif diff --git a/xlators/cluster/afr/src/Makefile.am b/xlators/cluster/afr/src/Makefile.am index 4e4b4c752..e192b599b 100644 --- a/xlators/cluster/afr/src/Makefile.am +++ b/xlators/cluster/afr/src/Makefile.am @@ -1,7 +1,7 @@  xlator_LTLIBRARIES = afr.la pump.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-self-heal-data.c afr-self-heal-common.c afr-self-heal-metadata.c afr-self-heal-entry.c afr-self-heal-algorithm.c afr-lk-common.c +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-self-heal-data.c afr-self-heal-common.c afr-self-heal-metadata.c afr-self-heal-entry.c afr-self-heal-algorithm.c afr-lk-common.c $(top_builddir)/xlators/lib/src/libxlator.c  afr_la_LDFLAGS = -module -avoidversion  afr_la_SOURCES = $(afr_common_source) afr.c @@ -11,10 +11,11 @@ pump_la_LDFLAGS = -module -avoidversion  pump_la_SOURCES =  $(afr_common_source) pump.c  pump_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-self-heal-common.h afr-self-heal-algorithm.h pump.h afr-mem-types.h afr-common.c +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-self-heal-common.h afr-self-heal-algorithm.h pump.h afr-mem-types.h afr-common.c $(top_builddir)/xlators/lib/src/libxlator.h  AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \ -	    -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/contrib/md5 -shared -nostartfiles $(GF_CFLAGS) +	    -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/contrib/md5 -shared -nostartfiles $(GF_CFLAGS) \ +	    -I$(top_srcdir)/xlators/lib/src  CLEANFILES = diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c index 399860767..ce6a6a363 100644 --- a/xlators/cluster/afr/src/afr-inode-read.c +++ b/xlators/cluster/afr/src/afr-inode-read.c @@ -657,6 +657,15 @@ out:  }  int32_t +afr_getxattr_unwind (void *arg, call_frame_t *frame, +                        int op_ret, int op_errno, dict_t *dict) + +{ +        AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict); +        return 0; +} + +int32_t  afr_getxattr (call_frame_t *frame, xlator_t *this,  	      loc_t *loc, const char *name)  { @@ -664,8 +673,11 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,  	xlator_t **       children   = NULL;  	int               call_child = 0;  	afr_local_t     * local      = NULL; +        xlator_list_t   * trav       = NULL; +        xlator_t       ** sub_volumes= NULL;          int               read_child = -1; +        int               i          = 0;  	int32_t op_ret   = -1;  	int32_t op_errno = 0; @@ -683,6 +695,11 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,  	ALLOC_OR_GOTO (local, afr_local_t, out);  	frame->local = local; +        loc_copy (&local->loc, loc); +        if (name) +                local->cont.getxattr.name       = gf_strdup (name); + +          if (name) {                  if (!strncmp (name, AFR_XATTR_PREFIX,                                strlen (AFR_XATTR_PREFIX))) { @@ -690,6 +707,60 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,                          op_errno = ENODATA;                          goto out;                  } +                if ((strcmp (GF_XATTR_MARKER_KEY, name) == 0) +                    && (-1 == frame->root->pid)) { + +                        local->marker.call_count = priv->child_count; + +                        sub_volumes = alloca ( priv->child_count * sizeof (xlator_t *)); +                        for (i = 0, trav = this->children; trav ; +                                                trav = trav->next, i++) { + +                                *(sub_volumes + i)  = trav->xlator; +                        } + +                        if (cluster_getmarkerattr (frame, this, loc, name, +                                                   local, afr_getxattr_unwind, +                                                   sub_volumes, +                                                   priv->child_count, +                                                   MARKER_UUID_TYPE, +                                                   priv->vol_uuid)) { + +                                op_errno = EINVAL; +                                goto out; +                       } + +                        return 0; +                } + +                if (*priv->vol_uuid) { +                        if ((match_uuid_local (name, priv->vol_uuid) == 0) +                            && (-1 == frame->root->pid)) { + +                                local->marker.call_count = priv->child_count; + +                                sub_volumes = alloca ( priv->child_count * sizeof (xlator_t *)); +                                for (i = 0, trav = this->children; trav ; +                                                trav = trav->next, i++) { + +                                        *(sub_volumes + i)  = trav->xlator; + +                                } + +                                if (cluster_getmarkerattr (frame, this, loc, +                                                           name, local, +                                                           afr_getxattr_unwind, +                                                           sub_volumes, +                                                           priv->child_count, +                                                           MARKER_XTIME_TYPE, +                                                           priv->vol_uuid)) { +                                        op_errno = EINVAL; +                                        goto out; +                                } + +                                return 0; +                        } +                }          } @@ -712,9 +783,6 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,                  local->cont.getxattr.last_tried = call_child;          } -	loc_copy (&local->loc, loc); -	if (name) -	  local->cont.getxattr.name       = gf_strdup (name);  	STACK_WIND_COOKIE (frame, afr_getxattr_cbk,  			   (void *) (long) call_child, diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index a7359f269..b0e434142 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -30,6 +30,8 @@  #include "compat-errno.h"  #include "afr-mem-types.h" +#include "libxlator.h" +  #define AFR_XATTR_PREFIX "trusted.afr"  struct _pump_private; @@ -89,6 +91,8 @@ typedef struct _afr_private {          pthread_mutex_t  mutex;          struct list_head saved_fds;   /* list of fds on which locks have succeeded */          gf_boolean_t     optimistic_change_log; + +        char                   vol_uuid[UUID_SIZE + 1];  } afr_private_t;  typedef struct { @@ -616,6 +620,8 @@ typedef struct _afr_local {  	} transaction;  	afr_self_heal_t self_heal; + +        struct marker_str     marker;  } afr_local_t; @@ -927,4 +933,8 @@ afr_transaction_local_init (afr_local_t *local, afr_private_t *priv)  	return 0;  } +int32_t +afr_marker_getxattr (call_frame_t *frame, xlator_t *this, +              loc_t *loc, const char *name,afr_local_t *local, afr_private_t *priv ); +  #endif /* __AFR_H__ */ diff --git a/xlators/cluster/dht/src/Makefile.am b/xlators/cluster/dht/src/Makefile.am index 4b69aa071..8ebcab044 100644 --- a/xlators/cluster/dht/src/Makefile.am +++ b/xlators/cluster/dht/src/Makefile.am @@ -4,7 +4,8 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster  dht_common_source = dht-layout.c dht-helper.c dht-linkfile.c \ -		dht-selfheal.c dht-rename.c dht-hashfn.c dht-diskusage.c +		dht-selfheal.c dht-rename.c dht-hashfn.c dht-diskusage.c \ +		$(top_builddir)/xlators/lib/src/libxlator.c  dht_la_SOURCES = $(dht_common_source) dht.c  @@ -20,10 +21,11 @@ nufa_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la  switch_la_LDFLAGS = -module -avoidversion  switch_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -noinst_HEADERS = dht-common.h dht-common.c dht-mem-types.h +noinst_HEADERS = dht-common.h dht-common.c dht-mem-types.h $(top_builddir)/xlators/lib/src/libxlator.h  AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \ -	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) +	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \ +	-I$(top_srcdir)/xlators/lib/src  CLEANFILES =  @@ -31,4 +33,4 @@ uninstall-local:  	rm -f $(DESTDIR)$(xlatordir)/distribute.so  install-data-hook: -	ln -sf dht.so $(DESTDIR)$(xlatordir)/distribute.so
\ No newline at end of file +	ln -sf dht.so $(DESTDIR)$(xlatordir)/distribute.so diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index e20472646..cca09927c 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -27,12 +27,14 @@  #include "glusterfs.h"  #include "xlator.h" +#include "libxlator.h"  #include "dht-common.h"  #include "defaults.h"  #include <sys/time.h>  #include <libgen.h> +  /* TODO:     - use volumename in xattr instead of "dht"     - use NS locks @@ -1834,6 +1836,14 @@ out:          return 0;  } +int32_t +dht_getxattr_unwind (void *getxattr, call_frame_t *frame, +                        int op_ret, int op_errno, dict_t *dict) +{ +        DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict); +        return 0; +} +  int  dht_getxattr (call_frame_t *frame, xlator_t *this, @@ -1845,6 +1855,7 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,  	dht_conf_t   *conf          = NULL;  	dht_local_t  *local         = NULL;          dht_layout_t *layout        = NULL; +        xlator_t     **sub_volumes  = NULL;          int           op_errno      = -1;          int           ret           = 0;          int           flag          = 0; @@ -1867,6 +1878,14 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,                  goto err;          } +        local = dht_local_init (frame); +        if (!local) { +                op_errno = ENOMEM; +                gf_log (this->name, GF_LOG_ERROR, +                       "Out of memory"); +                goto err; +        } +          if (key && (strcmp (key, GF_XATTR_PATHINFO_KEY) == 0)) {                  hashed_subvol = dht_subvol_get_hashed (this, loc);                  cached_subvol = dht_subvol_get_cached (this, loc->inode); @@ -1959,12 +1978,52 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,                  goto err;          } -        local = dht_local_init (frame); -        if (!local) { -                op_errno = ENOMEM; -                gf_log (this->name, GF_LOG_ERROR, -                       "Out of memory"); -                goto err; +        if (key && (!strcmp (GF_XATTR_MARKER_KEY, key)) +                && (-1 == frame->root->pid)) { + +                if (loc->inode-> ia_type == IA_IFDIR) { +                        cnt = layout->cnt; +                } else { +                        cnt = 1; +                } +                sub_volumes = alloca ( cnt * sizeof (xlator_t *)); +                for (i = 0; i < cnt; i++) +                        *(sub_volumes + i) = layout->list[i].xlator; + +                if (cluster_getmarkerattr (frame, this, loc, key, +                                           local, dht_getxattr_unwind, +                                           sub_volumes, cnt, +                                           MARKER_UUID_TYPE, conf->vol_uuid)) { +                        op_errno = EINVAL; +                        goto err; +                } + +                return 0; +        } + +        if (key && *conf->vol_uuid) { +                if ((match_uuid_local (key, conf->vol_uuid) == 0) && +                    (-1 == frame->root->pid)) { +                        if (loc->inode-> ia_type == IA_IFDIR) { +                                cnt = layout->cnt; +                        } else { +                                cnt = 1; +                        } +                        sub_volumes = alloca ( cnt * sizeof (xlator_t *)); +                        for (i = 0; i < cnt; i++) +                                sub_volumes[i] = layout->list[i].xlator; + +                        if (cluster_getmarkerattr (frame, this, loc, key, +                                                   local, dht_getxattr_unwind, +                                                   sub_volumes, cnt, +                                                   MARKER_XTIME_TYPE, +                                                   conf->vol_uuid)) { +                                op_errno = EINVAL; +                                goto err; +                        } + +                        return 0; +                }          }          ret = loc_dup (loc, &local->loc); diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index becc8d9c8..6a4daa65e 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -23,6 +23,7 @@  #endif  #include "dht-mem-types.h" +#include "libxlator.h"  #ifndef _DHT_H  #define _DHT_H @@ -128,6 +129,9 @@ struct dht_local {          /* gfid related */          uuid_t  gfid; + +        /*Marker Related*/ +        struct marker_str    marker;  };  typedef struct dht_local dht_local_t; @@ -160,6 +164,7 @@ struct dht_conf {          void          *private;     /* Can be used by wrapper xlators over                                         dht */          gf_boolean_t   use_readdirp; +        char           vol_uuid[UUID_SIZE + 1];  };  typedef struct dht_conf dht_conf_t; diff --git a/xlators/cluster/stripe/src/Makefile.am b/xlators/cluster/stripe/src/Makefile.am index 6d4fae4d2..0db3c9eeb 100644 --- a/xlators/cluster/stripe/src/Makefile.am +++ b/xlators/cluster/stripe/src/Makefile.am @@ -4,13 +4,14 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster  stripe_la_LDFLAGS = -module -avoidversion -stripe_la_SOURCES = stripe.c +stripe_la_SOURCES = stripe.c $(top_builddir)/xlators/lib/src/libxlator.c  stripe_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -noinst_HEADERS = stripe.h stripe-mem-types.h +noinst_HEADERS = stripe.h stripe-mem-types.h $(top_builddir)/xlators/lib/src/libxlator.h  AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ -	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) +	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \ +	-I$(top_srcdir)/xlators/lib/src  CLEANFILES =  diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 639fbfd8b..cc34a8468 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -34,6 +34,7 @@   */  #include "stripe.h" +#include "libxlator.h"  void  stripe_local_wipe (stripe_local_t *local) @@ -3896,6 +3897,7 @@ init (xlator_t *this)          priv->nodes_down = priv->child_count;          this->private = priv; +          ret = 0;  out:          if (ret) { @@ -3942,6 +3944,110 @@ out:          return;  } +int32_t +stripe_getxattr_unwind (void *getxattr, call_frame_t *frame, +                        int op_ret, int op_errno, dict_t *dict) + +{ +        STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); +        return 0; +} + +int32_t +stripe_getxattr (call_frame_t *frame, xlator_t *this, +              loc_t *loc, const char *name) +{ +        stripe_local_t     *local = NULL; +        xlator_list_t      *trav = NULL; +        stripe_private_t   *priv = NULL; +        int32_t             op_errno = EINVAL; +        int                 i = 0; +        xlator_t          **sub_volumes; + +        VALIDATE_OR_GOTO (frame, err); +        VALIDATE_OR_GOTO (this, err); +        VALIDATE_OR_GOTO (loc, err); +        VALIDATE_OR_GOTO (loc->path, err); +        VALIDATE_OR_GOTO (loc->inode, err); + +        priv = this->private; +        trav = this->children; + +        /* Initialization */ +        local = GF_CALLOC (1, sizeof (stripe_local_t), +                           gf_stripe_mt_stripe_local_t); +        if (!local) { +                op_errno = ENOMEM; +                goto err; +        } +        local->op_ret = -1; +        frame->local = local; +        loc_copy (&local->loc, loc); + + +        if (name && (strcmp (GF_XATTR_MARKER_KEY, name) == 0) +                 && (-1 == frame->root->pid)) { +                local->marker.call_count = priv->child_count; + +                sub_volumes = alloca ( priv->child_count * +                                       sizeof (xlator_t *)); +                for (i = 0, trav = this->children; trav ; +                                trav = trav->next, i++) { + +                        *(sub_volumes + i)  = trav->xlator; + +                } + +                if (cluster_getmarkerattr (frame, this, loc, name, +                                           local, stripe_getxattr_unwind, +                                           sub_volumes, priv->child_count, +                                           MARKER_UUID_TYPE, priv->vol_uuid)) { +                        op_errno = EINVAL; +                        goto err; +                } + +                return 0; +        } + +        if (*priv->vol_uuid) { +                if ((match_uuid_local (name, priv->vol_uuid) == 0) +                    && (-1 == frame->root->pid)) { +                        local->marker.call_count = priv->child_count; + +                        sub_volumes = alloca ( priv->child_count * +                                               sizeof (xlator_t *)); +                        for (i = 0, trav = this->children; trav ; +                                        trav = trav->next, i++) { + +                                *(sub_volumes + i) = trav->xlator; + +                        } + +                        if (cluster_getmarkerattr (frame, this, loc, name, +                                                   local, stripe_getxattr_unwind, +                                                   sub_volumes, +                                                   priv->child_count, +                                                   MARKER_XTIME_TYPE, +                                                   priv->vol_uuid)) { +                                op_errno = EINVAL; +                                goto err; +                        } +                        return 0; +                } +        } + + +        STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this), +                    FIRST_CHILD(this)->fops->getxattr, loc, name); + +        return 0; + +err: +        STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL); +        return 0; +} + +  struct xlator_fops fops = {          .stat        = stripe_stat, @@ -3967,6 +4073,8 @@ struct xlator_fops fops = {          .fsetattr    = stripe_fsetattr,          .lookup      = stripe_lookup,          .mknod       = stripe_mknod, + +        .getxattr    = stripe_getxattr,  };  struct xlator_cbks cbks = { diff --git a/xlators/cluster/stripe/src/stripe.h b/xlators/cluster/stripe/src/stripe.h index 6199c0061..86555144f 100644 --- a/xlators/cluster/stripe/src/stripe.h +++ b/xlators/cluster/stripe/src/stripe.h @@ -33,6 +33,7 @@  #include "compat.h"  #include "compat-errno.h"  #include "stripe-mem-types.h" +#include "libxlator.h"  #include <fnmatch.h>  #include <signal.h> @@ -84,6 +85,7 @@ struct stripe_private {          int8_t                  child_count;          int8_t                 *state; /* Current state of child node */          gf_boolean_t            xattr_supported;  /* default yes */ +        char                    vol_uuid[UUID_SIZE + 1];  };  /** @@ -163,6 +165,8 @@ struct stripe_local {          /* For File I/O fops */          dict_t              *dict; +        struct marker_str    marker; +          /* General usage */          off_t                offset;          off_t                stripe_size; @@ -180,4 +184,5 @@ struct stripe_local {  typedef struct stripe_local   stripe_local_t;  typedef struct stripe_private stripe_private_t; +  #endif /* _STRIPE_H_ */ diff --git a/xlators/lib/src/libxlator.c b/xlators/lib/src/libxlator.c new file mode 100644 index 000000000..7708f86e6 --- /dev/null +++ b/xlators/lib/src/libxlator.c @@ -0,0 +1,371 @@ +#include "mem-types.h" +#include "libxlator.h" + + +/*Copy the contents of oldtimebuf to newtimbuf*/ +static void +update_timebuf (uint32_t *oldtimbuf, uint32_t *newtimebuf) +{ +        newtimebuf[0] =  (oldtimbuf[0]); +        newtimebuf[1] =  (oldtimbuf[1]); +} + +/* Convert Timebuf in network order to host order */ +static void +get_hosttime (uint32_t *oldtimbuf, uint32_t *newtimebuf) +{ +        newtimebuf[0] = ntohl (oldtimbuf[0]); +        newtimebuf[1] = ntohl (oldtimbuf[1]); +} + + + +/* Match the Incoming trusted.glusterfs.<uuid>.xtime against volume uuid */ +int +match_uuid_local (const char *name, char *uuid) +{ +        name = strtail ((char *)name, MARKER_XATTR_PREFIX); +        if (!name || name++[0] != '.') +                return -1; + +        name = strtail ((char *)name, uuid); +        if (!name || strcmp (name, ".xtime") != 0) +                return -1; + +        return 0; +} + + + + +/* Aggregate all the <volid>.xtime attrs of the cluster and send the max*/ +int32_t +cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                        int op_ret, int op_errno, dict_t *dict) + +{ + +        int32_t            callcnt = 0; +        int                ret = -1; +        uint32_t          *net_timebuf; +        uint32_t           host_timebuf[2]; +        char              *marker_xattr; +        struct marker_str *local; +        char              *vol_uuid; + +        if (!this || !frame || !frame->local || !cookie) { +                gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref"); +                goto out; +        } + +        local = frame->local; +        if (!local || !local->vol_uuid) { +                gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref"); +                goto out; +        } + +        vol_uuid = local->vol_uuid; + +        if (op_ret && op_errno == ENOENT) { +                LOCK (&frame->lock); +                { +                        callcnt = --local->call_count; +                        local->enoent_count++; +                } +                goto done; +        } + +        if (op_ret && op_errno == ENOTCONN) { +                LOCK (&frame->lock); +                { +                        callcnt = --local->call_count; +                        local->enotconn_count++; +                } +                goto done; +        } + + +        LOCK (&frame->lock); +        { +                callcnt = --local->call_count; +                if (!gf_asprintf (& marker_xattr, "%s.%s.%s", +                                MARKER_XATTR_PREFIX, vol_uuid, XTIME)) { +                        op_errno = ENOMEM; +                        goto out; +                } + + +                if (dict_get_ptr (dict, marker_xattr, (void **)&net_timebuf)) { +                        gf_log (this->name, GF_LOG_WARNING, +                                "Unable to get <uuid>.xtime attr"); + +                        goto done; +                } + +                if (local->has_xtime) { + +                        get_hosttime (net_timebuf, host_timebuf); +                        if ( (host_timebuf[0]>local->host_timebuf[0]) || +                                (host_timebuf[0] == local->host_timebuf[0] && +                                 host_timebuf[1] >= local->host_timebuf[1])) { + +                                update_timebuf (net_timebuf, local->net_timebuf); +                                update_timebuf (host_timebuf, local->host_timebuf); + +                        } + +                } +                else { +                        get_hosttime (net_timebuf, local->host_timebuf); +                        update_timebuf (net_timebuf, local->net_timebuf); +                        local->has_xtime = _gf_true; +                } + + + +        } +done: +        UNLOCK (&frame->lock); + +        if (!callcnt) { + +                op_ret = 0; +                op_errno = 0; +                if (local->has_xtime) { +                        if (!dict) { +                                dict = dict_new(); +                                if (ret) { +                                        op_ret = -1; +                                        op_errno = ENOMEM; +                                        goto out; +                                } +                        } +                        ret = dict_set_static_bin (dict, marker_xattr, +                                           (void *)local->net_timebuf, 8); +                        if (ret) { +                                op_ret = -1; +                                op_errno = ENOMEM; +                                goto out; +                        } +                } +                else { +                        op_ret = -1; +                        if (local->enotconn_count) { +                                op_errno = ENOTCONN; +                                goto out; +                        } +                        if (local->enoent_count) { +                                op_errno = ENOENT; +                                goto out; +                        } +                        else { +                                op_errno = EINVAL; +                                goto out; +                        } +                } +out: +                if (local->xl_specf_unwind) { +                        frame->local = local->xl_local; +                        local->xl_specf_unwind (getxattr, frame, op_ret, +                                                 op_errno, dict); +                        return 0; +                } +                STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); + +        } + +        return 0; + +} + +int32_t +cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                        int op_ret, int op_errno, dict_t *dict) +{ +        int32_t              callcnt = 0; +        data_t              *data = NULL; +        struct volume_mark  *volmark = NULL; +        struct marker_str   *marker = NULL; +        char                *vol_uuid; + + +        if (!this || !frame || !cookie) { +                gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref"); +                goto out; +        } + +        marker = frame->local; + +        if (!marker) { +                gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref"); +                goto out; +        } + +        vol_uuid = marker->vol_uuid; + +        if (op_ret && (ENOENT == op_errno)) { +                LOCK (&frame->lock); +                { +                        callcnt = --marker->call_count; +                        marker->enoent_count++; +                } +                goto done; +        } + +        if (op_ret && (ENOTCONN == op_errno)) { +                LOCK (&frame->lock); +                { +                        callcnt = --marker->call_count; +                        marker->enotconn_count++; +                } +                goto done; +        } + +        if (!(data = dict_get (dict, GF_XATTR_MARKER_KEY))) { +                LOCK (&frame->lock); +                { +                        callcnt = --marker->call_count; +                } +                goto done; +        } + +        volmark = (struct volume_mark *)data->data; + +        LOCK (&frame->lock); +        { +                callcnt = --marker->call_count; + +                if (marker_has_volinfo (marker)) { + +                        if ((marker->volmark->major != volmark->major) || +                            (marker->volmark->minor != volmark->minor)) { +                                op_ret = -1; +                                op_errno = EINVAL; +                                goto out; +                        } +                        else if (volmark->retval) { +                                data_unref ((data_t *) marker->volmark); +                                marker->volmark = volmark; +                                callcnt = 0; +                        } +                        else if ( (volmark->sec > marker->volmark->sec) || +                                   ((volmark->sec == marker->volmark->sec) +                                      && (volmark->usec >= marker->volmark->usec))) { + +                                marker->volmark = volmark; +                        } + +                } else { +                        marker->volmark = volmark; +                        uuid_unparse (volmark->uuid, vol_uuid); +                        if (volmark->retval) +                                callcnt = 0; +                } +        } +done: +        UNLOCK (&frame->lock); + +        if (!callcnt) { +                op_ret = 0; +                op_errno = 0; +                if (marker_has_volinfo (marker)) { +                        if (!dict) { +                                dict = dict_new(); +                                if (!dict) { +                                        op_ret = -1; +                                        op_errno = ENOMEM; +                                        goto out; +                                } +                        } +                        if (dict_set_static_bin (dict, GF_XATTR_MARKER_KEY, +                                          marker->volmark, +                                          sizeof (struct volume_mark))) { +                                op_ret = -1; +                                op_errno = ENOMEM; +                        } +                        goto out; +                } +                if (marker->enotconn_count) { +                        op_ret = -1; +                        op_errno = ENOTCONN; +                        goto out; +                } +                if (marker->enoent_count) { +                        op_ret = -1; +                        op_errno = ENOENT; +                } +                else { +                        op_ret = -1; +                        op_errno = EINVAL; +                } + + out: +                if (marker->xl_specf_unwind) { +                        frame->local = marker->xl_local; +                        marker->xl_specf_unwind (getxattr, frame, op_ret, +                                                 op_errno, dict); +                        return 0; +                } +                STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); +        } +        return 0; +} + + +int32_t +cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc, +                       const char *name, void *xl_local, +                       xlator_specf_unwind_t xl_specf_getxattr_unwind, +                       xlator_t **sub_volumes, int count, int type, +                       char *vol_uuid) +{ +        int               i; +        struct marker_str *local; + +        VALIDATE_OR_GOTO (frame, err); +        VALIDATE_OR_GOTO (this, err); +        VALIDATE_OR_GOTO (loc, err); +        VALIDATE_OR_GOTO (loc->path, err); +        VALIDATE_OR_GOTO (loc->inode, err); +        VALIDATE_OR_GOTO (name, err); +        VALIDATE_OR_GOTO (xl_specf_getxattr_unwind, err); + +        local = GF_CALLOC (sizeof (struct marker_str), 1, +                            gf_common_mt_libxl_marker_local); + +        local->xl_local = xl_local; +        frame->local = local; + +        local->call_count = count; + +        local->xl_specf_unwind = xl_specf_getxattr_unwind; + +        local->vol_uuid = vol_uuid; + +        for (i=0; i < count; i++) { +                if (MARKER_UUID_TYPE == type) +                        STACK_WIND (frame, cluster_markeruuid_cbk, +                                    *(sub_volumes + i), +                                    (*(sub_volumes + i))->fops->getxattr, +                                    loc, name); +                else if (MARKER_XTIME_TYPE == type) +                        STACK_WIND (frame, cluster_markerxtime_cbk, +                                    *(sub_volumes + i), +                                    (*(sub_volumes + i))->fops->getxattr, +                                    loc, name); +                else { +                        gf_log (this->name, GF_LOG_WARNING, +                                 "Unrecognized type of marker attr recived"); +                        STACK_WIND (frame, default_getxattr_cbk, +                                    *(sub_volumes + i), +                                    (*(sub_volumes + i))->fops->getxattr, +                                    loc, name); +                        break; +                } +        } + +        return 0; +err: +        return -1; + +} diff --git a/xlators/lib/src/libxlator.h b/xlators/lib/src/libxlator.h new file mode 100644 index 000000000..be8a00936 --- /dev/null +++ b/xlators/lib/src/libxlator.h @@ -0,0 +1,86 @@ +#ifndef _LIBXLATOR_H +#define _LIBXLATOR_H + + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "xlator.h" +#include "logging.h" +#include "defaults.h" +#include "common-utils.h" +#include "compat.h" +#include "compat-errno.h" + + +#define MARKER_XATTR_PREFIX "trusted.glusterfs" +#define XTIME               "xtime" +#define VOLUME_MARK         "volume-mark" +#define GF_XATTR_MARKER_KEY MARKER_XATTR_PREFIX "." VOLUME_MARK +#define UUID_SIZE 36 +#define MARKER_UUID_TYPE    1 +#define MARKER_XTIME_TYPE   2 + + +typedef int32_t (*xlator_specf_unwind_t) (void *getxattr, call_frame_t *frame, +                                         int op_ret, int op_errno, dict_t *dict); + + +struct volume_mark { +        uint8_t major; +        uint8_t minor; +        uint8_t uuid[16]; +        uint8_t retval; +        uint32_t sec; +        uint32_t usec; +}__attribute__ ((__packed__)); + +struct marker_str { +        struct volume_mark    *volmark; +        data_t                *data; + +        uint32_t               host_timebuf[2]; +        uint32_t               net_timebuf[2]; +        int32_t                call_count; +        unsigned               has_xtime:1; +        int32_t                enoent_count; +        int32_t                enotconn_count; + +        xlator_specf_unwind_t  xl_specf_unwind; +        void                  *xl_local; +        char                  *vol_uuid; +}; + +static inline gf_boolean_t +marker_has_volinfo (struct marker_str *marker) +{ +       if (marker->volmark) +                return _gf_true; +       else +                return _gf_false; +} + +int32_t +cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                        int op_ret, int op_errno, dict_t *dict); + +int32_t +cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                        int op_ret, int op_errno, dict_t *dict); + +int32_t +cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc, +                       const char *name, void *xl_local, +                       xlator_specf_unwind_t xl_specf_getxattr_unwind, +                       xlator_t **sub_volumes, int count, int type, +                       char *vol_uuid); + +int +match_uuid_local (const char *name, char *uuid); + + + + +#endif /* !_LIBXLATOR_H */  | 
