diff options
author | Kotresh HR <khiremat@redhat.com> | 2019-06-24 13:06:49 +0530 |
---|---|---|
committer | Atin Mukherjee <amukherj@redhat.com> | 2019-07-22 06:56:35 +0000 |
commit | 06e92a2ee437c1a81c815129b1d188af0b4fa84e (patch) | |
tree | e4947489a478bd5fedff5eb8ce6b3aa91df8770e /libglusterfs/src | |
parent | 74f124619a71df9bdc5ae9fbc07bc19db05bc1d2 (diff) | |
download | glusterfs-06e92a2ee437c1a81c815129b1d188af0b4fa84e.tar.gz glusterfs-06e92a2ee437c1a81c815129b1d188af0b4fa84e.tar.xz glusterfs-06e92a2ee437c1a81c815129b1d188af0b4fa84e.zip |
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.
Change-Id: I5e535631ddef04195361ae0364336410a2895dd4
fixes: bz#1593542
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Diffstat (limited to 'libglusterfs/src')
-rw-r--r-- | libglusterfs/src/dict.c | 59 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs/dict.h | 5 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs/glusterfs-fops.h | 3 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs/glusterfs.h | 3 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs/iatt.h | 20 | ||||
-rw-r--r-- | libglusterfs/src/libglusterfs.sym | 3 |
6 files changed, 92 insertions, 1 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index 2a317e3698..b44dda33f0 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 7854c9feaa..3533725136 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-fops.h b/libglusterfs/src/glusterfs/glusterfs-fops.h index d295a67f85..030b270160 100644 --- a/libglusterfs/src/glusterfs/glusterfs-fops.h +++ b/libglusterfs/src/glusterfs/glusterfs-fops.h @@ -233,7 +233,8 @@ enum gf_dict_data_type_t { GF_DATA_TYPE_PTR = 6, GF_DATA_TYPE_GFUUID = 7, GF_DATA_TYPE_IATT = 8, - GF_DATA_TYPE_MAX = 9, + GF_DATA_TYPE_MDATA = 9, + GF_DATA_TYPE_MAX = 10, }; typedef enum gf_dict_data_type_t gf_dict_data_type_t; diff --git a/libglusterfs/src/glusterfs/glusterfs.h b/libglusterfs/src/glusterfs/glusterfs.h index c543b9a3b4..967bf5b40e 100644 --- a/libglusterfs/src/glusterfs/glusterfs.h +++ b/libglusterfs/src/glusterfs/glusterfs.h @@ -215,6 +215,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 bee7a0afa7..f03d68b02f 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 0e24630c6d..a4065e1c24 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 |