diff options
| -rw-r--r-- | xlators/storage/posix/src/posix-metadata.c | 111 | 
1 files changed, 60 insertions, 51 deletions
diff --git a/xlators/storage/posix/src/posix-metadata.c b/xlators/storage/posix/src/posix-metadata.c index eb2f24dbd69..00cd2409532 100644 --- a/xlators/storage/posix/src/posix-metadata.c +++ b/xlators/storage/posix/src/posix-metadata.c @@ -258,46 +258,38 @@ __posix_get_mdata_xattr (xlator_t *this, const char *real_path, int _fd,                           */                          __inode_ctx_set1 (inode, this, (uint64_t *)&mdata);                  } else { -                        /* Failed to get mdata from disk, xattr missing -                         * Even new file creation hits here first as posix_pstat -                         * is generally done before posix_set_ctime +                        /* Failed to get mdata from disk, xattr missing. +                         * This happens on two cases. +                         * 1. File is created before ctime is enabled. +                         * 2. On new file creation. +                         * +                         * Do nothing, just return success. It is as +                         * good as ctime feature is not enabled for this +                         * file. For files created before ctime is enabled, +                         * time attributes gets updated into ctime structure +                         * once the metadata modification fop happens and +                         * time attributes become consistent eventually. +                         * For new files, it would obviously get updated +                         * before the fop completion.                           */ -                       if (stbuf && op_errno != ENOENT) { -                               mdata->version = 1; -                               mdata->flags = 0; -                               mdata->ctime.tv_sec = stbuf->ia_ctime; -                               mdata->ctime.tv_nsec = stbuf->ia_ctime_nsec; -                               mdata->mtime.tv_sec = stbuf->ia_mtime; -                               mdata->mtime.tv_nsec = stbuf->ia_mtime_nsec; -                               mdata->atime.tv_sec = stbuf->ia_atime; -                               mdata->atime.tv_nsec = stbuf->ia_atime_nsec; -                               ret = posix_store_mdata_xattr (this, real_path, -                                                              _fd, inode, -                                                              mdata); -                               if (ret) { -                                       gf_msg (this->name, GF_LOG_ERROR, errno, -                                               P_MSG_STOREMDATA_FAILED, -                                               "file: %s: gfid: %s key:%s ", -                                               real_path ? real_path : "null", -                                               uuid_utoa(inode->gfid), -                                               GF_XATTR_MDATA_KEY); -                                       goto out; -                               } -                               __inode_ctx_set1 (inode, this, (uint64_t *)&mdata); -                       } else { -                              /* This case should not be hit. If it hits, don't -                               * fail, log warning, free mdata and move on -                               */ -                               gf_msg (this->name, GF_LOG_WARNING, op_errno, -                                       P_MSG_FETCHMDATA_FAILED, -                                       "file: %s: gfid: %s key:%s ", -                                       real_path ? real_path : "null", -                                       uuid_utoa(inode->gfid), -                                       GF_XATTR_MDATA_KEY); -                               GF_FREE (mdata); -                               ret = -1; -                               goto out; -                       } +                        if (stbuf && op_errno != ENOENT) { +                                ret = 0; +                                goto out; +                        } else { +                                /* This case should not be hit. If it hits, +                                 * don't fail, log warning, free mdata and move +                                 * on +                                 */ +                                gf_msg (this->name, GF_LOG_WARNING, op_errno, +                                        P_MSG_FETCHMDATA_FAILED, +                                        "file: %s: gfid: %s key:%s ", +                                        real_path ? real_path : "null", +                                        uuid_utoa(inode->gfid), +                                        GF_XATTR_MDATA_KEY); +                                GF_FREE (mdata); +                                ret = 0; +                                goto out; +                        }                  }          } @@ -390,7 +382,7 @@ posix_set_mdata_xattr (xlator_t *this, const char *real_path, int fd,                                   */                                  __inode_ctx_set1 (inode, this,                                                    (uint64_t *)&mdata); -                        } else if (ret && stbuf) { +                        } else if (ret && time) {                                  /*                                   * This is the first time creating the time                                   * attr. This happens when you activate this @@ -408,14 +400,28 @@ posix_set_mdata_xattr (xlator_t *this, const char *real_path, int fd,                                   * We should contact the time management                                   * xlators, and ask them to create an xattr.                                   */ +                                /* We should not be relying on backend file's +                                 * time attributes to load the initial ctime +                                 * time attribute structure. This is incorrect +                                 * as each replica set would have witnessed the +                                 * file creation at different times. +                                 * +                                 * For new file creation, ctime, atime and mtime +                                 * should be same, hence initiate the ctime +                                 * structure with the time from the frame. But +                                 * for the files which were created before ctime +                                 * feature is enabled, this is not accurate but +                                 * still fine as the times would get eventually +                                 * accurate. +                                 */                                  mdata->version = 1;                                  mdata->flags = 0; -                                mdata->ctime.tv_sec = stbuf->ia_ctime; -                                mdata->ctime.tv_nsec = stbuf->ia_ctime_nsec; -                                mdata->atime.tv_sec = stbuf->ia_atime; -                                mdata->atime.tv_nsec = stbuf->ia_atime_nsec; -                                mdata->mtime.tv_sec = stbuf->ia_mtime; -                                mdata->mtime.tv_nsec = stbuf->ia_mtime_nsec; +                                mdata->ctime.tv_sec = time->tv_sec; +                                mdata->ctime.tv_nsec = time->tv_nsec; +                                mdata->atime.tv_sec = time->tv_sec; +                                mdata->atime.tv_nsec = time->tv_nsec; +                                mdata->mtime.tv_sec = time->tv_sec; +                                mdata->mtime.tv_nsec = time->tv_nsec;                                  __inode_ctx_set1 (inode, this,                                                    (uint64_t *)&mdata); @@ -428,15 +434,18 @@ posix_set_mdata_xattr (xlator_t *this, const char *real_path, int fd,                   * just updating without comparison. But the ctime is not                   * allowed to changed to older date.                   */ +                  if (flag->ctime &&                      posix_compare_timespec (time, &mdata->ctime) > 0) {                          mdata->ctime = *time;                  } -                /* In distributed systems, there could races with fops updating -                 * mtime/atime which could result in different mtime/atime -                 * for same file. So this makes sure, only the highest time is -                 * retained. If the mtime/atime update comes from the explicit -                 * utime syscall, it is allowed to set to previous time + +                /* In distributed systems, there could be races with fops +                 * updating mtime/atime which could result in different +                 * mtime/atime for same file. So this makes sure, only the +                 * highest time is retained. If the mtime/atime update comes +                 * from the explicit utime syscall, it is allowed to set to +                 * previous time                   */                  if (update_utime) {                          if (flag->mtime) {  | 
