diff options
| author | Ravishankar N <ravishankar@redhat.com> | 2018-01-16 10:16:41 +0530 | 
|---|---|---|
| committer | Shyamsundar Ranganathan <srangana@redhat.com> | 2018-01-18 18:21:37 +0000 | 
| commit | f731824440c218999437412c569bacacf213d191 (patch) | |
| tree | 23ff52885ccb8671457567a9a3c0271391fff28b | |
| parent | 9601ff350dd309714ec3fa746a86e13ac1165591 (diff) | |
posix: delete stale gfid handles in nameless lookup
..in order for self-heal of symlinks to work properly (see BZ for
details).
Backport of https://review.gluster.org/#/c/19070/
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Change-Id: I9a011d00b07a690446f7fd3589e96f840e8b7501
BUG: 1534848
| -rw-r--r-- | tests/bugs/heal-symlinks.t | 65 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 17 | 
2 files changed, 81 insertions, 1 deletions
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.c b/xlators/storage/posix/src/posix.c index 3fd58b62454..e5ea5388fe5 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -156,7 +156,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; @@ -205,7 +208,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;          }  | 
