From 54f61abc7b1adffdf1e1cc3568e4df4d23da9a77 Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Tue, 15 May 2018 13:33:16 -0400 Subject: ctime: Fix updating ctime in rename and unlink 1. Successful rename was not updating ctime. Fixed the same. 2. Successful unlink when link count is more than 1 was not updating ctime. Fixed the same. 3. Copy ctime and flags during frame copy. Backport of: > Patch: https://review.gluster.org/20039 > BUG: 1580020 > Change-Id: Ied47275a36aea60254b2add7a59128a9c83b3645 fixes: bz#1582068 Change-Id: Ied47275a36aea60254b2add7a59128a9c83b3645 Signed-off-by: Kotresh HR --- libglusterfs/src/stack.h | 2 ++ xlators/features/utime/src/utime-helpers.c | 1 + xlators/storage/posix/src/posix-entry-ops.c | 23 +++++++++++++++++------ xlators/storage/posix/src/posix-metadata.c | 20 +++++++++++++------- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h index 18cbf39621a..3a98914645d 100644 --- a/libglusterfs/src/stack.h +++ b/libglusterfs/src/stack.h @@ -489,6 +489,8 @@ copy_frame (call_frame_t *frame) newstack->pid = oldstack->pid; newstack->op = oldstack->op; newstack->type = oldstack->type; + newstack->ctime = oldstack->ctime; + newstack->flags = oldstack->flags; if (call_stack_alloc_groups (newstack, oldstack->ngrps) != 0) { mem_put (newstack); return NULL; diff --git a/xlators/features/utime/src/utime-helpers.c b/xlators/features/utime/src/utime-helpers.c index d8632453e62..8dcd2647a35 100644 --- a/xlators/features/utime/src/utime-helpers.c +++ b/xlators/features/utime/src/utime-helpers.c @@ -60,6 +60,7 @@ utime_update_attribute_flags(call_frame_t *frame, glusterfs_fop_t fop) case GF_FOP_UNLINK: case GF_FOP_RMDIR: + frame->root->flags |= MDATA_CTIME; frame->root->flags |= MDATA_PAR_CTIME; frame->root->flags |= MDATA_PAR_MTIME; break; diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c index d8ec34a742b..1058339855b 100644 --- a/xlators/storage/posix/src/posix-entry-ops.c +++ b/xlators/storage/posix/src/posix-entry-ops.c @@ -915,14 +915,16 @@ out: } int32_t -posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *real_path, - struct iatt *stbuf, int32_t *op_errno, - loc_t *loc, gf_boolean_t get_link_count, +posix_unlink_gfid_handle_and_entry (call_frame_t *frame, xlator_t *this, + const char *real_path, struct iatt *stbuf, + int32_t *op_errno, loc_t *loc, + gf_boolean_t get_link_count, dict_t *rsp_dict) { int32_t ret = 0; struct iatt prebuf = {0,}; gf_boolean_t locked = _gf_false; + gf_boolean_t update_ctime = _gf_false; /* Unlink the gfid_handle_first */ if (stbuf && stbuf->ia_nlink == 1) { @@ -943,6 +945,8 @@ posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *real_path, "failed for path:%s with gfid %s", real_path, uuid_utoa (stbuf->ia_gfid)); } + } else { + update_ctime = _gf_true; } if (get_link_count) { @@ -976,6 +980,10 @@ posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *real_path, locked = _gf_false; } + if (update_ctime) { + posix_set_ctime (frame, this, NULL, -1, loc->inode, stbuf); + } + ret = dict_set_uint32 (rsp_dict, GET_LINK_COUNT, prebuf.ia_nlink); if (ret) gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_SET_XDATA_FAIL, @@ -1203,8 +1211,8 @@ posix_unlink (call_frame_t *frame, xlator_t *this, if (xdata && dict_get (xdata, GET_LINK_COUNT)) get_link_count = _gf_true; - op_ret = posix_unlink_gfid_handle_and_entry (this, real_path, &stbuf, - &op_errno, loc, + op_ret = posix_unlink_gfid_handle_and_entry (frame, this, real_path, + &stbuf, &op_errno, loc, get_link_count, unwind_dict); if (op_ret == -1) { @@ -1800,7 +1808,10 @@ unlock: goto out; } - posix_set_ctime (frame, this, real_newpath, -1, newloc->inode, &stbuf); + /* Since the same inode is later used and dst inode is not present, + * update ctime on source inode. It can't use old path because it + * doesn't exist and xattr has to be stored on disk */ + posix_set_ctime (frame, this, real_newpath, -1, oldloc->inode, &stbuf); op_ret = posix_pstat (this, oldloc->parent, oldloc->pargfid, par_oldpath, &postoldparent, _gf_false); diff --git a/xlators/storage/posix/src/posix-metadata.c b/xlators/storage/posix/src/posix-metadata.c index fda8fb5eaec..07d49da6b82 100644 --- a/xlators/storage/posix/src/posix-metadata.c +++ b/xlators/storage/posix/src/posix-metadata.c @@ -358,7 +358,6 @@ posix_set_mdata_xattr (xlator_t *this, const char *real_path, int fd, GF_VALIDATE_OR_GOTO ("posix", this, out); GF_VALIDATE_OR_GOTO (this->name, inode, out); - GF_VALIDATE_OR_GOTO (this->name, inode->gfid, out); LOCK (&inode->lock); { @@ -572,21 +571,28 @@ posix_set_ctime (call_frame_t *frame, xlator_t *this, const char* real_path, priv = this->private; - if (inode && priv->ctime) { + if (priv->ctime) { (void) posix_get_mdata_flag (frame->root->flags, &flag); + if (frame->root->ctime.tv_sec == 0) { + gf_msg (this->name, GF_LOG_WARNING, errno, + P_MSG_SETMDATA_FAILED, + "posix set mdata failed, No ctime : %s gfid:%s", + real_path, + inode ? uuid_utoa (inode->gfid) : "No inode"); + goto out; + } + ret = posix_set_mdata_xattr (this, real_path, fd, inode, &frame->root->ctime, stbuf, &flag); if (ret) { gf_msg (this->name, GF_LOG_WARNING, errno, P_MSG_SETMDATA_FAILED, "posix set mdata failed on file: %s gfid:%s", - real_path, uuid_utoa (inode->gfid)); + real_path, + inode ? uuid_utoa (inode->gfid) : "No inode"); } - } else { - gf_msg (this->name, GF_LOG_WARNING, errno, - P_MSG_SETMDATA_FAILED, - "posix set mdata failed on file"); } + out: return; } -- cgit