diff options
| author | Poornima G <pgurusid@redhat.com> | 2018-06-27 14:59:40 +0530 | 
|---|---|---|
| committer | Amar Tumballi <amarts@redhat.com> | 2018-07-11 04:11:59 +0000 | 
| commit | 69f77d28c3ecacba77fbae2f789b5110641347f3 (patch) | |
| tree | 746f1470476a981b6becaedb6c7c1e681f457f41 /libglusterfs | |
| parent | af6c6429f9743f287baaad68f8e3d56ed7390d1b (diff) | |
md-cache: Do not invalidate cache post set/remove xattr
Since setxattr and removexattr fops cbk do not carry poststat,
the stat cache was being invalidated in setxatr/remoxattr cbk.
Hence the further lookup wouldn't be served from cache.
To prevent this invalidation, md-cache is modified to get
the poststat in set/removexattr_cbk in dict.
Co-authored with Xavi Hernandez.
Change-Id: I6b946be2d20b807e2578825743c25ba5927a60b4
fixes: bz#1586018
Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
Signed-off-by: Poornima G <pgurusid@redhat.com>
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/dict.c | 77 | ||||
| -rw-r--r-- | libglusterfs/src/dict.h | 1 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 2 | ||||
| -rw-r--r-- | libglusterfs/src/libglusterfs.sym | 1 | 
4 files changed, 79 insertions, 2 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index bd22477f2c4..be47def148c 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -132,6 +132,8 @@ int32_t  is_data_equal (data_t *one,                 data_t *two)  { +        struct iatt *iatt1, *iatt2; +          if (!one || !two || !one->data || !two->data) {  		gf_msg_callingfn ("dict", GF_LOG_ERROR, EINVAL,                                    LG_MSG_INVALID_ARG, @@ -143,11 +145,63 @@ is_data_equal (data_t *one,          if (one == two)                  return 1; -        if (one->len != two->len) +        if (one->data == two->data) +                return 1; + +        if (one->data_type != two->data_type) {                  return 0; +        } -        if (one->data == two->data) +        if (one->data_type == GF_DATA_TYPE_IATT) { +                if ((one->len < sizeof(struct iatt)) || +                    (two->len < sizeof(struct iatt))) { +                        return 0; +                } + +                iatt1 = (struct iatt *)one->data; +                iatt2 = (struct iatt *)two->data; + +                /* Two iatt structs are considered equal if main fields are +                 * equal, even if times differ. +                 * TODO: maybe when ctime if fully operational we could +                 *       enforce time matching. */ +                if (iatt1->ia_ino != iatt2->ia_ino) { +                        return 0; +                } +                if (iatt1->ia_type != iatt2->ia_type) { +                        return 0; +                } +                if ((iatt1->ia_type == IA_IFBLK) || +                    (iatt1->ia_type == IA_IFCHR)) { +                        if (iatt1->ia_rdev != iatt2->ia_rdev) { +                                return 0; +                        } +                } +                if (gf_uuid_compare(iatt1->ia_gfid, iatt2->ia_gfid) != 0) { +                        return 0; +                } + +                /* TODO: ia_uid, ia_gid, ia_prot and ia_size can be changed +                 *       with some commands. Here we don't have enough +                 *       information to decide if they should match or not. */ +/* +                if ((iatt1->ia_uid != iatt2->ia_uid) || +                    (iatt1->ia_gid != iatt2->ia_gid) || +                    (st_mode_from_ia(iatt1->ia_prot, iatt1->ia_type) != +                            st_mode_from_ia(iatt2->ia_prot, iatt2->ia_type))) { +                        return 0; +                } +                if (iatt1->ia_type == IA_IFREG) { +                        if (iatt1->ia_size != iatt2->ia_size) { +                                return 0; +                        } +                } +*/                  return 1; +        } + +        if (one->len != two->len) +                return 0;          if (memcmp (one->data, two->data, one->len) == 0)                  return 1; @@ -1196,6 +1250,25 @@ data_to_bin (data_t *data)          return data->data;  } +struct iatt * +data_to_iatt (data_t *data, char *key) +{ +        VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_IATT, key, NULL); + +        /* We only check for smaller size. If it's bigger we simply ignore +         * the extra data. This way it's easy to do changes in the future that +         * pass more data but are backward compatible (if the initial contents +         * of the struct are maintained, of course). */ +        if (data->len < sizeof(struct iatt)) { +                gf_msg("glusterfs", GF_LOG_ERROR, ENOBUFS, +                       LG_MSG_UNDERSIZED_BUF, +                       "data value for '%s' is smaller than expected", key); +                return NULL; +        } + +        return (struct iatt *)data->data; +} +  int  dict_null_foreach_fn (dict_t *d, char *k,                        data_t *v, void *tmp) diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h index d0b05172c2e..52b6c8c62fe 100644 --- a/libglusterfs/src/dict.h +++ b/libglusterfs/src/dict.h @@ -166,6 +166,7 @@ char *data_to_str (data_t *data);  void *data_to_bin (data_t *data);  void *data_to_ptr (data_t *data);  data_t * data_copy (data_t *old); +struct iatt *data_to_iatt (data_t *data, char *key);  int dict_foreach (dict_t *this,                    int (*fn)(dict_t *this, diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 24f08a05f40..4c0936a9f08 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -321,6 +321,8 @@ enum gf_internal_fop_indicator {  #define DHT_MODE_IN_XDATA_KEY       "dht-get-mode-in-xattr"  #define GET_LINK_COUNT              "get-link-count"  #define GF_GET_SIZE                 "get-size" +#define GF_PRESTAT                 "virt-gf-prestat" +#define GF_POSTSTAT                "virt-gf-poststat"  /*CTR and Marker requires inode dentry link count from posix*/  #define GF_RESPONSE_LINK_COUNT_XDATA "gf_response_link_count" diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym index 465bb63eb5c..ca952d51942 100644 --- a/libglusterfs/src/libglusterfs.sym +++ b/libglusterfs/src/libglusterfs.sym @@ -147,6 +147,7 @@ data_to_uint16  data_to_uint32  data_to_uint64  data_to_uint8 +data_to_iatt  data_unref  default_access  default_access_cbk  | 
