Table of Contents

The VFS-FS protocol

This page provides the official documentation of the VFS-FS protocol of MINIX 3. It describes the protocol used between the VFS server and file servers responsible for mounted file systems. The current version documents the protocol used in Git commit db087ef. If you update this document because of changes to MINIX 3, please mention the revision number of the change in the wiki comment.

General information

The following information is written mainly for people implementing a file server.

Request and replies

All requests made in the VFS-FS protocol come from VFS; the file server only sends replies. Every request must be answered with exactly one reply. The first request from VFS is REQ_READSUPER; the last request is REQ_UNMOUNT. The file server must use sef_receive() or sef_receive_status() to receive messages, and should use send() to send replies.

The <minix/vfsif.h> header file provides the definitions for requests, replies and message fields. VFS puts the request code in the type field of the request message. Request codes are always in the range VFS_BASE to VFS_BASE+NREQS, exclusive. The file server puts reply code for a request in the type field of the reply message. This is always OK (0) or a negative error code. Any request not implemented by the file server must return EINVAL or, preferably, ENOSYS.

It is possible for the file server to send a request to VFS in response to a request from VFS. Such requests always have a positive nonzero request code, which allows them to be distinguished from replies. VFS will process requests from a FS in reply to its own request, repeatedly, until it receives an actual reply. Support for such nested calls is limited and may break arbitrarily. Currently, VFS allows only the getsysinfo() system call to be invoked this way, for use by ProcFS.

System interaction

The driver should use the System Event Framework (SEF). This framework automatically takes care of interaction with the Reincarnation Server (RS).

REQ_UNMOUNT is not a request for termination. Once the file system has been unmounted, the file server should terminate upon receipt of a SIGTERM signal. The file server must not terminate from a SIGTERM as long as the file system is still mounted (this situation can occur upon system shutdown), but should then terminate after processing a subsequent unmount request. In other words, the file server should terminate after it received a SIGTERM signal and it has been unmounted. The file system may, but need not support receipt of another REQ_READSUPER request after being unmounted.

Signals may be received by registering a signal handler callback function using the SEF API. Aside from the messages recognized by SEF, the file server will in principle not receive any messages besides requests from VFS.

General behavior

If a file server returns an error in response to a request, that request is expected not to have had any effect: the state of the file server is exactly the same before and after the request, and no “progress” has been made in any sense.

A notable exception to these are the EENTERMOUNT, ELEAVEMOUNT and ESYMLINK pseudo-errors returned by REQ_LOOKUP. These errors are interpreted by VFS as part of the path lookup process, and are never passed back to the application. No other requests must return these errors.

Inodes

VFS requests mainly revolve around inodes. In the VFS-FS protocol, inodes represent open files (of any type, including directories) in the system. Many requests operate on an inode, or on a directory entry (see below). An inode is uniquely identified by its inode number; the file server is responsible for picking inode numbers for its files. Inode number 0 is reserved and may mean “no inode” in some contexts.

Upon success, certain requests (REQ_READSUPER, REQ_LOOKUP, REQ_CREATE, REQ_NEWNODE) open an inode. Each open request for an inode increases that inode's reference count: the number of times the inode is opened by VFS. The REQ_PUTNODE request decreases an open inode's reference count, effectively closing the inode when its reference count has reached zero again. A file server should only treat the reference count as an indicator whether the inode is open or not. The actual reference count is meaningless, as VFS may delay REQ_PUTNODE requests for as long as the file remains open, or drop all but one references at any time.

VFS caches open inodes including some metadata, in the form of vnodes. Cached metadata includes the file's mode, size, owner UID and GID, and special device number. VFS only refers to open inodes in requests. That is, if an inode number is passed as part of a VFS request, the associated inode will have a nonzero reference count in the file server.

Some calls that open an inode (currently only REQ_CREATE) also allow the file server to provide an inode index value. This is an arbitrary number that is passed back in certain other calls that use the inode (currently REQ_READ and REQ_WRITE). No assumptions can be made about this value if it has not been set for an inode earlier. Typical use is speedup of inode lookups.

Grants

Data transferred between VFS (or the user process) and the FS that is not put in the request/reply messages, is passed using memory grants. An FS can use sys_safecopyfrom (for READ grants) or sys_safecopyto (for WRITE grants) to retrieve or store data. These functions may not succeed; any errors thrown by these functions must be passed back to VFS.

