Add support for rmdir
This commit is contained in:
parent
59dba8a2e1
commit
e709db8003
@ -307,7 +307,7 @@ impl Filesystem for OliveFilesystem {
|
||||
reply.error(ENOENT);
|
||||
return;
|
||||
}
|
||||
.to_owned();
|
||||
.to_owned();
|
||||
|
||||
let requester = self.requester.clone();
|
||||
|
||||
@ -337,11 +337,40 @@ impl Filesystem for OliveFilesystem {
|
||||
|
||||
/// Remove a directory.
|
||||
fn rmdir(&mut self, _req: &Request<'_>, parent: u64, name: &OsStr, reply: ReplyEmpty) {
|
||||
debug!(
|
||||
"[Not Implemented] rmdir(parent: {:#x?}, name: {:?})",
|
||||
parent, name,
|
||||
let name = if let Some(name) = name.to_str() {
|
||||
name
|
||||
} else {
|
||||
// If we can't decode the filename, pretend it doesn't exist.
|
||||
error!("rmdir: Filename not convertible.");
|
||||
reply.error(ENOENT);
|
||||
return;
|
||||
}
|
||||
.to_owned();
|
||||
|
||||
let requester = self.requester.clone();
|
||||
|
||||
self.spawn_with_error_handler(
|
||||
async move {
|
||||
let parent_vnode = VnodeId(
|
||||
parent
|
||||
.try_into()
|
||||
.context("Converting u64 inode to u32 VnodeId.")?,
|
||||
);
|
||||
|
||||
match requester.rmdir(parent_vnode, name).await? {
|
||||
DataResponse::Success(()) => {
|
||||
reply.ok();
|
||||
}
|
||||
DataResponse::Error { code, message } => {
|
||||
warn!("rmdir(parent: {:#x?}) failed: {:?}", parent_vnode, message);
|
||||
reply.error(code as c_int);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
},
|
||||
"rmdir",
|
||||
);
|
||||
reply.error(ENOSYS);
|
||||
}
|
||||
|
||||
/// Create a symbolic link.
|
||||
|
@ -232,6 +232,16 @@ impl Requester {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn rmdir(
|
||||
&self,
|
||||
dir_vnode: VnodeId,
|
||||
name: String,
|
||||
) -> anyhow::Result<DataResponse<()>> {
|
||||
self.internal
|
||||
.command(&DataCommand::RemoveDirectory { dir_vnode, name })
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn open(&self, vnode: VnodeId, mode: OpenMode) -> anyhow::Result<DataResponse<u32>> {
|
||||
self.internal
|
||||
.command(&DataCommand::OpenFile { vnode, mode })
|
||||
|
@ -99,6 +99,10 @@ pub enum DataCommand {
|
||||
dir_vnode: VnodeId,
|
||||
name: String,
|
||||
},
|
||||
RemoveDirectory {
|
||||
dir_vnode: VnodeId,
|
||||
name: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
|
@ -144,7 +144,7 @@ pub async fn handle_command_stream(
|
||||
.await
|
||||
.unwrap_or_else(error_to_response),
|
||||
)
|
||||
.await?;
|
||||
.await?;
|
||||
}
|
||||
DataCommand::Unlink { dir_vnode, name } => {
|
||||
send_bare_message(
|
||||
@ -154,7 +154,17 @@ pub async fn handle_command_stream(
|
||||
.await
|
||||
.unwrap_or_else(error_to_response),
|
||||
)
|
||||
.await?;
|
||||
.await?;
|
||||
}
|
||||
DataCommand::RemoveDirectory { dir_vnode, name } => {
|
||||
send_bare_message(
|
||||
&mut tx,
|
||||
&file_access
|
||||
.rmdir(dir_vnode, name)
|
||||
.await
|
||||
.unwrap_or_else(error_to_response),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -778,4 +778,20 @@ impl FileAccess {
|
||||
tokio::fs::remove_file(&target_path).await?;
|
||||
Ok(DataResponse::Success(()))
|
||||
}
|
||||
|
||||
/// Symlink safety:
|
||||
/// Makes an attempt to safely resolve symlinks, but there is a possibility of a TOCTOU race.
|
||||
/// TODO Revisit later for safety.
|
||||
pub async fn rmdir(
|
||||
&self,
|
||||
dir_vnode: VnodeId,
|
||||
name: String,
|
||||
) -> anyhow::Result<DataResponse<()>> {
|
||||
let parent_dir_resolved = self
|
||||
.resolve_vnode_including_follow_symlinks_safely_best_effort(dir_vnode)
|
||||
.await?;
|
||||
let target_path = parent_dir_resolved.join(name);
|
||||
tokio::fs::remove_dir(&target_path).await?;
|
||||
Ok(DataResponse::Success(()))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user