From a323861bf5331d11fbff8883c77ac67e3e4b6976 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Wed, 26 Oct 2022 15:29:06 -0700 Subject: [PATCH] p9: set filetype from directory to file in lcreate The 9p lcreate operation takes a directory fid as input and creates a file in that directory; when the operation completes, the same fid becomes a reference to the newly-created file. We updated the internal self.fids structure's file and path fields to point to the new file, but we neglected to update the filetype field, which would remain as the original FileType::Directory. This caused an issue with commit 53cd18e0629c ("p9: use *at() functions for set_attr"), since that change causes set_attr requests to validate the filetype is not a directory when attempting to set its length. BUG=b:253838039 TEST=tast run <...>.DefaultSharedFolder Change-Id: Ie46a660dd4616d669c924014e704e9b5703eb7e9 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3983116 Reviewed-by: Joel Hockey Commit-Queue: Daniel Verkamp --- common/p9/src/server/mod.rs | 1 + common/p9/src/server/tests.rs | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/common/p9/src/server/mod.rs b/common/p9/src/server/mod.rs index e324ecc101..3837a5bc6a 100644 --- a/common/p9/src/server/mod.rs +++ b/common/p9/src/server/mod.rs @@ -711,6 +711,7 @@ impl Server { let iounit = st.st_blksize as u32; fid.file = Some(file); + fid.filetype = FileType::Regular; // This fid now refers to the newly created file so we need to update the O_PATH fd for it // as well. diff --git a/common/p9/src/server/tests.rs b/common/p9/src/server/tests.rs index 8b448e8f17..d4425d714f 100644 --- a/common/p9/src/server/tests.rs +++ b/common/p9/src/server/tests.rs @@ -1276,3 +1276,41 @@ create_test!( ); create_test!(append_read_write_file_create, P9_APPEND | P9_RDWR, 0o600u32); create_test!(append_wronly_file_create, P9_APPEND | P9_WRONLY, 0o600u32); + +#[test] +fn lcreate_set_len() { + let (test_dir, mut server) = setup("lcreate_set_len"); + + let name = "foo.txt"; + let fid = ROOT_FID + 1; + create( + &mut server, + &*test_dir, + ROOT_FID, + fid, + name, + P9_RDWR, + 0o600u32, + ) + .expect("failed to create file"); + + let tsetattr = Tsetattr { + fid, + valid: 0x8, // P9_SETATTR_SIZE + size: 100, + // The other fields are not used because the relevant flags aren't set in `valid`. + mode: 0, + uid: 0, + gid: 0, + atime_sec: 0, + atime_nsec: 0, + mtime_sec: 0, + mtime_nsec: 0, + }; + server + .set_attr(&tsetattr) + .expect("failed to set file length after lcreate"); + + let tclunk = Tclunk { fid }; + server.clunk(&tclunk).expect("Unable to clunk file"); +}