From 431565e35afea5d99931276d3f0599473d088b8a Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Tue, 16 Jun 2015 17:59:23 +0530 Subject: features/shard: Use xattrop (as opposed to setxattr) for updates to size xattr Change-Id: Icd8984976812bb47ae7129426f6c1aa9393b3ab9 BUG: 1232391 Signed-off-by: Krutika Dhananjay Reviewed-on: http://review.gluster.org/11467 Reviewed-by: Pranith Kumar Karampuri Tested-by: Gluster Build System Tested-by: Pranith Kumar Karampuri --- xlators/cluster/dht/src/dht-inode-read.c | 4 +- xlators/features/shard/src/shard-mem-types.h | 2 +- xlators/features/shard/src/shard.c | 63 ++++++++++++++++++++-------- xlators/features/shard/src/shard.h | 4 +- 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c index d86e4288e1c..a5eda4e1270 100644 --- a/xlators/cluster/dht/src/dht-inode-read.c +++ b/xlators/cluster/dht/src/dht-inode-read.c @@ -969,7 +969,6 @@ dht_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, VALIDATE_OR_GOTO (this, err); VALIDATE_OR_GOTO (loc, err); VALIDATE_OR_GOTO (loc->inode, err); - VALIDATE_OR_GOTO (loc->path, err); local = dht_local_init (frame, loc, NULL, GF_FOP_XATTROP); if (!local) { @@ -980,7 +979,8 @@ dht_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, subvol = local->cached_subvol; if (!subvol) { gf_msg_debug (this->name, 0, - "no cached subvolume for path=%s", loc->path); + "no cached subvolume for gfid=%s", + uuid_utoa (loc->inode->gfid)); op_errno = EINVAL; goto err; } diff --git a/xlators/features/shard/src/shard-mem-types.h b/xlators/features/shard/src/shard-mem-types.h index 5a043278b7d..77f0cee7f58 100644 --- a/xlators/features/shard/src/shard-mem-types.h +++ b/xlators/features/shard/src/shard-mem-types.h @@ -17,7 +17,7 @@ enum gf_shard_mem_types_ { gf_shard_mt_inode_list, gf_shard_mt_inode_ctx_t, gf_shard_mt_iovec, - gf_shard_mt_uint64_t, + gf_shard_mt_int64_t, gf_shard_mt_end }; #endif diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index c99f9cf8fc1..681a403459c 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -338,7 +338,8 @@ shard_common_resolve_shards (call_frame_t *frame, xlator_t *this, int shard_update_file_size_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *xdata) + int32_t op_ret, int32_t op_errno, dict_t *dict, + dict_t *xdata) { shard_local_t *local = NULL; @@ -356,16 +357,15 @@ err: } int -shard_set_size_attrs (uint64_t size, uint64_t block_count, - uint64_t **size_attr_p) +shard_set_size_attrs (int64_t size, int64_t block_count, int64_t **size_attr_p) { int ret = -1; - uint64_t *size_attr = NULL; + int64_t *size_attr = NULL; if (!size_attr_p) goto out; - size_attr = GF_CALLOC (4, sizeof (uint64_t), gf_shard_mt_uint64_t); + size_attr = GF_CALLOC (4, sizeof (int64_t), gf_shard_mt_int64_t); if (!size_attr) goto out; @@ -390,7 +390,7 @@ shard_update_file_size (call_frame_t *frame, xlator_t *this, fd_t *fd, shard_post_update_size_fop_handler_t handler) { int ret = -1; - uint64_t *size_attr = NULL; + int64_t *size_attr = NULL; inode_t *inode = NULL; shard_local_t *local = NULL; dict_t *xattr_req = NULL; @@ -410,8 +410,8 @@ shard_update_file_size (call_frame_t *frame, xlator_t *this, fd_t *fd, else inode = loc->inode; - ret = shard_set_size_attrs (local->postbuf.ia_size + local->hole_size, - local->postbuf.ia_blocks, &size_attr); + ret = shard_set_size_attrs (local->delta_size + local->hole_size, + local->delta_blocks, &size_attr); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to set size attrs for" " %s", uuid_utoa (inode->gfid)); @@ -435,13 +435,13 @@ shard_update_file_size (call_frame_t *frame, xlator_t *this, fd_t *fd, if (fd) STACK_WIND (frame, shard_update_file_size_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsetxattr, fd, xattr_req, - 0, NULL); + FIRST_CHILD(this)->fops->fxattrop, fd, + GF_XATTROP_ADD_ARRAY64, xattr_req, NULL); else STACK_WIND (frame, shard_update_file_size_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setxattr, loc, xattr_req, - 0, NULL); + FIRST_CHILD(this)->fops->xattrop, loc, + GF_XATTROP_ADD_ARRAY64, xattr_req, NULL); dict_unref (xattr_req); return 0; @@ -918,6 +918,10 @@ shard_truncate_last_shard_cbk (call_frame_t *frame, void *cookie, } local->postbuf.ia_size = local->offset; local->postbuf.ia_blocks -= (prebuf->ia_blocks - postbuf->ia_blocks); + /* Let the delta be negative. We want xattrop to do subtraction */ + local->delta_size = local->postbuf.ia_size - local->prebuf.ia_size; + local->delta_blocks = postbuf->ia_blocks - prebuf->ia_blocks; + local->hole_size = 0; shard_update_file_size (frame, this, NULL, &local->loc, shard_post_update_size_truncate_handler); @@ -993,7 +997,14 @@ shard_truncate_htol (call_frame_t *frame, xlator_t *this, inode_t *inode) * unlinked do not exist. So shard xlator would now proceed to * do the final truncate + size updates. */ - shard_truncate_last_shard (frame, this, local->inode_list[0]); + local->postbuf.ia_size = local->offset; + local->postbuf.ia_blocks = local->prebuf.ia_blocks; + local->delta_size = local->postbuf.ia_size - + local->prebuf.ia_size; + local->delta_blocks = 0; + local->hole_size = 0; + shard_update_file_size (frame, this, local->fd, &local->loc, + shard_post_update_size_truncate_handler); return 0; } @@ -1445,12 +1456,13 @@ shard_post_lookup_truncate_handler (call_frame_t *frame, xlator_t *this) SHARD_STACK_UNWIND (ftruncate, frame, 0, 0, &local->prebuf, &local->postbuf, NULL); - - } else if (local->offset > local->prebuf.ia_size) { /* If the truncate is from a lower to a higher size, set the * new size xattr and unwind. */ + local->hole_size = local->offset - local->prebuf.ia_size; + local->delta_size = 0; + local->delta_blocks = 0; local->postbuf.ia_size = local->offset; shard_update_file_size (frame, this, NULL, &local->loc, shard_post_update_size_truncate_handler); @@ -1461,6 +1473,9 @@ shard_post_lookup_truncate_handler (call_frame_t *frame, xlator_t *this) * iii. update the new size using setxattr. * and unwind the fop. */ + local->hole_size = 0; + local->delta_size = (local->offset - local->prebuf.ia_size); + local->delta_blocks = 0; shard_truncate_begin (frame, this); } return 0; @@ -2834,6 +2849,10 @@ shard_post_update_size_writev_handler (call_frame_t *frame, xlator_t *this) local->op_errno, NULL, NULL, NULL); return 0; } + + local->postbuf.ia_size += (local->delta_size + local->hole_size); + local->postbuf.ia_blocks += local->delta_blocks; + SHARD_STACK_UNWIND (writev, frame, local->written_size, local->op_errno, &local->prebuf, &local->postbuf, local->xattr_rsp); return 0; @@ -2855,9 +2874,8 @@ shard_writev_do_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->op_errno = op_errno; } else { local->written_size += op_ret; - local->postbuf.ia_blocks += (postbuf->ia_blocks - - prebuf->ia_blocks); - local->postbuf.ia_size += (postbuf->ia_size - prebuf->ia_size); + local->delta_blocks += (postbuf->ia_blocks - prebuf->ia_blocks); + local->delta_size += (postbuf->ia_size - prebuf->ia_size); } if (anon_fd) @@ -2907,6 +2925,15 @@ shard_writev_do (call_frame_t *frame, xlator_t *this) local->call_count = call_count = local->num_blocks; last_block = local->last_block; + if (dict_set_uint32 (local->xattr_req, + GLUSTERFS_WRITE_UPDATE_ATOMIC, 4)) { + local->op_ret = -1; + local->op_errno = ENOMEM; + shard_writev_do_cbk (frame, (void *)(long)0, this, -1, ENOMEM, + NULL, NULL, NULL); + return 0; + } + while (cur_block <= last_block) { if (wind_failed) { shard_writev_do_cbk (frame, (void *) (long) 0, this, -1, diff --git a/xlators/features/shard/src/shard.h b/xlators/features/shard/src/shard.h index a90162bf9be..2e2b3abd593 100644 --- a/xlators/features/shard/src/shard.h +++ b/xlators/features/shard/src/shard.h @@ -67,7 +67,7 @@ #define SHARD_INODE_CREATE_INIT(this, local, xattr_req, loc, label) do { \ int __ret = -1; \ - uint64_t *__size_attr = NULL; \ + int64_t *__size_attr = NULL; \ shard_priv_t *__priv = NULL; \ \ __priv = this->private; \ @@ -155,6 +155,8 @@ typedef struct shard_local { size_t hole_size; size_t req_size; size_t readdir_size; + int64_t delta_size; + int delta_blocks; loc_t loc; loc_t dot_shard_loc; loc_t loc2; -- cgit