Blob Blame History Raw
From 80efc701cb29684355cd133fbf29c14948772ba1 Mon Sep 17 00:00:00 2001
From: Susant Palai <spalai@redhat.com>
Date: Wed, 11 Apr 2018 23:14:02 +0530
Subject: [PATCH 229/236] 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.

upstream patch: https://review.gluster.org/#/c/19849/

> Change-Id: I5805c463fb9a04ba5c24829b768127097ff8b9f9
> fixes: bz#1566207
> Signed-off-by: Susant Palai <spalai@redhat.com>
> (cherry picked from commit 87bcdd9465b140e0b9d33dadf3384e28b7b6ed9f)

Change-Id: I5805c463fb9a04ba5c24829b768127097ff8b9f9
BUG: 1563692
Signed-off-by: Susant Palai <spalai@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/136232
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
 xlators/cluster/dht/src/dht-inode-read.c |  4 ++--
 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 fa63fef..d1895eb 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 3e31eca..44697d2 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -893,7 +893,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,
@@ -904,9 +904,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);
         }
@@ -947,7 +947,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);
 }
-- 
1.8.3.1