12a457
From 8f8dec367d02bfa3587b4bd00f85474dbb5a948e Mon Sep 17 00:00:00 2001
12a457
From: vmallika <vmallika@redhat.com>
12a457
Date: Thu, 31 Mar 2016 07:35:35 +0530
12a457
Subject: [PATCH 53/80] server: send lookup on root inode when itable is created
12a457
12a457
This is a backport of http://review.gluster.org/#/c/13837
12a457
12a457
 * xlators like quota, marker, posix_acl can cause problems
12a457
   if inode-ctx are not created.
12a457
   sometime these xlarors may not get lookup on root inode
12a457
   with below cases
12a457
   1) client may not send lookup on root inode (like NSR leader)
12a457
   2) if the xlators on one of the bricks are not up,
12a457
      and client sending lookup during this time: brick
12a457
      can miss the lookup
12a457
   It is always better to make sure that there is one lookup
12a457
   on root. So send a first lookup when the inode table is created
12a457
12a457
 * When sending lookup on root, new inode is created, we need to
12a457
   use itable->root instead
12a457
12a457
> Change-Id: Iff2eeaa1a89795328833a7761789ef588f11218f
12a457
> BUG: 1320818
12a457
> Signed-off-by: vmallika <vmallika@redhat.com>
12a457
> Reviewed-on: http://review.gluster.org/13837
12a457
> Smoke: Gluster Build System <jenkins@build.gluster.com>
12a457
> CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
12a457
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
12a457
> Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
12a457
12a457
Change-Id: Ia764b95a420b2793324235fcabfdcad1f73f6bd3
12a457
BUG: 1302355
12a457
Signed-off-by: vmallika <vmallika@redhat.com>
12a457
Reviewed-on: https://code.engineering.redhat.com/gerrit/71536
12a457
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
12a457
Tested-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
12a457
---
12a457
 xlators/protocol/server/src/server-handshake.c |  140 +++++++++++++++++++-----
12a457
 xlators/protocol/server/src/server-helpers.c   |    9 ++
12a457
 xlators/protocol/server/src/server-helpers.h   |    4 +
12a457
 xlators/protocol/server/src/server-mem-types.h |    1 +
12a457
 xlators/protocol/server/src/server-resolve.c   |    6 +-
12a457
 xlators/protocol/server/src/server-rpc-fops.c  |    6 +-
12a457
 xlators/protocol/server/src/server.c           |    2 +
12a457
 xlators/protocol/server/src/server.h           |    2 +
12a457
 8 files changed, 139 insertions(+), 31 deletions(-)
12a457
12a457
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c
12a457
index af07979..77b81fe 100644
12a457
--- a/xlators/protocol/server/src/server-handshake.c
12a457
+++ b/xlators/protocol/server/src/server-handshake.c
12a457
@@ -327,12 +327,90 @@ fail:
12a457
         return 0;
12a457
 }
12a457
 
