summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrutika Dhananjay <kdhananj@redhat.com>2015-06-24 08:02:51 +0530
committerRaghavendra Bhat <raghavendra@redhat.com>2015-07-17 00:05:36 -0700
commitf9b3ba22f105772e268765d80adfeffd8f6f2776 (patch)
tree4e9326624892429c1308a8b0aea610654356c74c
parent50b0c7baad43dcd378a5740f154b38ec0ffe0f00 (diff)
cluster/afr: Pick gfid from poststat during fresh lookup for read child calculation
Backport of : http://review.gluster.org/11373 Change-Id: I03f11af082a0decf4ea084480b67e9e156964c76 BUG: 1235601 Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com> Reviewed-on: http://review.gluster.org/11408 Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: Raghavendra Bhat <raghavendra@redhat.com>
-rw-r--r--libglusterfs/src/inode.c22
-rw-r--r--libglusterfs/src/inode.h3
-rw-r--r--xlators/cluster/afr/src/afr-common.c68
-rw-r--r--xlators/cluster/afr/src/afr-dir-read.c7
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.c6
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.c5
-rw-r--r--xlators/cluster/afr/src/afr-read-txn.c4
-rw-r--r--xlators/cluster/afr/src/afr.h18
8 files changed, 92 insertions, 41 deletions
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index 3b1e05077e8..36f16094bc6 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -1862,6 +1862,28 @@ inode_ctx_reset0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
return ret;
}
+int
+inode_is_linked (inode_t *inode)
+{
+ int ret = 0;
+ inode_table_t *table = NULL;
+
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "inode not found");
+ return 0;
+ }
+
+ table = inode->table;
+
+ pthread_mutex_lock (&table->lock);
+ {
+ ret = __is_inode_hashed (inode);
+ }
+ pthread_mutex_unlock (&table->lock);
+
+ return ret;
+}
void
inode_dump (inode_t *inode, char *prefix)
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
index 5d373fcaec9..f5d011a5028 100644
--- a/libglusterfs/src/inode.h
+++ b/libglusterfs/src/inode.h
@@ -257,4 +257,7 @@ __inode_table_set_lru_limit (inode_table_t *table, uint32_t lru_limit);
void
inode_table_set_lru_limit (inode_table_t *table, uint32_t lru_limit);
+int
+inode_is_linked (inode_t *inode);
+
#endif /* _INODE_H */
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index 20cff5c5206..5de6b52b274 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -726,7 +726,7 @@ out:
int
-afr_hash_child (inode_t *inode, int32_t child_count, int hashmode)
+afr_hash_child (afr_read_subvol_args_t *args, int32_t child_count, int hashmode)
{
uuid_t gfid_copy = {0,};
pid_t pid;
@@ -735,11 +735,9 @@ afr_hash_child (inode_t *inode, int32_t child_count, int hashmode)
return -1;
}
- if (inode) {
- uuid_copy (gfid_copy, inode->gfid);
- }
+ uuid_copy (gfid_copy, args->gfid);
- if (hashmode > 1 && inode->ia_type != IA_IFDIR) {
+ if ((hashmode > 1) && (args->ia_type != IA_IFDIR)) {
/*
* Why getpid? Because it's one of the cheapest calls
* available - faster than gethostname etc. - and returns a
@@ -760,32 +758,41 @@ afr_hash_child (inode_t *inode, int32_t child_count, int hashmode)
int
afr_read_subvol_select_by_policy (inode_t *inode, xlator_t *this,
- unsigned char *readable)
+ unsigned char *readable,
+ afr_read_subvol_args_t *args)
{
- afr_private_t *priv = NULL;
- int read_subvol = -1;
- int i = 0;
+ int i = 0;
+ int read_subvol = -1;
+ afr_private_t *priv = NULL;
+ afr_read_subvol_args_t local_args = {0,};
priv = this->private;
/* first preference - explicitly specified or local subvolume */
if (priv->read_child >= 0 && readable[priv->read_child])
- return priv->read_child;
+ return priv->read_child;
+
+ if (inode_is_linked (inode)) {
+ uuid_copy (local_args.gfid, inode->gfid);
+ local_args.ia_type = inode->ia_type;
+ } else if (args) {
+ local_args = *args;
+ }
/* second preference - use hashed mode */
- read_subvol = afr_hash_child (inode, priv->child_count,
- priv->hash_mode);
+ read_subvol = afr_hash_child (&local_args, priv->child_count,
+ priv->hash_mode);
if (read_subvol >= 0 && readable[read_subvol])
- return read_subvol;
+ return read_subvol;
for (i = 0; i < priv->child_count; i++) {
- if (readable[i])
- return i;
+ if (readable[i])
+ return i;
}
- /* no readable subvolumes, either split brain or all subvols down */
+ /* no readable subvolumes, either split brain or all subvols down */
- return -1;
+ return -1;
}
@@ -808,7 +815,8 @@ afr_inode_read_subvol_type_get (inode_t *inode, xlator_t *this,
int
afr_read_subvol_get (inode_t *inode, xlator_t *this, int *subvol_p,
- int *event_p, afr_transaction_type type)
+ int *event_p, afr_transaction_type type,
+ afr_read_subvol_args_t *args)
{
afr_private_t *priv = NULL;
unsigned char *data_readable = NULL;
@@ -835,10 +843,10 @@ afr_read_subvol_get (inode_t *inode, xlator_t *this, int *subvol_p,
if (AFR_COUNT (intersection, priv->child_count) > 0)
subvol = afr_read_subvol_select_by_policy (inode, this,
- intersection);
+ intersection, args);
else
subvol = afr_read_subvol_select_by_policy (inode, this,
- readable);
+ readable, args);
if (subvol_p)
*subvol_p = subvol;
if (event_p)
@@ -1170,7 +1178,8 @@ afr_get_parent_read_subvol (xlator_t *this, inode_t *parent,
priv = this->private;
if (parent)
- par_read_subvol = afr_data_subvol_get (parent, this, 0, 0);
+ par_read_subvol = afr_data_subvol_get (parent, this, 0, 0,
+ NULL);
for (i = 0; i < priv->child_count; i++) {
if (!replies[i].valid)
@@ -1218,6 +1227,8 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this)
gf_boolean_t locked_entry = _gf_false;
gf_boolean_t can_interpret = _gf_true;
inode_t *parent = NULL;
+ ia_type_t ia_type = IA_INVAL;
+ afr_read_subvol_args_t args = {0,};
priv = this->private;
local = frame->local;
@@ -1263,6 +1274,7 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this)
if (read_subvol == -1 || !readable[read_subvol]) {
read_subvol = i;
uuid_copy (read_gfid, replies[i].poststat.ia_gfid);
+ ia_type = replies[i].poststat.ia_type;
local->op_ret = 0;
}
}
@@ -1308,14 +1320,16 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this)
a response from all the UP subvolumes and all of them resolved
to the same GFID
*/
+ uuid_copy (args.gfid, read_gfid);
+ args.ia_type = ia_type;
if (afr_replies_interpret (frame, this, local->inode)) {
read_subvol = afr_data_subvol_get (local->inode, this,
- 0, 0);
+ 0, 0, &args);
afr_inode_read_subvol_reset (local->inode, this);
goto cant_interpret;
} else {
read_subvol = afr_data_subvol_get (local->inode, this,
- 0, 0);
+ 0, 0, &args);
}
} else {
cant_interpret:
@@ -1783,7 +1797,7 @@ afr_discover_done (call_frame_t *frame, xlator_t *this)
afr_replies_interpret (frame, this, local->inode);
- read_subvol = afr_data_subvol_get (local->inode, this, 0, 0);
+ read_subvol = afr_data_subvol_get (local->inode, this, 0, 0, NULL);
if (read_subvol == -1) {
gf_log (this->name, GF_LOG_WARNING, "no read subvols for %s",
local->loc.path);
@@ -1942,7 +1956,7 @@ afr_discover (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req
}
afr_read_subvol_get (loc->inode, this, NULL, &event,
- AFR_DATA_TRANSACTION);
+ AFR_DATA_TRANSACTION, NULL);
if (event != local->event_generation)
afr_inode_refresh (frame, this, loc->inode, afr_discover_do);
@@ -2088,7 +2102,7 @@ afr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
}
afr_read_subvol_get (loc->parent, this, NULL, &event,
- AFR_DATA_TRANSACTION);
+ AFR_DATA_TRANSACTION, NULL);
if (event != local->event_generation)
afr_inode_refresh (frame, this, loc->parent, afr_lookup_do);
@@ -2408,7 +2422,7 @@ afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
- read_subvol = afr_data_subvol_get (local->inode, this, 0, 0);
+ read_subvol = afr_data_subvol_get (local->inode, this, 0, 0, NULL);
LOCK (&frame->lock);
{
diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c
index 984ed9c6095..11f583e42f1 100644
--- a/xlators/cluster/afr/src/afr-dir-read.c
+++ b/xlators/cluster/afr/src/afr-dir-read.c
@@ -153,7 +153,12 @@ afr_validate_read_subvol (inode_t *inode, xlator_t *this, int par_read_subvol)
if (!priv->consistent_metadata)
return 0;
- entry_read_subvol = afr_data_subvol_get (inode, this, 0, 0);
+ /* For an inode fetched through readdirp which is yet to be linked,
+ * inode ctx would not be initialised (yet). So this function returns
+ * -1 above due to gen being 0, which is why it is OK to pass NULL for
+ * read_subvol_args here.
+ */
+ entry_read_subvol = afr_data_subvol_get (inode, this, 0, 0, NULL);
if (entry_read_subvol != par_read_subvol)
return -1;
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
index f5c385c34a4..8bd7d47f89c 100644
--- a/xlators/cluster/afr/src/afr-dir-write.c
+++ b/xlators/cluster/afr/src/afr-dir-write.c
@@ -95,14 +95,14 @@ __afr_dir_write_finalize (call_frame_t *frame, xlator_t *this)
if (local->inode) {
afr_replies_interpret (frame, this, local->inode);
inode_read_subvol = afr_data_subvol_get (local->inode, this,
- NULL, NULL);
+ NULL, NULL, NULL);
}
if (local->parent)
parent_read_subvol = afr_data_subvol_get (local->parent, this,
- NULL, NULL);
+ NULL, NULL, NULL);
if (local->parent2)
parent2_read_subvol = afr_data_subvol_get (local->parent2, this,
- NULL, NULL);
+ NULL, NULL, NULL);
local->op_ret = -1;
local->op_errno = afr_final_errno (local, priv);
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c
index 0c3ba920937..d2c7ecc4740 100644
--- a/xlators/cluster/afr/src/afr-inode-write.c
+++ b/xlators/cluster/afr/src/afr-inode-write.c
@@ -53,10 +53,11 @@ __afr_inode_write_finalize (call_frame_t *frame, xlator_t *this)
if (local->inode) {
if (local->transaction.type == AFR_METADATA_TRANSACTION)
read_subvol = afr_metadata_subvol_get (local->inode, this,
- NULL, NULL);
+ NULL, NULL,
+ NULL);
else
read_subvol = afr_data_subvol_get (local->inode, this,
- NULL, NULL);
+ NULL, NULL, NULL);
}
local->op_ret = -1;
diff --git a/xlators/cluster/afr/src/afr-read-txn.c b/xlators/cluster/afr/src/afr-read-txn.c
index f19c91230e7..4efadb3f1d4 100644
--- a/xlators/cluster/afr/src/afr-read-txn.c
+++ b/xlators/cluster/afr/src/afr-read-txn.c
@@ -89,7 +89,7 @@ afr_read_txn_refresh_done (call_frame_t *frame, xlator_t *this, int err)
memcpy (local->readable, local->child_up, priv->child_count);
read_subvol = afr_read_subvol_select_by_policy (inode, this,
- local->readable);
+ local->readable, NULL);
if (read_subvol == -1)
AFR_READ_TXN_SET_ERROR_AND_GOTO (-1, EIO, -1, readfn);
@@ -216,7 +216,7 @@ afr_read_txn (call_frame_t *frame, xlator_t *this, inode_t *inode,
goto refresh;
read_subvol = afr_read_subvol_select_by_policy (inode, this,
- local->readable);
+ local->readable, NULL);
if (read_subvol < 0 || read_subvol > priv->child_count) {
gf_msg (this->name, GF_LOG_WARNING, 0, AFR_MSG_SPLIT_BRAIN,
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index f32ab9a9e71..d04f2755114 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -731,6 +731,10 @@ typedef struct _afr_local {
struct afr_reply *replies;
} afr_local_t;
+typedef struct afr_read_subvol_args {
+ ia_type_t ia_type;
+ uuid_t gfid;
+} afr_read_subvol_args_t;
/* did a call fail due to a child failing? */
#define child_went_down(op_ret, op_errno) (((op_ret) < 0) && \
@@ -764,7 +768,8 @@ afr_inode_read_subvol_reset (inode_t *inode, xlator_t *this);
int
afr_read_subvol_select_by_policy (inode_t *inode, xlator_t *this,
- unsigned char *readable);
+ unsigned char *readable,
+ afr_read_subvol_args_t *args);
int
afr_inode_read_subvol_type_get (inode_t *inode, xlator_t *this,
@@ -772,13 +777,14 @@ afr_inode_read_subvol_type_get (inode_t *inode, xlator_t *this,
int type);
int
afr_read_subvol_get (inode_t *inode, xlator_t *this, int *subvol_p,
- int *event_p, afr_transaction_type type);
+ int *event_p, afr_transaction_type type,
+ afr_read_subvol_args_t *args);
-#define afr_data_subvol_get(i, t, s, e) \
- afr_read_subvol_get(i, t, s, e, AFR_DATA_TRANSACTION)
+#define afr_data_subvol_get(i, t, s, e, a) \
+ afr_read_subvol_get(i, t, s, e, AFR_DATA_TRANSACTION, a)
-#define afr_metadata_subvol_get(i, t, s, e) \
- afr_read_subvol_get(i, t, s, e, AFR_METADATA_TRANSACTION)
+#define afr_metadata_subvol_get(i, t, s, e, a) \
+ afr_read_subvol_get(i, t, s, e, AFR_METADATA_TRANSACTION, a)
int
afr_inode_refresh (call_frame_t *frame, xlator_t *this, inode_t *inode,