diff options
| author | Kevin Vigor <kvigor@fb.com> | 2017-01-09 09:16:05 -0800 | 
|---|---|---|
| committer | Kevin Vigor <kvigor@fb.com> | 2017-01-09 09:16:05 -0800 | 
| commit | b49d30a20efee06eb5a5007a244f3c474366cb35 (patch) | |
| tree | 317639c5e045d9bbbcbd14e16d423b3ac86e4f70 | |
| parent | c5145b464e6ebc77021fe4ebef4aaf8312a323aa (diff) | |
| parent | 068e4f345f51438d252b1e330ca7049bd4a67e03 (diff) | |
Merge remote-tracking branch 'origin/release-3.8' into 3.8-merge
| -rw-r--r-- | geo-replication/syncdaemon/configinterface.py.in | 17 | ||||
| -rw-r--r-- | geo-replication/syncdaemon/resource.py | 9 | ||||
| -rw-r--r-- | libglusterfs/src/compat.h | 12 | ||||
| -rwxr-xr-x | tests/bugs/nfs/zero-atime.t | 31 | ||||
| -rw-r--r-- | tests/bugs/replicate/bug-1386188-sbrain-fav-child.t | 82 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 205 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-read-txn.c | 14 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.c | 159 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-data.c | 21 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 3 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-metadata.c | 15 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal.h | 24 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-transaction.c | 9 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 1 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-helper.c | 7 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-rebalance.c | 29 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 32 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 26 | 
18 files changed, 570 insertions, 126 deletions
diff --git a/geo-replication/syncdaemon/configinterface.py.in b/geo-replication/syncdaemon/configinterface.py.in index e1cf007a2b8..97afff1dda7 100644 --- a/geo-replication/syncdaemon/configinterface.py.in +++ b/geo-replication/syncdaemon/configinterface.py.in @@ -234,7 +234,7 @@ class GConffile(object):              self.config.readfp(fp)          self._normconfig() -    def get_realtime(self, opt): +    def get_realtime(self, opt, default_value=None):          try:              sres = os.stat(self.path)          except (OSError, IOError): @@ -248,7 +248,7 @@ class GConffile(object):             sres[ST_INO] != self.ino or self.mtime != sres[ST_MTIME]:              self._load() -        return self.get(opt, printValue=False) +        return self.get(opt, printValue=False, default_value=default_value)      def section(self, rx=False):          """get the section name of the section representing .peers @@ -347,7 +347,7 @@ class GConffile(object):          if self.config.has_section(self.section()):              update_from_sect(self.section(), MultiDict(dct, *self.auxdicts)) -    def get(self, opt=None, printValue=True): +    def get(self, opt=None, printValue=True, default_value=None):          """print the matching key/value pairs from .config,             or if @opt given, the value for @opt (according to the             logic described in .update_to) @@ -356,12 +356,13 @@ class GConffile(object):          self.update_to(d, allow_unresolved=True)          if opt:              opt = norm(opt) -            v = d.get(opt) -            if v: -                if printValue: +            v = d.get(opt, default_value) + +            if printValue: +                if v is not None:                      print(v) -                else: -                    return v +            else: +                return v          else:              for k, v in d.iteritems():                  if k == '__name__': diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py index 7daf7e49211..ecb94d56c7f 100644 --- a/geo-replication/syncdaemon/resource.py +++ b/geo-replication/syncdaemon/resource.py @@ -1003,8 +1003,10 @@ class SlaveRemote(object):              (boolify(gconf.sync_acls) and ['--acls'] or []) + \              ['.'] + list(args) -        if boolify(gconf.configinterface.get_realtime( -                "log_rsync_performance")): +        log_rsync_performance = boolify(gconf.configinterface.get_realtime( +            "log_rsync_performance", default_value=False)) + +        if log_rsync_performance:              # use stdout=PIPE only when log_rsync_performance enabled              # Else rsync will write to stdout and nobody is their              # to consume. If PIPE is full rsync hangs. @@ -1023,8 +1025,7 @@ class SlaveRemote(object):              for errline in stderr.strip().split("\n")[:-1]:                  logging.error("SYNC Error(Rsync): %s" % errline) -        if boolify(gconf.configinterface.get_realtime( -                "log_rsync_performance")): +        if log_rsync_performance:              rsync_msg = []              for line in stdout.split("\n"):                  if line.startswith("Number of files:") or \ diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h index 56736e52052..771ed983d32 100644 --- a/libglusterfs/src/compat.h +++ b/libglusterfs/src/compat.h @@ -444,6 +444,12 @@ int gf_mkostemp (char *tmpl, int suffixlen, int flags);  #ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC  /* Linux, Solaris, Cygwin */ +#define ST_ATIM_SEC(stbuf) ((stbuf)->st_atim.tv_sec) +#define ST_CTIM_SEC(stbuf) ((stbuf)->st_ctim.tv_sec) +#define ST_MTIM_SEC(stbuf) ((stbuf)->st_mtim.tv_sec) +#define ST_ATIM_SEC_SET(stbuf, val) ((stbuf)->st_atim.tv_sec = (val)) +#define ST_MTIM_SEC_SET(stbuf, val) ((stbuf)->st_mtim.tv_sec = (val)) +#define ST_CTIM_SEC_SET(stbuf, val) ((stbuf)->st_ctim.tv_sec = (val))  #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec)  #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec)  #define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.tv_nsec) @@ -452,6 +458,12 @@ int gf_mkostemp (char *tmpl, int suffixlen, int flags);  #define ST_CTIM_NSEC_SET(stbuf, val) ((stbuf)->st_ctim.tv_nsec = (val))  #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC)  /* FreeBSD, NetBSD */ +#define ST_ATIM_SEC(stbuf) ((stbuf)->st_atimespec.tv_sec) +#define ST_CTIM_SEC(stbuf) ((stbuf)->st_ctimespec.tv_sec) +#define ST_MTIM_SEC(stbuf) ((stbuf)->st_mtimespec.tv_sec) +#define ST_ATIM_SEC_SET(stbuf, val) ((stbuf)->st_atimespec.tv_sec = (val)) +#define ST_MTIM_SEC_SET(stbuf, val) ((stbuf)->st_mtimespec.tv_sec = (val)) +#define ST_CTIM_SEC_SET(stbuf, val) ((stbuf)->st_ctimespec.tv_sec = (val))  #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec)  #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec)  #define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.tv_nsec) diff --git a/tests/bugs/nfs/zero-atime.t b/tests/bugs/nfs/zero-atime.t new file mode 100755 index 00000000000..631240a692f --- /dev/null +++ b/tests/bugs/nfs/zero-atime.t @@ -0,0 +1,31 @@ +#!/bin/bash +# +# posix_do_utimes() sets atime and mtime to the values in the passed IATT. If +# not set, these values are 0 and cause a atime/mtime set to the Epoch. +# + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../nfs.rc + +cleanup + +TEST glusterd +TEST pidof glusterd + +TEST $CLI volume create $V0 $H0:$B0/$V0 +TEST $CLI volume set $V0 nfs.disable false +TEST $CLI volume start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available; +TEST mount_nfs $H0:/$V0 $N0 nolock + +# create a file for testing +TEST dd if=/dev/urandom of=$M0/small count=1 bs=1024k + +# timezone in UTC results in atime=0 if not set correctly +TEST TZ=UTC dd if=/dev/urandom of=$M0/small bs=64k count=1 conv=nocreat +TEST [ "$(stat --format=%X $M0/small)" != "0" ] + +TEST rm $M0/small + +cleanup diff --git a/tests/bugs/replicate/bug-1386188-sbrain-fav-child.t b/tests/bugs/replicate/bug-1386188-sbrain-fav-child.t new file mode 100644 index 00000000000..d049d95ef9a --- /dev/null +++ b/tests/bugs/replicate/bug-1386188-sbrain-fav-child.t @@ -0,0 +1,82 @@ +#!/bin/bash +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1} +TEST $CLI volume set $V0 self-heal-daemon off +TEST $CLI volume set $V0 data-self-heal off +TEST $CLI volume set $V0 entry-self-heal off +TEST $CLI volume set $V0 metadata-self-heal off +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0; +TEST touch $M0/data.txt +TEST touch $M0/mdata.txt + +#Create data and metadata split-brain +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST dd if=/dev/urandom of=$M0/data.txt bs=1024 count=1024 +TEST setfattr -n user.value -v value1 $M0/mdata.txt +TEST $CLI volume start $V0 force +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}0 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0 +TEST kill_brick $V0 $H0 $B0/${V0}1 +TEST dd if=/dev/urandom of=$M0/data.txt bs=1024 count=1024 +TEST setfattr -n user.value -v value2 $M0/mdata.txt + +TEST $CLI volume start $V0 force +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1 + +## Check that the file still in split-brain, +  ## I/O fails +  cat $M0/data.txt > /dev/null +  EXPECT "1" echo $? +  ## pending xattrs blame each other. +  brick0_pending=$(get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0/data.txt) +  brick1_pending=$(get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1/data.txt) +  TEST [ $brick0_pending -ne "000000000000000000000000" ] +  TEST [ $brick1_pending -ne "000000000000000000000000" ] + +  ## I/O fails +  getfattr -n user.value $M0/mdata.txt +  EXPECT "1" echo $? +  brick0_pending=$(get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0/mdata.txt) +  brick1_pending=$(get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1/mdata.txt) +  TEST [ $brick0_pending -ne "000000000000000000000000" ] +  TEST [ $brick1_pending -ne "000000000000000000000000" ] + +## Let us use mtime as fav-child policy. So brick0 will be source. +   # Set dirty (data part) on the sink brick to check if it is reset later along with the pending xattr. +   TEST setfattr -n trusted.afr.dirty -v 0x000000010000000000000000 $B0/${V0}1/data.txt +   # Set dirty (metadata part) on the sink brick to check if it is reset later along with the pending xattr. +   TEST setfattr -n trusted.afr.dirty -v 0x000000000000000100000000 $B0/${V0}1/mdata.txt + +   TEST $CLI volume set $V0 favorite-child-policy mtime + +   # Reading the file should be allowed and sink brick xattrs must be reset. +   cat $M0/data.txt > /dev/null +   EXPECT "0" echo $? +   TEST brick1_pending=$(get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1/data.txt) +   TEST brick1_dirty=$(get_hex_xattr trusted.afr.dirty $B0/${V0}1/data.txt) +   TEST [ $brick1_dirty -eq "000000000000000000000000" ] +   TEST [ $brick1_pending -eq "000000000000000000000000" ] + +   # Accessing the file should be allowed and sink brick xattrs must be reset. +   EXPECT "value2" echo $(getfattr --only-values -n user.value  $M0/mdata.txt) +   TEST brick1_pending=$(get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1/data.txt) +   TEST brick1_dirty=$(get_hex_xattr trusted.afr.dirty $B0/${V0}1/data.txt) +   TEST [ $brick1_dirty -eq "000000000000000000000000" ] +   TEST [ $brick1_pending -eq "000000000000000000000000" ] + +#Enable shd and heal the file. +TEST $CLI volume set $V0 cluster.self-heal-daemon on +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +EXPECT 0 get_pending_heal_count $V0 +cleanup; diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 747577c9380..0f878a9be86 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -979,6 +979,13 @@ ret:  	return -err;  } +int +afr_fav_child_reset_sink_xattrs (void *opaque); + +int +afr_fav_child_reset_sink_xattrs_cbk (int ret, call_frame_t *frame, +                                     void *opaque); +  gf_boolean_t  afr_selfheal_enabled (xlator_t *this)  { @@ -994,6 +1001,82 @@ afr_selfheal_enabled (xlator_t *this)  	return data || priv->metadata_self_heal || priv->entry_self_heal;  } + +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 op_errno = ENOMEM; +        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 || (local->is_read_txn && !event_generation)) { +                /* 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 = copy_frame (frame); +                if (!heal_frame) { +                        err = -EIO; +                        goto refresh_done; +                } +                heal_frame->root->pid = GF_CLIENT_PID_SELF_HEALD; +                heal_local = AFR_FRAME_INIT (heal_frame, op_errno); +                if (!heal_local) { +                        err = -EIO; +                        AFR_STACK_DESTROY (heal_frame); +                        goto refresh_done; +                } +                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; +} +  int  afr_inode_refresh_done (call_frame_t *frame, xlator_t *this)  { @@ -1012,8 +1095,6 @@ afr_inode_refresh_done (call_frame_t *frame, xlator_t *this)  	err = afr_inode_refresh_err (frame, this); -        afr_local_replies_wipe (local, this->private); -  	if (ret && afr_selfheal_enabled (this) && start_heal) {                  heal_frame = copy_frame (frame);                  if (!heal_frame) @@ -1033,7 +1114,7 @@ afr_inode_refresh_done (call_frame_t *frame, xlator_t *this)          }  refresh_done: -        local->refreshfn (frame, this, err); +        afr_txn_refresh_done (frame, this, err);  	return 0;  } @@ -5391,6 +5472,7 @@ afr_selfheal_locked_metadata_inspect (call_frame_t *frame, xlator_t *this,          unsigned char *sources = NULL;          unsigned char *sinks = NULL;          unsigned char *healed_sinks = NULL; +        unsigned char *undid_pending = NULL;          struct afr_reply *locked_replies = NULL;          afr_private_t *priv = this->private; @@ -5399,6 +5481,7 @@ afr_selfheal_locked_metadata_inspect (call_frame_t *frame, xlator_t *this,          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); @@ -5415,6 +5498,7 @@ afr_selfheal_locked_metadata_inspect (call_frame_t *frame, xlator_t *this,                  ret = __afr_selfheal_metadata_prepare (frame, this, inode,                                                         locked_on, sources,                                                         sinks, healed_sinks, +                                                       undid_pending,                                                         locked_replies,                                                         pending);                  *msh = afr_decide_heal_info (priv, sources, ret); @@ -5438,6 +5522,7 @@ afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this,          unsigned char *sources = NULL;          unsigned char *sinks = NULL;          unsigned char *healed_sinks = NULL; +        unsigned char *undid_pending = NULL;          afr_private_t   *priv = NULL;          fd_t          *fd = NULL;          struct afr_reply *locked_replies = NULL; @@ -5451,6 +5536,7 @@ afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this,          sources = alloca0 (priv->child_count);          sinks = alloca0 (priv->child_count);          healed_sinks = alloca0 (priv->child_count); +        undid_pending = alloca0 (priv->child_count);          /* Heal-info does an open() on the file being examined so that the           * current eager-lock holding client, if present, at some point sees @@ -5490,6 +5576,7 @@ afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this,                          ret = __afr_selfheal_data_prepare (frame, this, inode,                                                             data_lock, sources,                                                             sinks, healed_sinks, +                                                           undid_pending,                                                             locked_replies,                                                             pflag);                          *dsh = afr_decide_heal_info (priv, sources, ret); @@ -6025,3 +6112,115 @@ afr_get_msg_id (char *op_type)                  return AFR_MSG_ADD_BRICK_STATUS;          return -1;  } + +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); + +        if (heal_frame) +                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 < AFR_SH_MIN_PARTICIPANTS) +                                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 < AFR_SH_MIN_PARTICIPANTS) +                                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; + +} diff --git a/xlators/cluster/afr/src/afr-read-txn.c b/xlators/cluster/afr/src/afr-read-txn.c index 74749f029c8..926f7c4dc47 100644 --- a/xlators/cluster/afr/src/afr-read-txn.c +++ b/xlators/cluster/afr/src/afr-read-txn.c @@ -64,7 +64,6 @@ afr_read_txn_refresh_done (call_frame_t *frame, xlator_t *this, int err)  {  	afr_local_t *local = NULL;  	int read_subvol = 0; -	int event_generation = 0;  	inode_t *inode = NULL;  	int ret = -1;          int spb_choice = -1; @@ -76,18 +75,12 @@ afr_read_txn_refresh_done (call_frame_t *frame, xlator_t *this, int err)                  local->op_errno = -err;                  local->op_ret = -1;                  read_subvol = -1; +                gf_msg (this->name, GF_LOG_ERROR, EIO, AFR_MSG_SPLIT_BRAIN, +                        "Failing %s on gfid %s: split-brain observed.", +                        gf_fop_list[local->op], uuid_utoa (inode->gfid));                  goto readfn;          } -	ret = afr_inode_get_readable (frame, inode, this, local->readable, -			              &event_generation, -				      local->transaction.type); - -	if (ret == -EIO || !event_generation) -		/* Even after refresh, we don't have a good -		   read subvolume. Time to bail */ -                AFR_READ_TXN_SET_ERROR_AND_GOTO (-1, EIO, -1, readfn); -  	read_subvol = afr_read_subvol_select_by_policy (inode, this,  							local->readable, NULL);  	if (read_subvol == -1) @@ -208,6 +201,7 @@ afr_read_txn (call_frame_t *frame, xlator_t *this, inode_t *inode,  	local->readfn = readfn;  	local->inode = inode_ref (inode); +        local->is_read_txn = _gf_true;          if (priv->quorum_reads &&              priv->quorum_count && !afr_has_quorum (priv->child_up, this)) { diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index faee8dbb89b..40cfd01f4e9 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -144,8 +144,10 @@ err:  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, afr_transaction_type type, -			   struct afr_reply *replies, unsigned char *locked_on) +			   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; @@ -213,6 +215,10 @@ afr_selfheal_undo_pending (call_frame_t *frame, xlator_t *this, inode_t *inode,  			   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, @@ -734,6 +740,42 @@ afr_sh_fav_by_size (xlator_t *this, struct afr_reply *replies, inode_t *inode)          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; +        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; +}  int  afr_mark_split_brain_source_sinks_by_policy (call_frame_t *frame, @@ -755,24 +797,9 @@ afr_mark_split_brain_source_sinks_by_policy (call_frame_t *frame,          time_t time;          priv = this->private; -        if (priv->fav_child_policy == AFR_FAV_CHILD_BY_MAJORITY)  { -                fav_child = afr_sh_fav_by_majority (this, replies, inode); -                if (fav_child >= 0) -                        policy_str = "MAJORITY"; -        } else if (priv->fav_child_policy == AFR_FAV_CHILD_BY_MTIME)  { -                fav_child = afr_sh_fav_by_mtime (this, replies, inode); -                if (fav_child >= 0) -                        policy_str = "MTIME"; -        } else if (priv->fav_child_policy == AFR_FAV_CHILD_BY_CTIME)  { -                fav_child = afr_sh_fav_by_ctime (this, replies, inode); -                if (fav_child >= 0) -                        policy_str = "CTIME"; -        } else if (priv->fav_child_policy == AFR_FAV_CHILD_BY_SIZE)  { -                fav_child = afr_sh_fav_by_size (this, replies, inode); -                if (fav_child >= 0) -                        policy_str = "SIZE"; -        } +        fav_child = afr_sh_get_fav_by_policy (this, replies, inode, +                                              &policy_str);          if (fav_child > priv->child_count - 1) {                  gf_msg (this->name, GF_LOG_ERROR, 0,                          AFR_MSG_SBRAIN_FAV_CHILD_POLICY, "Invalid child (%d) " @@ -828,6 +855,7 @@ afr_mark_split_brain_source_sinks (call_frame_t *frame, xlator_t *this,          dict_t *xdata_req = NULL;          int heal_op = -1;          int ret = -1; +        int source = -1;          local = frame->local;          priv = this->private; @@ -837,27 +865,96 @@ afr_mark_split_brain_source_sinks (call_frame_t *frame, xlator_t *this,          if (ret)                  goto autoheal; -        ret = afr_mark_split_brain_source_sinks_by_heal_op (frame, this, +        source = afr_mark_split_brain_source_sinks_by_heal_op (frame, this,                                                              sources, sinks,                                                              healed_sinks,                                                              locked_on, replies,                                                              type, heal_op); -        return ret; +        return source;  autoheal:          /* Automatically heal if fav_child_policy is set. */          if (priv->fav_child_policy != AFR_FAV_CHILD_NONE) { -                ret = afr_mark_split_brain_source_sinks_by_policy (frame, this, -                                                                   inode, -                                                                   sources, -                                                                   sinks, +                source = afr_mark_split_brain_source_sinks_by_policy (frame, +                                                                      this, +                                                                      inode, +                                                                      sources, +                                                                      sinks,                                                                     healed_sinks, -                                                                   locked_on, -                                                                   replies, -                                                                   type); +                                                                      locked_on, +                                                                      replies, +                                                                      type); +                if (source != -1) { +                        ret = dict_set_int32 (xdata_req, "fav-child-policy", 1); +                        if (ret) +                                return -1; +                }          } -        return ret; +        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 (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 @@ -1895,11 +1992,15 @@ 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);  	if (!frame)  		return ret; +        local = frame->local; +        local->xdata_req = dict_new(); +          ret = afr_selfheal_do (frame, this, gfid);  	if (frame) diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index 87542799a5b..9c12e433097 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -581,6 +581,7 @@ __afr_selfheal_data_finalize_source (call_frame_t *frame, xlator_t *this,                                       unsigned char *sinks,  				     unsigned char *healed_sinks,  				     unsigned char *locked_on, +				     unsigned char *undid_pending,  				     struct afr_reply *replies,                                       uint64_t *witness)  { @@ -601,6 +602,12 @@ __afr_selfheal_data_finalize_source (call_frame_t *frame, xlator_t *this,                                                            AFR_DATA_TRANSACTION);                  if (source < 0)                          return -EIO; + +                _afr_fav_child_reset_sink_xattrs (frame, this, inode, source, +                                                 healed_sinks, undid_pending, +                                                 AFR_DATA_TRANSACTION, +                                                 locked_on, replies); +                  return source;  	} @@ -640,6 +647,7 @@ __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, gf_boolean_t *pflag)  {  	int ret = -1; @@ -675,8 +683,8 @@ __afr_selfheal_data_prepare (call_frame_t *frame, xlator_t *this,  	source = __afr_selfheal_data_finalize_source (frame, this, inode,                                                        sources, sinks,                                                        healed_sinks, -                                                      locked_on, replies, -                                                      witness); +                                                      locked_on, undid_pending, +                                                      replies, witness);  	if (source < 0)  		return -EIO; @@ -694,6 +702,7 @@ __afr_selfheal_data (call_frame_t *frame, xlator_t *this, fd_t *fd,  	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; @@ -705,6 +714,7 @@ __afr_selfheal_data (call_frame_t *frame, xlator_t *this, fd_t *fd,  	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); @@ -724,9 +734,8 @@ __afr_selfheal_data (call_frame_t *frame, xlator_t *this, fd_t *fd,  		ret = __afr_selfheal_data_prepare (frame, this, fd->inode,                                                     data_lock, sources, sinks, -                                                   healed_sinks, -						   locked_replies, -                                                   NULL); +                                                   healed_sinks, undid_pending, +                                                   locked_replies, NULL);  		if (ret < 0)  			goto unlock; @@ -785,7 +794,7 @@ restore_time:          }          ret = afr_selfheal_undo_pending (frame, this, fd->inode,                                           sources, sinks, healed_sinks, -                                         AFR_DATA_TRANSACTION, +                                         undid_pending, AFR_DATA_TRANSACTION,                                           locked_replies, data_lock);  skip_undo_pending:  	afr_selfheal_uninodelk (frame, this, fd->inode, this->name, 0, 0, diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 573b5435eae..9ab566b8242 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -897,6 +897,7 @@ __afr_selfheal_entry (call_frame_t *frame, xlator_t *this, fd_t *fd,  	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; @@ -908,6 +909,7 @@ __afr_selfheal_entry (call_frame_t *frame, xlator_t *this, fd_t *fd,  	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); @@ -980,6 +982,7 @@ unlock:                  ret = afr_selfheal_undo_pending (frame, this, fd->inode,                                                   sources, sinks, healed_sinks, +                                                 undid_pending,                                                   AFR_ENTRY_TRANSACTION,                                                   locked_replies, postop_lock);          } diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c index 85aaca7cefd..a67717bf9d4 100644 --- a/xlators/cluster/afr/src/afr-self-heal-metadata.c +++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c @@ -202,6 +202,7 @@ __afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this,                                           unsigned char *sources,                                           unsigned char *sinks,  					 unsigned char *healed_sinks, +					 unsigned char *undid_pending,  					 unsigned char *locked_on,  					 struct afr_reply *replies)  { @@ -223,8 +224,14 @@ __afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this,                                                              healed_sinks,                                                              locked_on, replies,                                                        AFR_METADATA_TRANSACTION); -                if (source >= 0) +                if (source >= 0) { +                        _afr_fav_child_reset_sink_xattrs (frame, this, inode, +                                                         source, healed_sinks, +                                                         undid_pending, +                                                       AFR_METADATA_TRANSACTION, +                                                         locked_on, replies);                          return source; +                }  		/* If this is a directory mtime/ctime only split brain  		   use the most recent */ @@ -304,6 +311,7 @@ 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, gf_boolean_t *pflag)  {  	int ret = -1; @@ -358,6 +366,7 @@ __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this, inode_t *i  	source = __afr_selfheal_metadata_finalize_source (frame, this, inode,                                                            sources, sinks,                                                            healed_sinks, +                                                          undid_pending,                                                            locked_on, replies);  	if (source < 0) @@ -375,6 +384,7 @@ afr_selfheal_metadata (call_frame_t *frame, xlator_t *this, inode_t *inode)  	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; @@ -384,6 +394,7 @@ afr_selfheal_metadata (call_frame_t *frame, xlator_t *this, inode_t *inode)  	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); @@ -399,6 +410,7 @@ afr_selfheal_metadata (call_frame_t *frame, xlator_t *this, inode_t *inode)  		ret = __afr_selfheal_metadata_prepare (frame, this, inode,                                                         data_lock, sources,                                                         sinks, healed_sinks, +                                                       undid_pending,  						       locked_replies, NULL);  		if (ret < 0)  			goto unlock; @@ -417,6 +429,7 @@ afr_selfheal_metadata (call_frame_t *frame, xlator_t *this, inode_t *inode)                  ret = afr_selfheal_undo_pending (frame, this, inode, sources,                                                   sinks, healed_sinks, +                                                 undid_pending,                                                   AFR_METADATA_TRANSACTION,                                                   locked_replies, data_lock);  	} diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h index 1705c967f60..500227abe24 100644 --- a/xlators/cluster/afr/src/afr-self-heal.h +++ b/xlators/cluster/afr/src/afr-self-heal.h @@ -167,8 +167,10 @@ afr_selfheal_extract_xattr (xlator_t *this, 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, afr_transaction_type type, -			   struct afr_reply *replies, unsigned char *locked_on); +			   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 (xlator_t *this, int dst, int source, inode_t *dir, @@ -229,6 +231,19 @@ afr_mark_split_brain_source_sinks (call_frame_t *frame, xlator_t *this,                                     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 @@ -239,8 +254,8 @@ __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, -                             struct afr_reply *replies, -                             gf_boolean_t *flag); +                             unsigned char *undid_pending, +                             struct afr_reply *replies, gf_boolean_t *flag);  int  __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this, @@ -248,6 +263,7 @@ __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this,                                   unsigned char *sources,                                   unsigned char *sinks,                                   unsigned char *healed_sinks, +                                 unsigned char *undid_pending,                                   struct afr_reply *replies,                                   gf_boolean_t *flag);  int diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index 4d0ed943a81..9cb735ea7fa 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -2261,19 +2261,12 @@ afr_write_txn_refresh_done (call_frame_t *frame, xlator_t *this, int err)          if (err) {                  local->op_errno = -err;                  local->op_ret = -1; -                goto fail; -        } -	ret = afr_inode_get_readable (frame, local->inode, this, -                                      local->readable, NULL, -				      local->transaction.type); -        if (ret < 0) {                  gf_msg (this->name, GF_LOG_ERROR, -ret, AFR_MSG_SPLIT_BRAIN,                          "Failing %s on gfid %s: split-brain observed.",                          gf_fop_list[local->op], uuid_utoa (local->inode->gfid)); -                local->op_ret = -1; -                local->op_errno = -ret;                  goto fail;          } +          afr_transaction_start (frame, this);          return 0;  fail: diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index d09aa6852c8..bbfa309b868 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -808,6 +808,7 @@ typedef struct _afr_local {          call_frame_t *heal_frame;          gf_boolean_t need_full_crawl; +        gf_boolean_t is_read_txn;  } afr_local_t; diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c index 255c0823aac..5e7f5fa4eb1 100644 --- a/xlators/cluster/dht/src/dht-helper.c +++ b/xlators/cluster/dht/src/dht-helper.c @@ -1320,6 +1320,9 @@ unlock:          UNLOCK(&inode->lock);  out: +        if (dict) { +                dict_unref (dict); +        }          loc_wipe (&tmp_loc); @@ -1588,6 +1591,10 @@ unlock:          ret = 0;  out: +        if (dict) { +                dict_unref (dict); +        } +          loc_wipe (&tmp_loc);          return ret;  } diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index 10fd878041e..ebc8a9c2492 100644 --- a/xlators/cluster/dht/src/dht-rebalance.c +++ b/xlators/cluster/dht/src/dht-rebalance.c @@ -2351,7 +2351,7 @@ gf_defrag_get_entry (xlator_t *this, int i, struct dht_container **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 *should_commit_hash) +                     int *should_commit_hash, int *perrno)  {          int                     ret             = -1;          char                    is_linkfile     = 0; @@ -2362,7 +2362,6 @@ gf_defrag_get_entry (xlator_t *this, int i, struct dht_container **container,          struct dht_container   *tmp_container   = NULL;          xlator_t               *hashed_subvol   = NULL;          xlator_t               *cached_subvol   = NULL; -        int                     fop_errno       = 0;          if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) {                  ret = -1; @@ -2390,7 +2389,7 @@ gf_defrag_get_entry (xlator_t *this, int i, struct dht_container **container,                                  DHT_MSG_MIGRATE_DATA_FAILED,                                  "Readdirp failed. Aborting data migration for "                                  "directory: %s", loc->path); -                        fop_errno = -ret; +                        *perrno = -ret;                          ret = -1;                          goto out;                  } @@ -2647,13 +2646,12 @@ out:                  dict_unref (xattr_rsp); -        errno = fop_errno;          return ret;  }  int  gf_defrag_process_dir (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, -                       dict_t *migrate_data) +                       dict_t *migrate_data, int *perrno)  {          int                      ret               = -1;          fd_t                    *fd                = NULL; @@ -2673,7 +2671,6 @@ gf_defrag_process_dir (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,          int                      throttle_up       = 0;          struct dir_dfmeta       *dir_dfmeta        = NULL;          int                      should_commit_hash = 1; -        int                      fop_errno         = 0;          gf_log (this->name, GF_LOG_INFO, "migrate data called on %s",                  loc->path); @@ -2700,7 +2697,7 @@ gf_defrag_process_dir (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,                          DHT_MSG_MIGRATE_DATA_FAILED,                          "Migrate data failed: Failed to open dir %s",                          loc->path); -                fop_errno = -ret; +                *perrno = -ret;                  ret = -1;                  goto out;          } @@ -2846,11 +2843,10 @@ gf_defrag_process_dir (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,                                                     loc, conf, defrag, fd,                                                     migrate_data, dir_dfmeta,                                                     xattr_req, -                                                   &should_commit_hash); +                                                   &should_commit_hash, perrno);                          if (ret) { -                                fop_errno = errno; -                                gf_log ("this->name", GF_LOG_WARNING, "Found " +                                gf_log (this->name, GF_LOG_WARNING, "Found "                                          "error from gf_defrag_get_entry");                                  ret = -1; @@ -2910,7 +2906,6 @@ out:                  ret = 2;          } -        errno = fop_errno;          return ret;  }  int @@ -3096,6 +3091,7 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,          inode_t                 *linked_inode   = NULL, *inode = NULL;          dht_conf_t              *conf           = NULL;          int                      should_commit_hash = 1; +        int                      perrno         = 0;          conf = this->private;          if (!conf) { @@ -3116,7 +3112,7 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,                  }                  if (-ret == ENOENT || -ret == ESTALE) { -                        gf_msg (this->name, GF_LOG_INFO, errno, +                        gf_msg (this->name, GF_LOG_INFO, -ret,                                  DHT_MSG_DIR_LOOKUP_FAILED,                                  "Dir:%s renamed or removed. Skipping",                                  loc->path); @@ -3134,10 +3130,11 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,          if ((defrag->cmd != GF_DEFRAG_CMD_START_TIER) &&              (defrag->cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX)) { -                ret = gf_defrag_process_dir (this, defrag, loc, migrate_data); +                ret = gf_defrag_process_dir (this, defrag, loc, migrate_data, +                                             &perrno); -                if (ret && ret != 2) { -                        if (errno == ENOENT || errno == ESTALE) { +                if (ret && (ret != 2)) { +                        if (perrno == ENOENT || perrno == ESTALE) {                                  ret = 0;                                  goto out;                          } else { @@ -3292,7 +3289,7 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,                                               NULL, NULL);                          if (ret) {                                  if (-ret == ENOENT || -ret == ESTALE) { -                                        gf_msg (this->name, GF_LOG_INFO, errno, +                                        gf_msg (this->name, GF_LOG_INFO, -ret,                                                  DHT_MSG_DIR_LOOKUP_FAILED,                                                  "Dir:%s renamed or removed. "                                                  "Skipping", loc->path); diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index 9a702b70313..66f26fc5256 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -1346,7 +1346,6 @@ static int  _get_slave_idx_slave_voluuid (dict_t *dict, char *key, data_t *value,                                void *data)  { -        char  *slave_voluuid                 = NULL;          char  *slave_info                    = NULL;          xlator_t  *this                      = NULL;          struct slave_vol_config *slave_cfg   = NULL; @@ -2863,10 +2862,8 @@ out:  static int  get_slavehost_from_voluuid (dict_t *dict, char *key, data_t *value, void *data)  { -        char *slave_voluuid                 = NULL;          char *slave_info                    = NULL;          char *tmp                           = NULL; -        char tmp_char                       = 0;          char *slave_host                    = NULL;          xlator_t  *this                     = NULL;          struct slave_vol_config *slave_vol  = NULL; @@ -3004,14 +3001,10 @@ glusterd_op_stage_gsync_create (dict_t *dict, char **op_errstr)          glusterd_volinfo_t *volinfo                   = NULL;          struct stat         stbuf                     = {0,};          xlator_t           *this                      = NULL; -        char                     *georep_session_wrkng_dir  = NULL;          struct slave_vol_config  slave1                     = {{0},}; -        int                      type                       = 0; -        char                     monitor_status[NAME_MAX]   = {0,};          char                     old_slave_url[SLAVE_URL_INFO_MAX] = {0};          char                     old_confpath[PATH_MAX]     = {0};          gf_boolean_t             is_running                 = _gf_false; -        int                      ret_status                 = 0;          char                     *statedir                  = NULL;          char                     statefiledir[PATH_MAX]     = {0,};          gf_boolean_t             is_different_slavehost     = _gf_false; @@ -3429,7 +3422,6 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)  {          int                 ret                   = 0;          int                 type                  = 0; -        int                 pfd                   = -1;          char               *volname               = NULL;          char               *slave                 = NULL;          char               *slave_url             = NULL; @@ -3444,7 +3436,6 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)          gf_boolean_t        exists                = _gf_false;          glusterd_volinfo_t *volinfo               = NULL;          char                    errmsg[PATH_MAX]  = {0,}; -        char                    pidfile[PATH_MAX] = {0,};          dict_t             *ctx                   = NULL;          gf_boolean_t        is_force              = 0;          gf_boolean_t        is_running            = _gf_false; @@ -3691,16 +3682,6 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)                          goto out;                  } -                pfd = gsyncd_getpidfile (volname, slave, pidfile, -                                         conf_path, &is_template_in_use); -                if (is_template_in_use) { -                        snprintf (errmsg, sizeof(errmsg), "pid-file entry " -                                  "missing in the config file(%s).", -                                  conf_path); -                        ret = -1; -                        goto out; -                } -                  ret = gsync_verify_config_options (dict, op_errstr, volname);                  goto out;                  break; @@ -3748,6 +3729,7 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)          }  out: +          if (path_list)                  GF_FREE (path_list); @@ -3772,7 +3754,6 @@ gd_pause_or_resume_gsync (dict_t *dict, char *master, char *slave,          char            pidfile[PATH_MAX]        = {0,};          char            errmsg[PATH_MAX]         = "";          char            buf [1024]               = {0,}; -        int             i                        = 0;          gf_boolean_t    is_template_in_use       = _gf_false;          char            monitor_status[NAME_MAX] = {0,};          char            *statefile               = NULL; @@ -4408,13 +4389,10 @@ int  glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave,                             char *conf_path, dict_t *dict, char *node)  { -        char                    brick_state_file[PATH_MAX] = ""; -        char                    brick_path[PATH_MAX]       = "";          char                    temp_conf_path[PATH_MAX]   = "";          char                   *working_conf_path          = NULL;          char                   *georep_session_wrkng_dir   = NULL;          char                   *master                     = NULL; -        char                    tmp[1024]                  = "";          char                    sts_val_name[1024]         = "";          char                    monitor_status[NAME_MAX]   = "";          char                   *statefile                  = NULL; @@ -4429,14 +4407,12 @@ glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave,          char                   *brick_host_uuid            = NULL;          int                     brick_host_uuid_length     = 0;          int                     gsync_count                = 0; -        int                     i                          = 0;          int                     ret                        = 0;          glusterd_brickinfo_t   *brickinfo                  = NULL;          gf_gsync_status_t      *sts_val                    = NULL;          gf_boolean_t            is_template_in_use         = _gf_false;          glusterd_conf_t        *priv                       = NULL;          struct stat             stbuf                      = {0,}; -        dict_t                 *statusd                    = NULL;          xlator_t               *this                       = NULL;          this = THIS; @@ -4845,7 +4821,6 @@ glusterd_get_gsync_status_mst_slv (glusterd_volinfo_t *volinfo,  {          char              *statefile = NULL;          uuid_t             uuid = {0, }; -        glusterd_conf_t    *priv = NULL;          int                ret = 0;          gf_boolean_t       is_template_in_use = _gf_false;          struct stat        stbuf = {0, }; @@ -4858,8 +4833,6 @@ glusterd_get_gsync_status_mst_slv (glusterd_volinfo_t *volinfo,          GF_ASSERT (slave);          GF_ASSERT (this->private); -        priv = this->private; -          ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);          if (ret) {                  gf_msg (this->name, GF_LOG_INFO, 0, GD_MSG_SESSION_INACTIVE, @@ -5489,7 +5462,6 @@ glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict)          char               *status_msg          = NULL;          gf_boolean_t        is_running          = _gf_false;          char               *conf_path           = NULL; -        char                errmsg[PATH_MAX]    = "";          char               *key                 = NULL;          xlator_t           *this                = NULL; @@ -6277,8 +6249,6 @@ glusterd_op_gsync_create (dict_t *dict, char **op_errstr, dict_t *rsp_dict)          xlator_t           *this                      = NULL;          char                old_working_dir[PATH_MAX] = {0};          char                new_working_dir[PATH_MAX] = {0}; -        char               *slave_info                = NULL; -        char                slave_url_info[SLAVE_URL_INFO_MAX] = {0};          char               *slave_voluuid             = NULL;          char               *old_slavehost             = NULL;          gf_boolean_t        is_existing_session       = _gf_false; diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index c40a087ec46..8f85f8c8ba1 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -374,7 +374,8 @@ posix_do_chown (xlator_t *this,  static int  posix_do_utimes (xlator_t *this,                   const char *path, -                 struct iatt *stbuf) +                 struct iatt *stbuf, +                 int valid)  {          int32_t ret = -1;          struct timeval tv[2]     = {{0,},{0,}}; @@ -391,10 +392,23 @@ posix_do_utimes (xlator_t *this,          if (S_ISLNK (stat.st_mode))                  is_symlink = 1; -        tv[0].tv_sec  = stbuf->ia_atime; -        tv[0].tv_usec = stbuf->ia_atime_nsec / 1000; -        tv[1].tv_sec  = stbuf->ia_mtime; -        tv[1].tv_usec = stbuf->ia_mtime_nsec / 1000; +        if ((valid & GF_SET_ATTR_ATIME) == GF_SET_ATTR_ATIME) { +                tv[0].tv_sec  = stbuf->ia_atime; +                tv[0].tv_usec = stbuf->ia_atime_nsec / 1000; +        } else { +                /* atime is not given, use current values */ +                tv[0].tv_sec  = ST_ATIM_SEC (&stat); +                tv[0].tv_usec = ST_ATIM_NSEC (&stat) / 1000; +        } + +        if ((valid & GF_SET_ATTR_MTIME) == GF_SET_ATTR_MTIME) { +                tv[1].tv_sec  = stbuf->ia_mtime; +                tv[1].tv_usec = stbuf->ia_mtime_nsec / 1000; +        } else { +                /* mtime is not given, use current values */ +                tv[1].tv_sec  = ST_MTIM_SEC (&stat); +                tv[1].tv_usec = ST_MTIM_NSEC (&stat) / 1000; +        }          ret = lutimes (path, tv);          if ((ret == -1) && (errno == ENOSYS)) { @@ -463,7 +477,7 @@ posix_setattr (call_frame_t *frame, xlator_t *this,          }          if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { -                op_ret = posix_do_utimes (this, real_path, stbuf); +                op_ret = posix_do_utimes (this, real_path, stbuf, valid);                  if (op_ret == -1) {                          op_errno = errno;                          gf_msg (this->name, GF_LOG_ERROR, errno,  | 
