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:
committed by
Dietmar Maurer
parent
7312ab9eef
commit
e7b60a16c8
@ -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),
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user