a3470f
From 2c8b94fb5359424a17dc0380b86cb17058f07bf6 Mon Sep 17 00:00:00 2001
a3470f
From: Sachin Prabhu <sprabhu@redhat.com>
a3470f
Date: Wed, 14 Feb 2018 10:36:27 +0530
a3470f
Subject: [PATCH 200/201] quick-read: Discard cache for fallocate, zerofill and
a3470f
 discard ops
a3470f
a3470f
The fallocate, zerofill and discard modify file data on the server thus
a3470f
rendering stale any cache held by the xlator on the client.
a3470f
a3470f
mainline:
a3470f
> BUG: 1524252
a3470f
> Reviewed-on: https://review.gluster.org/19018
a3470f
> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
a3470f
> Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
a3470f
(cherry picked from commit 429f2436b33793136836042ccc43ce4cfd7f89f3)
a3470f
a3470f
BUG: 1523599
a3470f
Change-Id: I432146c6390a0cd5869420c373f598da43915f3f
a3470f
Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
a3470f
Reviewed-on: https://code.engineering.redhat.com/gerrit/130229
a3470f
Tested-by: RHGS Build Bot <nigelb@redhat.com>
a3470f
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
a3470f
---
a3470f
 tests/bugs/quick-read/bz1523599/bz1523599.t      |  32 ++++
a3470f
 tests/bugs/quick-read/bz1523599/test_bz1523599.c | 196 +++++++++++++++++++++++
a3470f
 xlators/performance/quick-read/src/quick-read.c  |  40 ++++-
a3470f
 3 files changed, 267 insertions(+), 1 deletion(-)
a3470f
 create mode 100755 tests/bugs/quick-read/bz1523599/bz1523599.t
a3470f
 create mode 100644 tests/bugs/quick-read/bz1523599/test_bz1523599.c
