Skip to content

Commit

Permalink
Add real implementation of statx
Browse files Browse the repository at this point in the history
Fixes #2418
  • Loading branch information
tbodt committed Oct 21, 2024
1 parent 94c21ed commit e7ba8f3
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 1 deletion.
52 changes: 52 additions & 0 deletions fs/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,55 @@ dword_t sys_fstat64(fd_t fd_no, addr_t statbuf_addr) {
return _EFAULT;
return 0;
}

dword_t sys_statx(fd_t at_f, addr_t path_addr, int_t flags, uint_t mask, addr_t statx_addr) {
int err;
char path[MAX_PATH];
if (user_read_string(path_addr, path, sizeof(path)))
return _EFAULT;
struct fd *at = at_fd(at_f);
if (at == NULL)
return _EBADF;

STRACE("statx(at=%d, path=\"%s\", flags=%d, mask=%d, statx=0x%x)", at_f, path, flags, mask, statx_addr);

struct statbuf stat = {};

if ((flags & AT_EMPTY_PATH_) && strcmp(path, "") == 0) {
struct fd *fd = at;
int err = fd->mount->fs->fstat(fd, &stat);
if (err < 0)
return err;
} else {
bool follow_links = !(flags & AT_SYMLINK_NOFOLLOW_);
int err = generic_statat(at, path, &stat, follow_links);
if (err < 0)
return err;
}

// for now, ignore the requested mask and just fill in the same fields as stat returns
struct statx_ statx = {};
statx.mask = STATX_BASIC_STATS_;
statx.blksize = stat.blksize;
statx.nlink = stat.nlink;
statx.uid = stat.uid;
statx.gid = stat.gid;
statx.mode = stat.mode;
statx.ino = stat.inode;
statx.size = stat.size;
statx.blocks = stat.blocks;
statx.atime.sec = stat.atime;
statx.atime.nsec = stat.atime_nsec;
statx.mtime.sec = stat.mtime;
statx.mtime.nsec = stat.mtime_nsec;
statx.ctime.sec = stat.ctime;
statx.ctime.nsec = stat.ctime_nsec;
statx.rdev_major = dev_major(stat.rdev);
statx.rdev_minor = dev_minor(stat.rdev);
statx.dev_major = dev_major(stat.dev);
statx.dev_minor = dev_minor(stat.dev);

if (user_put(statx_addr, statx))
return _EFAULT;
return 0;
}
35 changes: 35 additions & 0 deletions fs/stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,39 @@ struct statfs64_ {
uint_t pad[4];
} __attribute__((packed));

struct statx_timestamp_ {
int64_t sec;
uint32_t nsec;
uint32_t _pad;
};

struct statx_ {
uint32_t mask;
uint32_t blksize;
uint64_t attributes;
uint32_t nlink;
uint32_t uid;
uint32_t gid;
uint16_t mode;
uint16_t _pad1;
uint64_t ino;
uint64_t size;
uint64_t blocks;
uint64_t attributes_mask;
struct statx_timestamp_ atime;
struct statx_timestamp_ btime;
struct statx_timestamp_ ctime;
struct statx_timestamp_ mtime;
uint32_t rdev_major;
uint32_t rdev_minor;
uint32_t dev_major;
uint32_t dev_minor;
uint64_t mnt_id;
uint32_t dio_mem_align;
uint32_t dio_offset_align;
uint32_t _pad2[24];
} __attribute__((packed));

#define STATX_BASIC_STATS_ 0x7ff

#endif
2 changes: 1 addition & 1 deletion kernel/calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ syscall_t syscall_table[] = {
[373] = (syscall_t) sys_shutdown,
[375] = (syscall_t) syscall_silent_stub, // membarrier
[377] = (syscall_t) sys_copy_file_range,
[383] = (syscall_t) syscall_silent_stub, // statx
[383] = (syscall_t) sys_statx,
[384] = (syscall_t) sys_arch_prctl,
[422] = (syscall_t) syscall_silent_stub, // futex_time64
[439] = (syscall_t) syscall_silent_stub, // faccessat2
Expand Down
1 change: 1 addition & 0 deletions kernel/calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ dword_t sys_statfs(addr_t path_addr, addr_t buf_addr);
dword_t sys_statfs64(addr_t path_addr, dword_t buf_size, addr_t buf_addr);
dword_t sys_fstatfs(fd_t f, addr_t buf_addr);
dword_t sys_fstatfs64(fd_t f, addr_t buf_addr);
dword_t sys_statx(fd_t at_f, addr_t path_addr, int_t flags, uint_t mask, addr_t statx_addr);

#define MS_READONLY_ (1 << 0)
#define MS_NOSUID_ (1 << 1)
Expand Down
1 change: 1 addition & 0 deletions kernel/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct attr {
((struct attr) {.type = attr_##_type, ._type = thing})

#define AT_SYMLINK_NOFOLLOW_ 0x100
#define AT_EMPTY_PATH_ 0x1000

struct fd *generic_open(const char *path, int flags, int mode);
struct fd *generic_openat(struct fd *at, const char *path, int flags, int mode);
Expand Down

0 comments on commit e7ba8f3

Please sign in to comment.