diff options
-rw-r--r-- | xlators/features/shard/src/shard.c | 294 | ||||
-rw-r--r-- | xlators/features/shard/src/shard.h | 4 |
2 files changed, 206 insertions, 92 deletions
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 52cf3d777f3..81a74b3c8b3 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,19 +1226,30 @@ shard_lookup_dot_shard (call_frame_t *frame, xlator_t *this, goto err; } - ret = dict_set_gfuuid (xattr_req, "gfid-req", priv->dot_shard_gfid, - true); + 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_gfuuid (xattr_req, "gfid-req", *gfid, false); 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; @@ -1187,6 +1257,8 @@ shard_lookup_dot_shard (call_frame_t *frame, xlator_t *this, err: if (xattr_req) dict_unref (xattr_req); + if (free_gfid) + GF_FREE (gfid); post_res_handler (frame, this); return 0; } @@ -2203,14 +2275,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 +2757,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 +3126,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 +3892,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 +4333,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 +4408,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 +4441,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 +4466,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_gfuuid (xattr_req, "gfid-req", priv->dot_shard_gfid, - true); + ret = dict_set_gfuuid (xattr_req, "gfid-req", *gfid, false); 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 +4527,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 75d39a19186..a1adb6a447b 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__ */ |