use std::io::{Read, Write};
use tracing::debug;
use crate::protocol::rpc;
use crate::protocol::xdr::{self, deserialize, nfs3, Serialize};
pub async fn nfsproc3_readlink(
xid: u32,
input: &mut impl Read,
output: &mut impl Write,
context: &rpc::Context,
) -> Result<(), anyhow::Error> {
let handle = deserialize::<nfs3::nfs_fh3>(input)?;
debug!("nfsproc3_readlink({:?},{:?}) ", xid, handle);
let id = context.vfs.fh_to_id(&handle);
if let Err(stat) = id {
xdr::rpc::make_success_reply(xid).serialize(output)?;
stat.serialize(output)?;
nfs3::post_op_attr::None.serialize(output)?;
return Ok(());
}
let id = id.unwrap();
let symlink_attr = match context.vfs.getattr(id).await {
Ok(v) => v,
Err(stat) => {
xdr::rpc::make_success_reply(xid).serialize(output)?;
stat.serialize(output)?;
nfs3::post_op_attr::None.serialize(output)?;
return Ok(());
}
};
let symlink_attr = nfs3::post_op_attr::Some(symlink_attr);
match context.vfs.readlink(id).await {
Ok(path) => {
debug!(" {:?} --> {:?}", xid, path);
xdr::rpc::make_success_reply(xid).serialize(output)?;
nfs3::nfsstat3::NFS3_OK.serialize(output)?;
symlink_attr.serialize(output)?;
path.serialize(output)?;
}
Err(stat) => {
xdr::rpc::make_success_reply(xid).serialize(output)?;
stat.serialize(output)?;
symlink_attr.serialize(output)?;
}
}
Ok(())
}