summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKotresh HR <khiremat@redhat.com>2018-05-21 12:57:45 -0400
committerKotresh HR <khiremat@redhat.com>2018-05-24 03:42:39 -0400
commit833808f42247bcb8db1be917f1ffd7841d9e226f (patch)
treea547480be5533bdb97ccd831a1ea92f395277409
parent096983831d11901daca0cb33b87bc5c1471a1ebf (diff)
posix/ctime: Fix gfid heal on first lookup
With ctime feature enabled, the gfid is not healing on first lookup. The fresh file logic depends on ctime and it was fetching from backend instead of xattr with ctime feature enabled. Fixed the same. Also fixed a possible hang with inode lock Backport of: > Patch: https://review.gluster.org/20052 > BUG: 1580532 > Change-Id: I020875c0462b284d6fa0e68304a422fa3d6a3e73 > Signed-off-by: Kotresh HR <khiremat@redhat.com> fixes: bz#1582080 Change-Id: I020875c0462b284d6fa0e68304a422fa3d6a3e73 Signed-off-by: Kotresh HR <khiremat@redhat.com>
-rw-r--r--xlators/storage/posix/src/posix-helpers.c52
-rw-r--r--xlators/storage/posix/src/posix-messages.h3
-rw-r--r--xlators/storage/posix/src/posix-metadata.c34
3 files changed, 62 insertions, 27 deletions
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
index 0ca9169..00118b2 100644
--- a/xlators/storage/posix/src/posix-helpers.c
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -1620,14 +1620,14 @@ unlock:
}
static int
-is_fresh_file (struct stat *stat)
+is_fresh_file (int64_t ctime_sec)
{
struct timeval tv;
gettimeofday (&tv, NULL);
- if ((stat->st_ctime >= (tv.tv_sec - 1))
- && (stat->st_ctime <= tv.tv_sec))
+ if ((ctime_sec >= (tv.tv_sec - 1))
+ && (ctime_sec <= tv.tv_sec))
return 1;
return 0;
@@ -1665,19 +1665,51 @@ posix_gfid_heal (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req
uuid_t uuid_curr;
int ret = 0;
struct stat stat = {0, };
+ struct iatt stbuf = {0, };
+ struct posix_private *priv = NULL;
+
+ priv = this->private;
if (!xattr_req)
return 0;
- if (sys_lstat (path, &stat) != 0) {
- return -errno;
- }
-
- ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
- if (ret != 16) {
- if (is_fresh_file (&stat)) {
+ if (loc->inode && priv->ctime) {
+ if (sys_lstat (path, &stat) != 0) {
+ return -errno;
+ }
+ /* stbuf is only to compare ctime, don't use it to access
+ * other fields as they are zero. */
+ ret = posix_get_mdata_xattr (this, path, -1, loc->inode,
+ &stbuf);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_WARNING, errno,
+ P_MSG_GETMDATA_FAILED,
+ "posix get mdata failed on gfid: %s",
+ uuid_utoa(loc->inode->gfid));
return -ENOENT;
}
+ ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
+ if (ret != 16) {
+ if (is_fresh_file (stbuf.ia_ctime)) {
+ gf_msg (this->name, GF_LOG_ERROR, ENOENT,
+ P_MSG_FRESHFILE,
+ "Fresh file: %s", path);
+ return -ENOENT;
+ }
+ }
+ } else {
+ if (sys_lstat (path, &stat) != 0) {
+ return -errno;
+ }
+ ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
+ if (ret != 16) {
+ if (is_fresh_file (stat.st_ctime)) {
+ gf_msg (this->name, GF_LOG_ERROR, ENOENT,
+ P_MSG_FRESHFILE,
+ "Fresh file: %s", path);
+ return -ENOENT;
+ }
+ }
}
posix_gfid_set (this, path, loc, xattr_req);
diff --git a/xlators/storage/posix/src/posix-messages.h b/xlators/storage/posix/src/posix-messages.h
index 2c23387..38e6d31 100644
--- a/xlators/storage/posix/src/posix-messages.h
+++ b/xlators/storage/posix/src/posix-messages.h
@@ -140,7 +140,8 @@ GLFS_MSGID(POSIX,
P_MSG_STOREMDATA_FAILED,
P_MSG_FETCHMDATA_FAILED,
P_MSG_GETMDATA_FAILED,
- P_MSG_SETMDATA_FAILED
+ P_MSG_SETMDATA_FAILED,
+ P_MSG_FRESHFILE
);
#endif /* !_GLUSTERD_MESSAGES_H_ */
diff --git a/xlators/storage/posix/src/posix-metadata.c b/xlators/storage/posix/src/posix-metadata.c
index 1110435..045ad25 100644
--- a/xlators/storage/posix/src/posix-metadata.c
+++ b/xlators/storage/posix/src/posix-metadata.c
@@ -59,10 +59,9 @@ posix_mdata_from_disk (posix_mdata_t *out, posix_mdata_disk_t *in)
/* posix_fetch_mdata_xattr fetches the posix_mdata_t from disk */
static int
posix_fetch_mdata_xattr (xlator_t *this, const char *real_path_arg, int _fd,
- inode_t *inode, posix_mdata_t *metadata)
+ inode_t *inode, posix_mdata_t *metadata, int *op_errno)
{
size_t size = -1;
- int op_errno = 0;
int op_ret = -1;
char *value = NULL;
gf_boolean_t fd_based_fop = _gf_false;
@@ -83,10 +82,11 @@ posix_fetch_mdata_xattr (xlator_t *this, const char *real_path_arg, int _fd,
MAKE_HANDLE_PATH (real_path, this, inode->gfid, NULL);
if (!real_path) {
uuid_utoa_r (inode->gfid, gfid_str);
- gf_msg (this->name, GF_LOG_WARNING, op_errno,
+ gf_msg (this->name, GF_LOG_WARNING, errno,
P_MSG_LSTAT_FAILED, "lstat on gfid %s failed",
gfid_str);
op_ret = -1;
+ *op_errno = errno;
goto out;
}
}
@@ -100,23 +100,23 @@ posix_fetch_mdata_xattr (xlator_t *this, const char *real_path_arg, int _fd,
}
if (size == -1) {
- op_errno = errno;
- if ((op_errno == ENOTSUP) || (op_errno == ENOSYS)) {
+ *op_errno = errno;
+ if ((*op_errno == ENOTSUP) || (*op_errno == ENOSYS)) {
GF_LOG_OCCASIONALLY (gf_posix_xattr_enotsup_log,
this->name, GF_LOG_WARNING,
"Extended attributes not "
"supported (try remounting"
" brick with 'user_xattr' "
"flag)");
- } else if (op_errno == ENOATTR ||
- op_errno == ENODATA) {
+ } else if (*op_errno == ENOATTR ||
+ *op_errno == ENODATA) {
gf_msg_debug (this->name, 0,
"No such attribute:%s for file %s "
"gfid: %s",
key, real_path ? real_path : (real_path_arg ? real_path_arg : "null"),
uuid_utoa(inode->gfid));
} else {
- gf_msg (this->name, GF_LOG_DEBUG, op_errno,
+ gf_msg (this->name, GF_LOG_DEBUG, *op_errno,
P_MSG_XATTR_FAILED, "getxattr failed"
" on %s gfid: %s key: %s ",
real_path ? real_path : (real_path_arg ? real_path_arg : "null"),
@@ -129,7 +129,7 @@ posix_fetch_mdata_xattr (xlator_t *this, const char *real_path_arg, int _fd,
value = GF_CALLOC (size + 1, sizeof(char), gf_posix_mt_char);
if (!value) {
op_ret = -1;
- op_errno = ENOMEM;
+ *op_errno = ENOMEM;
goto out;
}
@@ -142,7 +142,7 @@ posix_fetch_mdata_xattr (xlator_t *this, const char *real_path_arg, int _fd,
}
if (size == -1) {
op_ret = -1;
- op_errno = errno;
+ *op_errno = errno;
gf_msg (this->name, GF_LOG_ERROR, errno,
P_MSG_XATTR_FAILED, "getxattr failed on "
" on %s gfid: %s key: %s ",
@@ -234,6 +234,7 @@ __posix_get_mdata_xattr (xlator_t *this, const char *real_path, int _fd,
{
posix_mdata_t *mdata = NULL;
int ret = -1;
+ int op_errno = 0;
GF_VALIDATE_OR_GOTO (this->name, inode, out);
@@ -248,7 +249,7 @@ __posix_get_mdata_xattr (xlator_t *this, const char *real_path, int _fd,
}
ret = posix_fetch_mdata_xattr (this, real_path, _fd, inode,
- mdata);
+ mdata, &op_errno);
if (ret == 0) {
/* Got mdata from disk, set it in inode ctx. This case
@@ -261,7 +262,7 @@ __posix_get_mdata_xattr (xlator_t *this, const char *real_path, int _fd,
* Even new file creation hits here first as posix_pstat
* is generally done before posix_set_ctime
*/
- if (stbuf) {
+ if (stbuf && op_errno != ENOENT) {
mdata->version = 1;
mdata->flags = 0;
mdata->ctime.tv_sec = stbuf->ia_ctime;
@@ -287,14 +288,14 @@ __posix_get_mdata_xattr (xlator_t *this, const char *real_path, int _fd,
/* 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, errno,
+ 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;
+ ret = -1;
goto out;
}
}
@@ -355,6 +356,7 @@ posix_set_mdata_xattr (xlator_t *this, const char *real_path, int fd,
{
posix_mdata_t *mdata = NULL;
int ret = -1;
+ int op_errno = 0;
GF_VALIDATE_OR_GOTO ("posix", this, out);
GF_VALIDATE_OR_GOTO (this->name, inode, out);
@@ -378,7 +380,7 @@ posix_set_mdata_xattr (xlator_t *this, const char *real_path, int fd,
ret = posix_fetch_mdata_xattr (this, real_path, fd,
inode,
- (void *)mdata);
+ (void *)mdata, &op_errno);
if (ret == 0) {
/* Got mdata from disk, set it in inode ctx. This case
* is hit when in-memory status is lost due to brick
@@ -452,7 +454,7 @@ posix_set_mdata_xattr (xlator_t *this, const char *real_path, int fd,
"file: %s: gfid: %s key:%s ",
real_path ? real_path : "null",
uuid_utoa(inode->gfid), GF_XATTR_MDATA_KEY);
- goto out;
+ goto unlock;
}
}
unlock: