Blob Blame History Raw
From b7ee0d94438ad82ac50a7f856ac41be4fd4e28c7 Mon Sep 17 00:00:00 2001
From: Raghavendra Bhat <raghavendra@redhat.com>
Date: Tue, 14 Jul 2015 16:16:00 +0530
Subject: [PATCH 285/304] protocol/server: use different dict for resolving

                 Backport of: http://review.gluster.org/11661

protocol/server has to resolve the inode before continuing with any fop coming
from the clients. For resolving it, server xlator was using the same dict
associated with the fop. It causes problems in some situations.

If a directory's inode was forgotten because of lru limit being exceeded, then
when a create fop comes for an entry within that directory, server tries to
resolve it. But since the parent directory's inode is not found in the inode
table, it tries to do a hard resolve by doing a lookup on the parent gfid.

If any xlator below server wants to get some extended attributes whenever
lookup comes, then they set the new keys in the same dict that came along with
the create fop. Now, the lookup of the parent succeeds and the create fop
proceeds with the same dict (with extra keys present). posix xlaror creates
those xattrs that are present in the dict. Thus the xattrs which were not to
be present by default are also set as part of create. (Ex: bit-rot related
xattrs such as bad-file, version and sign xattrs)

> Change-Id: I4bdad175a1d7a04a3aa36073667c556d6c260263
> Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
> Reviewed-on: http://review.gluster.org/11661
> Reviewed-by: Vijaikumar Mallikarjuna <vmallika@redhat.com>
> Tested-by: NetBSD Build System <jenkins@build.gluster.org>
> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
> Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>

Change-Id: I55c788858bc15549f67cc80151a95d3c2a695376
BUG: 1251409
Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/55883
---
 xlators/protocol/server/src/server-resolve.c |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
index a7da519..906dc00 100644
--- a/xlators/protocol/server/src/server-resolve.c
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -106,6 +106,7 @@ resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
         server_resolve_t     *resolve = NULL;
         inode_t              *link_inode = NULL;
         loc_t                *resolve_loc = NULL;
+        dict_t               *dict = NULL;
 
         state = CALL_STATE (frame);
         resolve = state->resolve_now;
@@ -166,10 +167,19 @@ resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
         inode_path (resolve_loc->parent, resolve_loc->name,
                     (char **) &resolve_loc->path);
 
+        dict = dict_copy_with_ref (state->xdata, NULL);
+        if (!dict && state->xdata)
+                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY,
+                        "BUG: dict allocation failed (pargfid: %s, name: %s), "
+                        "still continuing", uuid_utoa (resolve_loc->gfid),
+                        resolve_loc->name);
+
         STACK_WIND (frame, resolve_gfid_entry_cbk,
                     frame->root->client->bound_xl,
                     frame->root->client->bound_xl->fops->lookup,
-                    &resolve->resolve_loc, state->xdata);
+                    &resolve->resolve_loc, dict);
+        if (dict)
+                dict_unref (dict);
         return 0;
 out:
         resolve_continue (frame);
@@ -185,6 +195,7 @@ resolve_gfid (call_frame_t *frame)
         server_resolve_t     *resolve = NULL;
         loc_t                *resolve_loc = NULL;
         int                   ret = 0;
+        dict_t               *xdata = NULL;
 
         state = CALL_STATE (frame);
         this  = frame->this;
@@ -199,10 +210,21 @@ resolve_gfid (call_frame_t *frame)
         resolve_loc->inode = inode_new (state->itable);
         ret = loc_path (resolve_loc, NULL);
 
+        xdata = dict_copy_with_ref (state->xdata, NULL);
+        if (!xdata && state->xdata)
+                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY,
+                        "BUG: dict allocation failed (gfid: %s), "
+                        "still continuing",
+                        uuid_utoa (resolve_loc->gfid));
+
         STACK_WIND (frame, resolve_gfid_cbk,
                     frame->root->client->bound_xl,
                     frame->root->client->bound_xl->fops->lookup,
-                    &resolve->resolve_loc, state->xdata);
+                    &resolve->resolve_loc, xdata);
+
+        if (xdata)
+                dict_unref (xdata);
+
         return 0;
 }
 
-- 
1.7.1