summaryrefslogtreecommitdiff
path: root/src/9p.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/9p.zig')
-rw-r--r--src/9p.zig18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/9p.zig b/src/9p.zig
index 9513fdb5..2948b9ed 100644
--- a/src/9p.zig
+++ b/src/9p.zig
@@ -511,7 +511,11 @@ pub fn Server(comptime fs: type, comptime fid_capacity: usize) type {
if (st.type != std.math.maxInt(u16) or st.dev != std.math.maxInt(u32) or
st.qid.type != std.math.maxInt(u8) or st.qid.version != std.math.maxInt(u32) or
st.qid.path != std.math.maxInt(u64) or st.mode != std.math.maxInt(u32) or
- st.atime != std.math.maxInt(u32) or st.mtime != std.math.maxInt(u32) or
+ st.atime != std.math.maxInt(u32) or
+ // Linux v9fs follows O_TRUNC with Twstat(length=0, mtime=now).
+ // Accept that timestamp hint with truncation; this control
+ // filesystem does not persist caller-selected timestamps.
+ (st.mtime != std.math.maxInt(u32) and st.length != 0) or
st.name.len != 0 or st.uid.len != 0 or st.gid.len != 0 or st.muid.len != 0)
return s.fail(tag, e_wstat);
if (st.length == std.math.maxInt(u64)) {
@@ -738,6 +742,7 @@ pub fn Server(comptime fs: type, comptime fid_capacity: usize) type {
return;
}
const f = s.jobFid() orelse return;
+ if (r.attr.node != 0) f.node = r.attr.node;
f.open = true;
f.omode = j.omode;
f.handle = r.handle;
@@ -1729,6 +1734,7 @@ test "9p server: Twstat with a zero length is the truncate, and so is OTRUNC" {
changes[11].muid = "writer";
for (changes) |change| {
for ([_]u64{ std.math.maxInt(u64), 0 }) |length| {
+ if (change.mtime != std.math.maxInt(u32) and length == 0) continue;
var attributes = change;
attributes.length = length;
const calls = h.fsys.calls;
@@ -1741,6 +1747,16 @@ test "9p server: Twstat with a zero length is the truncate, and so is OTRUNC" {
}
}
+ // Captured Linux v9fs O_TRUNC follow-up: length=0 plus current mtime.
+ var linux_truncate = sentinel;
+ linux_truncate.length = 0;
+ linux_truncate.mtime = 1789432552;
+ try h.send(21, .{ .twstat = .{ .fid = 1, .stat = linux_truncate } });
+ got = try h.reap();
+ try testing.expect(got.msg == .rwstat);
+ try testing.expectEqualStrings("", h.fsys.body);
+ h.fsys.body = "hello, body\n";
+
var zero = sentinel;
zero.length = 0;
try h.send(9, .{ .twstat = .{ .fid = 1, .stat = zero } });