For grants used to pass strings from VFS to the file server, the provided grant and string length will include the terminating '\0' character. A notable exception is REQ_SLINK, which provides an unterminated string for the link target; similarly, REQ_RDLINK is expected to return an unterminated string. In all other cases, file servers may check for a positive nonzero length and the presence of the terminating '\0' character as part of protection against VFS bugs.

Directory entries

Several calls manipulate directory entries. A directory entry is always provided in the form of a containing directory inode number, which is guaranteed to be an inode for a directory by VFS, and a last path component, which is a name string passed via a grant (usually in the REQ_GRANT field of the request message) and a string length (usually in the REQ_PATH_LENGTH field).

Such a name string will never contain a '/' slash character, or contain a '\0' character anywhere else but at the end. As indicated above, it is guaranteed to end with a '\0' character, and the passed string length will include that character. The maximum string length, including terminating '\0' character, is limited to PATH_MAX+1 bytes. A file server is free not to accept long names by returning an ENAMETOOLONG error.

VFS generally does not perform any other checks on the last path component of such directory entries, leaving those up to each file server. For example, when VFS requests the creation of a new directory entry, a file server will have to make sure that an entry with that name does not already exist in that directory.

Protection

VFS takes care of all checks to make sure that no write requests are sent to a read-only file system. In principle, the file system should never have to return an EROFS error. A file server may choose to perform this check itself anyway, to protect against VFS bugs.

VFS performs all access permission checks, with one exception. During lookups, when an inode is used as a directory in the process of resolving a path, the file server needs to check whether the caller has search access for that directory. A file server may choose to perform other checks itself as well to protect against VFS bugs, but may not always be able to, since not all requests provide the caller's user and group ID.

Device drivers

Every file server is responsible for raw transfers from (REQ_BREAD) and to (REQ_BWRITE) the device that it has been mounted on. This allows it to keep its cache synchronized. Before such raw transfers are initiated, VFS will send a REQ_NEW_DRIVER request to the file server to indicate which driver label to use. The root file server has more responsibilities as far as this is concerned; see the next section.

MINIX 3 supports restarting crashed device drivers. This includes the block device drivers that file systems are mounted on. File servers may assume a crash-only model: a block device driver either returns a valid response to a request, or communication results in an error. This may be an IPC-level error or an ERESTART response code. IPC-level errors may be transient, and the file server should retry the original request at least once to see if another IPC-level error is generated. If so, the FS may assume that the device driver has become fully unavailable. An ERESTART response code indicates the driver has been restarted and the file server should reissue a BDEV_OPEN to the driver before retrying the request. Other non-IPC error codes may be transient. For robustness, the FS may choose to retry an operation a few times before propagating up the error. If at all possible, the file system should use the libbdev library to talk to block device drivers, which transparently takes care of all these issues.

Root file server

The root file server (serving the “/” partition) has a number of additional responsibilities that other file servers do not have. In particular:

Pipes and sockets

While file systems may support files of type named pipe (S_IFIFO) and of type socket (S_IFSOCK), they need not implement support for pipe communication nor unix domain socket communication. This is all handled by the Pipe File Server (PFS). PFS is also responsible for cloned devices and is consequently the only file server that has to support REQ_NEWNODE, to create deleted open files.

Protocol messages

This specification reflects the protocol as it should be implemented, not how it is implemented by MFS. In particular, old and deprecated requests are not and should not be included.

The entire VFS-FS protocol is entirely POSIX-oriented. Any deviation from the requirements imposed by POSIX in this specification is unintentional except when mentioned explicitly. For convenience, links to the relevant Open Group function specifications and file access (ATIME), modification (MTIME) and change (CTIME) time update requirements are provided.

The reply codes in this document are advisory and mostly aimed at indicating additional restrictions needed for POSIX compliance. Not all of them may be applicable to every file server, and a file server may send other error codes where appropriate. Errors resulting from protocol validation checks (e.g. EROFS), and sys_safecopy.. errors, are not included.

The requests are ordered according to the following rough categorization:

Mounting and unmounting

REQ_READSUPER

Mount the file system.

Request fields

