refactor(tvix/store/fs): reduce write lock, return children
Very similar to the previous CL Change-Id: I0df07ddca742b7b9485d48771c8d295dc3aa7136 Reviewed-on: https://cl.tvl.fyi/c/depot/+/9979 Tested-by: BuildkiteCI Reviewed-by: Connor Brewster <cbrewster@hey.com>
This commit is contained in:
parent
2405399580
commit
9e6d89983a
1 changed files with 56 additions and 47 deletions
|
@ -441,65 +441,74 @@ impl FileSystem for TvixStoreFs {
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookup the inode data.
|
// lookup the inode data.
|
||||||
let mut inode_tracker = self.inode_tracker.write();
|
let dir_inode_data = {
|
||||||
let dir_inode_data = inode_tracker.get(inode).unwrap();
|
let inode_tracker = self.inode_tracker.read();
|
||||||
let dir_inode_data = match *dir_inode_data {
|
inode_tracker.get(inode).unwrap()
|
||||||
InodeData::Regular(..) | InodeData::Symlink(..) => {
|
};
|
||||||
warn!("Not a directory");
|
|
||||||
return Err(io::Error::from_raw_os_error(libc::ENOTDIR));
|
let children = match *dir_inode_data {
|
||||||
|
InodeData::Directory(DirectoryInodeData::Populated(ref _digest, ref children)) => {
|
||||||
|
children.to_vec()
|
||||||
}
|
}
|
||||||
InodeData::Directory(DirectoryInodeData::Sparse(ref directory_digest, _)) => {
|
InodeData::Directory(DirectoryInodeData::Sparse(ref directory_digest, _)) => {
|
||||||
let directory_digest = directory_digest.to_owned();
|
match self
|
||||||
let directory_service = self.directory_service.clone();
|
.tokio_handle
|
||||||
let task = self.tokio_handle.spawn(async move {
|
.block_on(self.tokio_handle.spawn({
|
||||||
fetch_directory_inode_data(directory_service, &directory_digest).await
|
let directory_digest = directory_digest.to_owned();
|
||||||
});
|
let directory_service = self.directory_service.clone();
|
||||||
match self.tokio_handle.block_on(task).unwrap() {
|
async move {
|
||||||
Ok(new_data) => {
|
fetch_directory_inode_data(directory_service, &directory_digest).await
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
Ok(
|
||||||
|
ref new_data @ InodeData::Directory(DirectoryInodeData::Populated(
|
||||||
|
ref _digest,
|
||||||
|
ref children,
|
||||||
|
)),
|
||||||
|
) => {
|
||||||
// update data in [self.inode_tracker] with populated variant.
|
// update data in [self.inode_tracker] with populated variant.
|
||||||
// FUTUREWORK: change put to return the data after
|
{
|
||||||
// inserting, so we don't need to lookup a second
|
let mut inode_tracker = self.inode_tracker.write();
|
||||||
// time?
|
inode_tracker.put(new_data.clone());
|
||||||
let ino = inode_tracker.put(new_data.clone());
|
}
|
||||||
inode_tracker.get(ino).unwrap()
|
children.to_vec()
|
||||||
}
|
}
|
||||||
|
// we know fetch_directory_inode_data only returns InodeData::Directory(DirectoryInodeData::Populated(..))
|
||||||
|
Ok(_) => panic!("unexpected type"),
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
return Err(io::Error::from_raw_os_error(libc::EIO));
|
return Err(io::Error::from_raw_os_error(libc::EIO));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InodeData::Directory(DirectoryInodeData::Populated(..)) => dir_inode_data,
|
InodeData::Regular(..) | InodeData::Symlink(..) => {
|
||||||
|
return Err(io::Error::from_raw_os_error(libc::ENOTDIR));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// now parent_data can only be InodeData::Directory(DirectoryInodeData::Populated(..))
|
for (i, (ino, child_node)) in children.iter().skip(offset as usize).enumerate() {
|
||||||
if let InodeData::Directory(DirectoryInodeData::Populated(ref _digest, ref children)) =
|
// the second parameter will become the "offset" parameter on the next call.
|
||||||
*dir_inode_data
|
let written = add_entry(fuse_backend_rs::api::filesystem::DirEntry {
|
||||||
{
|
ino: *ino,
|
||||||
for (i, (ino, child_node)) in children.iter().skip(offset as usize).enumerate() {
|
offset: offset + i as u64 + 1,
|
||||||
// the second parameter will become the "offset" parameter on the next call.
|
type_: match child_node {
|
||||||
let written = add_entry(fuse_backend_rs::api::filesystem::DirEntry {
|
#[allow(clippy::unnecessary_cast)]
|
||||||
ino: *ino,
|
// libc::S_IFDIR is u32 on Linux and u16 on MacOS
|
||||||
offset: offset + i as u64 + 1,
|
Node::Directory(_) => libc::S_IFDIR as u32,
|
||||||
type_: match child_node {
|
#[allow(clippy::unnecessary_cast)]
|
||||||
#[allow(clippy::unnecessary_cast)]
|
// libc::S_IFDIR is u32 on Linux and u16 on MacOS
|
||||||
// libc::S_IFDIR is u32 on Linux and u16 on MacOS
|
Node::File(_) => libc::S_IFREG as u32,
|
||||||
Node::Directory(_) => libc::S_IFDIR as u32,
|
#[allow(clippy::unnecessary_cast)]
|
||||||
#[allow(clippy::unnecessary_cast)]
|
// libc::S_IFDIR is u32 on Linux and u16 on MacOS
|
||||||
// libc::S_IFDIR is u32 on Linux and u16 on MacOS
|
Node::Symlink(_) => libc::S_IFLNK as u32,
|
||||||
Node::File(_) => libc::S_IFREG as u32,
|
},
|
||||||
#[allow(clippy::unnecessary_cast)]
|
name: child_node.get_name(),
|
||||||
// libc::S_IFDIR is u32 on Linux and u16 on MacOS
|
})?;
|
||||||
Node::Symlink(_) => libc::S_IFLNK as u32,
|
// If the buffer is full, add_entry will return `Ok(0)`.
|
||||||
},
|
if written == 0 {
|
||||||
name: child_node.get_name(),
|
break;
|
||||||
})?;
|
|
||||||
// If the buffer is full, add_entry will return `Ok(0)`.
|
|
||||||
if written == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
panic!("unexpected type")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Add table
Reference in a new issue