74096c
From 41aae052b5e3afe64d3e0668643726bab0e77265 Mon Sep 17 00:00:00 2001
74096c
From: Xavi Hernandez <xhernandez@redhat.com>
74096c
Date: Fri, 4 Sep 2020 14:49:50 +0200
74096c
Subject: [PATCH 525/526] open-behind: implement create fop
74096c
74096c
Open behind didn't implement create fop. This caused that files created
74096c
were not accounted for the number of open fd's. This could cause future
74096c
opens to be delayed when they shouldn't.
74096c
74096c
This patch implements the create fop. It also fixes a problem when
74096c
destroying the stack: when frame->local was not NULL, STACK_DESTROY()
74096c
tried to mem_put() it, which is not correct.
74096c
74096c
Upstream patch:
74096c
> Upstream-patch-link: https://review.gluster.org/#/c/glusterfs/+/24953
74096c
> Fixes: #1440
74096c
> Change-Id: Ic982bad07d4af30b915d7eb1fbcef7a847a45869
74096c
> Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
74096c
74096c
BUG: 1830713
74096c
Change-Id: Ic982bad07d4af30b915d7eb1fbcef7a847a45869
74096c
Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
74096c
Reviewed-on: https://code.engineering.redhat.com/gerrit/224489
74096c
Tested-by: RHGS Build Bot <nigelb@redhat.com>
74096c
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
74096c
---
74096c
 xlators/performance/open-behind/src/open-behind.c | 52 +++++++++++++++++++++++
74096c
 1 file changed, 52 insertions(+)
74096c
74096c
diff --git a/xlators/performance/open-behind/src/open-behind.c b/xlators/performance/open-behind/src/open-behind.c
74096c
index 1ab635e..600c3b6 100644
74096c
--- a/xlators/performance/open-behind/src/open-behind.c
74096c
+++ b/xlators/performance/open-behind/src/open-behind.c
74096c
@@ -336,6 +336,7 @@ ob_stub_dispatch(xlator_t *xl, ob_inode_t *ob_inode, fd_t *fd,
74096c
 static void
74096c
 ob_open_destroy(call_stub_t *stub, fd_t *fd)
74096c
 {
74096c
+    stub->frame->local = NULL;
74096c
     STACK_DESTROY(stub->frame->root);
74096c
     call_stub_destroy(stub);
74096c
     fd_unref(fd);
74096c
@@ -516,6 +517,56 @@ ob_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, fd_t *fd,
74096c
 }
74096c
 
74096c
 static int32_t
74096c
+ob_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
74096c
+          mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
74096c
+{
74096c
+    ob_inode_t *ob_inode;
74096c
+    call_stub_t *stub;
74096c
+    fd_t *first_fd;
74096c
+    ob_state_t state;
74096c
+
74096c
+    /* Create requests are never delayed. We always send them synchronously. */
74096c
+    state = ob_open_and_resume_fd(this, fd, 1, true, true, &ob_inode,
74096c
+                                  &first_fd);
74096c
+    if (state == OB_STATE_READY) {
74096c
+        /* There's no pending open, but there are other file descriptors opened
74096c
+         * so we simply forward the request synchronously. */
74096c
+        return default_create(frame, this, loc, flags, mode, umask, fd, xdata);
74096c
+    }
74096c
+
74096c
+    if (state == OB_STATE_OPEN_TRIGGERED) {
74096c
+        /* The first open is in progress (either because it was already issued
74096c
+         * or because this request triggered it). We try to create a new stub
74096c
+         * to retry the operation once the initial open completes. */
74096c
+        stub = fop_create_stub(frame, ob_create, loc, flags, mode, umask, fd,
74096c
+                               xdata);
74096c
+        if (stub != NULL) {
74096c
+            return ob_stub_dispatch(this, ob_inode, first_fd, stub);
74096c
+        }
74096c
+
74096c
+        state = -ENOMEM;
74096c
+    }
74096c
+
74096c
+    /* Since we forced a synchronous request, OB_STATE_FIRST_OPEN will never
74096c
+     * be returned by ob_open_and_resume_fd(). If we are here it can only be
74096c
+     * because there has been a problem. */
74096c
+
74096c
+    /* In case of failure we need to decrement the number of open files because
74096c
+     * ob_fdclose() won't be called. */
74096c
+
74096c
+    LOCK(&fd->inode->lock);
74096c
+    {
74096c
+        ob_inode->open_count--;
74096c
+    }
74096c
+    UNLOCK(&fd->inode->lock);
74096c
+
74096c
+    gf_smsg(this->name, GF_LOG_ERROR, -state, OPEN_BEHIND_MSG_FAILED, "fop=%s",
74096c
+            "create", "path=%s", loc->path, NULL);
74096c
+
74096c
+    return default_create_failure_cbk(frame, -state);
74096c
+}
74096c
+
74096c
+static int32_t
74096c
 ob_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
74096c
          off_t offset, uint32_t flags, dict_t *xdata)
74096c
 {
74096c
@@ -946,6 +997,7 @@ fini(xlator_t *this)
74096c
 
74096c
 struct xlator_fops fops = {
74096c
     .open = ob_open,
74096c
+    .create = ob_create,
74096c
     .readv = ob_readv,
74096c
     .writev = ob_writev,
74096c
     .flush = ob_flush,
74096c
-- 
74096c
1.8.3.1
74096c