<16% >REQ_GRANT <6% >m9_l2 <12% >cp_grant_id_t memory grant (READ) for the label of the block device driver to use
REQ_PATH_LEN m9_s2 unsigned short length of the label
REQ_DEV m9_l5 dev_t device number of block device to mount
REQ_FLAGS m9_s3 int flag field containing a bitwise combination of the following possible flags:
REQ_RDONLY (the file system is mounted read-only),
REQ_ISROOT (the file system is the root file system)

Reply fields

<16% >RES_INODE_NR <6% >m9_l1 <12% >ino_t upon success: inode number of the root inode
RES_MODE m9_s2 mode_t upon success: mode of the root inode
RES_FILE_SIZE_HI m9_l2 u32_t upon success: file size of the root inode (upper 32 bits)
RES_FILE_SIZE_LO m9_l3 u32_t upon success: file size of the root inode (lower 32 bits)
RES_UID m9_s4 uid_t upon success: user ID of the root inode
RES_GID m9_s1 gid_t upon success: group ID of the root inode

Reply codes

<16% >EINVAL label too long
EINVAL unable to retrieve endpoint from DS using label
EINVAL opening device driver failed
EINVAL reading superblock failed
OK file system initialized and mounted

Description

Notes


REQ_UNMOUNT

Unmount the file system.

Request fields

Reply fields

Reply codes

<16% >OK file system unmounted

Description

Notes


Inode open and close functions

REQ_LOOKUP

Resolve a path string to an inode.

Request fields

<16% >REQ_GRANT <6% >m9_l2 <12% >cp_grant_id_t memory grant (READWRITE) of the buffer containing the pathname
REQ_PATH_LEN m9_s2 int length of the remaining part of the string to resolve
REQ_PATH_SIZE m9_l5 size_t total size of the buffer
REQ_DIR_INO m9_l3 ino_t inode number of the starting directory
REQ_ROOT_INO m9_l4 ino_t inode number of the root directory of the caller, or 0 if not on this file system
REQ_FLAGS m9_s3 int flag field containing a bitwise combination of the following possible flags:
PATH_RET_SYMLINK (do not resolve a symlink as the last path component),
PATH_GET_UCRED (copy credentials from VFS instead of using REQ_UID and REQ_GID)
REQ_UID m9_s4 uid_t user ID of the caller
REQ_GID m9_s1 gid_t group ID of the caller
REQ_GRANT2 m9_l1 cp_grant_id_t memory grant (READ) of the vfs_ucred_t structure containing supplemental group data
REQ_UCRED_SIZE m9_s4 size_t total size of vfs_ucred_t structure

Reply fields

<16% >RES_INODE_NR <6% >m9_l1 <12% >ino_t upon success: resulting file inode number
RES_MODE m9_s2 mode_t upon success: resulting file mode
RES_FILE_SIZE_HI m9_l2 u32_t upon success: resulting file size (upper 32 bits)
RES_FILE_SIZE_LO m9_l3 u32_t upon success: resulting file size (lower 32 bits)
RES_DEV m9_l4 dev_t upon success: resulting file device number
RES_UID m9_s4 uid_t upon success: resulting file user ID
RES_GID m9_s1 gid_t upon success: resulting file group ID
RES_INODE_NR m9_l1 ino_t upon EENTERMOUNT: inode number of the mountpoint inode
RES_OFFSET m9_s2 int upon EENTERMOUNT and ELEAVEMOUNT and ESYMLINK: new starting offset of string within buffer
RES_SYMLOOP m9_s3 unsigned short upon EENTERMOUNT and ELEAVEMOUNT and ESYMLINK: number of symbolic links followed

Reply codes

<16% >ENAMETOOLONG provided path length exceeds what file server can handle
ENAMETOOLONG any of the path components is longer than the file system supports
ENOTDIR any of the intermediate path components is not a directory
EACCES the caller has no search access permission on any of the intermediate directories
ENFILE no inodes are available in memory
ELOOP more than SYMLOOP_MAX symlinks were encountered during the lookup
ENAMETOOLONG resulting path to copy back (including terminating '\0') does not fit in provided buffer
EENTERMOUNT a mountpoint was encountered
ELEAVEMOUNT “..” is followed from the file system root and the file system root is not the caller root inode
ESYMLINK an absolute symlink was encountered
OK inode successfully looked up and opened

Description

Notes


REQ_CREATE

Create a regular file.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number of the containing directory for the new file
REQ_MODE m9_s3 mode_t mode for the file
REQ_UID m9_s4 uid_t user ID for the file
REQ_GID m9_s1 gid_t group ID for the file
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) for the last path component
REQ_PATH_LEN m9_s2 unsigned short length of the last path component

