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

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

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

RES_INODE_NR

m9_l1

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

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

OK

file system unmounted

Description

Notes


Inode open and close functions

REQ_LOOKUP

Resolve a path string to an inode.

Request fields

REQ_GRANT

m9_l2

cp_grant_id_t

memory grant (READ|WRITE) 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

RES_INODE_NR

m9_l1

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

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

REQ_INODE_NR

m9_l1

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

RES_INODE_NR

m9_l1

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

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

REQ_MODE

m9_s3

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

RES_INODE_NR

m9_l1

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

ENFILE

no inodes are available

OK

temporary inode created and opened

Description

Notes


REQ_PUTNODE

Decrease an open file's reference count.

Request fields

REQ_INODE_NR

m9_l1

ino_t

inode number

REQ_COUNT

m9_l2

ino_t

number of references to drop

Reply fields

Reply codes

OK

reference count decreased

Description

Notes


Inode use functions

REQ_READ

Read from a file.

Request fields

REQ_INODE_NR

m9_l1

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

RES_SEEK_POS_HI

m9_l3

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

OK

results successfully (partially) read, or EOF reached

Description

Notes


REQ_WRITE

Write to a file.

Request fields

REQ_INODE_NR

m9_l1

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

RES_SEEK_POS_HI

m9_l3

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

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

REQ_INODE_NR

m9_l1

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

RES_SEEK_POS_HI

m9_l3

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

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

REQ_INODE_NR

m9_l1

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

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

REQ_INODE_NR

m9_l1

ino_t

inode number

Reply fields

Reply codes

OK

request processed successfully

Description

Notes


Inode metadata retrieval and manipulation

REQ_STAT

Retrieve file status.

Request fields

REQ_INODE_NR

m9_l1

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

OK

result stored in buffer

Description

Notes


REQ_CHOWN

Change file ownership.

Request fields

REQ_INODE_NR

m9_l1

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

RES_MODE

m9_s2

mode_t

upon success: resulting inode mode

Reply codes

OK

ownership changed

Description

Notes


REQ_CHMOD

Change file mode.

Request fields

REQ_INODE_NR

m9_l1

ino_t

inode number

REQ_MODE

m9_s3

mode_t

new mode for the file

Reply fields

RES_MODE

m9_s2

mode_t

upon success: resulting inode mode

Reply codes

OK

mode changed

Description

Notes


REQ_UTIME

Set file times.

Request fields

REQ_INODE_NR

m9_l1

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

OK

custom file times set

Description

Notes


Directory entry manipulation

REQ_MKDIR

Create a directory.

Request fields

REQ_INODE_NR

m9_l1

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

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

REQ_INODE_NR

m9_l1

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

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

REQ_INODE_NR

m9_l1

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

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

REQ_INODE_NR

m9_l1

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

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

REQ_INODE_NR

m9_l1

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

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

REQ_REN_OLD_DIR

m9_l3

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

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

REQ_INODE_NR

m9_l1

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

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

REQ_INODE_NR

m9_l1

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

RES_NBYTES

m9_l5

size_t

upon success: number of bytes written

Reply codes

OK

result stored in buffer

Description

Notes


Miscellaneous file system operations

REQ_MOUNTPOINT

Mark an inode as mountpoint.

Request fields

REQ_INODE_NR

m9_l1

ino_t

inode number of file to use as mountpoint

Reply fields

Reply codes

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

REQ_GRANT

m9_l2

cp_grant_id_t

memory grant (WRITE) to store resulting "struct statfs" in

Reply fields

Reply codes

OK

result stored in buffer

Description

Notes


REQ_STATVFS

Retrieve file system statistics (The POSIX equivalent of REQ_FSTATFS)

Request fields

REQ_GRANT

m9_l2

cp_grant_id_t

memory grant (WRITE) to store resulting "struct statvfs" in

Reply fields

Reply codes

OK

result stored in buffer

Description

Notes


REQ_SYNC

Write any unwritten data to disk.

Request fields

Reply fields

Reply codes

OK

request processed successfully

Description

Notes


Block I/O functions

REQ_FLUSH

Flush cached data for an unmounted device.

Request fields

REQ_DEV

m9_l5

dev_t

device number

Reply fields

Reply codes

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

REQ_DEV

m9_l5

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

OK

request processed successfully

Description

Notes


REQ_BREAD

Read from a block device directly.

Request fields

REQ_DEV2

m9_l1

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

RES_SEEK_POS_HI

m9_l3

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

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

REQ_DEV2

m9_l1

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

RES_SEEK_POS_HI

m9_l3

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

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

MinixWiki: DevelopersGuide/VfsFsProtocol (last edited 2012-01-19 15:27:46 by David van Moolenbroek)