12a457
+void
12a457
+server_first_lookup_done (rpcsvc_request_t *req, gf_setvolume_rsp *rsp) {
12a457
+
12a457
+        server_submit_reply (NULL, req, rsp, NULL, 0, NULL,
12a457
+                             (xdrproc_t)xdr_gf_setvolume_rsp);
12a457
+
12a457
+        GF_FREE (rsp->dict.dict_val);
12a457
+        GF_FREE (rsp);
12a457
+}
12a457
+
12a457
+
12a457
+int
12a457
+server_first_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
12a457
+                       int32_t op_ret, int32_t op_errno,
12a457
+                       inode_t *inode, struct iatt *buf, dict_t *xattr,
12a457
+                       struct iatt *postparent)
12a457
+{
12a457
+        rpcsvc_request_t     *req = NULL;
12a457
+        gf_setvolume_rsp     *rsp = NULL;
12a457
+
12a457
+        req = cookie;
12a457
+        rsp = frame->local;
12a457
+        frame->local = NULL;
12a457
+
12a457
+        if (op_ret < 0 || buf == NULL)
12a457
+                gf_log (this->name, GF_LOG_WARNING, "server first lookup failed"
12a457
+                        " on root inode: %s", strerror (op_errno));
12a457
+
12a457
+        /* Ignore error from lookup, don't set
12a457
+         * failure in rsp->op_ret. lookup on a snapview-server
12a457
+         * can fail with ESTALE
12a457
+         */
12a457
+        server_first_lookup_done (req, rsp);
12a457
+
12a457
+        STACK_DESTROY (frame->root);
12a457
+
12a457
+        return 0;
12a457
+}
12a457
+
12a457
+int
12a457
+server_first_lookup (xlator_t *this, xlator_t *xl, rpcsvc_request_t *req,
12a457
+                     gf_setvolume_rsp *rsp)
12a457
+{
12a457
+        call_frame_t       *frame  = NULL;
12a457
+        loc_t               loc    = {0, };
12a457
+
12a457
+        loc.path = "/";
12a457
+        loc.name = "";
12a457
+        loc.inode = xl->itable->root;
12a457
+        loc.parent = NULL;
12a457
+        gf_uuid_copy (loc.gfid, loc.inode->gfid);
12a457
+
12a457
+        frame = create_frame (this, this->ctx->pool);
12a457
+        if (!frame) {
12a457
+                gf_log ("fuse", GF_LOG_ERROR, "failed to create frame");
12a457
+                goto err;
12a457
+        }
12a457
+
12a457
+        frame->local = (void *)rsp;
12a457
+        frame->root->uid = frame->root->gid = 0;
12a457
+        frame->root->pid = -1;
12a457
+        frame->root->type = GF_OP_TYPE_FOP;
12a457
+
12a457
+        STACK_WIND_COOKIE (frame, server_first_lookup_cbk, (void *)req, xl,
12a457
+                           xl->fops->lookup, &loc, NULL);
12a457
+
12a457
+        return 0;
12a457
+
12a457
+err:
12a457
+        rsp->op_ret = -1;
12a457
+        rsp->op_errno = ENOMEM;
12a457
+        server_first_lookup_done (req, rsp);
12a457
+
12a457
+        frame->local = NULL;
12a457
+        STACK_DESTROY (frame->root);
12a457
+
12a457
+        return -1;
12a457
+}
12a457
 
12a457
 int
12a457
 server_setvolume (rpcsvc_request_t *req)
12a457
 {
12a457
         gf_setvolume_req     args          = {{0,},};
12a457
-        gf_setvolume_rsp     rsp           = {0,};
12a457
+        gf_setvolume_rsp    *rsp           = NULL;
12a457
         client_t            *client        = NULL;
12a457
         server_ctx_t        *serv_ctx      = NULL;
12a457
         server_conf_t       *conf          = NULL;
12a457
@@ -644,21 +722,24 @@ server_setvolume (rpcsvc_request_t *req)
12a457
                 goto fail;
12a457
         }
12a457
 
