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