I'm working on a fuse filesystem using fuse_mt
. In the process, I'm implementing a method of the FileSystemMT
trait that looks like this:
fn opendir(&self, _req: RequestInfo, _path: &Path, _flags: u32) -> ResultOpen {
Err(libc::ENOSYS)
}
opendir
is supposed to return a unique handle that identifies the directory.
In my implementation, I wanted to maintain a HashMap of directory handles that I can return when opendir is called. I have the following struct:
pub struct RtFS {
pub rt: Box<Artifactory>,
pub repo: String,
_dir_handles: HashMap<u64, String>,
_last_dir_handle: u64,
_last_file_handle: u64,
}
My plan was to initialize _last_dir_handle
with a random value, then increment it for each opendir call. Then, I would store each allocated handle in the _dir_handles
HashMap. This is where I ran into a problem. If I attempt to do this in the opendir function:
self._last_dir_handle += 1;
self._dir_handles.insert(
self._last_dir_handle,
path.to_str().expect("Could not convert path").to_string(),
);
then the borrow checker will (unsurprisingly) complain:
error[E0594]: cannot assign to `self._last_dir_handle` which is behind a `&` reference │
--> src/rtfs.rs:117:7 │
| │
110 | fn opendir(&self, _req: RequestInfo, path: &Path, _flags: u32) -> ResultOpen { │
| ----- help: consider changing this to be a mutable reference: `&mut self` │
... │
117 | self._last_dir_handle += 1; │
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written │
│
error[E0596]: cannot borrow `self._dir_handles` as mutable, as it is behind a `&` reference │
--> src/rtfs.rs:118:7 │
| │
110 | fn opendir(&self, _req: RequestInfo, path: &Path, _flags: u32) -> ResultOpen { │
| ----- help: consider changing this to be a mutable reference: `&mut self` │
... │
118 | self._dir_handles.insert( │
| ^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Adding mut
like the message suggests is not a solution because then the function won't match the trait. How can I solve this? I considered moving the state to the module level, but theoretically there could be more instances and I don't want them to clash.