From 3e9a9c029fac359477fb26d9cc7803749ba038b2 Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Thu, 28 Dec 2017 16:02:59 +0530 Subject: posix: delete stale gfid handles in nameless lookup ..in order for self-heal of symlinks to work properly (see BZ for details). Change-Id: I9a011d00b07a690446f7fd3589e96f840e8b7501 BUG: 1529488 Signed-off-by: Ravishankar N --- tests/bugs/heal-symlinks.t | 65 +++++++++++++++++++++++++++++ xlators/storage/posix/src/posix-entry-ops.c | 17 +++++++- 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/bugs/heal-symlinks.t diff --git a/tests/bugs/heal-symlinks.t b/tests/bugs/heal-symlinks.t new file mode 100644 index 00000000000..ecd2b525be1 --- /dev/null +++ b/tests/bugs/heal-symlinks.t @@ -0,0 +1,65 @@ +#!/bin/bash +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../afr.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 performance.stat-prefetch off +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0; + +cd $M0 +TEST "echo hello_world > FILE" +TEST ln -s FILE SOFTLINK + +# Remove symlink only (not the .glusterfs entry) and trigger named heal. +TEST rm -f $B0/${V0}2/SOFTLINK +TEST stat SOFTLINK + +# To heal and clear new-entry mark on source bricks. +TEST $CLI volume heal $V0 +EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0 + +EXPECT 2 stat -c %h $B0/${V0}2/SOFTLINK +EXPECT "hello_world" cat $B0/${V0}2/SOFTLINK + +cd - +cleanup +############################################################################### + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 disperse 3 redundancy 1 $H0:$B0/${V0}{0,1,2} +TEST $CLI volume set $V0 performance.stat-prefetch off +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0; + +cd $M0 +TEST "echo hello_world > FILE" +TEST ln -s FILE SOFTLINK + +# Remove symlink only (not the .glusterfs entry) and trigger named heal. +TEST rm -f $B0/${V0}2/SOFTLINK +TEST stat SOFTLINK + +# To heal and clear new-entry mark on source bricks. +TEST $CLI volume heal $V0 +EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0 + +EXPECT 2 stat -c %h $B0/${V0}2/SOFTLINK +TEST kill_brick $V0 $H0 $B0/${V0}0 +cd - +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0; +cd $M0 +EXPECT "hello_world" cat SOFTLINK + +cd - +cleanup +############################################################################### diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c index 5fb3a4b09c8..4d7ed5be7c8 100644 --- a/xlators/storage/posix/src/posix-entry-ops.c +++ b/xlators/storage/posix/src/posix-entry-ops.c @@ -171,7 +171,10 @@ posix_lookup (call_frame_t *frame, xlator_t *this, dict_t * xattr = NULL; char * real_path = NULL; char * par_path = NULL; + char *gfid_path = NULL; + uuid_t gfid = {0}; struct iatt postparent = {0,}; + struct stat statbuf = {0}; int32_t gfidless = 0; char *pgfid_xattr_key = NULL; int32_t nlink_samepgfid = 0; @@ -225,7 +228,19 @@ posix_lookup (call_frame_t *frame, xlator_t *this, "lstat on %s failed", real_path ? real_path : "null"); } - + if (loc_is_nameless(loc)) { + if (!op_errno) + op_errno = ESTALE; + loc_gfid (loc, gfid); + MAKE_HANDLE_ABSPATH (gfid_path, this, gfid); + op_ret = sys_lstat(gfid_path, &statbuf); + if (op_ret == 0 && statbuf.st_nlink == 1) { + gf_msg (this->name, GF_LOG_WARNING, ESTALE, + P_MSG_HANDLE_DELETE, "Found stale gfid " + "handle %s, removing it.", gfid_path); + posix_handle_unset (this, gfid, NULL); + } + } entry_ret = -1; goto parent; } -- cgit