diff options
author | Csaba Henk <csaba@redhat.com> | 2018-03-05 13:02:09 +0100 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2018-03-06 03:45:00 +0000 |
commit | 7f9c56dd38018d65f2902212c1f80171ac7218b1 (patch) | |
tree | a4a6b827de91129e6be54b03ac8f506f11f1f547 | |
parent | 2bb17551a597b382d77bb5ebc2671b45565cd542 (diff) |
fuse: enable proper "fgetattr"-like semantics
GETATTR FUSE message can carry a file handle
reference in which case it serves as a hint
for the FUSE server that the stat data is
preferably acquired in context of the given
filehandle (which we call '"fgetattr"-like
semantics').
So far FUSE ignored the GETTATTR provided
filehandle and grabbed a file handle
heuristically. This caused confusion in the
caching layers, which has been tracked down
as one of the reasons of referred BUG.
As of the BUG, this is just a partial fix.
BUG: 1512691
Change-Id: I67eebbf5407ca725ed111fbda4181ead10d03f6d
Signed-off-by: Csaba Henk <csaba@redhat.com>
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 076fbfddaf8..dee9b16abf3 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -930,7 +930,10 @@ fuse_getattr_resume (fuse_state_t *state) } if (!IA_ISDIR (state->loc.inode->ia_type)) { - state->fd = fd_lookup (state->loc.inode, 0); + if (state->fd == NULL) + state->fd = fd_lookup (state->loc.inode, state->finh->pid); + if (state->fd == NULL) + state->fd = fd_lookup (state->loc.inode, 0); } if (!state->fd) { @@ -956,9 +959,18 @@ fuse_getattr_resume (fuse_state_t *state) static void fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg) { +#if FUSE_KERNEL_MINOR_VERSION >= 9 + struct fuse_getattr_in *fgi = msg; + fuse_private_t *priv = NULL; +#endif fuse_state_t *state; GET_STATE (this, finh, state); +#if FUSE_KERNEL_MINOR_VERSION >= 9 + priv = this->private; + if (priv->proto_minor >= 9 && fgi->getattr_flags & FUSE_GETATTR_FH) + state->fd = fd_ref ((fd_t *)fgi->fh); +#endif fuse_resolve_inode_init (state, &state->resolve, state->finh->nodeid); |