summaryrefslogtreecommitdiffstats
path: root/xlators/performance/readdir-ahead/src/readdir-ahead.h
diff options
context:
space:
mode:
authorKrutika Dhananjay <kdhananj@redhat.com>2017-01-17 16:40:04 +0530
committerRaghavendra G <rgowdapp@redhat.com>2018-07-28 09:27:38 +0000
commit7131de81f72dda0ef685ed60d0887c6e14289b8c (patch)
tree0fe37d41fb6ff3c8cc1d93462fb37932ab50e95d /xlators/performance/readdir-ahead/src/readdir-ahead.h
parent2e0744570fe1f6148e0c7b1c1a5bf98cc4eaf990 (diff)
performance/readdir-ahead: Invalidate cached dentries if they're modified while in cache
PROBLEM: Entries that are readdirp'd ahead can undergo modification in terms of writes, truncates which could modify their iatts. When a readdir is finally wound at offset corresponding to these entries, the iatts that are returned to the application come from readdir-ahead's cache, which are stale by now. This problem gets further aggravated when caching translators/modules cache and continue to serve this stale information. FIX: Whenever a dentry undergoes modification, in the cbk of the modification fop, a "dirty" flag (default 0) is set in its inode ctx. When it's time for readdir-ahead to serve these entries, it will read the inode ctx and check if the entry is "dirty", and if it is, set the entry's attrs to all zeroes, as an indicator to fuse, md-cache etc not to cache these attributes. Also there is one tiny race between the entry creation and a readdirp on its parent dir, which could cause the inode-ctx setting and inode ctx reading to happen on two different inode objects. To prevent this, fuse-bridge is made to drop entries for which dentry->inode is not the same as linked inode, in readdirp cbk. Change-Id: If7396507632b5268442ca580473d5155fee9cbef BUG: 1390050 Updates: bz#1390050 Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com> Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Diffstat (limited to 'xlators/performance/readdir-ahead/src/readdir-ahead.h')
-rw-r--r--xlators/performance/readdir-ahead/src/readdir-ahead.h39
1 files changed, 38 insertions, 1 deletions
diff --git a/xlators/performance/readdir-ahead/src/readdir-ahead.h b/xlators/performance/readdir-ahead/src/readdir-ahead.h
index 3c06cc0f107..7ffb92a9be8 100644
--- a/xlators/performance/readdir-ahead/src/readdir-ahead.h
+++ b/xlators/performance/readdir-ahead/src/readdir-ahead.h
@@ -19,6 +19,37 @@
#define RDA_FD_BYPASS (1 << 4)
#define RDA_FD_PLUGGED (1 << 5)
+
+#define RDA_COMMON_MODIFICATION_FOP(name, frame, this, __inode, __xdata, args ...)\
+ do { \
+ struct rda_local *__local = NULL; \
+ \
+ __local = mem_get0 (this->local_pool); \
+ __local->inode = inode_ref (__inode); \
+ \
+ frame->local = __local; \
+ if (__xdata) \
+ __local->xattrs = dict_ref (__xdata); \
+ \
+ STACK_WIND (frame, rda_##name##_cbk, FIRST_CHILD(this), \
+ FIRST_CHILD(this)->fops->name, args, __xdata); \
+ } while (0)
+
+
+#define RDA_STACK_UNWIND(fop, frame, params ...) do { \
+ struct rda_local *__local = NULL; \
+ if (frame) { \
+ __local = frame->local; \
+ frame->local = NULL; \
+ } \
+ STACK_UNWIND_STRICT (fop, frame, params); \
+ if (__local) { \
+ rda_local_wipe (__local); \
+ mem_put (__local); \
+ } \
+} while (0)
+
+
struct rda_fd_ctx {
off_t cur_offset; /* current head of the ctx */
size_t cur_size; /* current size of the preload */
@@ -36,7 +67,9 @@ struct rda_local {
struct rda_fd_ctx *ctx;
fd_t *fd;
off_t offset;
- dict_t *xattrs; /* xattrs to be sent in readdirp() */
+ dict_t *xattrs; /* md-cache keys to be sent in readdirp() */
+ int32_t skip_dir;
+ inode_t *inode;
};
struct rda_priv {
@@ -48,4 +81,8 @@ struct rda_priv {
gf_boolean_t parallel_readdir;
};
+typedef struct rda_inode_ctx {
+ struct iatt statbuf;
+} rda_inode_ctx_t;
+
#endif /* __READDIR_AHEAD_H */