diff options
author | Susant Palai <spalai@redhat.com> | 2018-04-11 23:14:02 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2018-04-18 15:04:09 +0000 |
commit | 87bcdd9465b140e0b9d33dadf3384e28b7b6ed9f (patch) | |
tree | f4ed87c44555cb1839aa69537dcea1fad89044b1 | |
parent | d9cf6d25a4719c4f6fb4d88325f08e49fca18e6b (diff) |
fuse: do fd_resolve in fuse_getattr if fd is received
problem: With the current code, post graph switch the old fd is received for
fuse_getattr and since it is associated with old inode, it does not
have the inode ctx across xlators in new graph. Hence, dht
errored out saying "no layout" for fstat call. Hence the EINVAL.
Solution: if fd is passed, init and resolve fd to carry on getattr
test case:
- Created a single brick distributed volume
- Started untar
- Added a new-brick
Without this fix, untar used to abort with ERROR.
Change-Id: I5805c463fb9a04ba5c24829b768127097ff8b9f9
fixes: bz#1566207
Signed-off-by: Susant Palai <spalai@redhat.com>
-rw-r--r-- | xlators/cluster/dht/src/dht-inode-read.c | 4 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 13 |
2 files changed, 10 insertions, 7 deletions
diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c index fa63fefb903..d1895eb2abb 100644 --- a/xlators/cluster/dht/src/dht-inode-read.c +++ b/xlators/cluster/dht/src/dht-inode-read.c @@ -400,8 +400,8 @@ dht_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) layout = local->layout; if (!layout) { - gf_msg_debug (this->name, 0, - "no layout for fd=%p", fd); + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "no layout for fd=%p", fd); op_errno = EINVAL; goto err; } diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 1d105af04f1..f509d84a15b 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -921,7 +921,7 @@ fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, void fuse_getattr_resume (fuse_state_t *state) { - if (!state->loc.inode) { + if (!state->loc.inode && !(state->fd && state->fd->inode)) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRIu64": GETATTR %"PRIu64" (%s) resolution failed", state->finh->unique, state->finh->nodeid, @@ -932,9 +932,9 @@ fuse_getattr_resume (fuse_state_t *state) return; } - if (!IA_ISDIR (state->loc.inode->ia_type)) { - if (state->fd == NULL) - state->fd = fd_lookup (state->loc.inode, state->finh->pid); + if (state->fd == NULL && !IA_ISDIR (state->loc.inode->ia_type)) { + state->fd = fd_lookup (state->loc.inode, state->finh->pid); + if (state->fd == NULL) state->fd = fd_lookup (state->loc.inode, 0); } @@ -976,7 +976,10 @@ fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg, state->fd = fd_ref ((fd_t *)fgi->fh); #endif - fuse_resolve_inode_init (state, &state->resolve, state->finh->nodeid); + if (state->fd) + fuse_resolve_fd_init (state, &state->resolve, state->fd); + else + fuse_resolve_inode_init (state, &state->resolve, state->finh->nodeid); fuse_resolve_and_resume (state, fuse_getattr_resume); } |