[PATCH 0/4] 9pfs: Fix ftruncate-after-unlink

Greg Kurz posted 4 patches 3 weeks, 1 day ago
There is a newer version of this series
fsdev/file-op-9p.h |  5 +++++
hw/9pfs/9p-local.c | 49 ++++++++++++++++++++++++++++++++++------------
hw/9pfs/9p-synth.c | 22 +++++++++++++++++++++
hw/9pfs/9p-util.h  |  1 +
hw/9pfs/9p.c       | 21 +++++++++++++++-----
hw/9pfs/cofs.c     | 37 ++++++++++++++++++++++++++++++++++
hw/9pfs/coth.h     |  4 ++++
7 files changed, 122 insertions(+), 17 deletions(-)
[PATCH 0/4] 9pfs: Fix ftruncate-after-unlink
Posted by Greg Kurz 3 weeks, 1 day ago
QEMU 9.2 already fixed the long standing limitation of failing fstat() on
unlinked files. This series does something similar for ftruncate().

The following program can be straced inside the guest with a shared fs in
passthrough mode over 9p2000.L.

int main(void)
{
	struct stat st;
	int fd = creat("./foo", 0000);

	ftruncate(fd, 100);
	unlink("./foo");
	ftruncate(fd, 1000);
}

Before :

creat("./foo", 000)                     = 3
ftruncate(3, 100)                       = -1 EACCES (Permission denied)
unlink("./foo")                         = 0
ftruncate(3, 1000)                      = -1 ENOENT (No such file or directory)

After :

creat("./foo", 000)                     = 3
ftruncate(3, 100)                       = 0
unlink("./foo")                         = 0
ftruncate(3, 1000)                      = 0

Christian,

I'm not familiar enough with the latest changes to write a proper test
for this case and I don't have enough cycles to learn. I'm sorry for that
but I guess it will be a lot easier for you and I'll review.

Cheers,

--
Greg

Greg Kurz (4):
  9pfs: local : Introduce local_fid_fd() helper
  9pfs: Don't use file descriptors in core code
  9pfs: Introduce ftruncate file op
  9pfs: Introduce futimens file op

 fsdev/file-op-9p.h |  5 +++++
 hw/9pfs/9p-local.c | 49 ++++++++++++++++++++++++++++++++++------------
 hw/9pfs/9p-synth.c | 22 +++++++++++++++++++++
 hw/9pfs/9p-util.h  |  1 +
 hw/9pfs/9p.c       | 21 +++++++++++++++-----
 hw/9pfs/cofs.c     | 37 ++++++++++++++++++++++++++++++++++
 hw/9pfs/coth.h     |  4 ++++
 7 files changed, 122 insertions(+), 17 deletions(-)

-- 
2.48.1
Re: [PATCH 0/4] 9pfs: Fix ftruncate-after-unlink
Posted by Christian Schoenebeck 3 weeks, 1 day ago
On Monday, March 10, 2025 6:10:57 PM CET Greg Kurz wrote:
> QEMU 9.2 already fixed the long standing limitation of failing fstat() on
> unlinked files. This series does something similar for ftruncate().
> 
> The following program can be straced inside the guest with a shared fs in
> passthrough mode over 9p2000.L.
> 
> int main(void)
> {
> 	struct stat st;
> 	int fd = creat("./foo", 0000);
> 
> 	ftruncate(fd, 100);
> 	unlink("./foo");
> 	ftruncate(fd, 1000);
> }
> 
> Before :
> 
> creat("./foo", 000)                     = 3
> ftruncate(3, 100)                       = -1 EACCES (Permission denied)
> unlink("./foo")                         = 0
> ftruncate(3, 1000)                      = -1 ENOENT (No such file or directory)
> 
> After :
> 
> creat("./foo", 000)                     = 3
> ftruncate(3, 100)                       = 0
> unlink("./foo")                         = 0
> ftruncate(3, 1000)                      = 0
> 
> Christian,
> 
> I'm not familiar enough with the latest changes to write a proper test
> for this case and I don't have enough cycles to learn. I'm sorry for that
> but I guess it will be a lot easier for you and I'll review.

With the following test client patch applied:

  https://lore.kernel.org/all/E1trx7R-002JEJ-0l@kylie.crudebyte.com/

then something like this should do it:

diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c
index f515a9bb15..d15721e4b2 100644
--- a/tests/qtest/virtio-9p-test.c
+++ b/tests/qtest/virtio-9p-test.c
@@ -736,6 +736,12 @@ static void fs_use_after_unlink(void *obj, void *data,
         .data = buf
     }).count;
     g_assert_cmpint(count, ==, write_count);
+    tsetattr({ /* truncate file to (arbitrarily chosen) size 2001 */
+        .client = v9p, .fid = fid_file, .attr = (v9fs_attr) {
+            .valid = P9_SETATTR_SIZE,
+            .size = 2001
+        }
+    });
 }
 
 static void cleanup_9p_local_driver(void *data)

/Christian

> Cheers,
> 
> --
> Greg
> 
> Greg Kurz (4):
>   9pfs: local : Introduce local_fid_fd() helper
>   9pfs: Don't use file descriptors in core code
>   9pfs: Introduce ftruncate file op
>   9pfs: Introduce futimens file op
> 
>  fsdev/file-op-9p.h |  5 +++++
>  hw/9pfs/9p-local.c | 49 ++++++++++++++++++++++++++++++++++------------
>  hw/9pfs/9p-synth.c | 22 +++++++++++++++++++++
>  hw/9pfs/9p-util.h  |  1 +
>  hw/9pfs/9p.c       | 21 +++++++++++++++-----
>  hw/9pfs/cofs.c     | 37 ++++++++++++++++++++++++++++++++++
>  hw/9pfs/coth.h     |  4 ++++
>  7 files changed, 122 insertions(+), 17 deletions(-)
> 
>