12a457
-        if ((client->bound_xl != NULL) &&
12a457
-            (ret >= 0)                   &&
12a457
-            (client->bound_xl->itable == NULL)) {
12a457
-                /* create inode table for this bound_xl, if one doesn't
12a457
-                   already exist */
12a457
+        LOCK (&conf->itable_lock);
12a457
+        {
12a457
+                if (client->bound_xl->itable == NULL) {
12a457
+                        /* create inode table for this bound_xl, if one doesn't
12a457
+                           already exist */
12a457
 
12a457
-                gf_msg_trace (this->name, 0, "creating inode table with "
12a457
-                              "lru_limit=%"PRId32", xlator=%s",
12a457
-                              conf->inode_lru_limit, client->bound_xl->name);
12a457
+                        gf_msg_trace (this->name, 0, "creating inode table with"
12a457
+                                      " lru_limit=%"PRId32", xlator=%s",
12a457
+                                      conf->inode_lru_limit,
12a457
+                                      client->bound_xl->name);
12a457
 
12a457
-                /* TODO: what is this ? */
12a457
-                client->bound_xl->itable =
12a457
-                        inode_table_new (conf->inode_lru_limit,
12a457
-                                         client->bound_xl);
12a457
+                        /* TODO: what is this ? */
12a457
+                        client->bound_xl->itable =
12a457
+                                inode_table_new (conf->inode_lru_limit,
12a457
+                                                 client->bound_xl);
12a457
+                }
12a457
         }
12a457
+        UNLOCK (&conf->itable_lock);
12a457
 
12a457
         ret = dict_set_str (reply, "process-uuid",
12a457
                             this->ctx->process_uuid);
12a457
@@ -677,20 +758,25 @@ server_setvolume (rpcsvc_request_t *req)
12a457
                 gf_msg_debug (this->name, 0, "failed to set 'transport-ptr'");
12a457
 
12a457
 fail:
12a457
-        rsp.dict.dict_len = dict_serialized_length (reply);
12a457
-        if (rsp.dict.dict_len > UINT_MAX) {
12a457
+        rsp = GF_CALLOC (1, sizeof (gf_setvolume_rsp),
12a457
+                         gf_server_mt_setvolume_rsp_t);
12a457
+        GF_ASSERT (rsp);
12a457
+
12a457
+        rsp->op_ret = 0;
12a457
+        rsp->dict.dict_len = dict_serialized_length (reply);
12a457
+        if (rsp->dict.dict_len > UINT_MAX) {
12a457
                 gf_msg_debug ("server-handshake", 0, "failed to get serialized"
12a457
                                " length of reply dict");
12a457
                 op_ret   = -1;
12a457
                 op_errno = EINVAL;
12a457
-                rsp.dict.dict_len = 0;
12a457
+                rsp->dict.dict_len = 0;
12a457
         }
12a457
 
12a457
-        if (rsp.dict.dict_len) {
12a457
-                rsp.dict.dict_val = GF_CALLOC (1, rsp.dict.dict_len,
12a457
-                                               gf_server_mt_rsp_buf_t);
12a457
-                if (rsp.dict.dict_val) {
12a457
-                        ret = dict_serialize (reply, rsp.dict.dict_val);
12a457
+        if (rsp->dict.dict_len) {
12a457
+                rsp->dict.dict_val = GF_CALLOC (1, rsp->dict.dict_len,
12a457
+                                                gf_server_mt_rsp_buf_t);
12a457
+                if (rsp->dict.dict_val) {
12a457
+                        ret = dict_serialize (reply, rsp->dict.dict_val);
12a457
                         if (ret < 0) {
12a457
                                 gf_msg_debug ("server-handshake", 0, "failed "
12a457
                                               "to serialize reply dict");
12a457
@@ -699,8 +785,8 @@ fail:
12a457
                         }
12a457
                 }
12a457
         }
12a457
-        rsp.op_ret   = op_ret;
12a457
-        rsp.op_errno = gf_errno_to_error (op_errno);
12a457
+        rsp->op_ret   = op_ret;
12a457
+        rsp->op_errno = gf_errno_to_error (op_errno);
12a457
 
12a457
         /* if bound_xl is NULL or something fails, then put the connection
12a457
          * back. Otherwise the connection would have been added to the
12a457
@@ -717,14 +803,14 @@ fail:
12a457
                 gf_client_put (client, NULL);
12a457
                 req->trans->xl_private = NULL;
12a457
         }
12a457
-        server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
12a457
-                             (xdrproc_t)xdr_gf_setvolume_rsp);
12a457
 
12a457
+        if (op_ret >= 0 && client->bound_xl->itable)
12a457
+                server_first_lookup (this, client->bound_xl, req, rsp);
12a457
+        else
12a457
+                server_first_lookup_done (req, rsp);
12a457
 
12a457
         free (args.dict.dict_val);
12a457
 
12a457
-        GF_FREE (rsp.dict.dict_val);
12a457
-
12a457
         dict_unref (params);
12a457
         dict_unref (reply);
12a457
         dict_unref (config_params);
12a457
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
12a457
index 48df41c..f8621be 100644
12a457
--- a/xlators/protocol/server/src/server-helpers.c
12a457
+++ b/xlators/protocol/server/src/server-helpers.c
12a457
@@ -1220,3 +1220,12 @@ out:
12a457
 
12a457
         return ret;
12a457
 }
12a457
+
12a457
+inode_t *
12a457
+server_inode_new (inode_table_t *itable, uuid_t gfid) {
12a457
+        if (__is_root_gfid (gfid))
12a457
+                return itable->root;
12a457
+        else
12a457
+                return inode_new (itable);
12a457
+}
12a457
+
12a457
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
12a457
index 73b01b1..6cc5829 100644
12a457
--- a/xlators/protocol/server/src/server-helpers.h
12a457
+++ b/xlators/protocol/server/src/server-helpers.h
12a457
@@ -58,4 +58,8 @@ int auth_set_username_passwd (dict_t *input_params, dict_t *config_params,
12a457
 
12a457
 server_ctx_t *server_ctx_get (client_t *client, xlator_t *xlator);
12a457
 int server_process_event_upcall (xlator_t *this, void *data);
12a457
+
12a457
+inode_t *
12a457
+server_inode_new (inode_table_t *itable, uuid_t gfid);
12a457
+
12a457
 #endif /* !_SERVER_HELPERS_H */
12a457
diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h
12a457
index 19c3466..9e2fcbc 100644
12a457
--- a/xlators/protocol/server/src/server-mem-types.h
12a457
+++ b/xlators/protocol/server/src/server-mem-types.h
12a457
@@ -25,6 +25,7 @@ enum gf_server_mem_types_ {
12a457
         gf_server_mt_rsp_buf_t,
12a457
         gf_server_mt_volfile_ctx_t,
12a457
         gf_server_mt_timer_data_t,
12a457
+        gf_server_mt_setvolume_rsp_t,
12a457
         gf_server_mt_end,
12a457
 };
12a457
 #endif /* __SERVER_MEM_TYPES_H__ */
12a457
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
12a457
index 5f3d475..26bf37e 100644
12a457
--- a/xlators/protocol/server/src/server-resolve.c
12a457
+++ b/xlators/protocol/server/src/server-resolve.c
12a457
@@ -162,7 +162,8 @@ resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
12a457
 
12a457
         resolve_loc->name = resolve->bname;
12a457
 
12a457
-        resolve_loc->inode = inode_new (state->itable);
12a457
+        resolve_loc->inode = server_inode_new (state->itable,
12a457
+                                               resolve_loc->gfid);
12a457
 
12a457
         inode_path (resolve_loc->parent, resolve_loc->name,
12a457
                     (char **) &resolve_loc->path);
12a457
@@ -209,7 +210,8 @@ resolve_gfid (call_frame_t *frame)
12a457
         else if (!gf_uuid_is_null (resolve->gfid))
12a457
                 gf_uuid_copy (resolve_loc->gfid, resolve->gfid);
12a457
 
12a457
-        resolve_loc->inode = inode_new (state->itable);
12a457
+        resolve_loc->inode = server_inode_new (state->itable,
12a457
+                                               resolve_loc->gfid);
12a457
         ret = loc_path (resolve_loc, NULL);
12a457
 
12a457
         if (state->xdata) {
12a457
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
12a457
index 77d8a51..67c8797 100644
12a457
--- a/xlators/protocol/server/src/server-rpc-fops.c
12a457
+++ b/xlators/protocol/server/src/server-rpc-fops.c
12a457
@@ -96,7 +96,8 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
12a457
                 state->is_revalidate = 2;
12a457
                 loc_copy (&fresh_loc, &state->loc);
12a457
                 inode_unref (fresh_loc.inode);
12a457
-                fresh_loc.inode = inode_new (state->itable);
12a457
+                fresh_loc.inode = server_inode_new (state->itable,
12a457
+                                                    fresh_loc.gfid);
12a457
 
12a457
                 STACK_WIND (frame, server_lookup_cbk,
12a457
                             frame->root->client->bound_xl,
12a457
@@ -3090,7 +3091,8 @@ server_lookup_resume (call_frame_t *frame, xlator_t *bound_xl)
12a457
                 goto err;
12a457
 
12a457
         if (!state->loc.inode)
12a457
-                state->loc.inode = inode_new (state->itable);
12a457
+                state->loc.inode = server_inode_new (state->itable,
12a457
+                                                     state->loc.gfid);
12a457
         else
12a457
                 state->is_revalidate = 1;
12a457
 
12a457
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
12a457
index 81e9980..347a5fb 100644
12a457
--- a/xlators/protocol/server/src/server.c
12a457
+++ b/xlators/protocol/server/src/server.c
12a457
@@ -954,6 +954,8 @@ init (xlator_t *this)
12a457
         INIT_LIST_HEAD (&conf->xprt_list);
12a457
         pthread_mutex_init (&conf->mutex, NULL);
12a457
 
12a457
+        LOCK_INIT (&conf->itable_lock);
12a457
+
12a457
          /* Set event threads to the configured default */
12a457
         GF_OPTION_INIT("event-threads", conf->event_threads, int32, out);
12a457
         ret = server_check_event_threads (this, conf, STARTING_EVENT_THREADS,
12a457
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
12a457
index 37a1367..e1f3bf8 100644
12a457
--- a/xlators/protocol/server/src/server.h
12a457
+++ b/xlators/protocol/server/src/server.h
12a457
@@ -72,6 +72,8 @@ struct server_conf {
12a457
                                             * in case if volume set options
12a457
                                             * (say *.allow | *.reject) are
12a457
                                             * tweeked */
12a457
+
12a457
+        gf_lock_t               itable_lock;
12a457
 };
12a457
 typedef struct server_conf server_conf_t;
12a457
 
12a457
-- 
12a457
1.7.1
12a457