From e37ee6d509aa98587d55f9ea73bc831c10761eaa Mon Sep 17 00:00:00 2001 From: karthik-us Date: Fri, 3 Aug 2018 15:55:18 +0530 Subject: posix: Delete the entry if gfid link creation fails Problem: If the gfid link file inside .glusterfs is not present for a file, the operations which are dependent on the gfid will fail, complaining the link file does not exists inside .glusterfs. Fix: If the link file creation fails, fail the entry creation operation and delete the original file. Change-Id: Id767511de2da46b1f45aea45cb68b98d965ac96d fixes: bz#1612037 Signed-off-by: karthik-us --- ...20-mark-dirty-for-entry-txn-on-quorum-failure.t | 3 ++- xlators/storage/posix/src/posix-entry-ops.c | 27 ++++++++++++++-------- xlators/storage/posix/src/posix-helpers.c | 26 +++++++++++++++++---- xlators/storage/posix/src/posix.h | 2 +- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/tests/bugs/replicate/bug-1586020-mark-dirty-for-entry-txn-on-quorum-failure.t b/tests/bugs/replicate/bug-1586020-mark-dirty-for-entry-txn-on-quorum-failure.t index 7fec3b442d6..baf58bbf2a0 100644 --- a/tests/bugs/replicate/bug-1586020-mark-dirty-for-entry-txn-on-quorum-failure.t +++ b/tests/bugs/replicate/bug-1586020-mark-dirty-for-entry-txn-on-quorum-failure.t @@ -51,7 +51,8 @@ i=$(create_files) TEST ! ls $B0/${V0}0/file$i TEST ! ls $B0/${V0}1/file$i TEST ls $B0/${V0}2/file$i -EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.dirty $B0/${V0}2 +dirty=$(get_hex_xattr trusted.afr.dirty $B0/${V0}2) +TEST [ "$dirty" != "000000000000000000000000" ] EXPECT "000000010000000100000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2/file$i EXPECT "000000010000000100000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2/file$i diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c index cb96d76332a..acda68371d5 100644 --- a/xlators/storage/posix/src/posix-entry-ops.c +++ b/xlators/storage/posix/src/posix-entry-ops.c @@ -490,10 +490,13 @@ ignore: } if (!linked) { - op_ret = posix_gfid_set (this, real_path, loc, xdata); + op_ret = posix_gfid_set (this, real_path, loc, xdata, + frame->root->pid, &op_errno); if (op_ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_GFID_FAILED, - "setting gfid on %s failed", real_path); + gf_msg (this->name, GF_LOG_ERROR, op_errno, + P_MSG_GFID_FAILED, "setting gfid on %s failed", + real_path); + goto out; } else { gfid_set = _gf_true; } @@ -812,10 +815,12 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, "setting xattrs on %s failed", real_path); } - op_ret = posix_gfid_set (this, real_path, loc, xdata); + op_ret = posix_gfid_set (this, real_path, loc, xdata, frame->root->pid, + &op_errno); if (op_ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_GFID_FAILED, + gf_msg (this->name, GF_LOG_ERROR, op_errno, P_MSG_GFID_FAILED, "setting gfid on %s failed", real_path); + goto out; } else { gfid_set = _gf_true; } @@ -1508,10 +1513,12 @@ ignore: "setting xattrs on %s failed ", real_path); } - op_ret = posix_gfid_set (this, real_path, loc, xdata); + op_ret = posix_gfid_set (this, real_path, loc, xdata, frame->root->pid, + &op_errno); if (op_ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_GFID_FAILED, + gf_msg (this->name, GF_LOG_ERROR, op_errno, P_MSG_GFID_FAILED, "setting gfid on %s failed", real_path); + goto out; } else { gfid_set = _gf_true; } @@ -2164,10 +2171,12 @@ ignore: } fill_stat: - op_ret = posix_gfid_set (this, real_path, loc, xdata); + op_ret = posix_gfid_set (this, real_path, loc, xdata, frame->root->pid, + &op_errno); if (op_ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_GFID_FAILED, + gf_msg (this->name, GF_LOG_ERROR, op_errno, P_MSG_GFID_FAILED, "setting gfid on %s failed", real_path); + goto out; } else { gfid_set = _gf_true; } diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 11265bb802b..d521d80e8aa 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -955,7 +955,8 @@ out: } int -posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req) +posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, + dict_t *xattr_req, pid_t pid, int *op_errno) { uuid_t uuid_req; uuid_t uuid_curr; @@ -963,12 +964,24 @@ posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req) ssize_t size = 0; struct stat stat = {0, }; + *op_errno = 0; - if (!xattr_req) + if (!xattr_req) { + if (pid != GF_SERVER_PID_TRASH) { + gf_msg (this->name, GF_LOG_ERROR, EINVAL, + P_MSG_INVALID_ARGUMENT, "xattr_req is null"); + *op_errno = EINVAL; + ret = -1; + } goto out; + } - if (sys_lstat (path, &stat) != 0) + if (sys_lstat (path, &stat) != 0) { + ret = -1; + gf_msg (this->name, GF_LOG_ERROR, errno, + P_MSG_LSTAT_FAILED, "lsatat on %s failed", path); goto out; + } size = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16); if (size == 16) { @@ -981,12 +994,15 @@ posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req) gf_msg_debug (this->name, 0, "failed to get the gfid from dict for %s", loc->path); + *op_errno = -ret; + ret = -1; goto out; } if (gf_uuid_is_null (uuid_req)) { gf_msg (this->name, GF_LOG_ERROR, EINVAL, P_MSG_NULL_GFID, "gfid is null for %s", loc ? loc->path : ""); ret = -1; + *op_errno = EINVAL; goto out; } @@ -1005,6 +1021,8 @@ verify_handle: ret = posix_handle_soft (this, path, loc, uuid_curr, &stat); out: + if (!(*op_errno)) + *op_errno = errno; return ret; } @@ -1712,7 +1730,7 @@ posix_gfid_heal (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req } } - posix_gfid_set (this, path, loc, xattr_req); + posix_gfid_set (this, path, loc, xattr_req, GF_CLIENT_PID_MAX, &ret); return 0; } diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index a58d510df2e..b53afdf4b59 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -328,7 +328,7 @@ int __posix_inode_ctx_get_all (inode_t *inode, xlator_t *this, posix_inode_ctx_t **ctx); int posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, - dict_t *xattr_req); + dict_t *xattr_req, pid_t pid, int *op_errno); int posix_fdstat (xlator_t *this, inode_t *inode, int fd, struct iatt *stbuf_p); int posix_istat (xlator_t *this, inode_t *inode, uuid_t gfid, const char *basename, struct iatt *iatt); -- cgit