From 19d2e0e34b5f100fdbec1da8373badd624c02248 Mon Sep 17 00:00:00 2001 From: Tom Keiser Date: Thu, 14 Oct 2010 01:24:03 -0400 Subject: [PATCH] vol: make namei_ListAFSSubDirs deal with multiple/bad linktables The salvager ends up deadlocking when multiple linktables exist in the same volume group special directory. The issue is that we open and flock all discovered linktables, but only close out the last one found. Consequently, when our child scans the linktables again, we deadlock against the locked and leaked descriptor(s) our parent left around before forking. While we have so far been unable to root-cause the actual creation of spurious linktables, this patch will at least stop the salvager from deadlocking against itself when this occurs. Change-Id: I67821f2c99663c56e4ec0b008e1d2d3a8751df0e Reviewed-on: http://gerrit.openafs.org/2979 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/vol/namei_ops.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/vol/namei_ops.c b/src/vol/namei_ops.c index 9d5eda6324..8a3b2e8158 100644 --- a/src/vol/namei_ops.c +++ b/src/vol/namei_ops.c @@ -1846,14 +1846,31 @@ _namei_examine_special(char * path1, { int ret = 0; struct ViceInodeInfo info; + afs_uint32 inode_vgid; if (DecodeInode(path1, dname, &info, myIH->ih_vid) < 0) { ret = 0; goto error; } +#ifdef AFS_NT40_ENV + inode_vgid = myIH->ih_vid; +#else + inode_vgid = (info.inodeNumber >> NAMEI_UNIQSHIFT) & NAMEI_UNIQMASK; +#endif + if (info.u.param[2] != VI_LINKTABLE) { info.linkCount = 1; + } else if ((info.u.param[0] != myIH->ih_vid) || + (inode_vgid != myIH->ih_vid)) { + /* VGID encoded in linktable filename and/or OGM data isn't + * consistent with VGID encoded in namei path */ + Log("namei_ListAFSSubDirs: warning: inconsistent linktable " + "filename \"%s/%s\"; salvager will delete it " + "(dir_vgid=%u, inode_vgid=%u, ogm_vgid=%u)\n", + path1, dname, myIH->ih_vid, + (unsigned int)inode_vgid, + info.u.param[0]); } else { char path2[512]; /* Open this handle */ @@ -2414,6 +2431,11 @@ namei_ListAFSSubDirs(IHandle_t * dirIH, ninodes += code; #endif + if (linkHandle.fd_fd == INVALID_FD) { + Log("namei_ListAFSSubDirs: warning: VG %u does not have a link table; " + "salvager will recreate it.\n", dirIH->ih_vid); + } + /* Now run through all the other subdirs */ namei_HandleToVolDir(&name, &myIH); strlcpy(path1, name.n_path, sizeof(path1));