sys::fs service

The sys::fs service is in charge of operations related to the filesystems.

Behaviour

Operations and latency

A single filesystem operation request from a client process up to the hardware device traverses:

The response then goes up through all layers. Note that in all cases, the sys::hw don't need to be contacted, thanks to direct driver access.

In the best scenario, which is for natively supported filesystems on storage devices that don't require a dedicated driver, direct storage access is possible, reducing the traversal to:

  • Client
  • sys::fs service
  • Hardware storage device

List of natively supported filesystems

The following filesystems are natively supported, meaning they don't require a filesystem interface to work properly:

  • Btrfs
  • Ext2 / Ext3 / Ext4
  • NTFS
  • FAT12 / FAT16 / FAT32
  • exFAT

Extending supported filesystems

It is possible to use other filesystems that the natively supported ones, using filesystem interfaces.

This, however, creates a higher latency as direct access and operations are not permitted anymore. The typical sequence of operations becomes:

  • The client calls the sys::fs service to perform a given operation
  • The operation is transmitted to the related filesystem interface...
  • ...which in turns contact the sys::hw service...
  • ...which itself transmits the operation to the underlying storage driver

The information then goes up:

  • From the driver to sys::hw
  • Then to the filesystem interface which translates it
  • Then back to the sys::fs service
  • And finally to the client

Filesystems detection

The sys::fs serviec is responsible for detecting filesystems. It performs this by contacting the sys::hw service to enumerate and access the different storage devices, as well as being notified when a storage device is connected, disconnected or changes.

Filesystems are detected using a variety of methods. If all fail (which is, if the filesystem is not one that is natively supported), filesystem interfaces are used one by one to find one that can handle the said filesystem, using their IS_VALID_PARTITION method.

Each partition then gets an identifier, the filesystem unique identifier (FSID), which is consistent across reboots but different between computers to avoid collection of informations from the FSID alone.

Methods

0x0001 IS_FS_MOUNTED

Check if a given filesystem is mounted.

Required permission: fs.filesystems.mounted

Arguments:

Return value:

  • 0x01 if the filesystem is currently mounted, 0x00 else

Errors:

None

0x0002 ENUM_FS

Enumerate all available filesystems.

Required permission: fs.filesystems.list

Arguments:

None

Return value:

Errors:

None

0x0003 FS_METADATA

Get informations on a filesystem.

Required permission: fs.filesystems.metadata

Arguments:

Return value:

Errors:

  • 0x3000: The requested filesystem is currently not mounted

0x0004 FS_MOUNT

Mount an existing filesystem. If no mount path is provided, the filesystem will be mounted under the /mnt directory.

New filesystems are automatically detected when storage devices are connected.

Required permission: fs.filesystems.mount

Arguments:

Return value:

None

Errors:

  • 0x3000: Unknown FSID (8 bytes)
  • 0x3001: This filesystem is already mounted

0x0005 FS_UNMOUNT

Unmount a mounted filesystem.

Required permission fs.filesystems.unmount

Arguments:

Return value:

None

Errors:

  • 0x3000: Unknown FSID (8 bytes)
  • 0x3001: This filesystem is current not mounted

0x0006 FS_WATCH

Subscribe to FS_CHANGED notifications when a filesystem is mounted or unmounted.

Required permission: fs.filesystems.watch

Arguments:

None

Return value:

None

Errors:

None

0x0007 FS_UNWATCH

Unsubscribe from FS_WATCH.

Required permission: None

Arguments:

None

Return value:

None

Errors:

None

0x1000 ITEM_EXISTS

Check if a given item exists.

Required permissions:

  • fs.path.exists to check any item type
  • fs.feid.exists to check only FEID

Arguments:

Return value:

Errors:

  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted

0x1001 FEID_TO_SPLIT

Convert a FEID to the corresponding split path.

Required permissions:

  • fs.path.exists

Arguments:

Return value:

Errors:

  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted
  • 0x3002: The provided FEID was not found in the filesystem

