diff options
author | Xavier Hernandez <xhernandez@datalab.es> | 2017-05-09 19:40:21 +0200 |
---|---|---|
committer | Raghavendra Talur <rtalur@redhat.com> | 2017-07-07 07:46:43 +0000 |
commit | 0f725500f50f386a19e33b077c7590d75bb276d8 (patch) | |
tree | a7377ab660f97dd8ffff27510dc881192b904523 /tests/basic/ec/seek.c | |
parent | d393ff62094b41d25b0d2f3734d9ab474a9f51a3 (diff) |
cluster/ec: correctly handle end of file for seek
When a SEEK_HOLE was issued near to the end of file, sometimes an
offset beyond the end of file was returned. Another problem was that
using some offsets greater than the end of file returned successfully
instead of failing with ENXIO.
>Change-Id: I238d2884ba02fd19a78116b0f8f8e8d6338fb3f5
>BUG: 1449348
>Signed-off-by: Xavier Hernandez <xhernandez@datalab.es>
>Reviewed-on: https://review.gluster.org/17228
>Smoke: Gluster Build System <jenkins@build.gluster.org>
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
>Reviewed-by: Amar Tumballi <amarts@redhat.com>
>Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
>(cherry picked from commit eb96dd45f8e583c6bad84bf32ca17e2bb01dd38f)
Change-Id: I238d2884ba02fd19a78116b0f8f8e8d6338fb3f5
BUG: 1468126
Signed-off-by: Xavier Hernandez <xhernandez@datalab.es>
Reviewed-on: https://review.gluster.org/17711
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Diffstat (limited to 'tests/basic/ec/seek.c')
-rw-r--r-- | tests/basic/ec/seek.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/tests/basic/ec/seek.c b/tests/basic/ec/seek.c new file mode 100644 index 00000000000..67036ad4e75 --- /dev/null +++ b/tests/basic/ec/seek.c @@ -0,0 +1,185 @@ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> + +static char buffer[65536]; + +static int +parse_int(const char *text, size_t *value) +{ + char *ptr; + size_t val; + + val = strtoul(text, &ptr, 0); + if (*ptr != 0) { + return 0; + } + + *value = val; + + return 1; +} + +static int +fill_area(int fd, off_t offset, size_t size) +{ + size_t len; + ssize_t res; + + while (size > 0) { + len = sizeof(buffer); + if (len > size) { + len = size; + } + res = pwrite(fd, buffer, len, offset); + if (res < 0) { + fprintf(stderr, + "pwrite(%d, %p, %lu, %lu) failed: %d\n", + fd, buffer, size, offset, errno); + return 0; + } + if (res != len) { + fprintf(stderr, + "pwrite(%d, %p, %lu, %lu) didn't wrote all " + "data: %lu/%lu\n", + fd, buffer, size, offset, res, len); + return 0; + } + offset += len; + size -= len; + } + + return 1; +} + +static void +syntax(void) +{ + fprintf(stderr, "Syntax: seek create <path> <offset> <size> [...]\n"); + fprintf(stderr, " seek scan <path> data|hole <offset>\n"); +} + +static int +seek_create(const char *path, int argc, char *argv[]) +{ + size_t off, size; + int fd; + int ret = 1; + + fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644); + if (fd < 0) { + fprintf(stderr, "Failed to create the file\n"); + goto out; + } + + while (argc > 0) { + if (!parse_int(argv[0], &off) || + !parse_int(argv[1], &size)) { + syntax(); + goto out_close; + } + if (!fill_area(fd, off, size)) { + goto out_close; + } + argv += 2; + argc -= 2; + } + + ret = 0; + +out_close: + close(fd); +out: + return ret; +} + +static int +seek_scan(const char *path, const char *type, const char *pos) +{ + size_t off, res; + int fd, whence; + int ret = 1; + + if (strcmp(type, "data") == 0) { + whence = SEEK_DATA; + } else if (strcmp(type, "hole") == 0) { + whence = SEEK_HOLE; + } else { + syntax(); + goto out; + } + + if (!parse_int(pos, &off)) { + syntax(); + goto out; + } + + fd = open(path, O_RDWR); + if (fd < 0) { + fprintf(stderr, "Failed to open the file\n"); + goto out; + } + + res = lseek(fd, off, whence); + if (res == (off_t)-1) { + if (errno != ENXIO) { + fprintf(stderr, "seek(%d, %lu, %d) failed: %d\n", fd, + off, whence, errno); + goto out_close; + } + fprintf(stdout, "ENXIO\n"); + } else { + fprintf(stdout, "%lu\n", res); + } + + ret = 0; + +out_close: + close(fd); +out: + return ret; +} + +int +main(int argc, char *argv[]) +{ + int ret = 1; + + memset(buffer, 0x55, sizeof(buffer)); + + if (argc < 3) { + syntax(); + goto out; + } + + if (strcmp(argv[1], "create") == 0) { + if (((argc - 3) & 1) != 0) { + syntax(); + goto out; + } + ret = seek_create(argv[2], argc - 3, argv + 3); + } else if (strcmp(argv[1], "scan") == 0) { + if (argc != 5) { + syntax(); + goto out; + } + ret = seek_scan(argv[2], argv[3], argv[4]); + } else { + syntax(); + goto out; + } + + ret = 0; + +out: + return ret; +} + |