From 9be984ac2b71423b72ab3b1fa45b4d77a263ce1e Mon Sep 17 00:00:00 2001
From: Krutika Dhananjay <kdhananj@redhat.com>
Date: Wed, 28 Mar 2018 12:09:27 +0530
Subject: [PATCH 426/444] features/shard: Make operations on internal
directories generic
> Upstream: https://review.gluster.org/19892
> BUG: 1568521
> Change-Id: Iea7ad2102220c6d415909f8caef84167ce2d6818
Change-Id: Iea7ad2102220c6d415909f8caef84167ce2d6818
BUG: 1520882
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/154860
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Xavi Hernandez <xhernandez@redhat.com>
---
xlators/features/shard/src/shard.c | 295 +++++++++++++++++++++++++------------
xlators/features/shard/src/shard.h | 4 +
2 files changed, 206 insertions(+), 93 deletions(-)
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c
index f5fb181..5ff04df 100644
--- a/xlators/features/shard/src/shard.c
+++ b/xlators/features/shard/src/shard.c
@@ -546,30 +546,55 @@ shard_call_count_return (call_frame_t *frame)
return call_count;
}
+static char *
+shard_internal_dir_string (shard_internal_dir_type_t type)
+{
+ char *str = NULL;
+
+ switch (type) {
+ case SHARD_INTERNAL_DIR_DOT_SHARD:
+ str = ".shard";
+ break;
+ default:
+ break;
+ }
+ return str;
+}
+
static int
-shard_init_dot_shard_loc (xlator_t *this, shard_local_t *local)
+shard_init_internal_dir_loc (xlator_t *this, shard_local_t *local,
+ shard_internal_dir_type_t type)
{
- int ret = -1;
- loc_t *dot_shard_loc = NULL;
+ int ret = -1;
+ char *bname = NULL;
+ loc_t *internal_dir_loc = NULL;
if (!local)
return -1;
- dot_shard_loc = &local->dot_shard_loc;
- dot_shard_loc->inode = inode_new (this->itable);
- dot_shard_loc->parent = inode_ref (this->itable->root);
- ret = inode_path (dot_shard_loc->parent, GF_SHARD_DIR,
- (char **)&dot_shard_loc->path);
- if (ret < 0 || !(dot_shard_loc->inode)) {
+ switch (type) {
+ case SHARD_INTERNAL_DIR_DOT_SHARD:
+ internal_dir_loc = &local->dot_shard_loc;
+ bname = GF_SHARD_DIR;
+ break;
+ default:
+ break;
+ }
+
+ internal_dir_loc->inode = inode_new (this->itable);
+ internal_dir_loc->parent = inode_ref (this->itable->root);
+ ret = inode_path (internal_dir_loc->parent, bname,
+ (char **)&internal_dir_loc->path);
+ if (ret < 0 || !(internal_dir_loc->inode)) {
gf_msg (this->name, GF_LOG_ERROR, 0,
SHARD_MSG_INODE_PATH_FAILED,
- "Inode path failed on %s", GF_SHARD_DIR);
+ "Inode path failed on %s", bname);
goto out;
}
- dot_shard_loc->name = strrchr (dot_shard_loc->path, '/');
- if (dot_shard_loc->name)
- dot_shard_loc->name++;
+ internal_dir_loc->name = strrchr (internal_dir_loc->path, '/');
+ if (internal_dir_loc->name)
+ internal_dir_loc->name++;
ret = 0;
out:
@@ -1029,28 +1054,42 @@ out:
}
static inode_t *
-shard_link_dot_shard_inode (shard_local_t *local, inode_t *inode,
- struct iatt *buf)
+shard_link_internal_dir_inode (shard_local_t *local, inode_t *inode,
+ struct iatt *buf, shard_internal_dir_type_t type)
{
inode_t *linked_inode = NULL;
shard_priv_t *priv = NULL;
+ char *bname = NULL;
+ inode_t **priv_inode = NULL;
priv = THIS->private;
- linked_inode = inode_link (inode, inode->table->root, ".shard", buf);
+ switch (type) {
+ case SHARD_INTERNAL_DIR_DOT_SHARD:
+ bname = ".shard";
+ priv_inode = &priv->dot_shard_inode;
+ break;
+ default:
+ break;
+ }
+
+ linked_inode = inode_link (inode, inode->table->root, bname, buf);
inode_lookup (linked_inode);
- priv->dot_shard_inode = linked_inode;
+ *priv_inode = linked_inode;
return linked_inode;
}
int
-shard_refresh_dot_shard_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xdata,
- struct iatt *postparent)
+shard_refresh_internal_dir_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xdata,
+ struct iatt *postparent)
{
- shard_local_t *local = NULL;
+ shard_local_t *local = NULL;
+ inode_t *linked_inode = NULL;
+ shard_internal_dir_type_t type = (shard_internal_dir_type_t) cookie;
local = frame->local;
@@ -1061,27 +1100,37 @@ shard_refresh_dot_shard_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
/* To-Do: Fix refcount increment per call to
- * shard_link_dot_shard_inode().
+ * shard_link_internal_dir_inode().
*/
- shard_link_dot_shard_inode (local, inode, buf);
- shard_inode_ctx_set_refreshed_flag (inode, this);
+ linked_inode = shard_link_internal_dir_inode (local, inode, buf, type);
+ shard_inode_ctx_set_refreshed_flag (linked_inode, this);
out:
shard_common_resolve_shards (frame, this, local->post_res_handler);
return 0;
}
int
-shard_refresh_dot_shard (call_frame_t *frame, xlator_t *this)
+shard_refresh_internal_dir (call_frame_t *frame, xlator_t *this,
+ shard_internal_dir_type_t type)
{
loc_t loc = {0,};
inode_t *inode = NULL;
shard_priv_t *priv = NULL;
shard_local_t *local = NULL;
+ uuid_t gfid = {0,};
local = frame->local;
priv = this->private;
- inode = inode_find (this->itable, priv->dot_shard_gfid);
+ switch (type) {
+ case SHARD_INTERNAL_DIR_DOT_SHARD:
+ gf_uuid_copy (gfid, priv->dot_shard_gfid);
+ break;
+ default:
+ break;
+ }
+
+ inode = inode_find (this->itable, gfid);
if (!shard_inode_ctx_needs_lookup (inode, this)) {
local->op_ret = 0;
@@ -1092,10 +1141,11 @@ shard_refresh_dot_shard (call_frame_t *frame, xlator_t *this)
* call to inode_find()
*/
loc.inode = inode;
- gf_uuid_copy (loc.gfid, priv->dot_shard_gfid);
+ gf_uuid_copy (loc.gfid, gfid);
- STACK_WIND (frame, shard_refresh_dot_shard_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, &loc, NULL);
+ STACK_WIND_COOKIE (frame, shard_refresh_internal_dir_cbk,
+ (void *)(long) type, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, &loc, NULL);
loc_wipe (&loc);
return 0;
@@ -1106,13 +1156,14 @@ out:
}
int
-shard_lookup_dot_shard_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xdata,
- struct iatt *postparent)
+shard_lookup_internal_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xdata,
+ struct iatt *postparent)
{
- inode_t *link_inode = NULL;
- shard_local_t *local = NULL;
+ inode_t *link_inode = NULL;
+ shard_local_t *local = NULL;
+ shard_internal_dir_type_t type = (shard_internal_dir_type_t) cookie;
local = frame->local;
@@ -1124,17 +1175,17 @@ shard_lookup_dot_shard_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!IA_ISDIR (buf->ia_type)) {
gf_msg (this->name, GF_LOG_CRITICAL, 0,
- SHARD_MSG_DOT_SHARD_NODIR, "/.shard already exists and "
- "is not a directory. Please remove /.shard from all "
- "bricks and try again");
+ SHARD_MSG_DOT_SHARD_NODIR, "%s already exists and "
+ "is not a directory. Please remove it from all bricks "
+ "and try again", shard_internal_dir_string (type));
local->op_ret = -1;
local->op_errno = EIO;
goto unwind;
}
- link_inode = shard_link_dot_shard_inode (local, inode, buf);
+ link_inode = shard_link_internal_dir_inode (local, inode, buf, type);
if (link_inode != inode) {
- shard_refresh_dot_shard (frame, this);
+ shard_refresh_internal_dir (frame, this, type);
} else {
shard_inode_ctx_set_refreshed_flag (link_inode, this);
shard_common_resolve_shards (frame, this,
@@ -1148,18 +1199,26 @@ unwind:
}
int
-shard_lookup_dot_shard (call_frame_t *frame, xlator_t *this,
- shard_post_resolve_fop_handler_t post_res_handler)
+shard_lookup_internal_dir (call_frame_t *frame, xlator_t *this,
+ shard_post_resolve_fop_handler_t post_res_handler,
+ shard_internal_dir_type_t type)
{
int ret = -1;
dict_t *xattr_req = NULL;
shard_priv_t *priv = NULL;
shard_local_t *local = NULL;
+ uuid_t *gfid = NULL;
+ loc_t *loc = NULL;
+ gf_boolean_t free_gfid = _gf_true;
local = frame->local;
priv = this->private;
local->post_res_handler = post_res_handler;
+ gfid = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
+ if (!gfid)
+ goto err;
+
xattr_req = dict_new ();
if (!xattr_req) {
local->op_ret = -1;
@@ -1167,26 +1226,38 @@ shard_lookup_dot_shard (call_frame_t *frame, xlator_t *this,
goto err;
}
- ret = dict_set_static_bin (xattr_req, "gfid-req", priv->dot_shard_gfid,
- 16);
+ switch (type) {
+ case SHARD_INTERNAL_DIR_DOT_SHARD:
+ gf_uuid_copy (*gfid, priv->dot_shard_gfid);
+ loc = &local->dot_shard_loc;
+ break;
+ default:
+ break;
+ }
+
+ ret = dict_set_bin (xattr_req, "gfid-req", *gfid, 16);
if (ret) {
gf_msg (this->name, GF_LOG_ERROR, 0, SHARD_MSG_DICT_SET_FAILED,
- "Failed to set gfid of /.shard into dict");
+ "Failed to set gfid of %s into dict",
+ shard_internal_dir_string (type));
local->op_ret = -1;
local->op_errno = ENOMEM;
goto err;
+ } else {
+ free_gfid = _gf_false;
}
- STACK_WIND (frame, shard_lookup_dot_shard_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, &local->dot_shard_loc,
- xattr_req);
-
+ STACK_WIND_COOKIE (frame, shard_lookup_internal_dir_cbk,
+ (void *) (long) type, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
dict_unref (xattr_req);
return 0;
err:
if (xattr_req)
dict_unref (xattr_req);
+ if (free_gfid)
+ GF_FREE (gfid);
post_res_handler (frame, this);
return 0;
}
@@ -2203,14 +2274,17 @@ shard_truncate_begin (call_frame_t *frame, xlator_t *this)
local->dot_shard_loc.inode = inode_find (this->itable,
priv->dot_shard_gfid);
if (!local->dot_shard_loc.inode) {
- ret = shard_init_dot_shard_loc (this, local);
+ ret = shard_init_internal_dir_loc (this, local,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
if (ret)
goto err;
- shard_lookup_dot_shard (frame, this,
- shard_post_resolve_truncate_handler);
+ shard_lookup_internal_dir (frame, this,
+ shard_post_resolve_truncate_handler,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
} else {
local->post_res_handler = shard_post_resolve_truncate_handler;
- shard_refresh_dot_shard (frame, this);
+ shard_refresh_internal_dir (frame, this,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
}
return 0;
@@ -2682,14 +2756,17 @@ shard_unlink_base_file_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->dot_shard_loc.inode = inode_find (this->itable,
priv->dot_shard_gfid);
if (!local->dot_shard_loc.inode) {
- ret = shard_init_dot_shard_loc (this, local);
+ ret = shard_init_internal_dir_loc (this, local,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
if (ret)
goto unwind;
- shard_lookup_dot_shard (frame, this,
- shard_post_resolve_unlink_handler);
+ shard_lookup_internal_dir (frame, this,
+ shard_post_resolve_unlink_handler,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
} else {
local->post_res_handler = shard_post_resolve_unlink_handler;
- shard_refresh_dot_shard (frame, this);
+ shard_refresh_internal_dir (frame, this,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
}
return 0;
@@ -3048,14 +3125,17 @@ shard_rename_unlink_dst_shards_do (call_frame_t *frame, xlator_t *this)
local->dot_shard_loc.inode = inode_find (this->itable,
priv->dot_shard_gfid);
if (!local->dot_shard_loc.inode) {
- ret = shard_init_dot_shard_loc (this, local);
+ ret = shard_init_internal_dir_loc (this, local,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
if (ret)
goto out;
- shard_lookup_dot_shard (frame, this,
- shard_post_resolve_unlink_handler);
+ shard_lookup_internal_dir (frame, this,
+ shard_post_resolve_unlink_handler,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
} else {
local->post_res_handler = shard_post_resolve_unlink_handler;
- shard_refresh_dot_shard (frame, this);
+ shard_refresh_internal_dir (frame, this,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
}
return 0;
@@ -3811,14 +3891,17 @@ shard_post_lookup_readv_handler (call_frame_t *frame, xlator_t *this)
local->dot_shard_loc.inode = inode_find (this->itable,
priv->dot_shard_gfid);
if (!local->dot_shard_loc.inode) {
- ret = shard_init_dot_shard_loc (this, local);
+ ret = shard_init_internal_dir_loc (this, local,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
if (ret)
goto err;
- shard_lookup_dot_shard (frame, this,
- shard_post_resolve_readv_handler);
+ shard_lookup_internal_dir (frame, this,
+ shard_post_resolve_readv_handler,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
} else {
local->post_res_handler = shard_post_resolve_readv_handler;
- shard_refresh_dot_shard (frame, this);
+ shard_refresh_internal_dir (frame, this,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
}
return 0;
@@ -4249,8 +4332,9 @@ shard_common_inode_write_post_mknod_handler (call_frame_t *frame,
}
int
-shard_mkdir_dot_shard (call_frame_t *frame, xlator_t *this,
- shard_post_resolve_fop_handler_t handler);
+shard_mkdir_internal_dir (call_frame_t *frame, xlator_t *this,
+ shard_post_resolve_fop_handler_t handler,
+ shard_internal_dir_type_t type);
int
shard_common_inode_write_post_resolve_handler (call_frame_t *frame,
xlator_t *this)
@@ -4323,26 +4407,28 @@ shard_common_inode_write_post_lookup_handler (call_frame_t *frame,
if (!local->dot_shard_loc.inode) {
/*change handler*/
- shard_mkdir_dot_shard (frame, this,
- shard_common_inode_write_post_resolve_handler);
+ shard_mkdir_internal_dir (frame, this,
+ shard_common_inode_write_post_resolve_handler,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
} else {
/*change handler*/
local->post_res_handler =
shard_common_inode_write_post_resolve_handler;
- shard_refresh_dot_shard (frame, this);
+ shard_refresh_internal_dir (frame, this,
+ SHARD_INTERNAL_DIR_DOT_SHARD);
}
return 0;
}
int
-shard_mkdir_dot_shard_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+shard_mkdir_internal_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
{
- inode_t *link_inode = NULL;
- shard_local_t *local = NULL;
+ inode_t *link_inode = NULL;
+ shard_local_t *local = NULL;
+ shard_internal_dir_type_t type = (shard_internal_dir_type_t) cookie;
local = frame->local;
@@ -4354,17 +4440,19 @@ shard_mkdir_dot_shard_cbk (call_frame_t *frame, void *cookie,
local->op_errno = op_errno;
goto unwind;
} else {
- gf_msg_debug (this->name, 0, "mkdir on /.shard failed "
- "with EEXIST. Attempting lookup now");
- shard_lookup_dot_shard (frame, this,
- local->post_res_handler);
+ gf_msg_debug (this->name, 0, "mkdir on %s failed "
+ "with EEXIST. Attempting lookup now",
+ shard_internal_dir_string (type));
+ shard_lookup_internal_dir (frame, this,
+ local->post_res_handler,
+ type);
return 0;
}
}
- link_inode = shard_link_dot_shard_inode (local, inode, buf);
+ link_inode = shard_link_internal_dir_inode (local, inode, buf, type);
if (link_inode != inode) {
- shard_refresh_dot_shard (frame, this);
+ shard_refresh_internal_dir (frame, this, type);
} else {
shard_inode_ctx_set_refreshed_flag (link_inode, this);
shard_common_resolve_shards (frame, this,
@@ -4377,40 +4465,59 @@ unwind:
}
int
-shard_mkdir_dot_shard (call_frame_t *frame, xlator_t *this,
- shard_post_resolve_fop_handler_t handler)
+shard_mkdir_internal_dir (call_frame_t *frame, xlator_t *this,
+ shard_post_resolve_fop_handler_t handler,
+ shard_internal_dir_type_t type)
{
int ret = -1;
shard_local_t *local = NULL;
shard_priv_t *priv = NULL;
dict_t *xattr_req = NULL;
+ uuid_t *gfid = NULL;
+ loc_t *loc = NULL;
+ gf_boolean_t free_gfid = _gf_true;
local = frame->local;
priv = this->private;
local->post_res_handler = handler;
+ gfid = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
+ if (!gfid)
+ goto err;
+
+ switch (type) {
+ case SHARD_INTERNAL_DIR_DOT_SHARD:
+ gf_uuid_copy (*gfid, priv->dot_shard_gfid);
+ loc = &local->dot_shard_loc;
+ break;
+ default:
+ break;
+ }
xattr_req = dict_new ();
if (!xattr_req)
goto err;
- ret = shard_init_dot_shard_loc (this, local);
+ ret = shard_init_internal_dir_loc (this, local, type);
if (ret)
goto err;
- ret = dict_set_static_bin (xattr_req, "gfid-req", priv->dot_shard_gfid,
- 16);
+ ret = dict_set_bin (xattr_req, "gfid-req", *gfid, 16);
if (ret) {
gf_msg (this->name, GF_LOG_ERROR, 0, SHARD_MSG_DICT_SET_FAILED,
- "Failed to set gfid-req for /.shard");
+ "Failed to set gfid-req for %s",
+ shard_internal_dir_string (type));
goto err;
+ } else {
+ free_gfid = _gf_false;
}
SHARD_SET_ROOT_FS_ID (frame, local);
- STACK_WIND (frame, shard_mkdir_dot_shard_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir,
- &local->dot_shard_loc, 0755, 0, xattr_req);
+ STACK_WIND_COOKIE (frame, shard_mkdir_internal_dir_cbk,
+ (void *)(long) type, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mkdir, loc, 0755, 0,
+ xattr_req);
dict_unref (xattr_req);
return 0;
@@ -4419,6 +4526,8 @@ err:
dict_unref (xattr_req);
local->op_ret = -1;
local->op_errno = ENOMEM;
+ if (free_gfid)
+ GF_FREE (gfid);
handler (frame, this);
return 0;
}
diff --git a/xlators/features/shard/src/shard.h b/xlators/features/shard/src/shard.h
index 75d39a1..a1adb6a 100644
--- a/xlators/features/shard/src/shard.h
+++ b/xlators/features/shard/src/shard.h
@@ -278,4 +278,8 @@ typedef struct shard_inode_ctx {
inode_t *base_inode;
} shard_inode_ctx_t;
+typedef enum {
+ SHARD_INTERNAL_DIR_DOT_SHARD = 1,
+} shard_internal_dir_type_t;
+
#endif /* __SHARD_H__ */
--
1.8.3.1