/// Recursively copies `src` to `dst` using the given permission policy for
/// files. Directories containing a file called "tombstone" are not copied to
/// the destination.
///
/// NOTE: If the function returns an error, the changes to the file
/// system applied by this function are not undone.
Recursively copies `src` to `dst` using the given permission policy for
files. Directories containing a file called "tombstone" are not copied to
the destination.

If the function returns an error, the changes to the file
system applied by this function are not undone.
Recursively copies ` src ` to ` dst ` using the given permission policy for files . Directories containing a file called " tombstone " are not copied to the destination . If the function returns an error the changes to the file system applied by this function are not undone .
fn copy_recursively_respecting_tombstones(
    log: &ReplicaLogger,
    src: &Path,
    dst: &Path,
    dst_permissions: FilePermissions,
) -> std::io::Result<()> {
    let src_metadata = src.metadata()?;
    if src_metadata.is_dir() {
        if src.join("tombstone").exists() {
            // The source directory was marked as removed by placing a
            // 'tombstone' file inside. We don't want this directory in
            // a checkpoint.
            return Ok(());
        }
        let entries = src.read_dir()?;
        // Note: all the files and directories below DST and DST itself will be
        // synced after this function returns.  However, create_dir_all might
        // create some parents that won't be synced. It's fine because
        //
        //   1. We only care about internal consistency of checkpoints, and the
        //   parents create_dir_all might have created do not belong to a
        //   checkpoint.
        //
        //   2. We only invoke this function with DST being a child of a
        //   directory that is wiped out on replica start, so we don't care much
        //   about this temporary directory being properly synced.
        fs::create_dir_all(&dst)?;
        for entry_result in entries {
            let entry = entry_result?;
            let dst_entry = dst.join(entry.file_name());
            copy_recursively_respecting_tombstones(
                log,
                &entry.path(),
                &dst_entry,
                dst_permissions,
            )?;
        }
    } else {
        do_copy(log, src, dst)?;
        // We keep the directory writable though to make sure we can rename
        // them or delete the files.
        let dst_metadata = dst.metadata()?;
        let mut permissions = dst_metadata.permissions();
        match dst_permissions {
            FilePermissions::ReadOnly => permissions.set_readonly(true),
            FilePermissions::ReadWrite => permissions.set_readonly(false),
        }
        fs::set_permissions(dst, permissions)?;
    }
    // Note that the directory is synced after all the files and directories in
    // it had been recursively synced.
    sync_path(dst)
}
fn copy_recursively_respecting_tombstones ( log : & ReplicaLogger , src : & Path , dst : & Path , dst_permissions : FilePermissions , ) -> std :: io :: Result < ( ) > { let src_metadata = src . metadata ( ) ? ; if src_metadata . is_dir ( ) { if src . join ( " " ) . exists ( ) { // The source directory was marked as removed by placing a // 'tombstone' file inside. We don't want this directory in // a checkpoint. return Ok ( ( ) ) ; } let entries = src . read_dir ( ) ? ; // Note: all the files and directories below DST and DST itself will be // synced after this function returns.  However, create_dir_all might // create some parents that won't be synced. It's fine because // //   1. We only care about internal consistency of checkpoints, and the //   parents create_dir_all might have created do not belong to a //   checkpoint. // //   2. We only invoke this function with DST being a child of a //   directory that is wiped out on replica start, so we don't care much //   about this temporary directory being properly synced. fs :: create_dir_all ( & dst ) ? ; for entry_result in entries { let entry = entry_result ? ; let dst_entry = dst . join ( entry . file_name ( ) ) ; copy_recursively_respecting_tombstones ( log , & entry . path ( ) , & dst_entry , dst_permissions , ) ? ; } } else { do_copy ( log , src , dst ) ? ; // We keep the directory writable though to make sure we can rename // them or delete the files. let dst_metadata = dst . metadata ( ) ? ; let mut permissions = dst_metadata . permissions ( ) ; match dst_permissions { FilePermissions :: ReadOnly => permissions . set_readonly ( true ) , FilePermissions :: ReadWrite => permissions . set_readonly ( false ) , } fs :: set_permissions ( dst , permissions ) ? ; } // Note that the directory is synced after all the files and directories in // it had been recursively synced. sync_path ( dst ) }
Recursively copies `src` to `dst` using the given permission policy for
files.
Recursively copies ` src ` to ` dst ` using the given permission policy for files .
log
&ReplicaLogger
src
&Path
dst
&Path
dst_permissions
FilePermissions