0x1002 ITEM_METADATA

Get the metadata of a given item.

Required permissions:

  • fs.items.metadata to get symbolic links' metadata

Arguments:

Return value:

Errors:

  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted
  • 0x3002: The provided path was not found

0x2000 RENAME_ITEM

Rename an existing item.

Required permissions:

  • fs.items.move

Arguments:

Errors:

  • 0x3000: Invalid filename provided
  • 0x3001: Invalid FSID provided
  • 0x3002: Requested filesystem is currently not mounted
  • 0x3003: The provided path was not foud

0x2001 MOVE_ITEM

Move an existing item.

  • fs.items.move

Arguments:

Errors:

  • 0x1000: Invalid filename provided
  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted
  • 0x3002: The provided path was not found
  • 0x3003: Target directory was not found
  • 0x4000: Target directory's maximum capacity has been reached
  • 0x4001: Maximum nested items number has been reached
  • 0x4002: Maximum path length has been reached
  • 0x4003: Item cannot be moved for unspecified reasons
  • 0x4FFF: Unspecified filesystem error

0x2002 DELETE_ITEM

Delete an item.

Required permissions:

  • fs.items.remove.trash to send items to the trash
  • fs.items.remove to delete items permanently

Arguments:

  • FSID (40 bytes)
  • Filesystem path
  • Deletion mode (1 byte): 0x01 to send the item to the user's trash, 0x02 to delete it permanently

Return value:

None

Errors:

  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted
  • 0x3002: Item was not found
  • 0x3003: Cannot remove a non-empty directory
  • 0x4FFF: Unspecified filesystem error

0x3000 CREATE_DIRECTORY

Create a directory.

Required permissions:

  • fs.items.create

Arguments:

Return value:

None

Errors:

  • 0x1000: Invalid filename provided
  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted
  • 0x3002: Parent directory was not found
  • 0x4000: Directory's maximum capacity has been reached
  • 0x4001: Maximum nested items number has been reached
  • 0x4002: Maximum path length has been reached
  • 0x4FFF: Unspecified filesystem error

0x3001 READ_DIRECTORY

List all entries in a directory.

Required permissions:

  • fs.dir.read
  • fs.dir.read.hidden to also list hidden items

Arguments:

Return value:

Errors:

  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted
  • 0x3002: Directory was not found
  • 0x4FFF: Unspecified filesystem error

0x4000 OPEN_FILE

Open a file with the provided options.

Opening a file with read access will prevent writes and removal while the file is open. Opening a file with write access will prevent read, writes and removal while the file is open.

Note that read and write access can be enabled together.

Required permissions:

  • fs.items.create if the file must be created
  • fs.items.read for read access
  • fs.items.write for write access

Arguments:

Return value:

  • Opened file ID (8 bytes)

Errors:

  • 0x3000: Invalid FSID provided
  • 0x3001: Invalid parent directory provided
  • 0x3002: Requested filesystem is not currently mounted
  • 0x3003: Provided file path was not found
  • 0x3004: Provided directory path was not found
  • 0x4000: File is already opened
  • 0x4001: Directory's maximum capacity has been reached
  • 0x4002: Maximum nested items number has been reached
  • 0x4003: Maximum path length has been reached
  • 0x4FFF: Unspecified filesystem error

0x4001 CLOSE_FILE

Close a file.

Removes all locks on the opened file.

Arguments:

  • Opened file ID (8 bytes)

Errors:

  • 0x3000: Invalid opened file ID provided

0x4002 READ_FILE

Read an open file.

Required permissions:

None (implicitly given by the initial OPEN_FILE call)

Arguments:

  • Opened file ID (8 bytes)
  • Offset to read from (8 bytes)
  • Length to read (8 bytes)
  • Writable buffer pointer

Errors:

  • 0x3000: Invalid opened file ID provided
  • 0x3001: File is not opened in read mode
  • 0x3002: Provided offset is out-of-range
  • 0x3003: Provided offset + length is out-of-range
  • 0x4FFF: Unspecified filesystem error

0x4002 WRITE_FILE

Write an open file.

File will grow if needed.

Required permissions:

None (implicitly given by the initial OPEN_FILE call)

Arguments:

  • Opened file ID (8 bytes)
  • Offset to write from (8 bytes)
  • Length to write (8 bytes)
  • Readable buffer pointer
  • Truncate boolean (1 byte): truncate the file's length to the end of the written data

Errors:

  • 0x3000: Invalid opened file ID provided
  • 0x3001: File is not opened in write mode
  • 0x3002: Provided offset is out-of-range
  • 0x4000: Filesystem capacity exceeded
  • 0x4001: Maximum file size exceeded
  • 0x4FFF: Unspecified filesystem error

Create a symbolic link.

Required permissions:

  • fs.symlinks.create

Arguments:

Return value:

None

Errors:

  • 0x3000: Invalid filename provided
  • 0x3001: Invalid FSID provided
  • 0x3002: Requested filesystem is currently not mounted
  • 0x3003: Parent directory was not found
  • 0x3004: Cannot create symbolic links to cross-filesystem items
  • 0x3005: Cannot create symbolic links to non-existing items
  • 0x4000: Directory's maximum capacity has been reached
  • 0x4001: Maximum nested items number has been reached
  • 0x4002: Maximum path length has been reached
  • 0x4003: Storage's capacity exceeded
  • 0x4FFF: Unspecified filesystem error

Create a symbolic link.

Required permissions:

  • fs.symlinks.update

Arguments:

Return value:

None

Errors:

  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted
  • 0x3002: Provided path was not found
  • 0x3003: Cannot crate symbolic links to cross-filesystem items
  • 0x3004: Cannot crate symbolic links to non-existing items
  • 0x4FFF: Unspecified filesystem error

Read a symbolic link's target.

Required permissions:

  • fs.symlinks.read

Arguments:

Return value:

Errors:

  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted
  • 0x3002: Provided path was not found
  • 0x4000: Symbolic link is cyclic

0xA000 WATCH_ITEM

Watch an item for changes on its metadata or content. Any change will trigger a ITEM_CHANGED notification.

Required permission:

  • fs.items.metadata

Arguments:

  • FSID (8 bytes)
  • Path to watch
  • Generated watch identifier (8 bytes)

Errors:

  • 0x3000: Invalid FSID provided
  • 0x3001: Provided path was not found

0xA001 UNWATCH

Stop watching a content watched with WATCH_ITEM.

Arguments:

  • Generated watch identifier (8 bytes)

Errors:

  • 0x3000: Provided watch identifier was not found

0xF000 FORMAT

Asynchronously format the partition to get an empty filesystem.

Required permissions:

  • fs.filesystems.format

Arguments:

  • FSID (40 bytes)
  • Optional new partition's sector size, in bytes (8 bytes)

Return value:

  • Generated task identifier (8 bytes)

Error codes:

  • 0x1000: Invalid sector size provided
  • 0x3000: Invalid FSID provided
  • 0x3001: Requested filesystem is currently not mounted
  • 0x4000: Unspecified filesystem error

Notifications

0x0006 FS_CHANGED

Sent to a client which subscribed through FS_WATCH each time a filesystem is mounted or unmounted.

Datafield:

  • Mount status boolean (1 byte): indicate if the filesystem was mounted
  • FSID (8 bytes)

0xA000 ITEM_CHANGED

Notification sent to clients watching an item through the WATCH_ITEM method.

Datafield:

  • FSID (8 bytes)
  • FEID (8 bytes)
  • Event code (1 byte):
    • 0x01: item's metadata changed (timestamps excluded)
    • 0x02: item was moved
    • 0x03: item was deleted
    • 0x04: item was locked (only for the parent directory if case of a recursive lock)
    • 0x05: item was unlocked (only for the parent directory if case of a recursive lock)