diff options
Diffstat (limited to 'xlators/features/shard')
-rw-r--r-- | xlators/features/shard/src/shard.c | 359 | ||||
-rw-r--r-- | xlators/features/shard/src/shard.h | 10 |
2 files changed, 271 insertions, 98 deletions
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 506c22e2400..4afaf6ad128 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -256,9 +256,11 @@ shard_lookup_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) { - int ret = 0; - uint64_t size = 0; - shard_inode_ctx_t ctx_tmp = {0,}; + int ret = 0; + uint64_t size = 0; + void *size_attr = NULL; + shard_inode_ctx_t ctx_tmp = {0,}; + uint64_t size_array[4]; if (op_ret < 0) goto unwind; @@ -266,11 +268,34 @@ shard_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (IA_ISDIR (buf->ia_type)) goto unwind; + if (!shard_inode_ctx_get_block_size (inode, this, &size)) + goto unwind; + ret = dict_get_uint64 (xdata, GF_XATTR_SHARD_BLOCK_SIZE, &size); if (!ret) { ctx_tmp.block_size = ntoh64 (size); ctx_tmp.mode = st_mode_from_ia (buf->ia_prot, buf->ia_type); ctx_tmp.rdev = buf->ia_rdev; + /* Sharding xlator would fetch size and block count only if + * @size is present. The absence of GF_XATTR_SHARD_BLOCK_SIZE on + * the file looked up could be because it was created before + * sharding was enabled on the volume. + */ + ret = dict_get_ptr (xdata, GF_XATTR_SHARD_FILE_SIZE, + &size_attr); + if (ret) { + gf_log (this->name, GF_LOG_WARNING, "Failed to " + "get xattr "GF_XATTR_SHARD_FILE_SIZE" from disk" + " for %s", uuid_utoa (inode->gfid)); + op_ret = -1; + op_errno = ENOMEM; + goto unwind; + } + + memcpy (size_array, size_attr, sizeof (size_array)); + + buf->ia_size = ntoh64 (size_array[0]); + buf->ia_blocks = ntoh64 (size_array[2]); } /* else it is assumed that the file was created prior to enabling * sharding on the volume. @@ -281,10 +306,6 @@ shard_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "Failed to set inode ctx " "for %s", uuid_utoa (buf->ia_gfid)); - /* To-Do: return the call with aggregated values of ia_size and - * ia_blocks - */ - unwind: SHARD_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf, xdata, postparent); @@ -325,6 +346,15 @@ shard_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, } } + ret = dict_set_uint64 (local->xattr_req, GF_XATTR_SHARD_FILE_SIZE, + 8 * 4); + if (ret) { + gf_log (this->name, GF_LOG_WARNING, "Failed to set dict value: " + "key:%s for path %s.", GF_XATTR_SHARD_FILE_SIZE, + loc->path); + goto err; + } + STACK_WIND (frame, shard_lookup_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->lookup, loc, local->xattr_req); @@ -339,44 +369,207 @@ err: } int -shard_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf, - dict_t *xdata) +shard_lookup_base_file_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) { - /* To-Do: Update ia_size and ia_blocks in @buf before presenting it - * to the parent. - */ + shard_local_t *local = NULL; + + local = frame->local; + + if (op_ret < 0) { + local->op_ret = op_ret; + local->op_errno = op_errno; + goto unwind; + } + + local->prebuf = *buf; + if (shard_modify_size_and_block_count (&local->prebuf, xdata)) { + local->op_ret = -1; + local->op_errno = EINVAL; + goto unwind; + } - SHARD_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata); +unwind: + local->handler (frame, this); return 0; } int -shard_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +shard_lookup_base_file (call_frame_t *frame, xlator_t *this, + shard_post_fop_handler_t handler) +{ + shard_local_t *local = NULL; + dict_t *xattr_req = NULL; + + local = frame->local; + local->handler = handler; + + xattr_req = dict_new (); + if (!xattr_req) { + local->op_ret = -1; + local->op_errno = ENOMEM; + goto err; + } + + SHARD_MD_READ_FOP_INIT_REQ_DICT (this, xattr_req, local->loc.gfid, + local, err); + + STACK_WIND (frame, shard_lookup_base_file_cbk, FIRST_CHILD (this), + FIRST_CHILD(this)->fops->lookup, &local->loc, + xattr_req); + + dict_unref (xattr_req); + return 0; + +err: + if (xattr_req) + dict_unref (xattr_req); + handler (frame, this); + return 0; + +} + +int +shard_post_fstat_handler (call_frame_t *frame, xlator_t *this) { - STACK_WIND (frame, shard_stat_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->stat, loc, xdata); + shard_local_t *local = NULL; + + local = frame->local; + SHARD_STACK_UNWIND (fstat, frame, local->op_ret, local->op_errno, + &local->prebuf, local->xattr_rsp); return 0; } int -shard_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf, - dict_t *xdata) +shard_post_stat_handler (call_frame_t *frame, xlator_t *this) { - /* To-Do: Update ia_size and ia_blocks in @buf before presenting it - * to the parent. - */ - SHARD_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf, xdata); + shard_local_t *local = NULL; + + local = frame->local; + + SHARD_STACK_UNWIND (stat, frame, local->op_ret, local->op_errno, + &local->prebuf, local->xattr_rsp); + return 0; +} + +int +shard_common_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) +{ + shard_local_t *local = NULL; + + local = frame->local; + + if (op_ret < 0) { + local->op_ret = op_ret; + local->op_errno = op_errno; + goto unwind; + } + + local->prebuf = *buf; + if (shard_modify_size_and_block_count (&local->prebuf, xdata)) { + local->op_ret = -1; + local->op_errno = EINVAL; + goto unwind; + } + local->xattr_rsp = dict_ref (xdata); + +unwind: + local->handler (frame, this); + return 0; +} + +int +shard_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + int ret = -1; + uint64_t block_size = 0; + shard_local_t *local = NULL; + + ret = shard_inode_ctx_get_block_size (loc->inode, this, &block_size); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get block size " + "from inode ctx of %s", uuid_utoa (loc->inode->gfid)); + goto err; + } + + if (!block_size) { + STACK_WIND (frame, default_stat_cbk, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->stat, loc, xdata); + return 0; + } + + local = mem_get0 (this->local_pool); + if (!local) + goto err; + + frame->local = local; + + local->handler = shard_post_stat_handler; + local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new (); + if (!local->xattr_req) + goto err; + + SHARD_MD_READ_FOP_INIT_REQ_DICT (this, local->xattr_req, + local->loc.gfid, local, err); + + STACK_WIND (frame, shard_common_stat_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->stat, loc, local->xattr_req); + + return 0; + +err: + SHARD_STACK_UNWIND (stat, frame, -1, ENOMEM, NULL, NULL); return 0; } int shard_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { - STACK_WIND (frame, shard_fstat_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fstat, fd, xdata); + int ret = -1; + uint64_t block_size = 0; + shard_local_t *local = NULL; + + ret = shard_inode_ctx_get_block_size (fd->inode, this, &block_size); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get block size " + "from inode ctx of %s", uuid_utoa (fd->inode->gfid)); + goto err; + } + + if (!block_size) { + STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->fstat, fd, xdata); + return 0; + } + + if (!this->itable) + this->itable = fd->inode->table; + + local = mem_get0 (this->local_pool); + if (!local) + goto err; + + frame->local = local; + + local->handler = shard_post_fstat_handler; + local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new (); + if (!local->xattr_req) + goto err; + + SHARD_MD_READ_FOP_INIT_REQ_DICT (this, local->xattr_req, + fd->inode->gfid, local, err); + + STACK_WIND (frame, shard_common_stat_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fstat, fd, local->xattr_req); + return 0; + +err: + SHARD_STACK_UNWIND (fstat, frame, -1, ENOMEM, NULL, NULL); return 0; } @@ -921,72 +1114,25 @@ next: } int -shard_lookup_base_file_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_post_lookup_writev_handler (call_frame_t *frame, xlator_t *this) { - shard_local_t *local = NULL; + shard_local_t *local = NULL; local = frame->local; - if (op_ret < 0) - goto unwind; - - local->prebuf = *buf; - if (shard_modify_size_and_block_count (&local->prebuf, xdata)) { - op_ret = -1; - op_errno = EINVAL; - goto unwind; + if (local->op_ret < 0) { + SHARD_STACK_UNWIND (writev, frame, local->op_ret, + local->op_errno, NULL, NULL, NULL); + return 0; } local->postbuf = local->prebuf; - shard_writev_do (frame, this); return 0; - -unwind: - SHARD_STACK_UNWIND (writev, frame, op_ret, op_errno, NULL, NULL, NULL); - return 0; - } - -int -shard_lookup_base_file (call_frame_t *frame, xlator_t *this) -{ - fd_t *fd = NULL; - shard_local_t *local = NULL; - dict_t *xattr_req = NULL; - - local = frame->local; - fd = local->fd; - - xattr_req = dict_new (); - if (!xattr_req) - goto err; - - local->loc.inode = inode_new (fd->inode->table); - gf_uuid_copy (local->loc.gfid, fd->inode->gfid); - - SHARD_MD_READ_FOP_INIT_REQ_DICT (this, xattr_req, fd->inode->gfid, err); - - STACK_WIND (frame, shard_lookup_base_file_cbk, FIRST_CHILD (this), - FIRST_CHILD(this)->fops->lookup, &local->loc, - xattr_req); - - dict_unref (xattr_req); - return 0; - -err: - if (xattr_req) - dict_unref (xattr_req); - SHARD_STACK_UNWIND (writev, frame, -1, ENOMEM, NULL, NULL, NULL); - return 0; - -} - void + shard_link_block_inode (shard_local_t *local, int block_num, inode_t *inode, struct iatt *buf) { @@ -1036,7 +1182,8 @@ done: if (local->op_ret < 0) goto unwind; else - shard_lookup_base_file (frame, this); + shard_lookup_base_file (frame, this, + shard_post_lookup_writev_handler); } return 0; @@ -1205,7 +1352,8 @@ done: goto unwind; } else { if (!local->eexist_count) { - shard_lookup_base_file (frame, this); + shard_lookup_base_file (frame, this, + shard_post_lookup_writev_handler); } else { local->call_count = local->eexist_count; shard_writev_lookup_shards (frame, this); @@ -1379,7 +1527,8 @@ shard_common_resolve_shards (call_frame_t *frame, xlator_t *this) if (local->call_count) shard_writev_resume_mknod (frame, this); else - shard_lookup_base_file (frame, this); + shard_lookup_base_file (frame, this, + shard_post_lookup_writev_handler); return 0; } @@ -1446,7 +1595,7 @@ shard_lookup_dot_shard (call_frame_t *frame, xlator_t *this) ret = dict_set_static_bin (xattr_req, "gfid-req", priv->dot_shard_gfid, 16); - if (!ret) { + if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to set gfid of " "/.shard into dict"); goto err; @@ -1455,6 +1604,7 @@ shard_lookup_dot_shard (call_frame_t *frame, xlator_t *this) STACK_WIND (frame, shard_lookup_dot_shard_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, &local->dot_shard_loc, xattr_req); + dict_unref (xattr_req); return 0; @@ -1615,6 +1765,9 @@ shard_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, if (!local->inode_list) goto out; + local->loc.inode = inode_ref (fd->inode); + gf_uuid_copy (local->loc.gfid, fd->inode->gfid); + gf_log (this->name, GF_LOG_TRACE, "gfid=%s first_block=%"PRIu32" " "last_block=%"PRIu32" num_blocks=%"PRIu32" offset=%"PRId64" " "total_size=%lu", uuid_utoa (fd->inode->gfid), @@ -1676,11 +1829,11 @@ shard_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { - fd_t *fd = NULL; - gf_dirent_t *entry = NULL; - gf_dirent_t *tmp = NULL; - shard_local_t *local = NULL; - gf_dirent_t skipped; + fd_t *fd = NULL; + gf_dirent_t *entry = NULL; + gf_dirent_t *tmp = NULL; + shard_local_t *local = NULL; + gf_dirent_t skipped; INIT_LIST_HEAD (&skipped.list); @@ -1695,8 +1848,14 @@ shard_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, !(strcmp (entry->d_name, GF_SHARD_DIR))) { list_del_init (&entry->list); list_add_tail (&entry->list, &skipped.list); - break; + continue; } + + if (!entry->dict) + continue; + + shard_modify_size_and_block_count (&entry->d_stat, entry->dict); + } unwind: @@ -1710,30 +1869,38 @@ int shard_readdir_do (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, int whichop, dict_t *xdata) { - int op_errno = ENOMEM; shard_local_t *local = NULL; local = mem_get0 (this->local_pool); - if (!local) + if (!local) { + local->op_ret = -1; + local->op_errno = ENOMEM; goto err; + } frame->local = local; local->fd = fd_ref (fd); - if (whichop == GF_FOP_READDIR) + if (whichop == GF_FOP_READDIR) { STACK_WIND (frame, shard_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, fd, size, offset, xdata); - else + } else { + local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new (); + SHARD_MD_READ_FOP_INIT_REQ_DICT (this, local->xattr_req, + fd->inode->gfid, local, err); + STACK_WIND (frame, shard_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, - xdata); + local->xattr_req); + } return 0; err: - STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL, NULL); + STACK_UNWIND_STRICT (readdir, frame, local->op_ret, local->op_errno, + NULL, NULL); return 0; } diff --git a/xlators/features/shard/src/shard.h b/xlators/features/shard/src/shard.h index 0eeabc51f5e..14f181624f7 100644 --- a/xlators/features/shard/src/shard.h +++ b/xlators/features/shard/src/shard.h @@ -101,11 +101,13 @@ } while (0) -#define SHARD_MD_READ_FOP_INIT_REQ_DICT(this, xattr_req, gfid, label) do { \ +#define SHARD_MD_READ_FOP_INIT_REQ_DICT(this, dict, gfid, local, label) do { \ int __ret = -1; \ \ - __ret = dict_set_uint64 (xattr_req, GF_XATTR_SHARD_FILE_SIZE, 8 * 4); \ + __ret = dict_set_uint64 (dict, GF_XATTR_SHARD_FILE_SIZE, 8 * 4); \ if (__ret) { \ + local->op_ret = -1; \ + local->op_errno = ENOMEM; \ gf_log (this->name, GF_LOG_WARNING, "Failed to set dict" \ " value: key:%s for %s.", GF_XATTR_SHARD_FILE_SIZE, \ uuid_utoa (gfid)); \ @@ -126,6 +128,9 @@ typedef struct { char *domain; } shard_lock_t; +typedef int32_t (*shard_post_fop_handler_t) (call_frame_t *frame, + xlator_t *this); + typedef struct shard_local { int op_ret; int op_errno; @@ -151,6 +156,7 @@ typedef struct shard_local { struct iatt postbuf; struct iovec *vector; struct iobref *iobref; + shard_post_fop_handler_t handler; struct { int lock_count; fop_inodelk_cbk_t inodelk_cbk; |