Reply fields

<16% >RES_INODE_NR <6% >m9_l1 <12% >ino_t upon success: inode number of created file
RES_MODE m9_s2 mode_t upon success: mode of created file
RES_FILE_SIZE_HI m9_l2 u32_t upon success: file size of created file (upper 32 bits)
RES_FILE_SIZE_LO m9_l3 u32_t upon success: file size of created file (lower 32 bits)
RES_UID m9_s4 uid_t upon success: user ID of created file
RES_GID m9_s1 gid_t upon success: group ID of created file
RES_DEV m9_l4 dev_t upon success: device node index

Reply codes

<16% >ENAMETOOLONG the last path component is longer than the file system supports
EEXIST an entry with that name already exists in the given directory
ENFILE no inodes are available
ENOSPC no space is left on the device
EFBIG the containing directory can not handle any more entries
ENOENT the containing directory has been removed
OK regular file created and opened

Description

Notes


REQ_NEWNODE

Create an open, unlinked file.

Request fields

<16% >REQ_MODE <6% >m9_s3 <12% >mode_t mode for the inode
REQ_DEV m9_l5 dev_t device number for the inode
REQ_UID m9_s4 uid_t user ID for the inode
REQ_GID m9_s1 gid_t group ID for the inode

Reply fields

<16% >RES_INODE_NR <6% >m9_l1 <12% >ino_t upon success: inode number of the resulting inode
RES_MODE m9_s2 mode_t upon success: mode of the resulting inode
RES_FILE_SIZE_HI m9_l2 u32_t upon success: size of the resulting inode (upper 32 bits)
RES_FILE_SIZE_LO m9_l3 u32_t upon success: size of the resulting inode (lower 32 bits)
RES_DEV m9_l4 dev_t upon success: device number of the resulting inode
RES_UID m9_s4 uid_t upon success: user ID of the resulting inode
RES_GID m9_s1 gid_t upon success: group ID of the resulting inode

Reply codes

<16% >ENFILE no inodes are available
OK temporary inode created and opened

Description

Notes


REQ_PUTNODE

Decrease an open file's reference count.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number
REQ_COUNT m9_l2 ino_t number of references to drop

Reply fields

Reply codes

<16% >OK reference count decreased

Description

Notes


Inode use functions

REQ_READ

Read from a file.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number
REQ_GRANT m9_l2 cp_grant_id_t memory grant (WRITE) to store the resulting data in
REQ_SEEK_POS_HI m9_l3 u32_t seek position into the open file (upper 32 bits)
REQ_SEEK_POS_LO m9_l4 u32_t seek position into the open file (lower 32 bits)
REQ_NBYTES m9_l5 size_t number of bytes to read

Reply fields

<16% >RES_SEEK_POS_HI <6% >m9_l3 <12% >u32_t upon success: resulting file position (upper 32 bits)
RES_SEEK_POS_LO m9_l4 u32_t upon success: resulting file position (lower 32 bits)
RES_NBYTES m9_l5 size_t upon success: number of bytes read

Reply codes

<16% >OK results successfully (partially) read, or EOF reached

Description

Notes


REQ_WRITE

Write to a file.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) containing the data to write
REQ_SEEK_POS_HI m9_l3 u32_t seek position into the open file (upper 32 bits)
REQ_SEEK_POS_LO m9_l4 u32_t seek position into the open file (lower 32 bits)
REQ_NBYTES m9_l5 size_t number of bytes to write

Reply fields

<16% >RES_SEEK_POS_HI <6% >m9_l3 <12% >u32_t upon success: resulting file position (upper 32 bits)
RES_SEEK_POS_LO m9_l4 u32_t upon success: resulting file position (lower 32 bits)
RES_NBYTES m9_l5 size_t upon success: number of bytes written

Reply codes

<16% >ENOSPC no space is left on the device
EFBIG the write would make the resulting file size too big
OK results successfully written

Description

Notes


REQ_GETDENTS

Retrieve directory entries.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number of the directory
REQ_GRANT m9_l2 cp_grant_id_t memory grant (WRITE) to store resulting struct dirent entries and names in
REQ_MEM_SIZE m9_l5 size_t size of given memory grant
REQ_SEEK_POS_HI m9_l3 u32_t seek position into the open file (upper 32 bits)
REQ_SEEK_POS_LO m9_l4 u32_t seek position into the open file (lower 32 bits)

