Skip to content

Commit 30b8ac5

Browse files
committed
Fix double external path export bug
We don't want to move the file from an external location, but copy if external!
1 parent 49ab2b7 commit 30b8ac5

File tree

1 file changed

+40
-27
lines changed

1 file changed

+40
-27
lines changed

src/store/fs.rs

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,18 +1239,21 @@ async fn export_path_impl(
12391239
}
12401240
};
12411241
trace!("exporting {} to {}", cmd.hash.to_hex(), target.display());
1242-
let data = match data_location {
1243-
DataLocation::Inline(data) => MemOrFile::Mem(data),
1244-
DataLocation::Owned(size) => {
1245-
MemOrFile::File((ctx.options().path.data_path(&cmd.hash), size))
1246-
}
1247-
DataLocation::External(paths, size) => MemOrFile::File((
1248-
paths
1249-
.into_iter()
1250-
.next()
1251-
.ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "no external data path"))?,
1252-
size,
1253-
)),
1242+
let (data, external) = match data_location {
1243+
DataLocation::Inline(data) => (MemOrFile::Mem(data), false),
1244+
DataLocation::Owned(size) => (
1245+
MemOrFile::File((ctx.options().path.data_path(&cmd.hash), size)),
1246+
false,
1247+
),
1248+
DataLocation::External(paths, size) => (
1249+
MemOrFile::File((
1250+
paths.into_iter().next().ok_or_else(|| {
1251+
io::Error::new(io::ErrorKind::NotFound, "no external data path")
1252+
})?,
1253+
size,
1254+
)),
1255+
true,
1256+
),
12541257
};
12551258
let size = match &data {
12561259
MemOrFile::Mem(data) => data.len() as u64,
@@ -1274,24 +1277,34 @@ async fn export_path_impl(
12741277
);
12751278
}
12761279
ExportMode::TryReference => {
1277-
match std::fs::rename(&source_path, &target) {
1278-
Ok(()) => {}
1279-
Err(cause) => {
1280-
const ERR_CROSS: i32 = 18;
1281-
if cause.raw_os_error() == Some(ERR_CROSS) {
1282-
let source = fs::File::open(&source_path)?;
1283-
let mut target = fs::File::create(&target)?;
1284-
copy_with_progress(&source, size, &mut target, tx).await?;
1285-
} else {
1286-
return Err(cause.into());
1280+
if external {
1281+
let res =
1282+
reflink_or_copy_with_progress(&source_path, &target, size, tx).await?;
1283+
trace!(
1284+
"exported {} also to {}, {res:?}",
1285+
source_path.display(),
1286+
target.display()
1287+
);
1288+
} else {
1289+
match std::fs::rename(&source_path, &target) {
1290+
Ok(()) => {}
1291+
Err(cause) => {
1292+
const ERR_CROSS: i32 = 18;
1293+
if cause.raw_os_error() == Some(ERR_CROSS) {
1294+
let source = fs::File::open(&source_path)?;
1295+
let mut target = fs::File::create(&target)?;
1296+
copy_with_progress(&source, size, &mut target, tx).await?;
1297+
} else {
1298+
return Err(cause.into());
1299+
}
12871300
}
12881301
}
1302+
ctx.set(EntryState::Complete {
1303+
data_location: DataLocation::External(vec![target], size),
1304+
outboard_location,
1305+
})
1306+
.await?;
12891307
}
1290-
ctx.set(EntryState::Complete {
1291-
data_location: DataLocation::External(vec![target], size),
1292-
outboard_location,
1293-
})
1294-
.await?;
12951308
}
12961309
},
12971310
}

0 commit comments

Comments
 (0)