@@ -550,8 +550,9 @@ pub(crate) async fn handle_cow_write(
550550 None => return NotifAction :: Continue ,
551551 } ;
552552
553- // Phase 1: check if we need to pre-copy a file (under lock, no heavy I/O)
554- let ( copy_plan, copy_workdir, copy_rel) = {
553+ // Phase 1: check if we need to pre-copy a file (under lock, no heavy I/O).
554+ // Capture both layer roots here so Phase 2 needs no second lock.
555+ let ( copy_plan, copy_workdir, copy_upper, copy_rel) = {
555556 let mut st = cow_state. lock ( ) . await ;
556557 let cow = match st. branch . as_mut ( ) {
557558 Some ( c) => c,
@@ -562,30 +563,21 @@ pub(crate) async fn handle_cow_write(
562563 match cow_copy_rel ( & op, cow) {
563564 Some ( ( _match_path, ref rel) ) => {
564565 let workdir = cow. workdir ( ) . to_path_buf ( ) ;
566+ let upper = cow. upper_dir ( ) . to_path_buf ( ) ;
565567 match cow. prepare_copy ( rel) {
566- Ok ( plan) => ( Some ( plan) , workdir, rel. clone ( ) ) ,
568+ Ok ( plan) => ( Some ( plan) , workdir, upper , rel. clone ( ) ) ,
567569 Err ( crate :: error:: BranchError :: QuotaExceeded ) => return NotifAction :: Errno ( libc:: ENOSPC ) ,
568570 Err ( _) => return NotifAction :: Continue ,
569571 }
570572 }
571- None => ( None , std:: path:: PathBuf :: new ( ) , String :: new ( ) ) ,
573+ None => ( None , std:: path:: PathBuf :: new ( ) , std :: path :: PathBuf :: new ( ) , String :: new ( ) ) ,
572574 }
573575 } ;
574576 // Lock is released here
575577
576578 // Phase 2: execute the file copy outside the lock (if needed)
577579 if let Some ( crate :: cow:: seccomp:: CowCopyPlan :: NeedsCopy { upper, lower : _lower, file_size } ) = copy_plan {
578- // copy_workdir is workdir_root; we need upper_root for the dest side.
579- // Re-acquire it briefly: execute_deferred_copy needs both roots.
580- let uroot = {
581- let st = cow_state. lock ( ) . await ;
582- st. branch . as_ref ( ) . map ( |c| c. upper_dir ( ) . to_path_buf ( ) )
583- } ;
584- let uroot = match uroot {
585- Some ( p) => p,
586- None => return NotifAction :: Continue ,
587- } ;
588- if execute_deferred_copy ( cow_state, copy_workdir, uroot, copy_rel, upper, file_size) . await . is_none ( ) {
580+ if execute_deferred_copy ( cow_state, copy_workdir, copy_upper, copy_rel, upper, file_size) . await . is_none ( ) {
589581 return NotifAction :: Continue ;
590582 }
591583 }
0 commit comments