diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2017-01-17 16:40:04 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2018-08-18 07:28:53 +0000 |
commit | c9bde3021202f1d5c5a2d19ac05a510fc1f788ac (patch) | |
tree | eba54e5f791b33d079afae9655d5438d007c3091 /xlators/mount/fuse/src/fuse-bridge.c | |
parent | 045d70a5450daa85aa5564b6e9f93065c342ab12 (diff) |
performance/readdir-ahead: keep stats of cached dentries in sync with modifications
PROBLEM:
Stats of dentries that are readdirp'd ahead can become stale due to
fops like writes, truncate etc that modify the file pointed by
dentries. 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:
* Store the iatt in context of the inode pointed by dentry.
* Whenever the inode pointed by dentry undergoes modification, in cbk
of modification fop, update the iatt stored in inode-ctx to reflect
the modification.
* When serving a readdirp response from application, update iatts of
dentries with the iatts stored in the context of inodes pointed by
these dentries.
* Some fops don't have valid iatts in their responses. For eg., write
response whose data is still cached in write-behind will have zeroed
out stat. In this case keep only ia_type and ia_gfid and reset rest
of the iatt members to zero.
- fuse-bridge in this case just sends "entry" information back to
kernel and attr is not sent.
- gfapi sets entry->inode to NULL and zeroes out the entire stat
* 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, when entry->inode doesn't eqaul to linked_inode,
- fuse-bridge is made to send only "entry" information without
attributes
- gfapi sets entry->inode to NULL and zeroes out the entire stat.
Change-Id: Ia27ff49a61922e88c73a1547ad8aacc9968a69df
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/mount/fuse/src/fuse-bridge.c')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 20f015431a0..ee50329f03b 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -3056,6 +3056,10 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!linked_inode) goto next_entry; + if (entry->inode != linked_inode) { + memset (&entry->d_stat, 0, sizeof (entry->d_stat)); + } + feo->nodeid = inode_to_fuse_nodeid (linked_inode); if (!((strcmp (entry->d_name, ".") == 0) || @@ -3069,10 +3073,15 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, calc_timeout_sec (priv->entry_timeout); feo->entry_valid_nsec = calc_timeout_nsec (priv->entry_timeout); - feo->attr_valid = - calc_timeout_sec (priv->attribute_timeout); - feo->attr_valid_nsec = - calc_timeout_nsec (priv->attribute_timeout); + + if (entry->d_stat.ia_ctime) { + feo->attr_valid = + calc_timeout_sec (priv->attribute_timeout); + feo->attr_valid_nsec = + calc_timeout_nsec (priv->attribute_timeout); + } else { + feo->attr_valid = feo->attr_valid_nsec = 0; + } next_entry: if (size == max_size) |