Skip to content

Commit ba7b4a6

Browse files
committed
fuse_t_session: Correctly handle EOF
The fuse-t session uses a socket pair for communication but wasn't correctly handling EOF and so when trying to gracefully unmount it would just hang. This change simply deals with EOF in the channel and returns None when it occurs during header read and an error otherwise. Signed-off-by: Brian Olsen <[email protected]>
1 parent 402e7c5 commit ba7b4a6

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

src/transport/fusedev/fuse_t_session.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//! A FUSE session can have multiple FUSE channels so that FUSE requests are handled in parallel.
1010
1111
use std::fs::File;
12+
use std::io;
1213
use std::mem::size_of;
1314
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
1415
use std::os::unix::prelude::CommandExt;
@@ -259,12 +260,16 @@ impl FuseChannel {
259260
})
260261
}
261262

262-
fn read(&mut self, len: usize, offset: usize) -> Result<()> {
263+
fn read(&mut self, len: usize, offset: usize) -> Result<bool> {
263264
let read_buf = &mut self.buf[offset..offset + len];
264265
let mut total: usize = 0;
265266
let fd = self.file.as_raw_fd();
266267
while total < len {
267268
match read(fd, read_buf) {
269+
Ok(0) => {
270+
trace!("Read EOF");
271+
return Ok(true);
272+
}
268273
Ok(size) => {
269274
total += size;
270275
}
@@ -286,7 +291,7 @@ impl FuseChannel {
286291
}
287292
Errno::ENODEV => {
288293
info!("fuse filesystem umounted");
289-
return Ok(());
294+
return Ok(true);
290295
}
291296
e => {
292297
warn! {"read fuse dev failed on fd {}: {}", fd, e};
@@ -295,7 +300,7 @@ impl FuseChannel {
295300
},
296301
}
297302
}
298-
Ok(())
303+
Ok(false)
299304
}
300305

301306
/// Get next available FUSE request from the underlying fuse device file.
@@ -316,12 +321,19 @@ impl FuseChannel {
316321
let fd = self.file.as_raw_fd();
317322
let size = size_of::<InHeader>();
318323
// read header
319-
self.read(size, 0)?;
324+
if self.read(size, 0)? {
325+
return Ok(None);
326+
}
320327
let in_header = InHeader::from_slice(&self.buf[0..size]);
321328
let header_len = in_header.unwrap().len as usize;
322329
let should_read_size = header_len - size;
323330
if should_read_size > 0 {
324-
self.read(should_read_size, size)?;
331+
if !self.read(should_read_size, size)? {
332+
return Err(IoError(io::Error::new(
333+
io::ErrorKind::UnexpectedEof,
334+
"Unexpected EOF",
335+
)));
336+
}
325337
}
326338
drop(result);
327339

0 commit comments

Comments
 (0)