Skip to content

Commit d2ec9cb

Browse files
zyfjeffjiangliu
authored andcommitted
Implement the func of invalidate cache on the specified file name.
Use the invalidate entry provided by the fuse kernel to clear the entry cache, all code references the libfuse implementation. ref: https://github.com/libfuse/libfuse/blob/f44214be6a2abb4c98f61790cae565c06bdb431c/lib/fuse_lowlevel.c#L2332 Signed-off-by: zyfjeff <zyfjeff@linux.alibaba.com>
1 parent b1ab3d5 commit d2ec9cb

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

src/api/server/sync_io.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,44 @@ use crate::abi::virtio_fs::{RemovemappingIn, RemovemappingOne, SetupmappingIn};
1919
use crate::api::filesystem::{
2020
DirEntry, Entry, FileSystem, GetxattrReply, IoctlData, ListxattrReply,
2121
};
22+
#[cfg(feature = "fusedev")]
23+
use crate::transport::FuseDevWriter;
2224
use crate::transport::{pagesize, FsCacheReqHandler, Reader, Writer};
2325
use crate::{bytes_to_cstr, encode_io_error_kind, BitmapSlice, Error, Result};
2426

2527
impl<F: FileSystem + Sync> Server<F> {
28+
#[cfg(feature = "fusedev")]
29+
/// Use to send notify msg to kernel fuse
30+
pub fn notify_inval_entry<S: BitmapSlice>(
31+
&self,
32+
mut w: FuseDevWriter<'_, S>,
33+
parent: u64,
34+
name: &std::ffi::CStr,
35+
) -> Result<usize> {
36+
let mut buffer_writer = w.split_at(0).map_err(Error::FailedToSplitWriter)?;
37+
let mut entry = NotifyInvalEntryOut::default();
38+
let mut header = OutHeader::default();
39+
let name_with_null = name.to_bytes_with_nul();
40+
header.unique = 0;
41+
header.error = NotifyOpcode::InvalEntry as i32;
42+
header.len = std::mem::size_of::<OutHeader>() as u32
43+
+ std::mem::size_of::<NotifyInvalEntryOut>() as u32
44+
+ name_with_null.len() as u32;
45+
// the namelne don't contains the nul
46+
entry.namelen = (name_with_null.len() - 1) as u32;
47+
entry.parent = parent;
48+
49+
buffer_writer
50+
.write_obj(header)
51+
.map_err(Error::FailedToWrite)?;
52+
buffer_writer
53+
.write_obj(entry)
54+
.map_err(Error::FailedToWrite)?;
55+
buffer_writer
56+
.write(name_with_null)
57+
.map_err(Error::FailedToWrite)?;
58+
buffer_writer.commit(None).map_err(Error::InvalidMessage)
59+
}
2660
/// Main entrance to handle requests from the transport layer.
2761
///
2862
/// It receives Fuse requests from transport layers, parses the request according to Fuse ABI,

src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ pub enum Error {
7676
InvalidXattrSize((u32, usize)),
7777
/// Invalid message that the server cannot handle properly.
7878
InvalidMessage(io::Error),
79+
/// Failed to write buffer to writer.
80+
FailedToWrite(io::Error),
81+
/// Failed to split a writer.
82+
FailedToSplitWriter(transport::Error),
7983
}
8084

8185
impl error::Error for Error {}
@@ -95,6 +99,8 @@ impl fmt::Display for Error {
9599
decoded value: size = {size}, value.len() = {len}"
96100
),
97101
InvalidMessage(err) => write!(f, "cannot process fuse message: {err}"),
102+
FailedToWrite(err) => write!(f, "cannot write to buffer: {err}"),
103+
FailedToSplitWriter(err) => write!(f, "cannot split a writer: {err}"),
98104
}
99105
}
100106
}

0 commit comments

Comments
 (0)