From 6fb3260d59faab1e20ebf1e44f850f85f6b8342a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 18 Jul 2014 23:16:09 -0700 Subject: [PATCH] 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 --- src/os/LFNIndex.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/os/LFNIndex.cc b/src/os/LFNIndex.cc index f6c56d489539e..c021668f15921 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; -- 2.39.5