diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2017-01-17 16:40:04 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2018-07-28 09:27:38 +0000 |
commit | 7131de81f72dda0ef685ed60d0887c6e14289b8c (patch) | |
tree | 0fe37d41fb6ff3c8cc1d93462fb37932ab50e95d /xlators/performance/readdir-ahead/src/readdir-ahead.h | |
parent | 2e0744570fe1f6148e0c7b1c1a5bf98cc4eaf990 (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.h | 39 |
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 */ |