diff options
-rw-r--r-- | tests/bugs/shard/bug-1696136.c | 121 | ||||
-rw-r--r-- | tests/bugs/shard/bug-1696136.t | 33 | ||||
-rw-r--r-- | tests/bugs/shard/shard-fallocate.c | 2 | ||||
-rw-r--r-- | xlators/features/shard/src/shard.c | 12 |
4 files changed, 164 insertions, 4 deletions
diff --git a/tests/bugs/shard/bug-1696136.c b/tests/bugs/shard/bug-1696136.c new file mode 100644 index 00000000000..b9e8d1375e5 --- /dev/null +++ b/tests/bugs/shard/bug-1696136.c @@ -0,0 +1,121 @@ +#define _GNU_SOURCE +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +enum fallocate_flag { + TEST_FALLOCATE_NONE, + TEST_FALLOCATE_KEEP_SIZE, + TEST_FALLOCATE_ZERO_RANGE, + TEST_FALLOCATE_PUNCH_HOLE, + TEST_FALLOCATE_MAX, +}; + +int +get_fallocate_flag(int opcode) +{ + int ret = 0; + + switch (opcode) { + case TEST_FALLOCATE_NONE: + ret = 0; + break; + case TEST_FALLOCATE_KEEP_SIZE: + ret = FALLOC_FL_KEEP_SIZE; + break; + case TEST_FALLOCATE_ZERO_RANGE: + ret = FALLOC_FL_ZERO_RANGE; + break; + case TEST_FALLOCATE_PUNCH_HOLE: + ret = FALLOC_FL_PUNCH_HOLE; + break; + default: + ret = -1; + break; + } + return ret; +} + +int +main(int argc, char *argv[]) +{ + int ret = 1; + int opcode = -1; + off_t offset = 0; + size_t len = 0; + glfs_t *fs = NULL; + glfs_fd_t *fd = NULL; + + if (argc != 8) { + fprintf(stderr, + "Syntax: %s <host> <volname> <opcode> <offset> <len> " + "<file-path> <log-file>\n", + argv[0]); + return 1; + } + + fs = glfs_new(argv[2]); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server(fs, "tcp", argv[1], 24007); + if (ret != 0) { + fprintf(stderr, "glfs_set_volfile_server: returned %d\n", ret); + goto out; + } + + ret = glfs_set_logging(fs, argv[7], 7); + if (ret != 0) { + fprintf(stderr, "glfs_set_logging: returned %d\n", ret); + goto out; + } + + ret = glfs_init(fs); + if (ret != 0) { + fprintf(stderr, "glfs_init: returned %d\n", ret); + goto out; + } + + opcode = atoi(argv[3]); + opcode = get_fallocate_flag(opcode); + if (opcode < 0) { + fprintf(stderr, "get_fallocate_flag: invalid flag \n"); + goto out; + } + + offset = atoi(argv[4]); + len = atoi(argv[5]); + + fd = glfs_open(fs, argv[6], O_RDWR); + if (fd == NULL) { + fprintf(stderr, "glfs_open: returned NULL\n"); + goto out; + } + + ret = glfs_fallocate(fd, opcode, offset, len); + if (ret < 0) { + fprintf(stderr, "glfs_fallocate: returned %d\n", ret); + goto out; + } + + ret = glfs_unlink(fs, argv[6]); + if (ret < 0) { + fprintf(stderr, "glfs_unlink: returned %d\n", ret); + goto out; + } + /* Sleep for 3s to give enough time for background deletion to complete + * during which if the bug exists, the process will crash. + */ + sleep(3); + ret = 0; + +out: + if (fd) + glfs_close(fd); + glfs_fini(fs); + return ret; +} diff --git a/tests/bugs/shard/bug-1696136.t b/tests/bugs/shard/bug-1696136.t new file mode 100644 index 00000000000..b6dc858f083 --- /dev/null +++ b/tests/bugs/shard/bug-1696136.t @@ -0,0 +1,33 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../fallocate.rc + +cleanup + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2} +TEST $CLI volume set $V0 features.shard on +TEST $CLI volume set $V0 features.shard-block-size 4MB +TEST $CLI volume set $V0 features.shard-lru-limit 120 +TEST $CLI volume set $V0 performance.write-behind off +TEST $CLI volume start $V0 + +TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0 + +TEST build_tester $(dirname $0)/bug-1696136.c -lgfapi -Wall -O2 + +# Create a file +TEST touch $M0/file1 + +# Fallocate a 500M file. This will make sure number of participant shards are > lru-limit +TEST $(dirname $0)/bug-1696136 $H0 $V0 "0" "0" "536870912" /file1 `gluster --print-logdir`/glfs-$V0.log + +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 +rm -f $(dirname $0)/bug-1696136 + +cleanup diff --git a/tests/bugs/shard/shard-fallocate.c b/tests/bugs/shard/shard-fallocate.c index 3a784d3c02c..45b9ce00509 100644 --- a/tests/bugs/shard/shard-fallocate.c +++ b/tests/bugs/shard/shard-fallocate.c @@ -97,7 +97,7 @@ main(int argc, char *argv[]) } ret = glfs_fallocate(fd, opcode, offset, len); - if (ret <= 0) { + if (ret < 0) { fprintf(stderr, "glfs_fallocate: returned %d\n", ret); goto out; } diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 7a62f92f9ef..b8f5a31742e 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -2212,13 +2212,19 @@ shard_link_block_inode(shard_local_t *local, int block_num, inode_t *inode, xlator_t *this = NULL; inode_t *fsync_inode = NULL; shard_priv_t *priv = NULL; + inode_t *base_inode = NULL; this = THIS; priv = this->private; - if (local->loc.inode) + if (local->loc.inode) { gf_uuid_copy(gfid, local->loc.inode->gfid); - else + base_inode = local->loc.inode; + } else if (local->resolver_base_inode) { + gf_uuid_copy(gfid, local->resolver_base_inode->gfid); + base_inode = local->resolver_base_inode; + } else { gf_uuid_copy(gfid, local->base_gfid); + } shard_make_block_bname(block_num, gfid, block_bname, sizeof(block_bname)); @@ -2231,7 +2237,7 @@ shard_link_block_inode(shard_local_t *local, int block_num, inode_t *inode, LOCK(&priv->lock); { fsync_inode = __shard_update_shards_inode_list( - linked_inode, this, local->loc.inode, block_num, gfid); + linked_inode, this, base_inode, block_num, gfid); } UNLOCK(&priv->lock); if (fsync_inode) |