VFS: Introduce filesystem context [ver #9]
Subsystems (89)
David Howells
maintainerPATCH 1/1 Add manpage for fsinfo(2)
In reply to David HowellsAdd a manual page to document the fsinfo() system call.
---
man2/fsinfo.2 | 1017 +++++++++++++++++++++++++++++++++++++++++++++++++++ man2/ioctl_iflags.2 | 6 man2/stat.2 | 7 man2/statx.2 | 13 + man2/utime.2 | 7 man2/utimensat.2 | 7 6 files changed, 1057 insertions(+) create mode 100644 man2/fsinfo.2
man2/fsinfo.2 new file +1017 -0
@@ -0,0 +1,1017 @@ +'\" t +.\" Copyright (c) 2018 David Howells <[email protected]> +.\" +.\" %%%LICENSE_START(VERBATIM) +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of this +.\" manual under the conditions for verbatim copying, provided that the +.\" entire resulting derived work is distributed under the terms of a +.\" permission notice identical to this one. +.\" +.\" Since the Linux kernel and libraries are constantly changing, this +.\" manual page may be incorrect or out-of-date. The author(s) assume no +.\" responsibility for errors or omissions, or for damages resulting from +.\" the use of the information contained herein. The author(s) may not +.\" have taken the same level of care in the production of this manual, +.\" which is licensed free of charge, as they might when working +.\" professionally. +.\" +.\" Formatted or processed versions of this manual, if unaccompanied by +.\" the source, must acknowledge the copyright and authors of this work. +.\" %%%LICENSE_END +.\" +.TH FSINFO 2 2018-06-06 "Linux" "Linux Programmer's Manual" +.SH NAME +fsinfo \- Get filesystem information +.SH SYNOPSIS +.nf +.B #include <sys/types.h> +.br +.B #include <sys/fsinfo.h> +.br +.B #include <unistd.h> +.br +.BR "#include <fcntl.h> " "/* Definition of AT_* constants */" +.PP +.BI "int fsinfo(int " dirfd ", const char *" pathname "," +.BI " struct fsinfo_params *" params "," +.BI " void *" buffer ", size_t " buf_size ); +.fi +.PP +.IR Note : +There is no glibc wrapper for +.BR fsinfo (); +see NOTES. +.SH DESCRIPTION +.PP +fsinfo() retrieves the desired filesystem attribute, as selected by the +parameters pointed to by +.IR params , +and stores its value in the buffer pointed to by +.IR buffer . +.PP +The parameter structure is optional, defaulting to all the parameters being 0 +if the pointer is NULL. The structure looks like the following: +.PP +.in +4n +.nf +struct fsinfo_params { + __u32 at_flags; /* AT_SYMLINK_NOFOLLOW and similar flags */ + __u32 request; /* Requested attribute */ + __u32 Nth; /* Instance of attribute */ + __u32 Mth; /* Subinstance of Nth instance */ + __u32 __reserved[6]; /* Reserved params; all must be 0 */ +}; +.fi +.in +.PP +The filesystem to be queried is looked up using a combination of +.IR dfd ", " pathname " and " params->at_flags. +This is discussed in more detail below. +.PP +The desired attribute is indicated by +.IR params->request . +If +.I params +is NULL, this will default to +.BR fsinfo_attr_statfs , +which retrieves some of the information returned by +.BR statfs (). +The available attributes are described below in the "THE ATTRIBUTES" section. +.PP +Some attributes can have multiple values and some can even have multiple +instances with multiple values. For example, a network filesystem might use +multiple servers. The names of each of these servers can be retrieved by +using +.I params->Nth +to iterate through all the instances until error +.B ENODATA +occurs, indicating the end of the list. Further, each server might have +multiple addresses available; these can be enumerated using +.I params->Nth +to iterate the servers and +.I params->Mth +to iterate the addresses of the Nth server. +.PP +The amount of data written into the buffer depends on the attribute selected. +Some attributes return variable-length strings and some return fixed-size +structures. If either +.IR buffer " is NULL or " buf_size " is 0" +then the size of the attribute value will be returned and nothing will be +written into the buffer. +.PP +The +.I params->__reserved +parameters must all be 0. +.\"_______________________________________________________ +.SS +Allowance for Future Attribute Expansion +.PP +To allow for the future expansion and addition of fields to any fixed-size +structure attribute, +.BR fsinfo () +makes the following guarantees: +.RS 4m +.IP (1) 4m +It will always clear any excess space in the buffer. +.IP (2) 4m +It will always return the actual size of the data. +.IP (3) 4m +It will truncate the data to fit it into the buffer rather than giving an +error. +.IP (4) 4m +Any new version of a structure will incorporate all the fields from the old +version at same offsets. +.RE +.PP +So, for example, if the caller is running on an older version of the kernel +with an older, smaller version of the structure than was asked for, the kernel +will write the smaller version into the buffer and will clear the remainder of +the buffer to make sure any additional fields are set to 0. The function will +return the actual size of the data. +.PP +On the other hand, if the caller is running on a newer version of the kernel +with a newer version of the structure that is larger than the buffer, the write +to the buffer will be truncated to fit as necessary and the actual size of the +data will be returned. +.PP +Note that this doesn't apply to variable-length string attributes. + +.\"_______________________________________________________ +.SS +Invoking \fBfsinfo\fR(): +.PP +To access a file's status, no permissions are required on the file itself, but +in the case of +.BR fsinfo () +with a path, execute (search) permission is required on all of the directories +in +.I pathname +that lead to the file. +.PP +.BR fsinfo () +uses +.IR pathname ", " dirfd " and " params->at_flags +to locate the target file in one of a variety of ways: +.TP +[*] By absolute path. +.I pathname +points to an absolute path and +.I dirfd +is ignored. The file is looked up by name, starting from the root of the +filesystem as seen by the calling process. +.TP +[*] By cwd-relative path. +.I pathname +points to a relative path and +.IR dirfd " is " AT_FDCWD . +The file is looked up by name, starting from the current working directory. +.TP +[*] By dir-relative path. +.I pathname +points to relative path and +.I dirfd +indicates a file descriptor pointing to a directory. The file is looked up by +name, starting from the directory specified by +.IR dirfd . +.TP +[*] By file descriptor. +.IR pathname " is " NULL " and " dirfd +indicates a file descriptor. The file attached to the file descriptor is +queried directly. The file descriptor may point to any type of file, not just +a directory. +.PP +.I flags +can be used to influence a path-based lookup. A value for +.I flags +is constructed by OR'ing together zero or more of the following constants: +.TP +.BR AT_EMPTY_PATH +.\" commit 65cfc6722361570bfe255698d9cd4dccaf47570d +If +.I pathname +is an empty string, operate on the file referred to by +.IR dirfd +(which may have been obtained using the +.BR open (2) +.B O_PATH +flag). +If +.I dirfd +is +.BR AT_FDCWD , +the call operates on the current working directory. +In this case, +.I dirfd +can refer to any type of file, not just a directory. +This flag is Linux-specific; define +.B _GNU_SOURCE +.\" Before glibc 2.16, defining _ATFILE_SOURCE sufficed +to obtain its definition. +.TP +.BR AT_NO_AUTOMOUNT +Don't automount the terminal ("basename") component of +.I pathname +if it is a directory that is an automount point. This allows the caller to +gather attributes of the filesystem holding an automount point (rather than +the filesystem it would mount). This flag can be used in tools that scan +directories to prevent mass-automounting of a directory of automount points. +The +.B AT_NO_AUTOMOUNT +flag has no effect if the mount point has already been mounted over. +This flag is Linux-specific; define +.B _GNU_SOURCE +.\" Before glibc 2.16, defining _ATFILE_SOURCE sufficed +to obtain its definition. +.TP +.B AT_SYMLINK_NOFOLLOW +If +.I pathname +is a symbolic link, do not dereference it: +instead return information about the link itself, like +.BR lstat (). +.SH THE ATTRIBUTES +.PP +There is a range of attributes that can be selected from. These are: + +.\" __________________ fsinfo_attr_statfs __________________ +.TP +.B fsinfo_attr_statfs +This retrieves the "dynamic" +.B statfs +information, such as block and file counts, that are expected to change whilst +a filesystem is being used. This fills in the following structure: +.PP +.RS +.in +4n +.nf +struct fsinfo_statfs { + __u64 f_blocks; /* Total number of blocks in fs */ + __u64 f_bfree; /* Total number of free blocks */ + __u64 f_bavail; /* Number of free blocks available to ordinary user */ + __u64 f_files; /* Total number of file nodes in fs */ + __u64 f_ffree; /* Number of free file nodes */ + __u64 f_favail; /* Number of free file nodes available to ordinary user */ + __u32 f_bsize; /* Optimal block size */ + __u32 f_frsize; /* Fragment size */ +}; +.fi +.in +.RE +.IP +The fields correspond to those of the same name returned by +.BR statfs (). + +.\" __________________ fsinfo_attr_fsinfo __________________ +.TP +.B fsinfo_attr_fsinfo +This retrieves information about the +.BR fsinfo () +system call itself. This fills in the following structure: +.PP +.RS +.in +4n +.nf +struct fsinfo_fsinfo { + __u32 max_attr; + __u32 max_cap; +}; +.fi +.in +.RE +.IP +The +.I max_attr +value indicates the number of attributes supported by the +.BR fsinfo () +system call, and +.I max_cap +indicates the number of capability bits supported by the +.B fsinfo_attr_capabilities +attribute. The first corresponds to +.I fsinfo_attr__nr +and the second to +.I fsinfo_cap__nr +in the header file. + +.\" __________________ fsinfo_attr_ids __________________ +.TP +.B fsinfo_attr_ids +This retrieves a number of fixed IDs and other static information otherwise +available through +.BR statfs (). +The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_ids { + char f_fs_name[15 + 1]; /* Filesystem name */ + __u64 f_flags; /* Filesystem mount flags (MS_*) */ + __u64 f_fsid; /* Short 64-bit Filesystem ID */ + __u64 f_sb_id; /* Internal superblock ID */ + __u32 f_fstype; /* Filesystem type from linux/magic.h */ + __u32 f_dev_major; /* As st_dev_* from struct statx */ + __u32 f_dev_minor; +}; +.fi +.in +.RE +.IP +Most of these are filled in as for +.BR statfs (), +with the addition of the filesystem's symbolic name in +.I f_fs_name +and an identifier for use in notifications in +.IR f_sb_id . + +.\" __________________ fsinfo_attr_limits __________________ +.TP +.B fsinfo_attr_limits +This retrieves information about the limits of what a filesystem can support. +The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_limits { + __u64 max_file_size; + __u64 max_uid; + __u64 max_gid; + __u64 max_projid; + __u32 max_dev_major; + __u32 max_dev_minor; + __u32 max_hard_links; + __u32 max_xattr_body_len; + __u16 max_xattr_name_len; + __u16 max_filename_len; + __u16 max_symlink_len; + __u16 __reserved[1]; +}; +.fi +.in +.RE +.IP +These indicate the maximum supported sizes for a variety of filesystem objects, +including the file size, the extended attribute name length and body length, +the filename length and the symlink body length. +.IP +It also indicates the maximum representable values for a User ID, a Group ID, +a Project ID, a device major number and a device minor number. +.IP +And finally, it indicates the maximum number of hard links that can be made to +a file. +.IP +Note that some of these values may be zero if the underlying object or concept +is not supported by the filesystem or the medium. + +.\" __________________ fsinfo_attr_supports __________________ +.TP +.B fsinfo_attr_supports +This retrieves information about what bits a filesystem supports in various +masks. The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_supports { + __u64 stx_attributes; + __u32 stx_mask; + __u32 ioc_flags; + __u32 win_file_attrs; + __u32 __reserved[1]; +}; +.fi +.in +.RE +.IP +The +.IR stx_attributes " and " stx_mask +fields indicate what bits in the struct statx fields of the matching names +are supported by the filesystem. +.IP +The +.I ioc_flags +field indicates what FS_*_FL flag bits as used through the FS_IOC_GET/SETFLAGS +ioctls are supported by the filesystem. +.IP +The +.I win_file_attrs +indicates what DOS/Windows file attributes a filesystem supports, if any. + +.\" __________________ fsinfo_attr_capabilities __________________ +.TP +.B fsinfo_attr_capabilities +This retrieves information about what features a filesystem supports as a +series of single bit indicators. The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_capabilities { + __u8 capabilities[(fsinfo_cap__nr + 7) / 8]; +}; +.fi +.in +.RE +.IP +where the bit of interest can be found by: +.PP +.RS +.in +4n +.nf + p->capabilities[bit / 8] & (1 << (bit % 8))) +.fi +.in +.RE +.IP +The bits are listed by +.I enum fsinfo_capability +and +.B fsinfo_cap__nr +is one more than the last capability bit listed in the header file. +.IP +Note that the number of capability bits actually supported by the kernel can be +found using the +.B fsinfo_attr_fsinfo +attribute. +.IP +The capability bits and their meanings are listed below in the "THE +CAPABILITIES" section. + +.\" __________________ fsinfo_attr_timestamp_info __________________ +.TP +.B fsinfo_attr_timestamp_info +This retrieves information about what timestamp resolution and scope is +supported by a filesystem for each of the file timestamps. The following +structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_timestamp_info { + __s64 minimum_timestamp; + __s64 maximum_timestamp; + __u16 atime_gran_mantissa; + __u16 btime_gran_mantissa; + __u16 ctime_gran_mantissa; + __u16 mtime_gran_mantissa; + __s8 atime_gran_exponent; + __s8 btime_gran_exponent; + __s8 ctime_gran_exponent; + __s8 mtime_gran_exponent; + __u32 __reserved[1]; +}; +.fi +.in +.RE +.IP +where +.IR minimum_timestamp " and " maximum_timestamp +are the limits on the timestamps that the filesystem supports and +.IR *time_gran_mantissa " and " *time_gran_exponent +indicate the granularity of each timestamp in terms of seconds, using the +formula: +.PP +.RS +.in +4n +.nf +mantissa * pow(10, exponent) Seconds +.fi +.in +.RE +.IP +where exponent may be negative and the result may be a fraction of a second. +.IP +Four timestamps are detailed: \fBA\fPccess time, \fBB\fPirth/creation time, +\fBC\fPhange time and \fBM\fPodification time. Capability bits are defined +that specify whether each of these exist in the filesystem or not. +.IP +Note that the timestamp description may be approximated or inaccurate if the +file is actually remote or is the union of multiple objects. + +.\" __________________ fsinfo_attr_volume_id __________________ +.TP +.B fsinfo_attr_volume_id +This retrieves the system's superblock volume identifier as a variable-length +string. This does not necessarily represent a value stored in the medium but +might be constructed on the fly. +.IP +For instance, for a block device this is the block device identifier +(eg. "sdb2"); for AFS this would be the numeric volume identifier. + +.\" __________________ fsinfo_attr_volume_uuid __________________ +.TP +.B fsinfo_attr_volume_uuid +This retrieves the volume UUID, if there is one, as a little-endian binary +UUID. This fills in the following structure: +.PP +.RS +.in +4n +.nf +struct fsinfo_volume_uuid { + __u8 uuid[16]; +}; +.fi +.in +.RE +.IP + +.\" __________________ fsinfo_attr_volume_name __________________ +.TP +.B fsinfo_attr_volume_name +This retrieves the filesystem's volume name as a variable-length string. This +is expected to represent a name stored in the medium. +.IP +For a block device, this might be a label stored in the superblock. For a +network filesystem, this might be a logical volume name of some sort. + +.\" __________________ fsinfo_attr_cell/domain __________________ +.PP +.B fsinfo_attr_cell_name +.br +.B fsinfo_attr_domain_name +.br +.IP +These two attributes are variable-length string attributes that may be used to +obtain information about network filesystems. An AFS volume, for instance, +belongs to a named cell. CIFS shares may belong to a domain. + +.\" __________________ fsinfo_attr_realm_name __________________ +.TP +.B fsinfo_attr_realm_name +This attribute is variable-length string that indicates the Kerberos realm that +a filesystem's authentication tokens should come from. + +.\" __________________ fsinfo_attr_server_name __________________ +.TP +.B fsinfo_attr_server_name +This attribute is a multiple-value attribute that lists the names of the +servers that are backing a network filesystem. Each value is a variable-length +string. The values are enumerated by calling +.BR fsinfo () +multiple times, incrementing +.I params->Nth +each time until an ENODATA error occurs, thereby indicating the end of the +list. + +.\" __________________ fsinfo_attr_server_address __________________ +.TP +.B fsinfo_attr_server_address +This attribute is a multiple-instance, multiple-value attribute that lists the +addresses of the servers that are backing a network filesystem. Each value is +a structure of the following type: +.PP +.RS +.in +4n +.nf +struct fsinfo_server_address { + struct __kernel_sockaddr_storage address; +}; +.fi +.in +.RE +.IP +Where the address may be AF_INET, AF_INET6, AF_RXRPC or any other type as +appropriate to the filesystem. +.IP +The values are enumerated by calling +.IR fsinfo () +multiple times, incrementing +.I params->Nth +to step through the servers and +.I params->Mth +to step through the addresses of the Nth server each time until ENODATA errors +occur, thereby indicating either the end of a server's address list or the end +of the server list. +.IP +Barring the server list changing whilst being accessed, it is expected that the +.I params->Nth +will correspond to +.I params->Nth +for +.BR fsinfo_attr_server_name . + +.\" __________________ fsinfo_attr_parameter __________________ +.TP +.B fsinfo_attr_parameter +This attribute is a multiple-value attribute that lists the values of the mount +parameters for a filesystem as variable-length strings. +.IP +The parameters are enumerated by calling +.BR fsinfo () +multiple times, incrementing +.I params->Nth +to step through them until error ENODATA is given. +.IP +Parameter strings are presented in a form akin to the way they're passed to the +context created by the +.BR fsopen () +system call. For example, straight text parameters will be rendered as +something like: +.PP +.RS +.in +4n +.nf +"o data=journal" +"o noquota" +.fi +.in +.RE +.IP +Where the initial "word" indicates the option form. + +.\" __________________ fsinfo_attr_source __________________ +.TP +.B fsinfo_attr_source +This attribute is a multiple-value attribute that lists the mount sources for a +filesystem as variable-length strings. Normally only one source will be +available, but the possibility of having more than one is allowed for. +.IP +The sources are enumerated by calling +.BR fsinfo () +multiple times, incrementing +.I params->Nth +to step through them until error ENODATA is given. +.IP +Source strings are presented in a form akin to the way they're passed to the +context created by the +.BR fsopen () +system call. For example, they will be rendered as something like: +.PP +.RS +.in +4n +.nf +"s /dev/sda1" +"s example.com/pub/linux/" +.fi +.in +.RE +.IP +Where the initial "word" indicates the option form. + +.\" __________________ fsinfo_attr_name_encoding __________________ +.TP +.B fsinfo_attr_name_encoding +This attribute is variable-length string that indicates the filename encoding +used by the filesystem. The default is "utf8". Note that this may indicate a +non-8-bit encoding if that's what the underlying filesystem actually supports. + +.\" __________________ fsinfo_attr_name_codepage __________________ +.TP +.B fsinfo_attr_name_codepage +This attribute is variable-length string that indicates the codepage used to +translate filenames from the filesystem to the system if this is applicable to +the filesystem. + +.\" __________________ fsinfo_attr_io_size __________________ +.TP +.B fsinfo_attr_io_size +This retrieves information about the I/O sizes supported by the filesystem. +The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_io_size { + __u32 block_size; + __u32 max_single_read_size; + __u32 max_single_write_size; + __u32 best_read_size; + __u32 best_write_size; +}; +.fi +.in +.RE +.IP +Where +.I block_size +indicates the fundamental I/O block size of the filesystem as something +O_DIRECT read/write sizes must be a multiple of; +.IR max_single_write_size " and " max_single_write_size +indicate the maximum sizes for individual unbuffered data transfer operations; +and +.IR best_read_size " and " best_write_size +indicate the recommended I/O sizes. +.IP +Note that any of these may be zero if inapplicable or indeterminable. + + + +.SH THE CAPABILITIES +.PP +There are number of capability bits in a bit array that can be retrieved using +.BR fsinfo_attr_capabilities . +These give information about features of the filesystem driver and the specific +filesystem. + +.\" __________________ fsinfo_cap_is_*_fs __________________ +.PP +.B fsinfo_cap_is_kernel_fs +.br +.B fsinfo_cap_is_block_fs +.br +.B fsinfo_cap_is_flash_fs +.br +.B fsinfo_cap_is_network_fs +.br +.B fsinfo_cap_is_automounter_fs +.IP +These indicate the primary type of the filesystem. +.B kernel +filesystems are special communication interfaces that substitute files for +system calls; examples include procfs and sysfs. +.B block +filesystems require a block device on which to operate; examples include ext4 +and XFS. +.B flash +filesystems require an MTD device on which to operate; examples include JFFS2. +.B network +filesystems require access to the network and contact one or more servers; +examples include NFS and AFS. +.B automounter +filesystems are kernel special filesystems that host automount points and +triggers to dynamically create automount points. Examples include autofs and +AFS's dynamic root. + +.\" __________________ fsinfo_cap_automounts __________________ +.TP +.B fsinfo_cap_automounts +The filesystem may have automount points that can be triggered by pathwalk. + +.\" __________________ fsinfo_cap_adv_locks __________________ +.TP +.B fsinfo_cap_adv_locks +The filesystem supports advisory file locks. For a network filesystem, this +indicates that the advisory file locks are cross-client (and also between +server and its local filesystem on something like NFS). + +.\" __________________ fsinfo_cap_mand_locks __________________ +.TP +.B fsinfo_cap_mand_locks +The filesystem supports mandatory file locks. For a network filesystem, this +indicates that the mandatory file locks are cross-client (and also between +server and its local filesystem on something like NFS). + +.\" __________________ fsinfo_cap_leases __________________ +.TP +.B fsinfo_cap_leases +The filesystem supports leases. For a network filesystem, this means that the +server will tell the client to clean up its state on a file before passing the +lease to another client. + +.\" __________________ fsinfo_cap_*ids __________________ +.PP +.B fsinfo_cap_uids +.br +.B fsinfo_cap_gids +.br +.B fsinfo_cap_projids +.IP +These indicate that the filesystem supports numeric user IDs, group IDs and +project IDs respectively. + +.\" __________________ fsinfo_cap_id_* __________________ +.PP +.B fsinfo_cap_id_names +.br +.B fsinfo_cap_id_guids +.IP +These indicate that the filesystem employs textual names and/or GUIDs as +identifiers. + +.\" __________________ fsinfo_cap_windows_attrs __________________ +.TP +.B fsinfo_cap_windows_attrs +Indicates that the filesystem supports some Windows FILE_* attributes. + +.\" __________________ fsinfo_cap_*_quotas __________________ +.PP +.B fsinfo_cap_user_quotas +.br +.B fsinfo_cap_group_quotas +.br +.B fsinfo_cap_project_quotas +.IP +These indicate that the filesystem supports quotas for users, groups and +projects respectively. + +.\" __________________ fsinfo_cap_xattrs/filetypes __________________ +.PP +.B fsinfo_cap_xattrs +.br +.B fsinfo_cap_symlinks +.br +.B fsinfo_cap_hard_links +.br +.B fsinfo_cap_hard_links_1dir +.br +.B fsinfo_cap_device_files +.br +.B fsinfo_cap_unix_specials +.IP +These indicate that the filesystem supports respectively extended attributes; +symbolic links; hard links spanning direcories; hard links, but only within a +directory; block and character device files; and UNIX special files, such as +FIFO and socket. + +.\" __________________ fsinfo_cap_*journal* __________________ +.PP +.B fsinfo_cap_journal +.br +.B fsinfo_cap_data_is_journalled +.IP +The first of these indicates that the filesystem has a journal and the second +that the file data changes are being journalled. + +.\" __________________ fsinfo_cap_o_* __________________ +.PP +.B fsinfo_cap_o_sync +.br +.B fsinfo_cap_o_direct +.IP +These indicate that O_SYNC and O_DIRECT are supported respectively. + +.\" __________________ fsinfo_cap_o_* __________________ +.PP +.B fsinfo_cap_volume_id +.br +.B fsinfo_cap_volume_uuid +.br +.B fsinfo_cap_volume_name +.br +.B fsinfo_cap_volume_fsid +.br +.B fsinfo_cap_cell_name +.br +.B fsinfo_cap_domain_name +.br +.B fsinfo_cap_realm_name +.IP +These indicate if various attributes are supported by the filesystem, where +.B fsinfo_cap_X +here corresponds to +.BR fsinfo_attr_X . + +.\" __________________ fsinfo_cap_iver_* __________________ +.PP +.B fsinfo_cap_iver_all_change +.br +.B fsinfo_cap_iver_data_change +.br +.B fsinfo_cap_iver_mono_incr +.IP +These indicate if +.I i_version +on an inode in the filesystem is supported and +how it behaves. +.B all_change +indicates that i_version is incremented on metadata changes as well as data +changes. +.B data_change +indicates that i_version is only incremented on data changes, including +truncation. +.B mono_incr +indicates that i_version is incremented by exactly 1 for each change made. + +.\" __________________ fsinfo_cap_resource_forks __________________ +.TP +.B fsinfo_cap_resource_forks +This indicates that the filesystem supports some sort of resource fork or +alternate data stream on a file. This isn't the same as an extended attribute. + +.\" __________________ fsinfo_cap_name_* __________________ +.PP +.B fsinfo_cap_name_case_indep +.br +.B fsinfo_cap_name_non_utf8 +.br +.B fsinfo_cap_name_has_codepage +.IP +These indicate certain facts about the filenames in a filesystem: whether +they're case-independent; if they're not UTF-8; and if there's a codepage +employed to map the names. + +.\" __________________ fsinfo_cap_sparse __________________ +.TP +.B fsinfo_cap_sparse +This indicates that the filesystem supports sparse files. + +.\" __________________ fsinfo_cap_not_persistent __________________ +.TP +.B fsinfo_cap_not_persistent +This indicates that the filesystem is not persistent, and that any data stored +here will not be saved in the event that the filesystem is unmounted, the +machine is rebooted or the machine loses power. + +.\" __________________ fsinfo_cap_no_unix_mode __________________ +.TP +.B fsinfo_cap_no_unix_mode +This indicates that the filesystem doesn't support the UNIX mode permissions +bits. + +.\" __________________ fsinfo_cap_has_*time __________________ +.PP +.B fsinfo_cap_has_atime +.br +.B fsinfo_cap_has_btime +.br +.B fsinfo_cap_has_ctime +.br +.B fsinfo_cap_has_mtime +.IP +These indicate as to what timestamps a filesystem supports, including: Access +time, Birth/creation time, Change time (metadata and data) and Modification +time (data only). + + +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.SH RETURN VALUE +On success, the size of the value that the kernel has available is returned, +irrespective of whether the buffer is large enough to hold that. The data +written to the buffer will be truncated if it is not. On error, \-1 is +returned, and +.I errno +is set appropriately. +.SH ERRORS +.TP +.B EACCES +Search permission is denied for one of the directories +in the path prefix of +.IR pathname . +(See also +.BR path_resolution (7).) +.TP +.B EBADF +.I dirfd +is not a valid open file descriptor. +.TP +.B EFAULT +.I pathname +is NULL or +.IR pathname ", " params " or " buffer +point to a location outside the process's accessible address space. +.TP +.B EINVAL +Reserved flag specified in +.IR params->at_flags " or one of " params->__reserved[] +is not 0. +.TP +.B EOPNOTSUPP +Unsupported attribute requested in +.IR params->request . +This may be beyond the limit of the supported attribute set or may just not be +one that's supported by the filesystem. +.TP +.B ENODATA +Unavailable attribute value requested by +.IR params->Nth " and/or " params->Mth . +.TP +.B ELOOP +Too many symbolic links encountered while traversing the pathname. +.TP +.B ENAMETOOLONG +.I pathname +is too long. +.TP +.B ENOENT +A component of +.I pathname +does not exist, or +.I pathname +is an empty string and +.B AT_EMPTY_PATH +was not specified in +.IR params->at_flags . +.TP +.B ENOMEM +Out of memory (i.e., kernel memory). +.TP +.B ENOTDIR +A component of the path prefix of +.I pathname +is not a directory or +.I pathname +is relative and +.I dirfd +is a file descriptor referring to a file other than a directory. +.SH VERSIONS +.BR fsinfo () +was added to Linux in kernel 4.18. +.SH CONFORMING TO +.BR fsinfo () +is Linux-specific. +.SH NOTES +Glibc does not (yet) provide a wrapper for the +.BR fsinfo () +system call; call it using +.BR syscall (2). +.SH SEE ALSO +.BR ioctl_iflags (2), +.BR statx (2), +.BR statfs (2)
man2/ioctl_iflags.2 +6 -0
@@ -200,9 +200,15 @@ the effective user ID of the caller must match the owner of the file, or the caller must have the .BR CAP_FOWNER capability. +.PP +The set of flags supported by a filesystem can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_supports . .SH SEE ALSO .BR chattr (1), .BR lsattr (1), +.BR fsinfo (2), .BR mount (2), .BR btrfs (5), .BR ext4 (5),
man2/stat.2 +7 -0
@@ -532,6 +532,12 @@ If none of the aforementioned macros are defined, then the nanosecond values are exposed with names of the form .IR st_atimensec . .\" +.PP +Which timestamps are supported by a filesystem and their the ranges and +granularities can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_timestamp_info . .SS C library/kernel differences Over time, increases in the size of the .I stat
@@ -707,6 +713,7 @@ main(int argc, char *argv[]) .BR access (2), .BR chmod (2), .BR chown (2), +.BR fsinfo (2), .BR readlink (2), .BR utime (2), .BR capabilities (7),
man2/statx.2 +13 -0
@@ -534,12 +534,25 @@ Glibc does not (yet) provide a wrapper for the .BR statx () system call; call it using .BR syscall (2). +.PP +The sets of mask/stx_mask and stx_attributes bits supported by a filesystem +can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_supports . +.PP +Which timestamps are supported by a filesystem and their the ranges and +granularities can also be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_timestamp_info . .SH SEE ALSO .BR ls (1), .BR stat (1), .BR access (2), .BR chmod (2), .BR chown (2), +.BR fsinfo (2), .BR readlink (2), .BR stat (2), .BR utime (2),
man2/utime.2 +7 -0
@@ -181,9 +181,16 @@ on an append-only file. .\" is just a wrapper for .\" .BR utime () .\" and hence does not allow a subsecond resolution. +.PP +Which timestamps are supported by a filesystem and their the ranges and +granularities can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_timestamp_info . .SH SEE ALSO .BR chattr (1), .BR touch (1), +.BR fsinfo (2), .BR futimesat (2), .BR stat (2), .BR utimensat (2),
man2/utimensat.2 +7 -0
@@ -633,9 +633,16 @@ instead checks whether the .\" conversely, a process with a read-only file descriptor won't .\" be able to update the timestamps of a file, .\" even if it has write permission on the file. +.PP +Which timestamps are supported by a filesystem and their the ranges and +granularities can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_timestamp_info . .SH SEE ALSO .BR chattr (1), .BR touch (1), +.BR fsinfo (2), .BR futimesat (2), .BR openat (2), .BR stat (2),
Re: [MANPAGE PATCH] Add manpage for fsinfo(2)
Hello David,
See my previous mails.
There is no fsinfo(2) in the system call in the kernel currently. Will that call still be added, or was it replaced by fsconfig(2), which--as far as I can tell--dnot have a man-pages patch?
Thanks,
Michael
Quoted 1,155 lines · David Howells
Add a manual page to document the
fsinfo()system call.Signed-off-by David Howells <[email protected]>---
man2/fsinfo.2 | 1017 +++++++++++++++++++++++++++++++++++++++++++++++++++ man2/ioctl_iflags.2 | 6 man2/stat.2 | 7 man2/statx.2 | 13 + man2/utime.2 | 7 man2/utimensat.2 | 7 6 files changed, 1057 insertions(+) create mode 100644 man2/fsinfo.2man2/fsinfo.2 new file +1017
-0@@ -0,0 +1,1017 @@ +'\" t +.\" Copyright (c) 2018 David Howells <[email protected]> +.\" +.\" %%%LICENSE_START(VERBATIM) +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of this +.\" manual under the conditions for verbatim copying, provided that the +.\" entire resulting derived work is distributed under the terms of a +.\" permission notice identical to this one. +.\" +.\" Since the Linux kernel and libraries are constantly changing, this +.\" manual page may be incorrect or out-of-date. The author(s) assume no +.\" responsibility for errors or omissions, or for damages resulting from +.\" the use of the information contained herein. The author(s) may not +.\" have taken the same level of care in the production of this manual, +.\" which is licensed free of charge, as they might when working +.\" professionally. +.\" +.\" Formatted or processed versions of this manual, if unaccompanied by +.\" the source, must acknowledge the copyright and authors of this work. +.\" %%%LICENSE_END +.\" +.TH FSINFO 2 2018-06-06 "Linux" "Linux Programmer's Manual" +.SH NAME +fsinfo \- Get filesystem information +.SH SYNOPSIS +.nf +.B #include <sys/types.h> +.br +.B #include <sys/fsinfo.h> +.br +.B #include <unistd.h> +.br +.BR "#include <fcntl.h> " "/* Definition of AT_* constants */" +.PP +.BI "int fsinfo(int " dirfd ", const char *" pathname "," +.BI " struct fsinfo_params *" params "," +.BI " void *" buffer ", size_t " buf_size ); +.fi +.PP +.IR Note : +There is no glibc wrapper for +.BR fsinfo (); +see NOTES. +.SH DESCRIPTION +.PP +fsinfo() retrieves the desired filesystem attribute, as selected by the +parameters pointed to by +.IR params , +and stores its value in the buffer pointed to by +.IR buffer . +.PP +The parameter structure is optional, defaulting to all the parameters being 0 +if the pointer is NULL. The structure looks like the following: +.PP +.in +4n +.nf +struct fsinfo_params { + __u32 at_flags; /* AT_SYMLINK_NOFOLLOW and similar flags */ + __u32 request; /* Requested attribute */ + __u32 Nth; /* Instance of attribute */ + __u32 Mth; /* Subinstance of Nth instance */ + __u32 __reserved[6]; /* Reserved params; all must be 0 */ +}; +.fi +.in +.PP +The filesystem to be queried is looked up using a combination of +.IR dfd ", " pathname " and " params->at_flags. +This is discussed in more detail below. +.PP +The desired attribute is indicated by +.IR params->request . +If +.I params +is NULL, this will default to +.BR fsinfo_attr_statfs , +which retrieves some of the information returned by +.BR statfs (). +The available attributes are described below in the "THE ATTRIBUTES" section. +.PP +Some attributes can have multiple values and some can even have multiple +instances with multiple values. For example, a network filesystem might use +multiple servers. The names of each of these servers can be retrieved by +using +.I params->Nth +to iterate through all the instances until error +.B ENODATA +occurs, indicating the end of the list. Further, each server might have +multiple addresses available; these can be enumerated using +.I params->Nth +to iterate the servers and +.I params->Mth +to iterate the addresses of the Nth server. +.PP +The amount of data written into the buffer depends on the attribute selected. +Some attributes return variable-length strings and some return fixed-size +structures. If either +.IR buffer " is NULL or " buf_size " is 0" +then the size of the attribute value will be returned and nothing will be +written into the buffer. +.PP +The +.I params->__reserved +parameters must all be 0. +.\"_______________________________________________________ +.SS +Allowance for Future Attribute Expansion +.PP +To allow for the future expansion and addition of fields to any fixed-size +structure attribute, +.BR fsinfo () +makes the following guarantees: +.RS 4m +.IP (1) 4m +It will always clear any excess space in the buffer. +.IP (2) 4m +It will always return the actual size of the data. +.IP (3) 4m +It will truncate the data to fit it into the buffer rather than giving an +error. +.IP (4) 4m +Any new version of a structure will incorporate all the fields from the old +version at same offsets. +.RE +.PP +So, for example, if the caller is running on an older version of the kernel +with an older, smaller version of the structure than was asked for, the kernel +will write the smaller version into the buffer and will clear the remainder of +the buffer to make sure any additional fields are set to 0. The function will +return the actual size of the data. +.PP +On the other hand, if the caller is running on a newer version of the kernel +with a newer version of the structure that is larger than the buffer, the write +to the buffer will be truncated to fit as necessary and the actual size of the +data will be returned. +.PP +Note that this doesn't apply to variable-length string attributes. + +.\"_______________________________________________________ +.SS +Invoking \fBfsinfo\fR(): +.PP +To access a file's status, no permissions are required on the file itself, but +in the case of +.BR fsinfo () +with a path, execute (search) permission is required on all of the directories +in +.I pathname +that lead to the file. +.PP +.BR fsinfo () +uses +.IR pathname ", " dirfd " and " params->at_flags +to locate the target file in one of a variety of ways: +.TP +[*] By absolute path. +.I pathname +points to an absolute path and +.I dirfd +is ignored. The file is looked up by name, starting from the root of the +filesystem as seen by the calling process. +.TP +[*] By cwd-relative path. +.I pathname +points to a relative path and +.IR dirfd " is " AT_FDCWD . +The file is looked up by name, starting from the current working directory. +.TP +[*] By dir-relative path. +.I pathname +points to relative path and +.I dirfd +indicates a file descriptor pointing to a directory. The file is looked up by +name, starting from the directory specified by +.IR dirfd . +.TP +[*] By file descriptor. +.IR pathname " is " NULL " and " dirfd +indicates a file descriptor. The file attached to the file descriptor is +queried directly. The file descriptor may point to any type of file, not just +a directory. +.PP +.I flags +can be used to influence a path-based lookup. A value for +.I flags +is constructed by OR'ing together zero or more of the following constants: +.TP +.BR AT_EMPTY_PATH +.\" commit 65cfc6722361570bfe255698d9cd4dccaf47570d +If +.I pathname +is an empty string, operate on the file referred to by +.IR dirfd +(which may have been obtained using the +.BR open (2) +.B O_PATH +flag). +If +.I dirfd +is +.BR AT_FDCWD , +the call operates on the current working directory. +In this case, +.I dirfd +can refer to any type of file, not just a directory. +This flag is Linux-specific; define +.B _GNU_SOURCE +.\" Before glibc 2.16, defining _ATFILE_SOURCE sufficed +to obtain its definition. +.TP +.BR AT_NO_AUTOMOUNT +Don't automount the terminal ("basename") component of +.I pathname +if it is a directory that is an automount point. This allows the caller to +gather attributes of the filesystem holding an automount point (rather than +the filesystem it would mount). This flag can be used in tools that scan +directories to prevent mass-automounting of a directory of automount points. +The +.B AT_NO_AUTOMOUNT +flag has no effect if the mount point has already been mounted over. +This flag is Linux-specific; define +.B _GNU_SOURCE +.\" Before glibc 2.16, defining _ATFILE_SOURCE sufficed +to obtain its definition. +.TP +.B AT_SYMLINK_NOFOLLOW +If +.I pathname +is a symbolic link, do not dereference it: +instead return information about the link itself, like +.BR lstat (). +.SH THE ATTRIBUTES +.PP +There is a range of attributes that can be selected from. These are: + +.\" __________________ fsinfo_attr_statfs __________________ +.TP +.B fsinfo_attr_statfs +This retrieves the "dynamic" +.B statfs +information, such as block and file counts, that are expected to change whilst +a filesystem is being used. This fills in the following structure: +.PP +.RS +.in +4n +.nf +struct fsinfo_statfs { + __u64 f_blocks; /* Total number of blocks in fs */ + __u64 f_bfree; /* Total number of free blocks */ + __u64 f_bavail; /* Number of free blocks available to ordinary user */ + __u64 f_files; /* Total number of file nodes in fs */ + __u64 f_ffree; /* Number of free file nodes */ + __u64 f_favail; /* Number of free file nodes available to ordinary user */ + __u32 f_bsize; /* Optimal block size */ + __u32 f_frsize; /* Fragment size */ +}; +.fi +.in +.RE +.IP +The fields correspond to those of the same name returned by +.BR statfs (). + +.\" __________________ fsinfo_attr_fsinfo __________________ +.TP +.B fsinfo_attr_fsinfo +This retrieves information about the +.BR fsinfo () +system call itself. This fills in the following structure: +.PP +.RS +.in +4n +.nf +struct fsinfo_fsinfo { + __u32 max_attr; + __u32 max_cap; +}; +.fi +.in +.RE +.IP +The +.I max_attr +value indicates the number of attributes supported by the +.BR fsinfo () +system call, and +.I max_cap +indicates the number of capability bits supported by the +.B fsinfo_attr_capabilities +attribute. The first corresponds to +.I fsinfo_attr__nr +and the second to +.I fsinfo_cap__nr +in the header file. + +.\" __________________ fsinfo_attr_ids __________________ +.TP +.B fsinfo_attr_ids +This retrieves a number of fixed IDs and other static information otherwise +available through +.BR statfs (). +The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_ids { + char f_fs_name[15 + 1]; /* Filesystem name */ + __u64 f_flags; /* Filesystem mount flags (MS_*) */ + __u64 f_fsid; /* Short 64-bit Filesystem ID */ + __u64 f_sb_id; /* Internal superblock ID */ + __u32 f_fstype; /* Filesystem type from linux/magic.h */ + __u32 f_dev_major; /* As st_dev_* from struct statx */ + __u32 f_dev_minor; +}; +.fi +.in +.RE +.IP +Most of these are filled in as for +.BR statfs (), +with the addition of the filesystem's symbolic name in +.I f_fs_name +and an identifier for use in notifications in +.IR f_sb_id . + +.\" __________________ fsinfo_attr_limits __________________ +.TP +.B fsinfo_attr_limits +This retrieves information about the limits of what a filesystem can support. +The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_limits { + __u64 max_file_size; + __u64 max_uid; + __u64 max_gid; + __u64 max_projid; + __u32 max_dev_major; + __u32 max_dev_minor; + __u32 max_hard_links; + __u32 max_xattr_body_len; + __u16 max_xattr_name_len; + __u16 max_filename_len; + __u16 max_symlink_len; + __u16 __reserved[1]; +}; +.fi +.in +.RE +.IP +These indicate the maximum supported sizes for a variety of filesystem objects, +including the file size, the extended attribute name length and body length, +the filename length and the symlink body length. +.IP +It also indicates the maximum representable values for a User ID, a Group ID, +a Project ID, a device major number and a device minor number. +.IP +And finally, it indicates the maximum number of hard links that can be made to +a file. +.IP +Note that some of these values may be zero if the underlying object or concept +is not supported by the filesystem or the medium. + +.\" __________________ fsinfo_attr_supports __________________ +.TP +.B fsinfo_attr_supports +This retrieves information about what bits a filesystem supports in various +masks. The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_supports { + __u64 stx_attributes; + __u32 stx_mask; + __u32 ioc_flags; + __u32 win_file_attrs; + __u32 __reserved[1]; +}; +.fi +.in +.RE +.IP +The +.IR stx_attributes " and " stx_mask +fields indicate what bits in the struct statx fields of the matching names +are supported by the filesystem. +.IP +The +.I ioc_flags +field indicates what FS_*_FL flag bits as used through the FS_IOC_GET/SETFLAGS +ioctls are supported by the filesystem. +.IP +The +.I win_file_attrs +indicates what DOS/Windows file attributes a filesystem supports, if any. + +.\" __________________ fsinfo_attr_capabilities __________________ +.TP +.B fsinfo_attr_capabilities +This retrieves information about what features a filesystem supports as a +series of single bit indicators. The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_capabilities { + __u8 capabilities[(fsinfo_cap__nr + 7) / 8]; +}; +.fi +.in +.RE +.IP +where the bit of interest can be found by: +.PP +.RS +.in +4n +.nf + p->capabilities[bit / 8] & (1 << (bit % 8))) +.fi +.in +.RE +.IP +The bits are listed by +.I enum fsinfo_capability +and +.B fsinfo_cap__nr +is one more than the last capability bit listed in the header file. +.IP +Note that the number of capability bits actually supported by the kernel can be +found using the +.B fsinfo_attr_fsinfo +attribute. +.IP +The capability bits and their meanings are listed below in the "THE +CAPABILITIES" section. + +.\" __________________ fsinfo_attr_timestamp_info __________________ +.TP +.B fsinfo_attr_timestamp_info +This retrieves information about what timestamp resolution and scope is +supported by a filesystem for each of the file timestamps. The following +structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_timestamp_info { + __s64 minimum_timestamp; + __s64 maximum_timestamp; + __u16 atime_gran_mantissa; + __u16 btime_gran_mantissa; + __u16 ctime_gran_mantissa; + __u16 mtime_gran_mantissa; + __s8 atime_gran_exponent; + __s8 btime_gran_exponent; + __s8 ctime_gran_exponent; + __s8 mtime_gran_exponent; + __u32 __reserved[1]; +}; +.fi +.in +.RE +.IP +where +.IR minimum_timestamp " and " maximum_timestamp +are the limits on the timestamps that the filesystem supports and +.IR *time_gran_mantissa " and " *time_gran_exponent +indicate the granularity of each timestamp in terms of seconds, using the +formula: +.PP +.RS +.in +4n +.nf +mantissa * pow(10, exponent) Seconds +.fi +.in +.RE +.IP +where exponent may be negative and the result may be a fraction of a second. +.IP +Four timestamps are detailed: \fBA\fPccess time, \fBB\fPirth/creation time, +\fBC\fPhange time and \fBM\fPodification time. Capability bits are defined +that specify whether each of these exist in the filesystem or not. +.IP +Note that the timestamp description may be approximated or inaccurate if the +file is actually remote or is the union of multiple objects. + +.\" __________________ fsinfo_attr_volume_id __________________ +.TP +.B fsinfo_attr_volume_id +This retrieves the system's superblock volume identifier as a variable-length +string. This does not necessarily represent a value stored in the medium but +might be constructed on the fly. +.IP +For instance, for a block device this is the block device identifier +(eg. "sdb2"); for AFS this would be the numeric volume identifier. + +.\" __________________ fsinfo_attr_volume_uuid __________________ +.TP +.B fsinfo_attr_volume_uuid +This retrieves the volume UUID, if there is one, as a little-endian binary +UUID. This fills in the following structure: +.PP +.RS +.in +4n +.nf +struct fsinfo_volume_uuid { + __u8 uuid[16]; +}; +.fi +.in +.RE +.IP + +.\" __________________ fsinfo_attr_volume_name __________________ +.TP +.B fsinfo_attr_volume_name +This retrieves the filesystem's volume name as a variable-length string. This +is expected to represent a name stored in the medium. +.IP +For a block device, this might be a label stored in the superblock. For a +network filesystem, this might be a logical volume name of some sort. + +.\" __________________ fsinfo_attr_cell/domain __________________ +.PP +.B fsinfo_attr_cell_name +.br +.B fsinfo_attr_domain_name +.br +.IP +These two attributes are variable-length string attributes that may be used to +obtain information about network filesystems. An AFS volume, for instance, +belongs to a named cell. CIFS shares may belong to a domain. + +.\" __________________ fsinfo_attr_realm_name __________________ +.TP +.B fsinfo_attr_realm_name +This attribute is variable-length string that indicates the Kerberos realm that +a filesystem's authentication tokens should come from. + +.\" __________________ fsinfo_attr_server_name __________________ +.TP +.B fsinfo_attr_server_name +This attribute is a multiple-value attribute that lists the names of the +servers that are backing a network filesystem. Each value is a variable-length +string. The values are enumerated by calling +.BR fsinfo () +multiple times, incrementing +.I params->Nth +each time until an ENODATA error occurs, thereby indicating the end of the +list. + +.\" __________________ fsinfo_attr_server_address __________________ +.TP +.B fsinfo_attr_server_address +This attribute is a multiple-instance, multiple-value attribute that lists the +addresses of the servers that are backing a network filesystem. Each value is +a structure of the following type: +.PP +.RS +.in +4n +.nf +struct fsinfo_server_address { + struct __kernel_sockaddr_storage address; +}; +.fi +.in +.RE +.IP +Where the address may be AF_INET, AF_INET6, AF_RXRPC or any other type as +appropriate to the filesystem. +.IP +The values are enumerated by calling +.IR fsinfo () +multiple times, incrementing +.I params->Nth +to step through the servers and +.I params->Mth +to step through the addresses of the Nth server each time until ENODATA errors +occur, thereby indicating either the end of a server's address list or the end +of the server list. +.IP +Barring the server list changing whilst being accessed, it is expected that the +.I params->Nth +will correspond to +.I params->Nth +for +.BR fsinfo_attr_server_name . + +.\" __________________ fsinfo_attr_parameter __________________ +.TP +.B fsinfo_attr_parameter +This attribute is a multiple-value attribute that lists the values of the mount +parameters for a filesystem as variable-length strings. +.IP +The parameters are enumerated by calling +.BR fsinfo () +multiple times, incrementing +.I params->Nth +to step through them until error ENODATA is given. +.IP +Parameter strings are presented in a form akin to the way they're passed to the +context created by the +.BR fsopen () +system call. For example, straight text parameters will be rendered as +something like: +.PP +.RS +.in +4n +.nf +"o data=journal" +"o noquota" +.fi +.in +.RE +.IP +Where the initial "word" indicates the option form. + +.\" __________________ fsinfo_attr_source __________________ +.TP +.B fsinfo_attr_source +This attribute is a multiple-value attribute that lists the mount sources for a +filesystem as variable-length strings. Normally only one source will be +available, but the possibility of having more than one is allowed for. +.IP +The sources are enumerated by calling +.BR fsinfo () +multiple times, incrementing +.I params->Nth +to step through them until error ENODATA is given. +.IP +Source strings are presented in a form akin to the way they're passed to the +context created by the +.BR fsopen () +system call. For example, they will be rendered as something like: +.PP +.RS +.in +4n +.nf +"s /dev/sda1" +"s example.com/pub/linux/" +.fi +.in +.RE +.IP +Where the initial "word" indicates the option form. + +.\" __________________ fsinfo_attr_name_encoding __________________ +.TP +.B fsinfo_attr_name_encoding +This attribute is variable-length string that indicates the filename encoding +used by the filesystem. The default is "utf8". Note that this may indicate a +non-8-bit encoding if that's what the underlying filesystem actually supports. + +.\" __________________ fsinfo_attr_name_codepage __________________ +.TP +.B fsinfo_attr_name_codepage +This attribute is variable-length string that indicates the codepage used to +translate filenames from the filesystem to the system if this is applicable to +the filesystem. + +.\" __________________ fsinfo_attr_io_size __________________ +.TP +.B fsinfo_attr_io_size +This retrieves information about the I/O sizes supported by the filesystem. +The following structure is filled in: +.PP +.RS +.in +4n +.nf +struct fsinfo_io_size { + __u32 block_size; + __u32 max_single_read_size; + __u32 max_single_write_size; + __u32 best_read_size; + __u32 best_write_size; +}; +.fi +.in +.RE +.IP +Where +.I block_size +indicates the fundamental I/O block size of the filesystem as something +O_DIRECT read/write sizes must be a multiple of; +.IR max_single_write_size " and " max_single_write_size +indicate the maximum sizes for individual unbuffered data transfer operations; +and +.IR best_read_size " and " best_write_size +indicate the recommended I/O sizes. +.IP +Note that any of these may be zero if inapplicable or indeterminable. + + + +.SH THE CAPABILITIES +.PP +There are number of capability bits in a bit array that can be retrieved using +.BR fsinfo_attr_capabilities . +These give information about features of the filesystem driver and the specific +filesystem. + +.\" __________________ fsinfo_cap_is_*_fs __________________ +.PP +.B fsinfo_cap_is_kernel_fs +.br +.B fsinfo_cap_is_block_fs +.br +.B fsinfo_cap_is_flash_fs +.br +.B fsinfo_cap_is_network_fs +.br +.B fsinfo_cap_is_automounter_fs +.IP +These indicate the primary type of the filesystem. +.B kernel +filesystems are special communication interfaces that substitute files for +system calls; examples include procfs and sysfs. +.B block +filesystems require a block device on which to operate; examples include ext4 +and XFS. +.B flash +filesystems require an MTD device on which to operate; examples include JFFS2. +.B network +filesystems require access to the network and contact one or more servers; +examples include NFS and AFS. +.B automounter +filesystems are kernel special filesystems that host automount points and +triggers to dynamically create automount points. Examples include autofs and +AFS's dynamic root. + +.\" __________________ fsinfo_cap_automounts __________________ +.TP +.B fsinfo_cap_automounts +The filesystem may have automount points that can be triggered by pathwalk. + +.\" __________________ fsinfo_cap_adv_locks __________________ +.TP +.B fsinfo_cap_adv_locks +The filesystem supports advisory file locks. For a network filesystem, this +indicates that the advisory file locks are cross-client (and also between +server and its local filesystem on something like NFS). + +.\" __________________ fsinfo_cap_mand_locks __________________ +.TP +.B fsinfo_cap_mand_locks +The filesystem supports mandatory file locks. For a network filesystem, this +indicates that the mandatory file locks are cross-client (and also between +server and its local filesystem on something like NFS). + +.\" __________________ fsinfo_cap_leases __________________ +.TP +.B fsinfo_cap_leases +The filesystem supports leases. For a network filesystem, this means that the +server will tell the client to clean up its state on a file before passing the +lease to another client. + +.\" __________________ fsinfo_cap_*ids __________________ +.PP +.B fsinfo_cap_uids +.br +.B fsinfo_cap_gids +.br +.B fsinfo_cap_projids +.IP +These indicate that the filesystem supports numeric user IDs, group IDs and +project IDs respectively. + +.\" __________________ fsinfo_cap_id_* __________________ +.PP +.B fsinfo_cap_id_names +.br +.B fsinfo_cap_id_guids +.IP +These indicate that the filesystem employs textual names and/or GUIDs as +identifiers. + +.\" __________________ fsinfo_cap_windows_attrs __________________ +.TP +.B fsinfo_cap_windows_attrs +Indicates that the filesystem supports some Windows FILE_* attributes. + +.\" __________________ fsinfo_cap_*_quotas __________________ +.PP +.B fsinfo_cap_user_quotas +.br +.B fsinfo_cap_group_quotas +.br +.B fsinfo_cap_project_quotas +.IP +These indicate that the filesystem supports quotas for users, groups and +projects respectively. + +.\" __________________ fsinfo_cap_xattrs/filetypes __________________ +.PP +.B fsinfo_cap_xattrs +.br +.B fsinfo_cap_symlinks +.br +.B fsinfo_cap_hard_links +.br +.B fsinfo_cap_hard_links_1dir +.br +.B fsinfo_cap_device_files +.br +.B fsinfo_cap_unix_specials +.IP +These indicate that the filesystem supports respectively extended attributes; +symbolic links; hard links spanning direcories; hard links, but only within a +directory; block and character device files; and UNIX special files, such as +FIFO and socket. + +.\" __________________ fsinfo_cap_*journal* __________________ +.PP +.B fsinfo_cap_journal +.br +.B fsinfo_cap_data_is_journalled +.IP +The first of these indicates that the filesystem has a journal and the second +that the file data changes are being journalled. + +.\" __________________ fsinfo_cap_o_* __________________ +.PP +.B fsinfo_cap_o_sync +.br +.B fsinfo_cap_o_direct +.IP +These indicate that O_SYNC and O_DIRECT are supported respectively. + +.\" __________________ fsinfo_cap_o_* __________________ +.PP +.B fsinfo_cap_volume_id +.br +.B fsinfo_cap_volume_uuid +.br +.B fsinfo_cap_volume_name +.br +.B fsinfo_cap_volume_fsid +.br +.B fsinfo_cap_cell_name +.br +.B fsinfo_cap_domain_name +.br +.B fsinfo_cap_realm_name +.IP +These indicate if various attributes are supported by the filesystem, where +.B fsinfo_cap_X +here corresponds to +.BR fsinfo_attr_X . + +.\" __________________ fsinfo_cap_iver_* __________________ +.PP +.B fsinfo_cap_iver_all_change +.br +.B fsinfo_cap_iver_data_change +.br +.B fsinfo_cap_iver_mono_incr +.IP +These indicate if +.I i_version +on an inode in the filesystem is supported and +how it behaves. +.B all_change +indicates that i_version is incremented on metadata changes as well as data +changes. +.B data_change +indicates that i_version is only incremented on data changes, including +truncation. +.B mono_incr +indicates that i_version is incremented by exactly 1 for each change made. + +.\" __________________ fsinfo_cap_resource_forks __________________ +.TP +.B fsinfo_cap_resource_forks +This indicates that the filesystem supports some sort of resource fork or +alternate data stream on a file. This isn't the same as an extended attribute. + +.\" __________________ fsinfo_cap_name_* __________________ +.PP +.B fsinfo_cap_name_case_indep +.br +.B fsinfo_cap_name_non_utf8 +.br +.B fsinfo_cap_name_has_codepage +.IP +These indicate certain facts about the filenames in a filesystem: whether +they're case-independent; if they're not UTF-8; and if there's a codepage +employed to map the names. + +.\" __________________ fsinfo_cap_sparse __________________ +.TP +.B fsinfo_cap_sparse +This indicates that the filesystem supports sparse files. + +.\" __________________ fsinfo_cap_not_persistent __________________ +.TP +.B fsinfo_cap_not_persistent +This indicates that the filesystem is not persistent, and that any data stored +here will not be saved in the event that the filesystem is unmounted, the +machine is rebooted or the machine loses power. + +.\" __________________ fsinfo_cap_no_unix_mode __________________ +.TP +.B fsinfo_cap_no_unix_mode +This indicates that the filesystem doesn't support the UNIX mode permissions +bits. + +.\" __________________ fsinfo_cap_has_*time __________________ +.PP +.B fsinfo_cap_has_atime +.br +.B fsinfo_cap_has_btime +.br +.B fsinfo_cap_has_ctime +.br +.B fsinfo_cap_has_mtime +.IP +These indicate as to what timestamps a filesystem supports, including: Access +time, Birth/creation time, Change time (metadata and data) and Modification +time (data only). + + +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.SH RETURN VALUE +On success, the size of the value that the kernel has available is returned, +irrespective of whether the buffer is large enough to hold that. The data +written to the buffer will be truncated if it is not. On error, \-1 is +returned, and +.I errno +is set appropriately. +.SH ERRORS +.TP +.B EACCES +Search permission is denied for one of the directories +in the path prefix of +.IR pathname . +(See also +.BR path_resolution (7).) +.TP +.B EBADF +.I dirfd +is not a valid open file descriptor. +.TP +.B EFAULT +.I pathname +is NULL or +.IR pathname ", " params " or " buffer +point to a location outside the process's accessible address space. +.TP +.B EINVAL +Reserved flag specified in +.IR params->at_flags " or one of " params->__reserved[] +is not 0. +.TP +.B EOPNOTSUPP +Unsupported attribute requested in +.IR params->request . +This may be beyond the limit of the supported attribute set or may just not be +one that's supported by the filesystem. +.TP +.B ENODATA +Unavailable attribute value requested by +.IR params->Nth " and/or " params->Mth . +.TP +.B ELOOP +Too many symbolic links encountered while traversing the pathname. +.TP +.B ENAMETOOLONG +.I pathname +is too long. +.TP +.B ENOENT +A component of +.I pathname +does not exist, or +.I pathname +is an empty string and +.B AT_EMPTY_PATH +was not specified in +.IR params->at_flags . +.TP +.B ENOMEM +Out of memory (i.e., kernel memory). +.TP +.B ENOTDIR +A component of the path prefix of +.I pathname +is not a directory or +.I pathname +is relative and +.I dirfd +is a file descriptor referring to a file other than a directory. +.SH VERSIONS +.BR fsinfo () +was added to Linux in kernel 4.18. +.SH CONFORMING TO +.BR fsinfo () +is Linux-specific. +.SH NOTES +Glibc does not (yet) provide a wrapper for the +.BR fsinfo () +system call; call it using +.BR syscall (2). +.SH SEE ALSO +.BR ioctl_iflags (2), +.BR statx (2), +.BR statfs (2)man2/ioctl_iflags.2 +6
-0@@ -200,9 +200,15 @@ the effective user ID of the caller must match the owner of the file, or the caller must have the .BR CAP_FOWNER capability. +.PP +The set of flags supported by a filesystem can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_supports . .SH SEE ALSO .BR chattr (1), .BR lsattr (1), +.BR fsinfo (2), .BR mount (2), .BR btrfs (5), .BR ext4 (5),man2/stat.2 +7
-0@@ -532,6 +532,12 @@ If none of the aforementioned macros are defined, then the nanosecond values are exposed with names of the form .IR st_atimensec . .\" +.PP +Which timestamps are supported by a filesystem and their the ranges and +granularities can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_timestamp_info . .SS C library/kernel differences Over time, increases in the size of the .I stat@@ -707,6 +713,7 @@ main(int argc, char *argv[]) .BR access (2), .BR chmod (2), .BR chown (2), +.BR fsinfo (2), .BR readlink (2), .BR utime (2), .BR capabilities (7),man2/statx.2 +13
-0@@ -534,12 +534,25 @@ Glibc does not (yet) provide a wrapper for the .BR statx () system call; call it using .BR syscall (2). +.PP +The sets of mask/stx_mask and stx_attributes bits supported by a filesystem +can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_supports . +.PP +Which timestamps are supported by a filesystem and their the ranges and +granularities can also be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_timestamp_info . .SH SEE ALSO .BR ls (1), .BR stat (1), .BR access (2), .BR chmod (2), .BR chown (2), +.BR fsinfo (2), .BR readlink (2), .BR stat (2), .BR utime (2),man2/utime.2 +7
-0@@ -181,9 +181,16 @@ on an append-only file. .\" is just a wrapper for .\" .BR utime () .\" and hence does not allow a subsecond resolution. +.PP +Which timestamps are supported by a filesystem and their the ranges and +granularities can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_timestamp_info . .SH SEE ALSO .BR chattr (1), .BR touch (1), +.BR fsinfo (2), .BR futimesat (2), .BR stat (2), .BR utimensat (2),man2/utimensat.2 +7
-0@@ -633,9 +633,16 @@ instead checks whether the .\" conversely, a process with a read-only file descriptor won't .\" be able to update the timestamps of a file, .\" even if it has write permission on the file. +.PP +Which timestamps are supported by a filesystem and their the ranges and +granularities can be determined by calling +.IR fsinfo (2) +with attribute +.IR fsinfo_attr_timestamp_info . .SH SEE ALSO .BR chattr (1), .BR touch (1), +.BR fsinfo (2), .BR futimesat (2), .BR openat (2), .BR stat (2),
Signature · 3 lines
Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/
David Howells
maintainerRe: [MANPAGE PATCH] Add manpage for fsinfo(2)
Quoted 2 lines · Michael Kerrisk (man-pages)
There is no fsinfo(2) in the system call in the kernel currently. Will that call still be added,
Hopefully, but I'm not sure it'll be ready by the next merge window.
Quoted 1 line
or was it replaced by fsconfig(2),
They're different things and not interchangeable.
David
David Howells
maintainerPATCH 32/32 afs: Add fsinfo support [ver #9]
In reply to David HowellsAdd fsinfo support to the AFS filesystem.
---
fs/afs/super.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+)
fs/afs/super.c +133 -0
@@ -26,6 +26,7 @@#include <linux/sched.h> #include <linux/nsproxy.h> #include <linux/magic.h> +#include <linux/fsinfo.h> #include <net/net_namespace.h> #include "internal.h"
@@ -34,6 +35,7 @@ static void afs_kill_super(struct super_block *sb);static struct inode *afs_alloc_inode (struct super_block *sb);static void afs_destroy_inode (struct inode *inode);static int afs_statfs (struct dentry *dentry,struct kstatfs *buf); +static int afs_get_fsinfo (struct dentry *dentry,struct fsinfo_kparams *params);static int afs_show_devname (struct seq_file *m,struct dentry *root);static int afs_show_options (struct seq_file *m,struct dentry *root);static int afs_init_fs_context (struct fs_context *fc,struct dentry *reference);
@@ -51,6 +53,7 @@ int afs_net_id;static const struct super_operations afs_super_ops = { .statfs = afs_statfs, + .get_fsinfo = afs_get_fsinfo, .alloc_inode = afs_alloc_inode, .drop_inode = afs_drop_inode, .destroy_inode = afs_destroy_inode,
@@ -750,3 +753,133 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf)return ret; } + +/* +* Get filesystem information. +*/ +static int afs_get_fsinfo (struct dentry *dentry,struct fsinfo_kparams *params) +{ +struct fsinfo_timestamp_info *tsinfo; +struct fsinfo_server_address *addr; +struct fsinfo_capabilities *caps; +struct fsinfo_supports *sup; +struct afs_server_list *slist; +struct afs_super_info *as =AFS_FS_S (dentry->d_sb); +struct afs_addr_list *alist; +struct afs_server *server; +struct afs_volume *volume = as->volume; +struct afs_cell *cell = as->cell; +struct afs_net *net =afs_d2net (dentry); +bool dyn_root = as->dyn_root; +int ret; + +switch (params->request) { +case fsinfo_attr_timestamp_info: + tsinfo = params->buffer; + tsinfo->minimum_timestamp =0 ; + tsinfo->maximum_timestamp =UINT_MAX ; + tsinfo->mtime_gran_mantissa =1 ; + tsinfo->mtime_gran_exponent =0 ; +return sizeof (*tsinfo); + +case fsinfo_attr_supports: + sup = params->buffer; + sup->stx_mask = (STATX_TYPE |STATX_MODE | +STATX_NLINK | +STATX_UID |STATX_GID | +STATX_MTIME |STATX_INO | +STATX_SIZE ); + sup->stx_attributes =STATX_ATTR_AUTOMOUNT ; +return sizeof (*sup); + +case fsinfo_attr_capabilities: + caps = params->buffer; +if (dyn_root) { +fsinfo_set_cap (caps, fsinfo_cap_is_automounter_fs); +fsinfo_set_cap (caps, fsinfo_cap_automounts); + }else { +fsinfo_set_cap (caps, fsinfo_cap_is_network_fs); +fsinfo_set_cap (caps, fsinfo_cap_automounts); +fsinfo_set_cap (caps, fsinfo_cap_adv_locks); +fsinfo_set_cap (caps, fsinfo_cap_uids); +fsinfo_set_cap (caps, fsinfo_cap_gids); +fsinfo_set_cap (caps, fsinfo_cap_volume_id); +fsinfo_set_cap (caps, fsinfo_cap_volume_name); +fsinfo_set_cap (caps, fsinfo_cap_cell_name); +fsinfo_set_cap (caps, fsinfo_cap_iver_mono_incr); +fsinfo_set_cap (caps, fsinfo_cap_symlinks); +fsinfo_set_cap (caps, fsinfo_cap_hard_links_1dir); +fsinfo_set_cap (caps, fsinfo_cap_has_mtime); + } +return sizeof (*caps); + +case fsinfo_attr_volume_name: +if (dyn_root) +return -EOPNOTSUPP ; +if (params->buffer) +memcpy (params->buffer, volume->name, volume->name_len); +return volume->name_len; + +case fsinfo_attr_cell_name: +if (dyn_root) +return -EOPNOTSUPP ; +if (params->buffer) +memcpy (params->buffer, cell->name, cell->name_len); +return cell->name_len; + +case fsinfo_attr_server_name: +if (dyn_root) +return -EOPNOTSUPP ; +read_lock (&volume->servers_lock); + slist =afs_get_serverlist (volume->servers); +read_unlock (&volume->servers_lock); + +if (params->Nth < slist->nr_servers) { + server = slist->servers[params->Nth].server; +if (params->buffer) + ret =sprintf (params->buffer,"%pU" , &server->uuid); +else + ret =16 *2 +4 ; + }else { + ret = -ENODATA ; + } + +afs_put_serverlist (net, slist); +return ret; + +case fsinfo_attr_server_address: + addr = params->buffer; +if (dyn_root) +return -EOPNOTSUPP ; +read_lock (&volume->servers_lock); + slist =afs_get_serverlist (volume->servers); +read_unlock (&volume->servers_lock); + + ret = -ENODATA ; +if (params->Nth >= slist->nr_servers) + goto put_slist; + server = slist->servers[params->Nth].server; + +read_lock (&server->fs_lock); + alist =afs_get_addrlist (rcu_access_pointer (server->addresses)); +read_unlock (&server->fs_lock); +if (!alist) + goto put_slist; + +if (params->Mth >= alist->nr_addrs) + goto put_alist; + +memcpy (addr, &alist->addrs[params->Mth], +sizeof (struct sockaddr_rxrpc )); + ret =sizeof (*addr); + + put_alist: +afs_put_addrlist (alist); + put_slist: +afs_put_serverlist (net, slist); +return ret; + +default : +return generic_fsinfo (dentry, params); + } +}
Quoted 11 lines · David Howells
Here are a set of patches to create a filesystem context prior to setting up a new mount, populating it with the parsed options/binary data, creating the superblock and then effecting the mount. This is also used for remount since much of the parsing stuff is common in many filesystems.
This allows namespaces and other information to be conveyed through the mount procedure.
This also allows Miklós Szeredi's idea of doing:
Quoted 7 lines
fd = fsopen("nfs"); write(fd, "option=val", ...); mfd = fsmount(fd, MS_NODEV); move_mount(mfd, "", AT_FDCWD, "/mnt", MOVE_MOUNT_F_EMPTY_PATH);that he presented at LSF-2017 to be implemented (see the relevant patches in the series).
All your documentation (both commit logs, man-pages and in-kernel actual docs you add) only talk about "what".
They don't talk about _why_.
I can imagine why's. But I think that the "why" is actually way mnore important than the what. At no point did I see a "this is the current interface, and it doesn't work for xyz, so here's the new interface that allows us to do stuff".
When you have a diffstat like this:
171 files changed, 7147 insertions(+), 1805 deletions(-)
I sure want to see an explanation for *WHY* it adds 5000+ lines of core code.
Also, I want to hear about sane security models. One of the things people really want to do is have users do their own mounts. We've had security issues in that area. Why does this improve on it, or make it even worse?
And by "secuyrity models" I absolutely do not mean "here's how you can do complex smack rules for it".
Linus
David Howells
maintainerQuoted 9 lines · Linus Torvalds
All your documentation (both commit logs, man-pages and in-kernel actual docs you add) only talk about "what".
They don't talk about _why_.
I can imagine why's. But I think that the "why" is actually way mnore important than the what. At no point did I see a "this is the current interface, and it doesn't work for xyz, so here's the new interface that allows us to do stuff".
Firstly, there are a bunch of problems with the current mount(2) syscall:
(1) It's actually six or seven different interfaces rolled into one and weird combinations of flags make it do different things beyond the original specification of the syscall.
(2) It produces a particularly large and diverse set of errors, which have to be mapped back to a small error code. Yes, there's dmesg - if you have it configured - but you can't necessarily see that if you're doing a mount inside of a container.
(3) It copies a PAGE_SIZE block of data for each of the type, device name and options.
(4) The size of the buffers is PAGE_SIZE - and this is arch dependent.
(5) You can't mount into another mount namespace. I could, for example, build a container without having to be in that container's namespace if I can do it from outside.
(6) It's not really geared for the specification of multiple sources, but some filesystems really want that - overlayfs, for example.
and some problems in the internal kernel api:
(1) There's no defined way to supply namespace configuration for the superblock - so, for instance, I can't say that I want to create a superblock in a particular network namespace (on automount, say).
NFS hacks around this by creating multiple shadow file_system_types with different ->mount() ops.
(2) When calling mount internally, unless you have NFS-like hacks, you have to generate or otherwise provide text config data which then gets parsed, when some of the time you could bypass the parsing stage entirely.
(3) The amount of data in the data buffer is not known, but the data buffer might be on a kernel stack somewhere, leading to the possibility of tripping the stack underrun guard.
and other issues too:
(1) Superblock remount in some filesystems applies options on an as-parsed basis, so if there's a parse failure, a partial alteration with no rollback is effected.
(2) Under some circumstances, the mount data may get copied multiple times so that it can have multiple parsers applied to it or because it has to be parsed multiple times - for instance, once to get the preliminary info required to access the on-disk superblock and then again to update the superblock record in the kernel.
I want to be able to add support for a bunch of things:
(1) UID, GID and Project ID mapping/translation. I want to be able to install a translation table of some sort on the superblock to translate source identifiers (which may be foreign numeric UIDs/GIDs, text names, GUIDs) into system identifiers. This needs to be done before the superblock is published[*].
Note that this may, for example, involve using the context and the superblock held therein to issue an RPC to a server to look up translations.
[*] By "published" I mean made available through mount so that other
userspace processes can access it by path.
Maybe specifying a translation range element with something like:
write(fd, "t uid <srcuid> <nsuid> <count>");
The translation information also needs to propagate over an automount in some circumstances.
(2) Namespace configuration. I want to be able to tell the superblock creation process what namespaces should be applied when it created (in particular the userns and netns) for containerisation purposes, e.g.:
write(fd, "n user=<fd> net=<fd>");
(3) Namespace propagation. I want to have a properly defined mechanism for propagating namespace configuration over automounts within the kernel. This will be particularly useful for network filesystems.
(4) Pre-mount attribute query. A chunk of the changes is actually the fsinfo() syscall to query attributes of the filesystem beyond what's available in statx() and statfs(). This will allow a created superblock to be queried before it is published.
(5) Upcall for configuration. I would like to be able to query configuration that's stored in userspace when an automount is made. For instance, to look up network parameters for NFS or to find a cache selector for fscache.
The internal fs_context could be passed to the upcall process or the kernel could read a config file directly if named appropriately for the superblock, perhaps:
[/etc/fscontext.d/afs/example.com/cell.cfg] realm = EXAMPLE.COM
translation = uid,3000,4000,100 fscache = tag=fred
(6) Event notifications. I want to be able to install a watch on a superblock before it is published to catch things like quota events and EIO.
(7) Large and binary parameters. There might be at some point a need to pass large/binary objects like Microsoft PACs around. If I understand PACs correctly, you can obtain these from the Kerberos server and then pass them to the file server when you connect.
Having it possible to pass large or binary objects as individual writes makes parsing these trivial. OTOH, some or all of this can potentially be handled with the use of the keyrings interface - as the afs filesystem does for passing kerberos tokens around; it's just that that seems overkill for a parameter you may only need once.
Quoted 5 lines
When you have a diffstat like this:
171 files changed, 7147 insertions(+), 1805 deletions(-)I sure want to see an explanation for *WHY* it adds 5000+ lines of core code.
Note that there's a chunk more core code to be removed too, once all the filesystems have been converted, including some of the added code.
Quoted 4 lines
Also, I want to hear about sane security models. One of the things people really want to do is have users do their own mounts. We've had security issues in that area. Why does this improve on it, or make it even worse?
At the moment, I think it's fairly neutral in that regard. Currently, you have to have CAP_SYS_ADMIN to call fsopen() and again to call fsmount().
To supervise user-triggered mounting, I might need to add something to permit upcalling for permission or configuration, then this could be in the parent of a container, say, or something dispatched from systemd in the system root. It should be able to restrict the sources and options that a non-privileged or container-based mount request is given.
An upcall to an arbiter could be passed the fs-context fd as an argument and could then use fsinfo() to query the context, including the option flags.
It also might be possible to handle this through LSM policy, particularly if I formalise the specification of *all* sources in the context. For example, I could require things like:
write(fd, "s store /dev/sda1"); // Specify the storage device
write(fd, "s jnl /dev/sda2"); // Specify a separate journal
write(fd, "s nfs example.com"); // Specify an NFS server
write(fd, "s afs example.com"); // Specify an AFS cell
Then the LSMs could be asked to rule on whether the "store" and "jnl" block devices could be used for those purposes by the caller and "nfs" or "afs" names could be looked up in the DNS.
David
David Howells
maintainerGetting rid of the usage of write() -- was Re: [PATCH 00/32] VFS: Introduce filesystem context [ver #9]
In reply to David HowellsHi Linus, Al,
I'm thinking of adding in the attached patch as a starting point for replacing write() as the method by which configuration/actioning is done.
For the moment, it just glues the key and the value back together inside the kernel and passes that on to the filesystem. I'm still working on a patch to pass key,val pairs through, but just the patch below would allow Al to take up the UAPI bits into linux-next.
David
---
vfs: Add a syscall for configuring and triggering actions on a context
Add a syscall for configuring a filesystem creation context and triggering actions upon it, to be used in conjunction with fsopen, fspick and fsmount.
long fsconfig(int fs_fd, unsigned int cmd, const char *key,
const void *value, int aux);
Where fs_fd indicates the context, cmd indicates the action to take, key indicates the parameter name for parameter-setting actions and, if needed, value points to a buffer containing the value and aux can give more information for the value.
The following command IDs are proposed:
(*) fsconfig_set_flag: No value is specified. The parameter must be
boolean in nature. The key may be prefixed with "no" to invert the setting. value must be NULL and aux must be 0.
(*) fsconfig_set_string: A string value is specified. The parameter can
be expecting boolean, integer, string or take a path. A conversion to an appropriate type will be attempted (which may include looking up as a path). value points to a NUL-terminated string and aux must be 0.
(*) fsconfig_set_binary: A binary blob is specified. value points to
the blob and aux indicates its size. The parameter must be expecting a blob.
(*) fsconfig_set_path: A non-empty path is specified. The parameter must
be expecting a path object. value points to a NUL-terminated string that is the path and aux is a file descriptor at which to start a relative lookup or AT_FDCWD.
(*) fsconfig_set_path_empty: As fsconfig_set_path, but with AT_EMPTY_PATH
implied.
(*) fsconfig_set_fd: An open file descriptor is specified. value must
be NULL and aux indicates the file descriptor.
(*) fsconfig_cmd_create: Trigger superblock creation.
(*) fsconfig_cmd_reconfigure: Trigger superblock reconfiguration.
For the "set" command IDs, the idea is that the file_system_type will point to a list of parameters and the types of value that those parameters expect to take. The core code can then do the parse and argument conversion and then give the LSM and FS a cooked option or array of options to use.
Source specification is also done the same way same way, using special keys "source", "source1", "source2", etc..
[!] Note that, for the moment, the key and value are just glued back together and handed to the filesystem. Every filesystem that uses options uses match_token() and co. to do this, and this will need to be changed - but not all at once.
Example usage:
fd = fsopen("ext4", FSOPEN_CLOEXEC);
fsconfig(fd, fsconfig_set_path, "source", "/dev/sda1", AT_FDCWD);
fsconfig(fd, fsconfig_set_path_empty, "journal_path", "", journal_fd);
fsconfig(fd, fsconfig_set_fd, "journal_fd", "", journal_fd);
fsconfig(fd, fsconfig_set_flag, "user_xattr", NULL, 0);
fsconfig(fd, fsconfig_set_flag, "noacl", NULL, 0);
fsconfig(fd, fsconfig_set_string, "sb", "1", 0);
fsconfig(fd, fsconfig_set_string, "errors", "continue", 0);
fsconfig(fd, fsconfig_set_string, "data", "journal", 0);
fsconfig(fd, fsconfig_set_string, "context", "unconfined_u:...", 0);
fsconfig(fd, fsconfig_cmd_create, NULL, NULL, 0);
mfd = fsmount(fd, FSMOUNT_CLOEXEC, MS_NOEXEC);or:
fd = fsopen("ext4", FSOPEN_CLOEXEC);
fsconfig(fd, fsconfig_set_string, "source", "/dev/sda1", 0);
fsconfig(fd, fsconfig_cmd_create, NULL, NULL, 0);
mfd = fsmount(fd, FSMOUNT_CLOEXEC, MS_NOEXEC);or:
fd = fsopen("afs", FSOPEN_CLOEXEC);
fsconfig(fd, fsconfig_set_string, "source", "#grand.central.org:root.cell", 0);
fsconfig(fd, fsconfig_cmd_create, NULL, NULL, 0);
mfd = fsmount(fd, FSMOUNT_CLOEXEC, MS_NOEXEC);or:
fd = fsopen("jffs2", FSOPEN_CLOEXEC);
fsconfig(fd, fsconfig_set_string, "source", "mtd0", 0);
fsconfig(fd, fsconfig_cmd_create, NULL, NULL, 0);
mfd = fsmount(fd, FSMOUNT_CLOEXEC, MS_NOEXEC);
---
arch/x86/entry/syscalls/syscall_32.tbl | 1
arch/x86/entry/syscalls/syscall_64.tbl | 1
fs/fs_context.c | 177 ++++++++++------
fs/fsopen.c | 363 +++++++++++++++++++++------------
include/linux/fs_context.h | 2
include/linux/syscalls.h | 2
include/uapi/linux/fs.h | 14 +
samples/mount_api/test-fsmount.c | 24 +-
8 files changed, 382 insertions(+), 202 deletions(-)arch/x86/entry/syscalls/syscall_32.tbl +1 -0
@@ -404,3 +404,4 @@ 390 i386 fsmount sys_fsmount __ia32_sys_fsmount 391 i386 fspick sys_fspick __ia32_sys_fspick 392 i386 fsinfo sys_fsinfo __ia32_sys_fsinfo +393 i386 fsconfig sys_fsconfig __ia32_sys_fsconfig
arch/x86/entry/syscalls/syscall_64.tbl +1 -0
@@ -349,6 +349,7 @@ 338 common fsmount __x64_sys_fsmount 339 common fspick __x64_sys_fspick 340 common fsinfo __x64_sys_fsinfo +341 common fsconfig __x64_sys_fsconfig # # x32-specific system call numbers start at 512 to avoid cache impact
fs/fs_context.c +116 -61
248 lines not on this page · raw message
fs/fsopen.c +232 -131
380 lines not on this page · raw message
include/linux/fs_context.h +1 -1
@@ -99,7 +99,7 @@ extern struct fs_context *vfs_new_fs_context(struct file_system_type *fs_type,extern struct fs_context *vfs_sb_reconfig (struct path *path,unsigned int ms_flags);extern struct fs_context *vfs_dup_fs_context (struct fs_context *src);extern int vfs_set_fs_source (struct fs_context *fc,const char *source,size_t len); -extern int vfs_parse_fs_option (struct fs_context *fc,char *opt,size_t len); +extern int vfs_parse_fs_option (struct fs_context *fc,char *key,void *value,size_t v_len);extern int generic_parse_monolithic (struct fs_context *fc,void *data,size_t data_size);extern int vfs_get_tree (struct fs_context *fc);extern void put_fs_context (struct fs_context *fc);
include/linux/syscalls.h +2 -0
@@ -911,6 +911,8 @@ asmlinkage long sys_fspick(int dfd, const char __user *path, unsigned int flags)asmlinkage long sys_fsinfo (int dfd,const char __user *path,struct fsinfo_params __user *params,void __user *buffer,size_t buf_size); +asmlinkage long sys_fsconfig (int fs_fd,unsigned int cmd,const char __user *key, +const void __user *value,unsigned int aux);/* * Architecture-specific system calls
include/uapi/linux/fs.h +14 -0
@@ -356,4 +356,18 @@ typedef int __bitwise __kernel_rwf_t;#define FSPICK_NO_AUTOMOUNT 0x00000004#define FSPICK_EMPTY_PATH 0x00000008 +/* +* The type of fsconfig() call made. +*/ +enum fsconfig_command { + fsconfig_set_flag,/* Set parameter, supplying no value */ + fsconfig_set_string,/* Set parameter, supplying a string value */ + fsconfig_set_binary,/* Set parameter, supplying a binary blob value */ + fsconfig_set_path,/* Set parameter, supplying an object by path */ + fsconfig_set_path_empty,/* Set parameter, supplying an object by (empty) path */ + fsconfig_set_fd,/* Set parameter, supplying an object by fd */ + fsconfig_cmd_create,/* Invoke superblock creation */ + fsconfig_cmd_reconfigure,/* Invoke superblock reconfiguration */ +}; +#endif /* _UAPI_LINUX_FS_H */
samples/mount_api/test-fsmount.c +15 -9
@@ -16,7 +16,7 @@#include <fcntl.h> #include <sys/prctl.h> #include <sys/wait.h> -#include <linux/mount.h> +#include <linux/fs.h> #include <linux/unistd.h> #define E (x) do { if ((x) == -1) { perror(#x); exit(1); } } while(0)
@@ -58,12 +58,6 @@ void mount_error(int fd, const char *s)exit (1 ); } -#define E_write (fd, s) \ - do { \ - if (write(fd, s, sizeof(s) - 1) == -1) \ - mount_error(fd, s); \ - } while (0) -static inline int fsopen (const char *fs_name,unsigned int flags) {return syscall (__NR_fsopen, fs_name, flags);
@@ -74,6 +68,12 @@ static inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)return syscall (__NR_fsmount, fsfd, flags, ms_flags); } +static inline int fsconfig (int fsfd,unsigned int cmd, +const char *key,const void *val,int aux) +{ +return syscall (__NR_fsconfig, fsfd, cmd, key, val, aux); +} +static inline int move_mount (int from_dfd,const char *from_pathname,int to_dfd,const char *to_pathname,unsigned int flags)
@@ -83,6 +83,12 @@ static inline int move_mount(int from_dfd, const char *from_pathname, to_dfd, to_pathname, flags); } +#define E_fsconfig (fd, cmd, key, val, aux) \ + do { \ + if (fsconfig(fd, cmd, key, val, aux) == -1) \ + mount_error(fd, key ?: "create"); \ + } while (0) +int main (int argc,char *argv[]) {int fsfd, mfd;
@@ -94,8 +100,8 @@ int main(int argc, char *argv[])exit (1 ); } -E_write (fsfd,"s #grand.central.org:root.cell." ); -E_write (fsfd,"x create" ); +E_fsconfig (fsfd, fsconfig_set_string,"source" ,"#grand.central.org:root.cell." ,0 ); +E_fsconfig (fsfd, fsconfig_cmd_create,NULL ,NULL ,0 ); mfd =fsmount (fsfd,0 ,MS_RDONLY );if (mfd <0 )