From: Sage Weil Date: Sat, 19 Jul 2014 00:28:18 +0000 (-0700) Subject: os/LFNIndex: remove alt xattr after unlink X-Git-Tag: v0.84~71^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ec36f0a130d67df6cbeefcc9c2d83eb703b6b28c;p=ceph.git os/LFNIndex: remove alt xattr after unlink After we unlink, if the nlink on the inode is still non-zero, remove the alt xattr. We can *only* do this after the rename or unlink operation because we don't want to leave a file system link in place without the matching xattr; hence the fsync_dir() call. Note that this might leak an alt xattr if we happen to fail after the rename/unlink but before the removexattr is committed. We'll fix that next. Signed-off-by: Sage Weil --- diff --git a/src/os/LFNIndex.cc b/src/os/LFNIndex.cc index 6f14589ac15f..f6c56d489539 100644 --- a/src/os/LFNIndex.cc +++ b/src/os/LFNIndex.cc @@ -883,15 +883,19 @@ int LFNIndex::lfn_unlink(const vector &path, } } } + string full_path = get_full_path(path, mangled_name); + int fd = ::open(full_path.c_str(), O_RDONLY); + if (fd < 0) + return -errno; + FDCloser f(fd); if (i == removed_index + 1) { - string full_path = get_full_path(path, mangled_name); maybe_inject_failure(); int r = ::unlink(full_path.c_str()); maybe_inject_failure(); if (r < 0) return -errno; } else { - string rename_to = get_full_path(path, mangled_name); + string& rename_to = full_path; string rename_from = get_full_path(path, lfn_get_short_name(oid, i - 1)); maybe_inject_failure(); int r = ::rename(rename_from.c_str(), rename_to.c_str()); @@ -899,7 +903,15 @@ int LFNIndex::lfn_unlink(const vector &path, if (r < 0) return -errno; } - return 0; + struct stat st; + int r = ::fstat(fd, &st); + if (r == 0 && st.st_nlink > 0) { + // remove alt attr + dout(20) << __func__ << " removing alt attr from " << full_path << dendl; + fsync_dir(path); + chain_fremovexattr(fd, get_alt_lfn_attr().c_str()); + } + return r; } int LFNIndex::lfn_translate(const vector &path,