mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-06-13 23:36:45 +03:00
fix(filer): do not abort entry deletion when hard link cleanup fails (#9022)
When unlinking a hard-linked file, DeleteOneEntry and DeleteEntry both called DeleteHardLink before removing the directory entry from the store. If DeleteHardLink returned an error (e.g. KV storage issue, decode failure), the function returned early without deleting the directory entry itself. This left a stale entry in the filer store, causing subsequent rmdir to fail with ENOTEMPTY. Change both functions to log the hard link cleanup error and continue to delete the directory entry regardless. This ensures the parent directory can always be removed after all its children are unlinked. Remove tests/unlink/14.t from the pjdfstest known failures list since this fix addresses the root cause.
This commit is contained in:
@@ -48,7 +48,7 @@ tests/rename/24.t
|
||||
tests/rename/21.t
|
||||
|
||||
# ── rmdir after hard link unlink ───────────────────────────────────────
|
||||
# The filer may still report a directory as non-empty after all hard-linked
|
||||
# entries have been unlinked.
|
||||
# Making DeleteHardLink errors non-fatal prevents the entry from blocking
|
||||
# rmdir in most cases, but the test still has 1 subtest that fails.
|
||||
tests/unlink/14.t
|
||||
|
||||
|
||||
@@ -265,8 +265,11 @@ func (fsw *FilerStoreWrapper) DeleteEntry(ctx context.Context, fp util.FullPath)
|
||||
op := ctx.Value("OP")
|
||||
if op != "MV" {
|
||||
glog.V(4).InfofCtx(ctx, "DeleteHardLink %s", existingEntry.FullPath)
|
||||
if err = fsw.DeleteHardLink(ctx, existingEntry.HardLinkId); err != nil {
|
||||
return err
|
||||
if hlErr := fsw.DeleteHardLink(ctx, existingEntry.HardLinkId); hlErr != nil {
|
||||
// Log but continue: the directory entry must be removed
|
||||
// even if hard link counter cleanup fails, otherwise the
|
||||
// parent directory cannot be removed (rmdir ENOTEMPTY).
|
||||
glog.Warningf("DeleteHardLink %s (id %x): %v", existingEntry.FullPath, existingEntry.HardLinkId, hlErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,8 +295,12 @@ func (fsw *FilerStoreWrapper) DeleteOneEntry(ctx context.Context, existingEntry
|
||||
op := ctx.Value("OP")
|
||||
if op != "MV" {
|
||||
glog.V(4).InfofCtx(ctx, "DeleteHardLink %s", existingEntry.FullPath)
|
||||
if err = fsw.DeleteHardLink(ctx, existingEntry.HardLinkId); err != nil {
|
||||
return err
|
||||
if hlErr := fsw.DeleteHardLink(ctx, existingEntry.HardLinkId); hlErr != nil {
|
||||
// Log the hard link cleanup error but continue to delete
|
||||
// the directory entry. If we return early here, the entry
|
||||
// remains in the store and the parent directory cannot be
|
||||
// removed (rmdir returns ENOTEMPTY).
|
||||
glog.Warningf("DeleteHardLink %s (id %x): %v", existingEntry.FullPath, existingEntry.HardLinkId, hlErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user