summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <rgowdapp@redhat.com>2017-09-19 09:44:55 +0530
committerAmar Tumballi <amarts@redhat.com>2017-12-02 11:46:52 +0000
commit59d1cc720f52357f7a6f20bb630febc6a622c99c (patch)
tree25e63a078962d0b1a32fab07a6152d424b6406d3
parente785faead91f74dce7c832848f2e8f3f43bd0be5 (diff)
cluster/dht: populate inode in dentry for single subvolume dht
... in readdirp response if dentry points to a directory inode. This is a special case where the entire layout is stored in one single subvolume and hence no need for lookup to construct the layout Change-Id: I44fd951e2393ec9dac2af120469be47081a32185 BUG: 1492625 Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
-rw-r--r--xlators/cluster/dht/src/dht-common.c67
-rw-r--r--xlators/cluster/dht/src/dht-layout.c3
2 files changed, 69 insertions, 1 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index ab649c08612..f5411f406d9 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -6274,6 +6274,49 @@ err:
}
+/* dht_readdirp_cbk creates a new dentry and dentry->inode is not assigned.
+ This functions assigns an inode if all of the following conditions are true:
+
+ * DHT has only one child. In this case the entire layout is present on this
+ single child and hence we can set complete layout in inode.
+ * backend has complete layout and there are no anomalies in it and from this
+ information layout can be constructed and set in inode.
+*/
+
+void
+dht_populate_inode_for_dentry (xlator_t *this, xlator_t *subvol,
+ gf_dirent_t *entry, gf_dirent_t *orig_entry)
+{
+ dht_layout_t *layout = NULL;
+ int ret = 0;
+ loc_t loc = {0, };
+
+ layout = dht_layout_new (this, 1);
+ if (!layout)
+ goto out;
+
+ ret = dht_layout_merge (this, layout, subvol, 0, 0, orig_entry->dict);
+ if (!ret) {
+ gf_uuid_copy (loc.gfid, orig_entry->d_stat.ia_gfid);
+ loc.inode = inode_ref (orig_entry->inode);
+
+ ret = dht_layout_normalize (this, &loc, layout);
+ if (ret == 0) {
+ dht_layout_set (this, orig_entry->inode, layout);
+ entry->inode = inode_ref (orig_entry->inode);
+ layout = NULL;
+ }
+
+ loc_wipe (&loc);
+ }
+
+ if (layout)
+ dht_layout_unref (this, layout);
+
+out:
+ return;
+}
+
int
dht_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
int op_errno, gf_dirent_t *orig_entries, dict_t *xdata)
@@ -6285,7 +6328,7 @@ dht_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
xlator_t *next_subvol = NULL;
off_t next_offset = 0;
int count = 0;
- dht_layout_t *layout = 0;
+ dht_layout_t *layout = NULL;
dht_conf_t *conf = NULL;
dht_methods_t *methods = NULL;
xlator_t *subvol = 0;
@@ -6411,6 +6454,13 @@ list:
dht_inode_ctx_time_update (orig_entry->inode,
this, &entry->d_stat,
1);
+
+ if (conf->subvolume_cnt == 1) {
+ dht_populate_inode_for_dentry (this,
+ prev,
+ entry,
+ orig_entry);
+ }
}
} else {
if (orig_entry->inode) {
@@ -6694,6 +6744,21 @@ dht_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
GF_READDIR_SKIP_DIRS);
}
}
+
+ if (conf->subvolume_cnt == 1) {
+ ret = dict_set_uint32 (local->xattr,
+ conf->xattr_name, 4 * 4);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_WARNING,
+ ENOMEM,
+ DHT_MSG_DICT_SET_FAILED,
+ "Failed to set dictionary "
+ "value:key = %s ",
+ conf->xattr_name);
+ }
+ }
+
+
}
STACK_WIND_COOKIE (frame, dht_readdirp_cbk, xvol, xvol,
diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c
index 3414dc91908..419ce329a1d 100644
--- a/xlators/cluster/dht/src/dht-layout.c
+++ b/xlators/cluster/dht/src/dht-layout.c
@@ -366,6 +366,9 @@ dht_layout_merge (xlator_t *this, dht_layout_t *layout, xlator_t *subvol,
err = op_errno;
}
+ if (!layout)
+ goto out;
+
for (i = 0; i < layout->cnt; i++) {
if (layout->list[i].xlator == NULL) {
layout->list[i].err = err;