Reply fields

<16% >RES_SEEK_POS_HI <6% >m9_l3 <12% >u32_t upon success: new seek position into the file (upper 32 bits)
RES_SEEK_POS_LO m9_l4 u32_t upon success: new seek position into the file (lower 32 bits)
RES_NBYTES m9_l5 size_t upon success: the amount of resulting bytes stored, with 0 for EOF

Reply codes

<16% >ENOENT the given file position is not aligned to the internal data structures (file system specific)
EINVAL the given buffer is too small to store even one entry (including padding)
OK stored zero or more entries in the user's buffer

Description

Notes


REQ_FTRUNC

Set size, or free space, of an open file.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number
REQ_TRC_START_HI m9_l2 u32_t new file size or starting position (inclusive) of region to free (upper 32 bits)
REQ_TRC_START_LO m9_l3 u32_t new file size or starting position (inclusive) of region to free (lower 32 bits)
REQ_TRC_END_HI m9_l4 u32_t zero or ending position (exclusive) of region to free (upper 32 bits)
REQ_TRC_END_LO m9_l5 u32_t zero or ending position (exclusive) of region to free (lower 32 bits)

Reply fields

Reply codes

<16% >EFBIG the resulting file would be too big
OK file size changed and/or holes created

Description

Notes


REQ_INHIBREAD

Mark file as target of seek operation.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number

Reply fields

Reply codes

<16% >OK request processed successfully

Description

Notes


Inode metadata retrieval and manipulation

REQ_STAT

Retrieve file status.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number
REQ_GRANT m9_l2 cp_grant_id_t memory grant (WRITE) to store resulting “struct stat” in

Reply fields

Reply codes

<16% >OK result stored in buffer

Description

Notes


REQ_CHOWN

Change file ownership.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number
REQ_UID m9_s4 uid_t new user ID for the file
REQ_GID m9_s1 gid_t new group ID for the file

Reply fields

<16% >RES_MODE <6% >m9_s2 <12% >mode_t upon success: resulting inode mode

Reply codes

<16% >OK ownership changed

Description

Notes


REQ_CHMOD

Change file mode.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number
REQ_MODE m9_s3 mode_t new mode for the file

Reply fields

<16% >RES_MODE <6% >m9_s2 <12% >mode_t upon success: resulting inode mode

Reply codes

<16% >OK mode changed

Description

Notes


REQ_UTIME

Set file times.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number
REQ_ACTIME m9_l2 time_t new access time
REQ_MODTIME m9_l3 time_t new modification time

Reply fields

Reply codes

<16% >OK custom file times set

Description

Notes


Directory entry manipulation

REQ_MKDIR

Create a directory.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number of the containing directory for the new file
REQ_MODE m9_s3 mode_t mode for the directory
REQ_UID m9_s4 uid_t user ID for the directory
REQ_GID m9_s1 gid_t group ID for the directory
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) for the last path component
REQ_PATH_LEN m9_s2 unsigned short length of the last path component

Reply fields

Reply codes

<16% >ENAMETOOLONG the last path component is longer than the file system supports
EEXIST a directory entry with that name already exists
ENFILE no inodes are available
ENOSPC no space is left on the device
EFBIG the containing directory can not handle any more entries
EMLINK the containing directory has the maximum number of links already
ENOENT the containing directory has been removed
OK directory created

Description

Notes


REQ_MKNOD

Create a special file.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number of the containing directory for the new file
REQ_MODE m9_s3 mode_t mode for the file
REQ_DEV m9_l5 dev_t device number
REQ_UID m9_s4 uid_t user ID for the file
REQ_GID m9_s1 gid_t group ID for the file
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) for the last path component
REQ_PATH_LEN m9_s2 unsigned short length of the last path component

Reply fields

Reply codes

<16% >ENAMETOOLONG the last path component is longer than the file system supports
EEXIST a directory entry with that name already exists
EINVAL the given file type is invalid or not supported
ENFILE no inodes are available
ENOSPC no space is left on the device
EFBIG the containing directory can not handle any more entries
ENOENT the containing directory has been removed
OK special file created

Description

Notes


