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