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 <c.ebner@proxmox.com>
This commit is contained in:
Christian Ebner 2019-06-05 14:26:16 +02:00 committed by Dietmar Maurer
parent 4800df7ba6
commit a4cc8eb7c5
1 changed files with 23 additions and 10 deletions

View File

@ -405,24 +405,37 @@ impl <'a, W: Write> Encoder<'a, W> {
if !self.has_features(CA_FORMAT_WITH_QUOTA_PROJID) { if !self.has_features(CA_FORMAT_WITH_QUOTA_PROJID) {
return Ok(None); return Ok(None);
} }
let projid = match magic {
match magic {
//TODO ZFS quota //TODO ZFS quota
EXT4_SUPER_MAGIC | XFS_SUPER_MAGIC | FUSE_SUPER_MAGIC => { EXT4_SUPER_MAGIC | XFS_SUPER_MAGIC | FUSE_SUPER_MAGIC => {
let mut fsxattr = fs::FSXAttr::default(); let mut fsxattr = fs::FSXAttr::default();
unsafe { let res = unsafe {
fs::fs_ioc_fsgetxattr(fd, &mut fsxattr) 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), _ => 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> { fn write_entry(&mut self, entry: CaFormatEntry) -> Result<(), Error> {