Create a hard link to a file.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t link file inode number
REQ_DIR_INO m9_l3 ino_t inode number of the containing directory for the new link
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) for the last path component
REQ_PATH_LEN m9_s2 unsigned short length of the last path component

Reply fields

Reply codes

<16% >ENAMETOOLONG the last path component is longer than the file system supports
EEXIST a directory entry with that name already exists
EPERM the linked file is a directory
EMLINK the linked inode has the maximum number of links already
ENOSPC no space is left on the device
EFBIG the containing directory can not handle any more entries
ENOENT the containing directory has been removed
OK new link created

Description

Notes


Unlink a file.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number of the containing directory for the file
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) for last path component
REQ_PATH_LEN m9_s2 unsigned short length of the last path component

Reply fields

Reply codes

<16% >ENAMETOOLONG the last path component is longer than the file system supports
ENOENT no directory entry with that name exists
EPERM the given name refers to a directory
OK unlinked file

Description

Notes


REQ_RMDIR

Remove an empty directory.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number of the containing directory for the file
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) for last path component
REQ_PATH_LEN m9_s2 unsigned short length of the last path component

Reply fields

Reply codes

<16% >ENAMETOOLONG the last path component is longer than the file system supports
ENOENT no directory entry with that name exists
ENOTDIR the given name does not refer to a directory.
ENOTEMPTY the given directory is not empty
EINVAL the given directory is “.” or “..”
EBUSY the given directory is the root directory of the file system
OK removed directory

Description

Notes


REQ_RENAME

Rename a file or directory.

Request fields

<16% >REQ_REN_OLD_DIR <6% >m9_l3 <12% >ino_t inode number of containing directory for the old file
REQ_REN_NEW_DIR m9_l4 ino_t inode number of containing directory for the new file
REQ_REN_GRANT_OLD m9_l2 cp_grant_id_t memory grant (READ) for the old last path component
REQ_REN_LEN_OLD m9_s1 unsigned short length of the old last path component
REQ_REN_GRANT_NEW m9_l1 cp_grant_id_t memory grant (READ) for the new last path component
REQ_REN_LEN_NEW m9_s2 unsigned short length of the new last path component

Reply fields

Reply codes

<16% >ENAMETOOLONG the last path component of the old or new file is longer than the file system supports
ENOENT the old file does not exist
OK the old and new last path component and containing directory are the same
EBUSY the old file is a mountpoint directory
EINVAL an attempt is made to move a directory to within its own subtree
EINVAL the old or new last path component is “.” or “..”
EMLINK the old file is a directory and the new file doesn't exist but the new containing directory has the maximum number of links
ENOTDIR the old file is a directory and the new file exists but is not a directory
EISDIR the old file is not a directory and the new file exists but is a directory
ENOTEMPTY the new file is a directory but is not empty
EBUSY the new file is the root directory of the file system
ENOSPC no space is left on the device
EFBIG the new containing directory can not handle any more entries
ENOENT the new containing directory has been removed
OK file renamed

Description

Notes


Create a symbolic link.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number of the containing directory for the new file
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) for the link name's last path component
REQ_PATH_LEN m9_s2 unsigned short length of the link name's last path component
REQ_GRANT3 m9_l3 cp_grant_id_t memory grant (READ) for the link target (not including a trailing '\0')
REQ_MEM_SIZE m9_l5 size_t length of the link target (not including a trailing '\0')
REQ_UID m9_s4 uid_t user ID for the new symlink
REQ_GID m9_s1 gid_t group ID for the new symlink

Reply fields

Reply codes

<16% >ENAMETOOLONG the last path component is longer than the file system supports
EEXIST a directory entry with that name already exists
ENFILE no inodes are available
ENOSPC no space is left on the device
EFBIG the containing directory can not handle any more entries
ENOENT the containing directory has been removed
ENAMETOOLONG the link target contains '\0' bytes
OK symbolic link created

Description

Notes


Retrieve symbolic link target.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number
REQ_GRANT m9_l2 cp_grant_id_t memory grant (WRITE) for buffer to write result to
REQ_MEM_SIZE m9_l5 size_t size of buffer to write to

Reply fields

<16% >RES_NBYTES <6% >m9_l5 <12% >size_t upon success: number of bytes written

Reply codes

<16% >OK result stored in buffer

Description

Notes


Miscellaneous file system operations

REQ_MOUNTPOINT

Mark an inode as mountpoint.

