@@ -614,11 +614,21 @@ impl<OC: ObjectClient + Send + Sync + Clone> Metablock for Superblock<OC> {
614614 } ;
615615
616616 match write_status {
617- WriteStatus :: LocalUnopened | WriteStatus :: LocalOpen | WriteStatus :: PendingRename => {
617+ // Safe to delete - no upload has started yet.
618+ WriteStatus :: LocalUnopened => {
619+ debug ! (
620+ parent = parent_ino,
621+ ?name,
622+ "unlink on LocalUnopened file, no s3 cleanup needed" ,
623+ ) ;
624+ }
625+ WriteStatus :: LocalOpen | WriteStatus :: PendingRename => {
626+ // Active upload in progress - cannot safely delete without cancellation logic.
618627 // In the future, we may permit `unlink` and cancel any in-flight uploads.
619628 warn ! (
620629 parent = parent_ino,
621630 ?name,
631+ ?write_status,
622632 "unlink on local file not allowed until write is complete" ,
623633 ) ;
624634 return Err ( InodeError :: UnlinkNotPermittedWhileWriting ( inode. err ( ) ) ) ;
@@ -652,13 +662,19 @@ impl<OC: ObjectClient + Send + Sync + Clone> Metablock for Superblock<OC> {
652662 debug_assert ! ( false , "inodes never change kind" ) ;
653663 return Err ( InodeError :: NotADirectory ( parent. err ( ) ) ) ;
654664 }
655- InodeKindData :: Directory { children, .. } => {
665+ InodeKindData :: Directory {
666+ children,
667+ writing_children,
668+ ..
669+ } => {
656670 // We want to remove the original child.
657671 // If there is a mismatch in inode number between the existing inode and the deleted inode, we invalidate the existing inode's stat.
658672 // If for some reason the child with the specified name was already removed, we do nothing as this is the desired state.
659673 if let Some ( existing_inode) = children. get ( inode. name ( ) ) {
660674 if existing_inode. ino ( ) == inode. ino ( ) {
661675 children. remove ( inode. name ( ) ) ;
676+ // Also clean up writing_children for local files in LocalUnopened state
677+ writing_children. remove ( & inode. ino ( ) ) ;
662678 } else {
663679 // Mismatch in inode number, thus the existing inode might not be the same one we deleted
664680 let mut state = existing_inode. get_mut_inode_state_no_check ( ) ;
0 commit comments