diff --git a/test/pjdfstest/known_failures.txt b/test/pjdfstest/known_failures.txt index 7eafe800c..d16be3e94 100644 --- a/test/pjdfstest/known_failures.txt +++ b/test/pjdfstest/known_failures.txt @@ -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 diff --git a/weed/filer/filerstore_wrapper.go b/weed/filer/filerstore_wrapper.go index d782281e0..9b39d5eee 100644 --- a/weed/filer/filerstore_wrapper.go +++ b/weed/filer/filerstore_wrapper.go @@ -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) } } }