mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-10-23 04:46:29 +00:00
ext2: Fix permission of the root directory
When a source directory path is given to the ext2 logic, its metadata such as mode should be copied to the disk. Before this patch, some unit tests that dump files in the created file system with `debugfs` failed to clean up these files after completion because the top directory permission is not set properly. BUG=b:351994509 TEST=CQ Change-Id: I9315d8cae45a738e8abcda1a4313a89d5fa7bd16 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5687140 Reviewed-by: Takaya Saeki <takayas@chromium.org> Commit-Queue: Keiichi Watanabe <keiichiw@chromium.org>
This commit is contained in:
parent
18c8261043
commit
046a6acc64
3 changed files with 43 additions and 14 deletions
|
@ -716,6 +716,20 @@ impl<'a> Ext2<'a> {
|
|||
|
||||
/// Walks through `src_dir` and copies directories and files to the new file system.
|
||||
fn copy_dirtree<P: AsRef<Path>>(&mut self, arena: &'a Arena<'a>, src_dir: P) -> Result<()> {
|
||||
// Update the root directory's metadata with the metadata of `src_dir`.
|
||||
let root_inode_num = InodeNum::new(2).expect("2 is a valid inode number");
|
||||
let group_id = self.group_num_for_inode(root_inode_num);
|
||||
let gm = &mut self.group_metadata[group_id];
|
||||
let inode: &mut &mut Inode = gm
|
||||
.inode_table
|
||||
.get_mut(&root_inode_num)
|
||||
.expect("root dir is not stored");
|
||||
let metadata = src_dir
|
||||
.as_ref()
|
||||
.metadata()
|
||||
.with_context(|| format!("failed to get metadata of {:?}", src_dir.as_ref()))?;
|
||||
inode.update_metadata(&metadata);
|
||||
|
||||
self.copy_dirtree_rec(arena, InodeNum(2), src_dir)
|
||||
}
|
||||
|
||||
|
|
|
@ -173,13 +173,13 @@ impl InodeBlock {
|
|||
#[derive(Default, Debug, Copy, Clone, FromZeroes, FromBytes, AsBytes)]
|
||||
pub(crate) struct Inode {
|
||||
mode: u16,
|
||||
_uid: u16,
|
||||
uid: u16,
|
||||
pub size: u32,
|
||||
atime: u32,
|
||||
ctime: u32,
|
||||
mtime: u32,
|
||||
_dtime: u32,
|
||||
_gid: u16,
|
||||
gid: u16,
|
||||
pub links_count: u16,
|
||||
pub blocks: InodeBlocksCount,
|
||||
_flags: u32,
|
||||
|
@ -192,8 +192,8 @@ pub(crate) struct Inode {
|
|||
_fragment_num: u8,
|
||||
_fragment_size: u8,
|
||||
_reserved1: u16,
|
||||
_uid_high: u16,
|
||||
_gid_high: u16,
|
||||
uid_high: u16,
|
||||
gid_high: u16,
|
||||
_reserved2: u32,
|
||||
}
|
||||
|
||||
|
@ -278,10 +278,10 @@ impl Inode {
|
|||
atime: now,
|
||||
ctime: now,
|
||||
mtime: now,
|
||||
_uid: uid_low,
|
||||
_gid: gid_low,
|
||||
_uid_high: uid_high,
|
||||
_gid_high: gid_high,
|
||||
uid: uid_low,
|
||||
gid: gid_low,
|
||||
uid_high,
|
||||
gid_high,
|
||||
..Default::default()
|
||||
};
|
||||
Ok(inode)
|
||||
|
@ -319,8 +319,8 @@ impl Inode {
|
|||
|
||||
*inode = Inode {
|
||||
mode,
|
||||
_uid: uid_low,
|
||||
_gid: gid_low,
|
||||
uid: uid_low,
|
||||
gid: gid_low,
|
||||
size,
|
||||
atime,
|
||||
ctime,
|
||||
|
@ -328,16 +328,29 @@ impl Inode {
|
|||
links_count,
|
||||
blocks,
|
||||
block,
|
||||
|
||||
_uid_high: uid_high,
|
||||
_gid_high: gid_high,
|
||||
|
||||
uid_high,
|
||||
gid_high,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(inode)
|
||||
}
|
||||
|
||||
pub fn update_metadata(&mut self, m: &std::fs::Metadata) {
|
||||
self.mode = m.mode() as u16;
|
||||
|
||||
let uid: u32 = m.uid();
|
||||
self.uid_high = (uid >> 16) as u16;
|
||||
self.uid = uid as u16;
|
||||
let gid = m.gid();
|
||||
self.gid_high = (gid >> 16) as u16;
|
||||
self.gid = gid as u16;
|
||||
|
||||
self.atime = m.atime() as u32;
|
||||
self.ctime = m.ctime() as u32;
|
||||
self.mtime = m.mtime() as u32;
|
||||
}
|
||||
|
||||
pub fn typ(&self) -> Option<InodeType> {
|
||||
InodeType::n((self.mode >> 12) as u8)
|
||||
}
|
||||
|
|
|
@ -236,6 +236,8 @@ fn test_simple_dir() {
|
|||
);
|
||||
|
||||
assert_eq_dirs(&td, &dir, &disk);
|
||||
|
||||
td.close().unwrap(); // make sure that tempdir is properly deleted.
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue