diff options
-rw-r--r-- | xlators/storage/posix/src/posix-metadata.c | 76 |
1 files changed, 58 insertions, 18 deletions
diff --git a/xlators/storage/posix/src/posix-metadata.c b/xlators/storage/posix/src/posix-metadata.c index 647c0bb3a65..57791fa9536 100644 --- a/xlators/storage/posix/src/posix-metadata.c +++ b/xlators/storage/posix/src/posix-metadata.c @@ -344,33 +344,73 @@ posix_set_mdata_xattr_legacy_files(xlator_t *this, inode_t *inode, struct mdata_iatt *mdata_iatt, int *op_errno) { posix_mdata_t *mdata = NULL; + posix_mdata_t imdata = { + 0, + }; int ret = 0; + gf_boolean_t mdata_already_set = _gf_false; GF_VALIDATE_OR_GOTO("posix", this, out); GF_VALIDATE_OR_GOTO(this->name, inode, out); LOCK(&inode->lock); { - mdata = GF_CALLOC(1, sizeof(posix_mdata_t), gf_posix_mt_mdata_attr); - if (!mdata) { - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, P_MSG_NOMEM, - "Could not allocate mdata. gfid: %s", - uuid_utoa(inode->gfid)); - ret = -1; - *op_errno = ENOMEM; - goto unlock; - } + ret = __inode_ctx_get1(inode, this, (uint64_t *)&mdata); + if (ret == 0 && mdata) { + mdata_already_set = _gf_true; + } else if (ret == -1 || !mdata) { + mdata = GF_CALLOC(1, sizeof(posix_mdata_t), gf_posix_mt_mdata_attr); + if (!mdata) { + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, P_MSG_NOMEM, + "Could not allocate mdata. gfid: %s", + uuid_utoa(inode->gfid)); + ret = -1; + *op_errno = ENOMEM; + goto unlock; + } + + ret = posix_fetch_mdata_xattr(this, NULL, -1, inode, (void *)mdata, + op_errno); + if (ret == 0) { + /* Got mdata from disk. This is a race, another client + * has healed the xattr during lookup. So set it in inode + * ctx */ + __inode_ctx_set1(inode, this, (uint64_t *)&mdata); + mdata_already_set = _gf_true; + } else { + *op_errno = 0; + mdata->version = 1; + mdata->flags = 0; + mdata->ctime.tv_sec = mdata_iatt->ia_ctime; + mdata->ctime.tv_nsec = mdata_iatt->ia_ctime_nsec; + mdata->atime.tv_sec = mdata_iatt->ia_atime; + mdata->atime.tv_nsec = mdata_iatt->ia_atime_nsec; + mdata->mtime.tv_sec = mdata_iatt->ia_mtime; + mdata->mtime.tv_nsec = mdata_iatt->ia_mtime_nsec; - mdata->version = 1; - mdata->flags = 0; - mdata->ctime.tv_sec = mdata_iatt->ia_ctime; - mdata->ctime.tv_nsec = mdata_iatt->ia_ctime_nsec; - mdata->atime.tv_sec = mdata_iatt->ia_atime; - mdata->atime.tv_nsec = mdata_iatt->ia_atime_nsec; - mdata->mtime.tv_sec = mdata_iatt->ia_mtime; - mdata->mtime.tv_nsec = mdata_iatt->ia_mtime_nsec; + __inode_ctx_set1(inode, this, (uint64_t *)&mdata); + } + } - __inode_ctx_set1(inode, this, (uint64_t *)&mdata); + if (mdata_already_set) { + /* Compare and update the larger time */ + imdata.ctime.tv_sec = mdata_iatt->ia_ctime; + imdata.ctime.tv_nsec = mdata_iatt->ia_ctime_nsec; + imdata.atime.tv_sec = mdata_iatt->ia_atime; + imdata.atime.tv_nsec = mdata_iatt->ia_atime_nsec; + imdata.mtime.tv_sec = mdata_iatt->ia_mtime; + imdata.mtime.tv_nsec = mdata_iatt->ia_mtime_nsec; + + if (posix_compare_timespec(&imdata.ctime, &mdata->ctime) > 0) { + mdata->ctime = imdata.ctime; + } + if (posix_compare_timespec(&imdata.mtime, &mdata->mtime) > 0) { + mdata->mtime = imdata.mtime; + } + if (posix_compare_timespec(&imdata.atime, &mdata->atime) > 0) { + mdata->atime = imdata.atime; + } + } ret = posix_store_mdata_xattr(this, NULL, -1, inode, mdata); if (ret) { |