a3470f
a3470f
diff --git a/tests/bugs/quick-read/bz1523599/bz1523599.t b/tests/bugs/quick-read/bz1523599/bz1523599.t
a3470f
new file mode 100755
a3470f
index 0000000..5027efe
a3470f
--- /dev/null
a3470f
+++ b/tests/bugs/quick-read/bz1523599/bz1523599.t
a3470f
@@ -0,0 +1,32 @@
a3470f
+#!/bin/bash
a3470f
+
a3470f
+. $(dirname $0)/../../../include.rc
a3470f
+. $(dirname $0)/../../../volume.rc
a3470f
+. $(dirname $0)/../../../fileio.rc
a3470f
+
a3470f
+cleanup;
a3470f
+
a3470f
+TEST glusterd
a3470f
+TEST pidof glusterd
a3470f
+
a3470f
+TEST $CLI volume create $V0 $H0:$B0/brick1;
a3470f
+EXPECT 'Created' volinfo_field $V0 'Status';
a3470f
+
a3470f
+TEST $CLI volume start $V0;
a3470f
+EXPECT 'Started' volinfo_field $V0 'Status';
a3470f
+
a3470f
+logdir=`gluster --print-logdir`
a3470f
+
a3470f
+TEST build_tester $(dirname $0)/test_bz1523599.c -lgfapi -o $(dirname $0)/test_bz1523599
a3470f
+TEST ./$(dirname $0)/test_bz1523599 0 $H0 $V0 test_bz1523599 $logdir/bz1523599.log
a3470f
+TEST ./$(dirname $0)/test_bz1523599 1 $H0 $V0 test_bz1523599 $logdir/bz1523599.log
a3470f
+TEST ./$(dirname $0)/test_bz1523599 0 $H0 $V0 test_bz1523599 $logdir/bz1523599.log
a3470f
+TEST ./$(dirname $0)/test_bz1523599 2 $H0 $V0 test_bz1523599 $logdir/bz1523599.log
a3470f
+
a3470f
+cleanup_tester $(dirname $0)/test_bz1523599
a3470f
+
a3470f
+TEST $CLI volume stop $V0
a3470f
+TEST $CLI volume delete $V0
a3470f
+
a3470f
+cleanup;
a3470f
+
a3470f
diff --git a/tests/bugs/quick-read/bz1523599/test_bz1523599.c b/tests/bugs/quick-read/bz1523599/test_bz1523599.c
a3470f
new file mode 100644
a3470f
index 0000000..f0166e1
a3470f
--- /dev/null
a3470f
+++ b/tests/bugs/quick-read/bz1523599/test_bz1523599.c
a3470f
@@ -0,0 +1,196 @@
a3470f
+/*
a3470f
+ * ./test_bz1523599 0 vm140-111 gv0 test211 log
a3470f
+ * ./test_bz1523599 1 vm140-111 gv0 test211 log
a3470f
+ * Open - Discard - Read - Then check read information to see if the initial TEST_STR_LEN/2 bytes read zero
a3470f
+ */
a3470f
+
a3470f
+#define _GNU_SOURCE
a3470f
+#include <stdio.h>
a3470f
+#include <stdlib.h>
a3470f
+#include <glusterfs/api/glfs.h>
a3470f
+#include <glusterfs/api/glfs-handles.h>
a3470f
+#include <errno.h>
a3470f
+#include <sys/uio.h>
a3470f
+
a3470f
+#define TEST_STR_LEN 2048
a3470f
+
a3470f
+enum fallocate_flag {
a3470f
+        TEST_WRITE,
a3470f
+        TEST_DISCARD,
a3470f
+        TEST_ZEROFILL,
a3470f
+};
a3470f
+
a3470f
+void print_str(char *str, int len)
a3470f
+{
a3470f
+        int i, addr;
a3470f
+
a3470f
+        printf("%07x\t", 0);
a3470f
+        for (i = 0; i < len; i++) {
a3470f
+                printf("%02x", str[i]);
a3470f
+                if (i) {
a3470f
+                        if ((i + 1) % 16 == 0)
a3470f
+                                printf("\n%07x\t", i+1);
a3470f
+                        else if ((i + 1) % 4 == 0)
a3470f
+                                printf(" ");
a3470f
+                }
a3470f
+        }
a3470f
+        printf("\n");
a3470f
+}
a3470f
+
a3470f
+int
a3470f
+test_read(char *str, int total_length, int len_zero)
a3470f
+{
a3470f
+        int i;
a3470f
+        int ret = 0;
a3470f
+
a3470f
+        for (i = 0; i < len_zero; i++) {
a3470f
+                if (str[i]) {
a3470f
+                        fprintf(stderr, "char at position %d not zeroed out\n",
a3470f
+                                i);
a3470f
+                        ret = -EIO;
a3470f
+                        goto out;
a3470f
+                }
a3470f
+        }
a3470f
+
a3470f
+        for (i = len_zero; i < total_length; i++) {
a3470f
+                if (str[i] != 0x11) {
a3470f
+                        fprintf(stderr,
a3470f
+                                "char at position %d does not contain pattern\n",
a3470f
+                                i);
a3470f
+                        ret = -EIO;
a3470f
+                        goto out;
a3470f
+                }
a3470f
+        }
a3470f
+out:
a3470f
+        return ret;
a3470f
+}
a3470f
+
a3470f
+int main(int argc, char *argv[])
a3470f
+{
a3470f
+        int opcode;
a3470f
+        char *host_name, *volume_name, *file_path, *glfs_log_path;
a3470f
+        glfs_t *fs = NULL;
a3470f
+        glfs_fd_t *fd = NULL;
a3470f
+        off_t offset = 0;
a3470f
+        size_t len_zero = TEST_STR_LEN / 2;
a3470f
+        char writestr[TEST_STR_LEN];
a3470f
+        char readstr[TEST_STR_LEN];
a3470f
+        struct iovec iov = {&readstr, TEST_STR_LEN};
a3470f
+        int i;
a3470f
+        int ret = 1;
a3470f
+
a3470f
+        for (i = 0; i < TEST_STR_LEN; i++)
a3470f
+                writestr[i] = 0x11;
a3470f
+        for (i = 0; i < TEST_STR_LEN; i++)
a3470f
+                readstr[i] = 0x22;
a3470f
+
a3470f
+        if (argc != 6) {
a3470f
+                fprintf(stderr,
a3470f
+                        "Syntax: %s <test type> <host> <volname> <file-path> <log-file>\n",
a3470f
+                        argv[0]);
a3470f
+                return 1;
a3470f
+        }
a3470f
+
a3470f
+        opcode = atoi(argv[1]);
a3470f
+        host_name = argv[2];
a3470f
+        volume_name = argv[3];
a3470f
+        file_path = argv[4];
a3470f
+        glfs_log_path = argv[5];
a3470f
+
a3470f
+        fs = glfs_new(volume_name);
a3470f
+        if (!fs) {
a3470f
+                perror("glfs_new");
a3470f
+                return 1;
a3470f
+        }
a3470f
+
a3470f
+        ret = glfs_set_volfile_server(fs, "tcp", host_name, 24007);
a3470f
+        if (ret != 0) {
a3470f
+                perror("glfs_set_volfile_server");
a3470f
+                goto out;
a3470f
+        }
a3470f
+
a3470f
+        ret = glfs_set_logging(fs, glfs_log_path, 7);
a3470f
+        if (ret != 0) {
a3470f
+                perror("glfs_set_logging");
a3470f
+                goto out;
a3470f
+        }
a3470f
+
a3470f
+        ret = glfs_init(fs);
a3470f
+        if (ret != 0) {
a3470f
+                perror("glfs_init");
a3470f
+                goto out;
a3470f
+        }
a3470f
+
a3470f
+        fd = glfs_creat(fs, file_path, O_RDWR, 0777);
a3470f
+        if (fd == NULL) {
a3470f
+                perror("glfs_creat");
a3470f
+                ret = -1;
a3470f
+                goto out;
a3470f
+        }
a3470f
+
a3470f
+        switch (opcode) {
a3470f
+        case TEST_WRITE:
a3470f
+                fprintf(stderr, "Test Write\n");
a3470f
+                ret = glfs_write(fd, writestr, TEST_STR_LEN, 0);
a3470f
+                if (ret < 0) {
a3470f
+                        perror("glfs_write");
a3470f
+                        goto out;
a3470f
+                } else if (ret != TEST_STR_LEN) {
a3470f
+                        fprintf(stderr, "insufficient data written %d \n", ret);
a3470f
+                        ret = -EIO;
a3470f
+                        goto out;
a3470f
+                }
a3470f
+                ret = 0;
a3470f
+                goto out;
a3470f
+        case TEST_DISCARD:
a3470f
+                fprintf(stderr, "Test Discard\n");
a3470f
+                ret = glfs_discard(fd, offset, len_zero);
a3470f
+                if (ret < 0) {
a3470f
+                        if (errno == EOPNOTSUPP) {
a3470f
+                                fprintf(stderr, "Operation not supported\n");
a3470f
+                                ret = 0;
a3470f
+                                goto out;
a3470f
+                        }
a3470f
+                        perror("glfs_discard");
a3470f
+                        goto out;
a3470f
+                }
a3470f
+                goto test_read;
a3470f
+        case TEST_ZEROFILL:
a3470f
+                fprintf(stderr, "Test Zerofill\n");
a3470f
+                ret = glfs_zerofill(fd, offset, len_zero);
a3470f
+                if (ret < 0) {
a3470f
+                        if (errno == EOPNOTSUPP) {
a3470f
+                                fprintf(stderr, "Operation not supported\n");
a3470f
+                                ret = 0;
a3470f
+                                goto out;
a3470f
+                        }
a3470f
+                        perror("glfs_zerofill");
a3470f
+                        goto out;
a3470f
+                }
a3470f
+                goto test_read;
a3470f
+        default:
a3470f
+                ret = -1;
a3470f
+                fprintf(stderr, "Incorrect test code %d\n", opcode);
a3470f
+                goto out;
a3470f
+        }
a3470f
+
a3470f
+test_read:
a3470f
+        ret = glfs_readv(fd, &iov, 1, 0);
a3470f
+        if (ret < 0) {
a3470f
+                perror("glfs_readv");
a3470f
+                goto out;
a3470f
+        }
a3470f
+
a3470f
+        /* printf("Read str\n"); print_str(readstr, TEST_STR_LEN); printf("\n"); */
a3470f
+        ret = test_read(readstr, TEST_STR_LEN, len_zero);
a3470f
+
a3470f
+out:
a3470f
+        if (fd)
a3470f
+                glfs_close(fd);
a3470f
+        glfs_fini(fs);
a3470f
+
a3470f
+        if (ret)
a3470f
+                return -1;
a3470f
+
a3470f
+        return 0;
a3470f
+}
a3470f
diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c
a3470f
index 92b2f82..61232c1 100644
a3470f
--- a/xlators/performance/quick-read/src/quick-read.c
a3470f
+++ b/xlators/performance/quick-read/src/quick-read.c
a3470f
@@ -668,6 +668,41 @@ qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
a3470f
 	return 0;
