summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2012-11-16 12:06:36 +0530
committerAnand Avati <avati@redhat.com>2013-01-29 11:01:34 -0800
commit088050b257ac9cbd2115587b0f7306760c44a4a3 (patch)
tree74e1070291e6d2baecafad66af35d337abe79808
parentf811441e257cafb975dfcd16f14b4378beee524e (diff)
performance/io-cache: propagate errors while unwinding frame in
read path. Change-Id: Ieb5d592a987e8681d5ec019da309f75e3b207580 BUG: 858242 Signed-off-by: Raghavendra G <raghavendra@gluster.com> Reviewed-on: http://review.gluster.org/4204 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
-rw-r--r--tests/bugs/bug-858242.c77
-rwxr-xr-xtests/bugs/bug-858242.t51
-rw-r--r--xlators/performance/io-cache/src/page.c16
3 files changed, 139 insertions, 5 deletions
diff --git a/tests/bugs/bug-858242.c b/tests/bugs/bug-858242.c
new file mode 100644
index 00000000000..a42262e225c
--- /dev/null
+++ b/tests/bugs/bug-858242.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+ char *filename = NULL, *volname = NULL, *cmd = NULL;
+ char buffer[1024] = {0, };
+ int fd = -1;
+ int ret = -1;
+ struct stat statbuf = {0, };
+
+ if (argc != 3) {
+ fprintf (stderr, "usage: %s <file-name> <volname>\n", argv[0]);
+ goto out;
+ }
+
+ filename = argv[1];
+ volname = argv[2];
+
+ fd = open (filename, O_RDWR | O_CREAT, 0);
+ if (fd < 0) {
+ fprintf (stderr, "open (%s) failed (%s)\n", filename,
+ strerror (errno));
+ goto out;
+ }
+
+ ret = write (fd, "test-content", 12);
+ if (ret < 0) {
+ fprintf (stderr, "write failed (%s)", strerror (errno));
+ goto out;
+ }
+
+ ret = fsync (fd);
+ if (ret < 0) {
+ fprintf (stderr, "fsync failed (%s)", strerror (errno));
+ goto out;
+ }
+
+ ret = fstat (fd, &statbuf);
+ if (ret < 0) {
+ fprintf (stderr, "fstat failed (%s)", strerror (errno));
+ goto out;
+ }
+
+ ret = asprintf (&cmd, "gluster --mode=script volume stop %s force",
+ volname);
+ if (ret < 0) {
+ fprintf (stderr, "cannot construct cli command string (%s)",
+ strerror (errno));
+ goto out;
+ }
+
+ ret = system (cmd);
+ if (ret < 0) {
+ fprintf (stderr, "stopping volume (%s) failed", volname);
+ goto out;
+ }
+
+ ret = read (fd, buffer, 1024);
+ if (ret >= 0) {
+ fprintf (stderr, "read should've returned error, "
+ "but is successful\n");
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
diff --git a/tests/bugs/bug-858242.t b/tests/bugs/bug-858242.t
new file mode 100755
index 00000000000..2009ee7e4b2
--- /dev/null
+++ b/tests/bugs/bug-858242.t
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume info;
+
+function volinfo_field()
+{
+ local vol=$1;
+ local field=$2;
+
+ $CLI volume info $vol | grep "^$field: " | sed 's/.*: //';
+}
+
+TEST $CLI volume create $V0 $H0:$B0/brick1;
+EXPECT 'Created' volinfo_field $V0 'Status';
+
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+TEST $CLI volume set $V0 performance.quick-read off
+
+#mount on a random dir
+TEST glusterfs --entry-timeout=3600 --attribute-timeout=3600 -s $H0 --volfile-id=$V0 $M0 --direct-io-mode=yes
+
+function cleanup_tester ()
+{
+ local exe=$1
+ rm -f $exe
+}
+
+function build_tester ()
+{
+ local cfile=$1
+ local fname=$(basename "$cfile")
+ local ext="${fname##*.}"
+ local execname="${fname%.*}"
+ gcc -g -o $(dirname $cfile)/$execname $cfile
+}
+
+build_tester $(dirname $0)/bug-858242.c
+
+TEST $(dirname $0)/bug-858242 $M0/testfile $V0
+
+TEST rm -rf $(dirname $0)/858242
+cleanup;
+
diff --git a/xlators/performance/io-cache/src/page.c b/xlators/performance/io-cache/src/page.c
index c18c04a0bdb..54c6f9b5019 100644
--- a/xlators/performance/io-cache/src/page.c
+++ b/xlators/performance/io-cache/src/page.c
@@ -804,7 +804,7 @@ ioc_frame_unwind (call_frame_t *frame)
int32_t copied = 0;
struct iobref *iobref = NULL;
struct iatt stbuf = {0,};
- int32_t op_ret = 0;
+ int32_t op_ret = 0, op_errno = 0;
GF_ASSERT (frame);
@@ -813,7 +813,13 @@ ioc_frame_unwind (call_frame_t *frame)
gf_log (frame->this->name, GF_LOG_WARNING,
"local is NULL");
op_ret = -1;
- local->op_errno = ENOMEM;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ if (local->op_ret < 0) {
+ op_ret = local->op_ret;
+ op_errno = local->op_errno;
goto unwind;
}
@@ -822,7 +828,7 @@ ioc_frame_unwind (call_frame_t *frame)
iobref = iobref_new ();
if (iobref == NULL) {
op_ret = -1;
- local->op_errno = ENOMEM;
+ op_errno = ENOMEM;
}
if (list_empty (&local->fill_list)) {
@@ -839,7 +845,7 @@ ioc_frame_unwind (call_frame_t *frame)
vector = GF_CALLOC (count, sizeof (*vector), gf_ioc_mt_iovec);
if (vector == NULL) {
op_ret = -1;
- local->op_errno = ENOMEM;
+ op_errno = ENOMEM;
}
list_for_each_entry_safe (fill, next, &local->fill_list, list) {
@@ -869,7 +875,7 @@ unwind:
// ioc_local_unlock (local);
- STACK_UNWIND_STRICT (readv, frame, op_ret, local->op_errno, vector,
+ STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector,
count, &stbuf, iobref, NULL);
if (iobref != NULL) {