summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/storage/posix/src/posix-metadata.c76
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) {