From a169b912b7fdaf78bbc4e68c7739b054918472bf Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 19 Mar 2026 12:24:33 +0200 Subject: fix: replay fs metadata operations --- AGENTS.md | 5 +-- ioriot/src/replay/rioop.c | 96 +++++++++++++++++++++++++++++++++++++++++------ ioriot/src/replay/rioop.h | 8 ++++ 3 files changed, 94 insertions(+), 15 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index bf3f908..0929bdc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -162,9 +162,8 @@ Architecture note: - On modern x86_64 systems, some operations may surface as modern entry points rather than legacy ones. For example, `open` may appear as `openat`, and `stat` / `lstat` may appear as `newfstatat` in `strace`. -- Some replay entries are intentionally no-ops today: `statfs`, `fstatfs`, - `readahead`, `readlink`, `readlinkat`, `sync`, `syncfs`, and - `sync_file_range`. +- `readdir` replay typically appears as `getdents64` in `strace`, and legacy + compat syscalls may replay through the closest modern libc entry point. ### 8. Initialize the replay tree diff --git a/ioriot/src/replay/rioop.c b/ioriot/src/replay/rioop.c index 0d20eff..2a53510 100644 --- a/ioriot/src/replay/rioop.c +++ b/ioriot/src/replay/rioop.c @@ -14,6 +14,8 @@ #include "rioop.h" +#include + #include "../vfd.h" #include "rworker.h" @@ -127,18 +129,18 @@ _rioop_find_handler(const rioop_entry_s *entries, const size_t num_entries, static const rioop_entry_s _RIOOP_HANDLERS[] = { {FSTAT, rioop_fstat}, - {FSTATFS, _rioop_noop}, - {FSTATFS64, _rioop_noop}, + {FSTATFS, rioop_fstatfs}, + {FSTATFS64, rioop_fstatfs}, {FSTAT_AT, rioop_stat}, {LSTAT, rioop_stat}, {STAT, rioop_stat}, - {STATFS, _rioop_noop}, - {STATFS64, _rioop_noop}, + {STATFS, rioop_statfs}, + {STATFS64, rioop_statfs}, {READ, rioop_read}, {READV, rioop_read}, - {READAHEAD, _rioop_noop}, - {READLINK, _rioop_noop}, - {READLINK_AT, _rioop_noop}, + {READAHEAD, rioop_readahead}, + {READLINK, rioop_readlink}, + {READLINK_AT, rioop_readlinkat}, {WRITE, rioop_write}, {WRITEV, rioop_write}, {OPEN, _rioop_open_default}, @@ -155,9 +157,9 @@ static const rioop_entry_s _RIOOP_HANDLERS[] = { {RMDIR, rioop_rmdir}, {FSYNC, rioop_fsync}, {FDATASYNC, rioop_fdatasync}, - {SYNC, _rioop_noop}, - {SYNCFS, _rioop_noop}, - {SYNC_FILE_RANGE, _rioop_noop}, + {SYNC, rioop_sync}, + {SYNCFS, rioop_syncfs}, + {SYNC_FILE_RANGE, rioop_sync_file_range}, {FCNTL, rioop_fcntl}, {GETDENTS, rioop_getdents}, {READDIR, rioop_readdir}, @@ -184,8 +186,14 @@ void rioop_test(void) _rioop_open_default); assert(_rioop_find_handler(_RIOOP_HANDLERS, handler_count, CREAT) == _rioop_open_creat); - assert(_rioop_find_handler(_RIOOP_HANDLERS, handler_count, READAHEAD) == - _rioop_noop); + assert(_rioop_find_handler(_RIOOP_HANDLERS, handler_count, STATFS) == + rioop_statfs); + assert(_rioop_find_handler(_RIOOP_HANDLERS, handler_count, FSTATFS) == + rioop_fstatfs); + assert(_rioop_find_handler(_RIOOP_HANDLERS, handler_count, READLINK) == + rioop_readlink); + assert(_rioop_find_handler(_RIOOP_HANDLERS, handler_count, SYNCFS) == + rioop_syncfs); assert(_rioop_find_handler(_RIOOP_HANDLERS, handler_count, READDIR) == rioop_readdir); assert(_rioop_find_handler(_RIOOP_HANDLERS, handler_count, -1) == NULL); @@ -221,6 +229,14 @@ void rioop_fstat(rprocess_s *p, rthread_s *t, rtask_s *task) fstat(vfd->fd, &buf); } +void rioop_fstatfs(rprocess_s *p, rthread_s *t, rtask_s *task) +{ + _Init_fd(3); + _Init_virtfd; + struct statfs buf; + fstatfs(vfd->fd, &buf); +} + void rioop_rename(rprocess_s *p, rthread_s *t, rtask_s *task) { _Init_path(3); @@ -239,6 +255,36 @@ void rioop_read(rprocess_s *p, rthread_s *t, rtask_s *task) free(buf); } +void rioop_readahead(rprocess_s *p, rthread_s *t, rtask_s *task) +{ + _Init_fd(3); + _Init_offset(4); + _Init_bytes(5); + _Init_virtfd; + readahead(vfd->fd, offset, bytes); +} + +void rioop_readlink(rprocess_s *p, rthread_s *t, rtask_s *task) +{ + _Init_path(3); + char buf[MAX_LINE_LEN]; + readlink(path, buf, sizeof(buf)); +} + +void rioop_readlinkat(rprocess_s *p, rthread_s *t, rtask_s *task) +{ + _Init_path(3); + char buf[MAX_LINE_LEN]; + readlinkat(AT_FDCWD, path, buf, sizeof(buf)); +} + +void rioop_statfs(rprocess_s *p, rthread_s *t, rtask_s *task) +{ + _Init_path(3); + struct statfs buf; + statfs(path, &buf); +} + void rioop_write(rprocess_s *p, rthread_s *t, rtask_s *task) { _Init_fd(3); @@ -400,6 +446,32 @@ void rioop_fdatasync(rprocess_s *p, rthread_s *t, rtask_s *task) fdatasync(vfd->fd); } +void rioop_sync(rprocess_s *p, rthread_s *t, rtask_s *task) +{ + (void)p; + (void)t; + (void)task; + sync(); +} + +void rioop_syncfs(rprocess_s *p, rthread_s *t, rtask_s *task) +{ + _Init_fd(3); + _Init_virtfd; + syncfs(vfd->fd); +} + +void rioop_sync_file_range(rprocess_s *p, rthread_s *t, rtask_s *task) +{ + _Init_fd(3); + _Init_offset(4); + _Init_bytes(5); + _Init_virtfd; + + // The current capture format does not preserve sync_file_range flags. + sync_file_range(vfd->fd, offset, bytes, 0); +} + void rioop_fcntl(rprocess_s *p, rthread_s *t, rtask_s *task) { _Init_fd(3); diff --git a/ioriot/src/replay/rioop.h b/ioriot/src/replay/rioop.h index 5d0db2b..280a5ad 100644 --- a/ioriot/src/replay/rioop.h +++ b/ioriot/src/replay/rioop.h @@ -36,14 +36,22 @@ void rioop_fcntl(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_fdatasync(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_fstat(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_fsync(rprocess_s *p, rthread_s *t, rtask_s *task); +void rioop_fstatfs(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_getdents(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_mkdir(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_open(rprocess_s *p, rthread_s *t, rtask_s *task, int flags_); +void rioop_readahead(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_read(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_readdir(rprocess_s *p, rthread_s *t, rtask_s *task); +void rioop_readlink(rprocess_s *p, rthread_s *t, rtask_s *task); +void rioop_readlinkat(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_rename(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_stat(rprocess_s *p, rthread_s *t, rtask_s *task); +void rioop_statfs(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_lseek(rprocess_s *p, rthread_s *t, rtask_s *task); +void rioop_sync(rprocess_s *p, rthread_s *t, rtask_s *task); +void rioop_syncfs(rprocess_s *p, rthread_s *t, rtask_s *task); +void rioop_sync_file_range(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_unlink(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_rmdir(rprocess_s *p, rthread_s *t, rtask_s *task); void rioop_write(rprocess_s *p, rthread_s *t, rtask_s *task); -- cgit v1.2.3