diff options
author | Soumya Koduri <skoduri@redhat.com> | 2015-12-14 17:52:37 +0530 |
---|---|---|
committer | Kaushal M <kaushal@redhat.com> | 2016-10-03 05:15:26 -0700 |
commit | fee92f7c6abc651e88a8b52d5187286a4b8df2c3 (patch) | |
tree | 67dbd730f3974294ed7c50294565363dc27c0e3e | |
parent | 48f4ca93d5ea859ae5975239bf3d288709fdaf12 (diff) |
Upcall/cache-invalidation: Use parent stbuf while updating parent entry
For *create* fops (CREATE, MKDIR, MKNOD), we invalidate the parent
entry. Hence send parent attributes in the stat field.
Also "UP_PARENT_DENTRY_FLAGS" has to be set only for the fops which shall
result in two invalidations requests - one for the inode on which fop is
being performed and another on parent entry.
In case of CREATE/MKDIR/MKNOD fops, there shall be only one invalidation
request sent, that too on parent inode. We send invalidation directly on
parent inode's gfid. So there is no necessity to set these flags which
when set shall endup invalidating the parent's parent entry.
Cherry picked from commit f4282bd927e2e0d826d62cf1192102382c5697b2:
> Change-Id: I7514ee08382081e3e060818ede497dbca26987dc
> BUG: 1291259
> Signed-off-by: Soumya Koduri <skoduri@redhat.com>
> Reviewed-on: http://review.gluster.org/12962
> CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
> Smoke: Gluster Build System <jenkins@build.gluster.com>
> Reviewed-by: Niels de Vos <ndevos@redhat.com>
Change-Id: I7514ee08382081e3e060818ede497dbca26987dc
BUG: 1347715
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Reviewed-on: http://review.gluster.org/15600
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: Kaushal M <kaushal@redhat.com>
-rw-r--r-- | tests/basic/gfapi/Makefile.am | 3 | ||||
-rw-r--r-- | tests/basic/gfapi/bug1291259.c | 161 | ||||
-rwxr-xr-x | tests/basic/gfapi/bug1291259.sh | 30 | ||||
-rw-r--r-- | xlators/features/upcall/src/upcall-cache-invalidation.h | 2 | ||||
-rw-r--r-- | xlators/features/upcall/src/upcall.c | 8 |
5 files changed, 198 insertions, 6 deletions
diff --git a/tests/basic/gfapi/Makefile.am b/tests/basic/gfapi/Makefile.am index b166fcc3fa6..8ca03c72639 100644 --- a/tests/basic/gfapi/Makefile.am +++ b/tests/basic/gfapi/Makefile.am @@ -4,7 +4,8 @@ CFLAGS = -Wall -g $(shell pkg-config --cflags glusterfs-api) LDFLAGS = $(shell pkg-config --libs glusterfs-api) -BINARIES = upcall-cache-invalidate libgfapi-fini-hang anonymous_fd seek +BINARIES = upcall-cache-invalidate libgfapi-fini-hang anonymous_fd seek \ + bug1283983 bug1291259 %: %.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ diff --git a/tests/basic/gfapi/bug1291259.c b/tests/basic/gfapi/bug1291259.c new file mode 100644 index 00000000000..35f39938cb3 --- /dev/null +++ b/tests/basic/gfapi/bug1291259.c @@ -0,0 +1,161 @@ +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> +#include <alloca.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> +int gfapi = 1; + +#define LOG_ERR(func, ret) do { \ + if (ret != 0) { \ + fprintf (stderr, "%s : returned error ret(%d), errno(%d)\n", \ + func, ret, errno); \ + exit(1); \ + } else { \ + fprintf (stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) +#define LOG_IF_NO_ERR(func, ret) do { \ + if (ret == 0) { \ + fprintf (stderr, "%s : hasn't returned error %d\n", \ + func, ret); \ + exit(1); \ + } else { \ + fprintf (stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) + +#define GLAPI_UUID_LENGTH 16 +int +main (int argc, char *argv[]) +{ + glfs_t *fs = NULL; + glfs_t *fs2 = NULL; + int ret = 0, i; + glfs_fd_t *fd = NULL; + char *filename = "/a1"; + char *filename2 = "/a2"; + struct stat sb = {0, }; + struct callback_arg cbk; + char *logfile = NULL; + char *volname = NULL; + int cnt = 1; + int upcall_received = 0; + struct callback_inode_arg *in_arg = NULL; + struct glfs_object *root = NULL, *leaf = NULL; + unsigned char globjhdl[GFAPI_HANDLE_LENGTH]; + unsigned char globjhdl2[GFAPI_HANDLE_LENGTH]; + + cbk.reason = 0; + + fprintf (stderr, "Starting libgfapi_fini\n"); + if (argc != 3) { + fprintf (stderr, "Invalid argument\n"); + exit(1); + } + + volname = argv[1]; + logfile = argv[2]; + + + fs = glfs_new (volname); + if (!fs) { + fprintf (stderr, "glfs_new: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server (fs, "tcp", "localhost", 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging (fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init (fs); + LOG_ERR("glfs_init", ret); + + fs2 = glfs_new (volname); + if (!fs) { + fprintf (stderr, "glfs_new: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server (fs2, "tcp", "localhost", 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging (fs2, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init (fs2); + LOG_ERR("glfs_init", ret); + + sleep (2); + root = glfs_h_lookupat (fs, NULL, "/", &sb, 0); + if (!root) { + ret = -1; + LOG_ERR ("glfs_h_lookupat root", ret); + } + leaf = glfs_h_lookupat (fs, root, filename, &sb, 0); + if (!leaf) { + ret = -1; + LOG_IF_NO_ERR ("glfs_h_lookupat leaf", ret); + } + + root = glfs_h_lookupat (fs2, NULL, "/", &sb, 0); + if (!root) { + ret = -1; + LOG_ERR ("glfs_h_lookupat root", ret); + } + leaf = glfs_h_creat (fs2, root, filename, O_RDWR, 0644, &sb); + if (!leaf) { + ret = -1; + LOG_ERR ("glfs_h_lookupat leaf", ret); + } + fprintf (stderr, "glfs_h_create leaf - %p\n", leaf); + + while (cnt++ < 5) { + ret = glfs_h_poll_upcall(fs, &cbk); + LOG_ERR ("glfs_h_poll_upcall", ret); + + if (cbk.reason == GFAPI_INODE_INVALIDATE) { + fprintf (stderr, "Upcall received(%d)\n", + cbk.reason); + in_arg = (struct callback_inode_arg *)(cbk.event_arg); + + ret = glfs_h_extract_handle (root, + globjhdl+GLAPI_UUID_LENGTH, + GFAPI_HANDLE_LENGTH); + LOG_ERR("glfs_h_extract_handle", (ret != 16)); + + ret = glfs_h_extract_handle (in_arg->object, + globjhdl2+GLAPI_UUID_LENGTH, + GFAPI_HANDLE_LENGTH); + LOG_ERR("glfs_h_extract_handle", (ret != 16)); + + if (memcmp (globjhdl+GLAPI_UUID_LENGTH, + globjhdl2+GLAPI_UUID_LENGTH, 16)) { + fprintf (stderr, "Error: gfid mismatch\n"); + exit (1); + } + upcall_received = 1; + } + } + + if (!upcall_received) { + fprintf (stderr, "Error: Upcall not received\n"); + exit (1); + } + + ret = glfs_fini(fs); + LOG_ERR("glfs_fini", ret); + + fprintf (stderr, "End of libgfapi_fini\n"); + + exit(0); +} + + diff --git a/tests/basic/gfapi/bug1291259.sh b/tests/basic/gfapi/bug1291259.sh new file mode 100755 index 00000000000..edbac7e6b12 --- /dev/null +++ b/tests/basic/gfapi/bug1291259.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 localhost:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +logdir=`gluster --print-logdir` + +## Enable Upcall cache-invalidation feature +TEST $CLI volume set $V0 features.cache-invalidation on; + +build_tester $(dirname $0)/bug1291259.c -lgfapi -o $(dirname $0)/bug1291259 + +TEST ./$(dirname $0)/bug1291259 $V0 $logdir/bug1291259.log + +cleanup_tester $(dirname $0)/bug1291259 + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup; diff --git a/xlators/features/upcall/src/upcall-cache-invalidation.h b/xlators/features/upcall/src/upcall-cache-invalidation.h index edb8285827f..7c5d9e1add2 100644 --- a/xlators/features/upcall/src/upcall-cache-invalidation.h +++ b/xlators/features/upcall/src/upcall-cache-invalidation.h @@ -48,7 +48,7 @@ #define UP_RENAME_FLAGS (UP_RENAME) /* to invalidate parent directory entries for fops -rename, unlink, - * rmdir, mkdir, create */ + * rmdir, link */ #define UP_PARENT_DENTRY_FLAGS (UP_PARENT_TIMES) /* for fop - unlink, link, rmdir, mkdir */ diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c index 4e9650066d4..6fb4e802d23 100644 --- a/xlators/features/upcall/src/upcall.c +++ b/xlators/features/upcall/src/upcall.c @@ -642,7 +642,7 @@ up_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, /* invalidate parent's entry too */ flags = UP_TIMES; upcall_cache_invalidate (frame, this, client, local->inode, flags, - stbuf, postparent, NULL); + postparent, NULL, NULL); out: UPCALL_STACK_UNWIND (mkdir, frame, op_ret, op_errno, @@ -704,7 +704,7 @@ up_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, /* However invalidate parent's entry */ flags = UP_TIMES; upcall_cache_invalidate (frame, this, client, local->inode, flags, - stbuf, postparent, NULL); + postparent, NULL, NULL); out: UPCALL_STACK_UNWIND (create, frame, op_ret, op_errno, fd, @@ -1054,7 +1054,7 @@ up_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, /* invalidate parent's entry too */ flags = UP_TIMES; upcall_cache_invalidate (frame, this, client, local->inode, flags, - buf, postparent, NULL); + postparent, NULL, NULL); out: UPCALL_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, buf, @@ -1115,7 +1115,7 @@ up_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, /* invalidate parent's entry too */ flags = UP_TIMES; upcall_cache_invalidate (frame, this, client, local->inode, flags, - buf, postparent, NULL); + postparent, NULL, NULL); out: UPCALL_STACK_UNWIND (symlink, frame, op_ret, op_errno, inode, buf, |