summaryrefslogtreecommitdiffstats
path: root/libglusterfs
diff options
context:
space:
mode:
authorKotresh HR <khiremat@redhat.com>2019-06-24 13:06:49 +0530
committerRinku Kothiya <rkothiya@redhat.com>2019-08-19 11:27:14 +0000
commit8d2aebf93baed6f8555cd02545d6f95da59cc7f3 (patch)
tree1ea84070457dea886fd46d33e3fd69812ff5eb02 /libglusterfs
parent8b7ceb3934f8e2dbcbabe5d1c0244c2bacda92c3 (diff)
ctime: Set mdata xattr on legacy files
Problem: The files which were created before ctime enabled would not have "trusted.glusterfs.mdata"(stores time attributes) xattr. Upon fops which modifies either ctime or mtime, the xattr gets created with latest ctime, mtime and atime, which is incorrect. It should update only the corresponding time attribute and rest from backend Solution: Creating xattr with values from brick is not possible as each brick of replica set would have different times. So create the xattr upon successful lookup if the xattr is not created Note To Reviewers: The time attributes used to set xattr is got from successful lookup. Instead of sending the whole iatt over the wire via setxattr, a structure called mdata_iatt is sent. The mdata_iatt contains only time attributes. Backport of: > Patch: https://review.gluster.org/22936 > Change-Id: I5e535631ddef04195361ae0364336410a2895dd4 > BUG: 1593542 > Signed-off-by: Kotresh HR <khiremat@redhat.com> Change-Id: I5e535631ddef04195361ae0364336410a2895dd4 updates: bz#1739430 Signed-off-by: Kotresh HR <khiremat@redhat.com>
Diffstat (limited to 'libglusterfs')
-rw-r--r--libglusterfs/src/dict.c59
-rw-r--r--libglusterfs/src/glusterfs/dict.h5
-rw-r--r--libglusterfs/src/glusterfs/glusterfs.h3
-rw-r--r--libglusterfs/src/glusterfs/iatt.h20
-rw-r--r--libglusterfs/src/libglusterfs.sym3
5 files changed, 90 insertions, 0 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index 2a317e36981..b44dda33f00 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -118,6 +118,7 @@ int32_t
is_data_equal(data_t *one, data_t *two)
{
struct iatt *iatt1, *iatt2;
+ struct mdata_iatt *mdata_iatt1, *mdata_iatt2;
if (!one || !two || !one->data || !two->data) {
gf_msg_callingfn("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
@@ -182,6 +183,24 @@ is_data_equal(data_t *one, data_t *two)
*/
return 1;
}
+ if (one->data_type == GF_DATA_TYPE_MDATA) {
+ if ((one->len < sizeof(struct mdata_iatt)) ||
+ (two->len < sizeof(struct mdata_iatt))) {
+ return 0;
+ }
+ mdata_iatt1 = (struct mdata_iatt *)one->data;
+ mdata_iatt2 = (struct mdata_iatt *)two->data;
+
+ if (mdata_iatt1->ia_atime != mdata_iatt2->ia_atime ||
+ mdata_iatt1->ia_mtime != mdata_iatt2->ia_mtime ||
+ mdata_iatt1->ia_ctime != mdata_iatt2->ia_ctime ||
+ mdata_iatt1->ia_atime_nsec != mdata_iatt2->ia_atime_nsec ||
+ mdata_iatt1->ia_mtime_nsec != mdata_iatt2->ia_mtime_nsec ||
+ mdata_iatt1->ia_ctime_nsec != mdata_iatt2->ia_ctime_nsec) {
+ return 0;
+ }
+ return 1;
+ }
if (one->len != two->len)
return 0;
@@ -1072,6 +1091,7 @@ static char *data_type_name[GF_DATA_TYPE_MAX] = {
[GF_DATA_TYPE_PTR] = "pointer",
[GF_DATA_TYPE_GFUUID] = "gf-uuid",
[GF_DATA_TYPE_IATT] = "iatt",
+ [GF_DATA_TYPE_MDATA] = "mdata",
};
int64_t
@@ -2660,6 +2680,45 @@ err:
}
int
+dict_set_mdata(dict_t *this, char *key, struct mdata_iatt *mdata,
+ bool is_static)
+{
+ return dict_set_bin_common(this, key, mdata, sizeof(struct mdata_iatt),
+ is_static, GF_DATA_TYPE_MDATA);
+}
+
+int
+dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata)
+{
+ data_t *data = NULL;
+ int ret = -EINVAL;
+
+ if (!this || !key || !mdata) {
+ goto err;
+ }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_MDATA, key, -EINVAL);
+ if (data->len < sizeof(struct mdata_iatt)) {
+ gf_msg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF,
+ "data value for '%s' is smaller than expected", key);
+ ret = -ENOBUFS;
+ goto err;
+ }
+
+ memcpy(mdata, data->data, min(data->len, sizeof(struct mdata_iatt)));
+
+err:
+ if (data)
+ data_unref(data);
+
+ return ret;
+}
+
+int
dict_set_iatt(dict_t *this, char *key, struct iatt *iatt, bool is_static)
{
return dict_set_bin_common(this, key, iatt, sizeof(struct iatt), is_static,
diff --git a/libglusterfs/src/glusterfs/dict.h b/libglusterfs/src/glusterfs/dict.h
index 7854c9feaa1..35337251360 100644
--- a/libglusterfs/src/glusterfs/dict.h
+++ b/libglusterfs/src/glusterfs/dict.h
@@ -391,6 +391,11 @@ GF_MUST_CHECK int
dict_set_iatt(dict_t *this, char *key, struct iatt *iatt, bool is_static);
GF_MUST_CHECK int
dict_get_iatt(dict_t *this, char *key, struct iatt *iatt);
+GF_MUST_CHECK int
+dict_set_mdata(dict_t *this, char *key, struct mdata_iatt *mdata,
+ bool is_static);
+GF_MUST_CHECK int
+dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata);
void
dict_dump_to_statedump(dict_t *dict, char *dict_name, char *domain);
diff --git a/libglusterfs/src/glusterfs/glusterfs.h b/libglusterfs/src/glusterfs/glusterfs.h
index 18d8d2136f8..d4c800b7416 100644
--- a/libglusterfs/src/glusterfs/glusterfs.h
+++ b/libglusterfs/src/glusterfs/glusterfs.h
@@ -229,6 +229,9 @@ enum gf_internal_fop_indicator {
#define VIRTUAL_QUOTA_XATTR_CLEANUP_KEY "glusterfs.quota-xattr-cleanup"
#define QUOTA_READ_ONLY_KEY "trusted.glusterfs.quota.read-only"
+/* ctime related */
+#define CTIME_MDATA_XDATA_KEY "set-ctime-mdata"
+
/* afr related */
#define AFR_XATTR_PREFIX "trusted.afr"
diff --git a/libglusterfs/src/glusterfs/iatt.h b/libglusterfs/src/glusterfs/iatt.h
index bee7a0afa77..f03d68b02f0 100644
--- a/libglusterfs/src/glusterfs/iatt.h
+++ b/libglusterfs/src/glusterfs/iatt.h
@@ -92,6 +92,15 @@ struct old_iatt {
uint32_t ia_ctime_nsec;
};
+struct mdata_iatt {
+ int64_t ia_atime; /* last access time */
+ int64_t ia_mtime; /* last modification time */
+ int64_t ia_ctime; /* last status change time */
+ uint32_t ia_atime_nsec;
+ uint32_t ia_mtime_nsec;
+ uint32_t ia_ctime_nsec;
+};
+
/* 64-bit mask for valid members in struct iatt. */
#define IATT_TYPE 0x0000000000000001U
#define IATT_MODE 0x0000000000000002U
@@ -313,6 +322,17 @@ st_mode_from_ia(ia_prot_t prot, ia_type_t type)
return st_mode;
}
+static inline void
+iatt_to_mdata(struct mdata_iatt *mdata, struct iatt *iatt)
+{
+ mdata->ia_atime = iatt->ia_atime;
+ mdata->ia_atime_nsec = iatt->ia_atime_nsec;
+ mdata->ia_mtime = iatt->ia_mtime;
+ mdata->ia_mtime_nsec = iatt->ia_mtime_nsec;
+ mdata->ia_ctime = iatt->ia_ctime;
+ mdata->ia_ctime_nsec = iatt->ia_ctime_nsec;
+}
+
static inline int
iatt_from_stat(struct iatt *iatt, struct stat *stat)
{
diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym
index 188cda27bc5..60b3f317cc8 100644
--- a/libglusterfs/src/libglusterfs.sym
+++ b/libglusterfs/src/libglusterfs.sym
@@ -375,6 +375,7 @@ dict_get_bin
dict_get_double
dict_get_gfuuid
dict_get_iatt
+dict_get_mdata
dict_get_int16
dict_get_int32
dict_get_int32n
@@ -412,6 +413,7 @@ dict_set_dynstrn
dict_set_dynstr_with_alloc
dict_set_gfuuid
dict_set_iatt
+dict_set_mdata
dict_set_int16
dict_set_int32
dict_set_int32n
@@ -504,6 +506,7 @@ fop_lease_stub
fop_link_stub
fop_lk_stub
fop_log_level
+fop_lookup_cbk_stub
fop_lookup_stub
fop_mkdir_stub
fop_mknod_stub