From a4cc8eb7c509275a666e1139162b9d0effa6bce2 Mon Sep 17 00:00:00 2001 From: Christian Ebner Date: Wed, 5 Jun 2019 14:26:16 +0200 Subject: [PATCH] src/pxar/encoder.rs: check if ioctl supported by filesystem Reading the quota project id relies on a ioctl call to get fsxattr. On FUSE filesystems, ioctl calls might not be supported and will fail with an errno indicating no support. For these cases, the error is ignored and the default project id is used (indicated by returning Ok(None)). Signed-off-by: Christian Ebner --- src/pxar/encoder.rs | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/pxar/encoder.rs b/src/pxar/encoder.rs index d4fa7684..575065d4 100644 --- a/src/pxar/encoder.rs +++ b/src/pxar/encoder.rs @@ -405,24 +405,37 @@ impl <'a, W: Write> Encoder<'a, W> { if !self.has_features(CA_FORMAT_WITH_QUOTA_PROJID) { return Ok(None); } - let projid = match magic { + + match magic { //TODO ZFS quota EXT4_SUPER_MAGIC | XFS_SUPER_MAGIC | FUSE_SUPER_MAGIC => { let mut fsxattr = fs::FSXAttr::default(); - unsafe { + let res = unsafe { fs::fs_ioc_fsgetxattr(fd, &mut fsxattr) - .map_err(|err| format_err!("error while reading quota project id for {:#?} - {}", self.full_path(), err))?; + }; + + // On some FUSE filesystems it can happen that ioctl is not supported. + // For these cases projid is set to 0 while the error is ignored. + if let Err(err) = res { + let errno = err.as_errno().ok_or_else(|| { + format_err!("error while reading quota project id for {:#?}", self.full_path()) + })?; + if errno_is_unsupported(errno) { + return Ok(None); + } else { + bail!("error while reading quota project id for {:#?} - {}", self.full_path(), errno); + } + } + + let projid = fsxattr.fsx_projid as u64; + if projid == 0 { + return Ok(None); + } else { + return Ok(Some(CaFormatQuotaProjID { projid })); } - fsxattr.fsx_projid as u64 }, _ => return Ok(None), - }; - println!("Encountered projid: {} for {:#?}", projid, self.full_path()); - if projid == 0 { - return Ok(None); } - - Ok(Some(CaFormatQuotaProjID { projid })) } fn write_entry(&mut self, entry: CaFormatEntry) -> Result<(), Error> {