a3470f
 }
a3470f
 
a3470f
+static int
a3470f
+qr_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int keep_size,
a3470f
+              off_t offset, size_t len, dict_t *xdata)
a3470f
+{
a3470f
+        qr_inode_prune (this, fd->inode);
a3470f
+
a3470f
+        STACK_WIND (frame, default_fallocate_cbk,
a3470f
+                    FIRST_CHILD (this), FIRST_CHILD (this)->fops->fallocate,
a3470f
+                    fd, keep_size, offset, len, xdata);
a3470f
+        return 0;
a3470f
+}
a3470f
+
a3470f
+static int
a3470f
+qr_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
a3470f
+              size_t len, dict_t *xdata)
a3470f
+{
a3470f
+        qr_inode_prune (this, fd->inode);
a3470f
+
a3470f
+        STACK_WIND (frame, default_discard_cbk,
a3470f
+                    FIRST_CHILD (this), FIRST_CHILD (this)->fops->discard,
a3470f
+                    fd, offset, len, xdata);
a3470f
+        return 0;
a3470f
+}
a3470f
+
a3470f
+static int
a3470f
+qr_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
a3470f
+              off_t len, dict_t *xdata)
a3470f
+{
a3470f
+        qr_inode_prune (this, fd->inode);
a3470f
+
a3470f
+        STACK_WIND (frame, default_zerofill_cbk,
a3470f
+                    FIRST_CHILD (this), FIRST_CHILD (this)->fops->zerofill,
a3470f
+                    fd, offset, len, xdata);
a3470f
+        return 0;
a3470f
+}
a3470f
 
a3470f
 int
a3470f
 qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
a3470f
@@ -1128,7 +1163,10 @@ struct xlator_fops fops = {
a3470f
         .readv       = qr_readv,
a3470f
 	.writev      = qr_writev,
a3470f
 	.truncate    = qr_truncate,
a3470f
-	.ftruncate   = qr_ftruncate
a3470f
+        .ftruncate   = qr_ftruncate,
a3470f
+        .fallocate   = qr_fallocate,
a3470f
+        .discard     = qr_discard,
a3470f
+        .zerofill    = qr_zerofill
a3470f
 };
a3470f
 
a3470f
 struct xlator_cbks cbks = {
a3470f
-- 
a3470f
1.8.3.1
a3470f