Skip to content

Commit

Permalink
Remove the device and inode numbers from the API.
Browse files Browse the repository at this point in the history
As discussed [here], remove the fields which correspond to `st_dev`, `st_ino`,
and `d_ino` in POSIX from the stat and directory entry structs.

 - Device numbers assume the existence of a global device number space,
   which creates implicit relationships between otherwise unrelated
   components.

 - Not all filesystem implementations have these numbers. And some that
   do have these numbers require extra implementation cost to retrieve them.

 - These numbers leak potentially sensitive or identifying information from the
   underlying filesystem implementation.

In their place, provide some functions, `is-same-object`,
`metadata-hash`, and `metadata-hash-at`, for explicitly testing whether two
handles are the same file or have the same metadata, respectively. This doesn't
cover all possible use cases for device and inode numbers, but we can
add more functions as need arises.

[here]: WebAssembly#65 (comment)
  • Loading branch information
sunfishcode committed Jul 20, 2023
1 parent 58e3e5d commit 65d5421
Showing 1 changed file with 47 additions and 22 deletions.
69 changes: 47 additions & 22 deletions wit/types.wit
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,6 @@ interface types {
///
/// Note: This was called `filestat` in earlier versions of WASI.
record descriptor-stat {
/// Device ID of device containing the file.
device: device,
/// File serial number.
inode: inode,
/// File type.
%type: descriptor-type,
/// Number of hard links to the file.
Expand Down Expand Up @@ -166,14 +162,6 @@ interface types {
/// Number of hard links to an inode.
type link-count = u64

/// Identifier for a device containing a file system. Can be used in
/// combination with `inode` to uniquely identify a file or directory in
/// the filesystem.
type device = u64

/// Filesystem object serial number that is unique within its file system.
type inode = u64

/// When setting a timestamp, this gives the value to set it to.
variant new-timestamp {
/// Leave the timestamp set to its previous value.
Expand All @@ -187,14 +175,6 @@ interface types {

/// A directory entry.
record directory-entry {
/// The serial number of the object referred to by this directory entry.
/// May be none if the inode value is not known.
///
/// When this is none, libc implementations might do an extra `stat-at`
/// call to retrieve the inode number to fill their `d_ino` fields, so
/// implementations which can set this to a non-none value should do so.
inode: option<inode>,

/// The type of the file referred to by this directory entry.
%type: descriptor-type,

Expand Down Expand Up @@ -485,14 +465,20 @@ interface types {

/// Return the attributes of an open file or directory.
///
/// Note: This is similar to `fstat` in POSIX.
/// Note: This is similar to `fstat` in POSIX, except that it does not return
/// device and inode information. For testing whether two descriptors refer to
/// the same underlying filesystem object, use `is-same-object`. To obtain
/// additional data that can be used do determine whether a file has been
/// modified, use `metadata-hash`.
///
/// Note: This was called `fd_filestat_get` in earlier versions of WASI.
stat: func(this: descriptor) -> result<descriptor-stat, error-code>

/// Return the attributes of a file or directory.
///
/// Note: This is similar to `fstatat` in POSIX.
/// Note: This is similar to `fstatat` in POSIX, except that it does not
/// return device and inode information. See the `stat` description for a
/// discussion of alternatives.
///
/// Note: This was called `path_filestat_get` in earlier versions of WASI.
stat-at: func(
Expand Down Expand Up @@ -800,4 +786,43 @@ interface types {
/// Dispose of the specified `directory-entry-stream`, after which it may no longer
/// be used.
drop-directory-entry-stream: func(this: directory-entry-stream)

/// Test whether two descriptors refer to the same filesystem object.
///
/// In POSIX, this corresponds to testing whether the two descriptors have the
/// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers.
/// wasi-filesystem does not expose device and inode numbers, so this function
/// may be used instead.
is-same-object: func(other: descriptor) -> bool

/// Return a hash of the metadata associated with a filesystem object referred
/// to by a descriptor.
///
/// This returns a hash of the last-modification timestamp and file size, and
/// may also include the inode number, device number, birth timestamp, and
/// other metadata fields that may change when the file is modified or
/// replaced.
///
/// Implementations are encourated to provide the following properties:
///
/// - If the file is not modified or replaced, the computed hash value should
/// usually not change.
/// - If the object is modified or replaced, the computed hash value should
/// usually change.
/// - The inputs to the hash should not be easily computable from the
/// computed hash.
///
/// However, none of these is required.
metadata-hash: func() -> result<tuple<u64, u64>, error-code>

/// Return a hash of the metadata associated with a filesystem object referred
/// to by a directory descriptor and a relative path.
///
/// This performs the same hash computation as `metadata-hash`.
metadata-hash-at: func(
/// Flags determining the method of how the path is resolved.
path-flags: path-flags,
/// The relative path of the file or directory to inspect.
path: string,
) -> result<tuple<u64, u64>, error-code>
}

0 comments on commit 65d5421

Please sign in to comment.