Request fields

<16% >REQ_INODE_NR <6% >m9_l1 <12% >ino_t inode number of file to use as mountpoint

Reply fields

Reply codes

<16% >EBUSY inode already in use as mountpoint
ENOTDIR given inode is not a directory
OK inode marked as mountpoint

Description

Notes


REQ_FSTATFS

Retrieve file system status.

Request fields

<16% >REQ_GRANT <6% >m9_l2 <12% >cp_grant_id_t memory grant (WRITE) to store resulting “struct statfs” in

Reply fields

Reply codes

<16% >OK result stored in buffer

Description

Notes


REQ_STATVFS

Retrieve file system statistics (The POSIX equivalent of REQ_FSTATFS)

Request fields

<16% >REQ_GRANT <6% >m9_l2 <12% >cp_grant_id_t memory grant (WRITE) to store resulting “struct statvfs” in

Reply fields

Reply codes

<16% >OK result stored in buffer

Description

Notes


REQ_SYNC

Write any unwritten data to disk.

Request fields

Reply fields

Reply codes

<16% >OK request processed successfully

Description

Notes


Block I/O functions

REQ_FLUSH

Flush cached data for an unmounted device.

Request fields

<16% >REQ_DEV <6% >m9_l5 <12% >dev_t device number

Reply fields

Reply codes

<16% >EBUSY the device is mounted
OK cache flushed and invalidated for this device

Description

Notes


REQ_NEW_DRIVER

Set a new driver label for a major device.

Request fields

<16% >REQ_DEV <6% >m9_l5 <12% >dev_t device number
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) for the label of the block device driver to use
REQ_PATH_LEN m9_s2 unsigned short length of the label

Reply fields

Reply codes

<16% >OK request processed successfully

Description

Notes


REQ_BREAD

Read from a block device directly.

Request fields

<16% >REQ_DEV2 <6% >m9_l1 <12% >dev_t device number
REQ_GRANT m9_l2 cp_grant_id_t memory grant (WRITE) to store the resulting data in
REQ_SEEK_POS_HI m9_l3 u32_t read position (upper 32 bits)
REQ_SEEK_POS_LO m9_l4 u32_t read position (lower 32 bits)
REQ_NBYTES m9_l5 size_t number of bytes to read

Reply fields

<16% >RES_SEEK_POS_HI <6% >m9_l3 <12% >u32_t upon success: resulting position (upper 32 bits)
RES_SEEK_POS_LO m9_l4 u32_t upon success: resulting position (lower 32 bits)
RES_NBYTES m9_l5 size_t upon success: total number of bytes read

Reply codes

<16% >EIO I/O error reported by the device driver
OK results successfully (partially) read, or EOF reached

Description

Notes


REQ_BWRITE

Write to a block device directly.

Request fields

<16% >REQ_DEV2 <6% >m9_l1 <12% >dev_t device number
REQ_GRANT m9_l2 cp_grant_id_t memory grant (READ) containing the data to write
REQ_SEEK_POS_HI m9_l3 u32_t write position (upper 32 bits)
REQ_SEEK_POS_LO m9_l4 u32_t write position (lower 32 bits)
REQ_NBYTES m9_l5 size_t number of bytes to write

Reply fields

<16% >RES_SEEK_POS_HI <6% >m9_l3 <12% >u32_t upon success: resulting position (upper 32 bits)
RES_SEEK_POS_LO m9_l4 u32_t upon success: resulting position (lower 32 bits)
RES_NBYTES m9_l5 size_t upon success: total number of bytes written

Reply codes

<16% >EIO I/O error reported by the device driver
OK results successfully (partially) written, or EOF reached

Description

Notes


Additional information

Implementing the lookup request

The following pseudocode presents one possible approach to implementing the heart of the REQ_LOOKUP request:

For file servers that do not support symbolic links and/or mountpoints, the lookup can be simplified accordingly.

If at least one symlink was resolved, and the returned error is EENTERMOUNT, ELEAVEMOUNT or ESYMLINK, then the unresolved part of the new path must be copied back to VFS.

Regardless,

References

An extension of this protocol is under development, to add support for failure resilience and dynamic updates.

This document is not based on the original VFS-FS protocol documentation by Balazs Gerofi. However, that document may still provide additional insights.

Design and implementation of the MINIX Virtual File system by Balazs Gerofi, August, 2006