summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Vigor <kvigor@fb.com>2017-01-09 09:16:05 -0800
committerKevin Vigor <kvigor@fb.com>2017-01-09 09:16:05 -0800
commitb49d30a20efee06eb5a5007a244f3c474366cb35 (patch)
tree317639c5e045d9bbbcbd14e16d423b3ac86e4f70
parentc5145b464e6ebc77021fe4ebef4aaf8312a323aa (diff)
parent068e4f345f51438d252b1e330ca7049bd4a67e03 (diff)
Merge remote-tracking branch 'origin/release-3.8' into 3.8-merge
-rw-r--r--geo-replication/syncdaemon/configinterface.py.in17
-rw-r--r--geo-replication/syncdaemon/resource.py9
-rw-r--r--libglusterfs/src/compat.h12
-rwxr-xr-xtests/bugs/nfs/zero-atime.t31
-rw-r--r--tests/bugs/replicate/bug-1386188-sbrain-fav-child.t82
-rw-r--r--xlators/cluster/afr/src/afr-common.c205
-rw-r--r--xlators/cluster/afr/src/afr-read-txn.c14
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c159
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-data.c21
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-entry.c3
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-metadata.c15
-rw-r--r--xlators/cluster/afr/src/afr-self-heal.h24
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c9
-rw-r--r--xlators/cluster/afr/src/afr.h1
-rw-r--r--xlators/cluster/dht/src/dht-helper.c7
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c29
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-geo-rep.c32
-rw-r--r--xlators/storage/posix/src/posix.c26
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,