pxar: impl storing/dumping/restoring of quota project ids

Allows to store/dump/restore the quota project id associated with an inode in
order to correctly restore project quotas.
The project id is obtained/set via ioctl calls getting/setting the fsxattr
associated with the given file descriptor.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
Christian Ebner
2019-05-29 14:34:05 +02:00
committed by Dietmar Maurer
parent 7312ab9eef
commit e7b60a16c8
2 changed files with 79 additions and 0 deletions

View File

@ -23,6 +23,7 @@ use nix::NixPath;
use crate::tools::io::ops::*;
use crate::tools::vec;
use crate::tools::fs;
use crate::tools::acl;
use crate::tools::xattr;
@ -169,6 +170,7 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
fn restore_attributes(&mut self, entry: &CaFormatEntry, fd: RawFd) -> Result<CaFormatHeader, Error> {
let mut xattrs = Vec::new();
let mut fcaps = None;
let mut quota_projid = None;
let mut acl_user = Vec::new();
let mut acl_group = Vec::new();
@ -238,6 +240,13 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
self.skip_bytes(size)?;
}
},
CA_FORMAT_QUOTA_PROJID => {
if self.has_features(CA_FORMAT_WITH_QUOTA_PROJID) {
quota_projid = Some(self.read_item::<CaFormatQuotaProjID>()?);
} else {
self.skip_bytes(size)?;
}
},
_ => break,
}
head = self.read_item()?;
@ -288,6 +297,7 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
}
acl.set_file(&proc_path, acl::ACL_TYPE_DEFAULT)?;
}
self.restore_quota_projid(fd, quota_projid)?;
Ok(head)
}
@ -307,6 +317,23 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
Ok(())
}
fn restore_quota_projid(&mut self, fd: RawFd, projid: Option<CaFormatQuotaProjID>) -> Result<(), Error> {
if let Some(projid) = projid {
let mut fsxattr = fs::FSXAttr::default();
unsafe {
fs::fs_ioc_fsgetxattr(fd, &mut fsxattr)
.map_err(|err| format_err!("error while getting fsxattr to restore quota project id - {}", err))?;
}
fsxattr.fsx_projid = projid.projid as u32;
unsafe {
fs::fs_ioc_fssetxattr(fd, &fsxattr)
.map_err(|err| format_err!("error while setting fsxattr to restore quota project id - {}", err))?;
}
}
Ok(())
}
fn restore_mode(&mut self, entry: &CaFormatEntry, fd: RawFd) -> Result<(), Error> {
let mode = Mode::from_bits_truncate((entry.mode as u32) & 0o7777);
@ -827,6 +854,12 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
println!("ACLDefaultGroup: {:?}", default_group);
}
},
CA_FORMAT_QUOTA_PROJID => {
let quota_projid = self.read_item::<CaFormatQuotaProjID>()?;
if verbose && self.has_features(CA_FORMAT_WITH_QUOTA_PROJID) {
println!("Quota project id: {:?}", quota_projid);
}
},
_ => return Ok(false),
}