From: Sage Weil Date: Sat, 19 Jul 2014 06:16:09 +0000 (-0700) Subject: os/LFNIndex: only consider alt xattr if nlink > 1 X-Git-Tag: v0.84~71^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6fb3260d59faab1e20ebf1e44f850f85f6b8342a;p=ceph.git os/LFNIndex: only consider alt xattr if nlink > 1 If we are doing a lookup, the main xattr fails, we'll check if there is an alt xattr. If it exists, but the nlink on the inode is only 1, we will kill the xattr. This cleans up the mess left over by an incomplete lfn_unlink operation. This resolves the problem with an lfn_link to a second long name that hashes to the same short_name: we will ignore the old name the moment the old link goes away. Fixes: #8701 Signed-off-by: Sage Weil --- diff --git a/src/os/LFNIndex.cc b/src/os/LFNIndex.cc index f6c56d489539..c021668f1592 100644 --- a/src/os/LFNIndex.cc +++ b/src/os/LFNIndex.cc @@ -799,6 +799,23 @@ int LFNIndex::lfn_get_name(const vector &path, r = chain_getxattr(candidate_path.c_str(), get_alt_lfn_attr().c_str(), buf, sizeof(buf)); if (r > 0) { + // only consider alt name if nlink > 1 + struct stat st; + int rc = ::stat(candidate_path.c_str(), &st); + if (rc < 0) + return -errno; + if (st.st_nlink <= 1) { + // left over from incomplete unlink, remove + maybe_inject_failure(); + dout(20) << __func__ << " found extra alt attr for " << candidate_path + << ", long name " << string(buf, r) << dendl; + rc = chain_removexattr(candidate_path.c_str(), + get_alt_lfn_attr().c_str()); + maybe_inject_failure(); + if (rc < 0) + return rc; + continue; + } buf[MIN((int)sizeof(buf) - 1, r)] = '\0'; if (!strcmp(buf, full_name.c_str())) { dout(20) << __func__ << " used alt attr for " << full_name << dendl;