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