fsconfig(2)
πΈ NAME πΈ
fsconfig β configure new or existing filesystem context
(it lives in section 2 of the Linux manual, aka the System Calls Manual, so yeah bestie, this is kernel business π )
π LIBRARY π
Standard C library (libc, -lc)
β¨ SYNOPSIS β¨
#include <sys/mount.h>
int fsconfig(int fd, unsigned int cmd,
const char *_Nullable key,
const void *_Nullable value, int aux);
π DESCRIPTION π
Okay so fsconfig() is part of the whole suite of file-descriptor-based mount facilities in Linux. Think of it as the girl in the group chat who actually knows what's going on with your mounts.
fsconfig() is how you supply parameters to β and issue commands against β the filesystem configuration context that's hanging out behind the file descriptor fd. And where do those contexts come from? Two places, bestie:
- You can create one with
fsopen(2), or - you can instantiate one from a filesystem instance that already exists, using
fspick(2).
The cmd argument is the command getting issued. Some commands just feed parameters into the context (this is the equivalent of mount options you'd pass to mount(8)), and the other ones are meta-operations on the filesystem context itself. Here's the full list of valid cmd values, no gatekeeping:
FSCONFIG_SET_FLAGβ Sets the flag parameter named by key. value must beNULL, and aux must be0.FSCONFIG_SET_STRINGβ Sets the string parameter named by key to the value you point at with value. value points to a null-terminated string, and aux must be0.FSCONFIG_SET_BINARYβ Sets the blob parameter named by key to the contents of the binary blob in value. value points to the start of a buffer that is aux bytes long.FSCONFIG_SET_FDβ Sets the file parameter named by key to the open file description referenced by the file descriptor aux. value must beNULL.
You can also use FSCONFIG_SET_STRING for file parameters, with value set to a null-terminated string holding a base-10 representation of the file descriptor number. This route exists mainly for compatibility with older mount(2)-based programs, and it only works for parameters that accept nothing but file descriptor arguments. iykyk.
FSCONFIG_SET_PATHβ Sets the path parameter named by key to the object at a provided path, resolved in a way that's similar toopenat(2). value points to a null-terminated pathname string, and aux is equivalent to the dirfd argument ofopenat(2). Go readopenat(2) for whyFSCONFIG_SET_PATHeven needs to exist.
You can also use FSCONFIG_SET_STRING for path parameters β that behaves exactly like FSCONFIG_SET_PATH with aux set to AT_FDCWD.
FSCONFIG_SET_PATH_EMPTYβ Same asFSCONFIG_SET_PATH, except that if value is an empty string, the file descriptor specified by aux is operated on directly and can be any type of file β not just a directory. This is equivalent to whatAT_EMPTY_PATHdoes with most"*at()"system calls. And if aux isAT_FDCWD, the parameter gets set to the current working directory of the calling process.FSCONFIG_CMD_CREATEβ This one tells the filesystem driver to instantiate an instance of the filesystem in the kernel, using the parameters sitting in the filesystem configuration context. key and value must beNULL, and aux must be0.
This command can only be issued once in the lifetime of a filesystem context. No reruns, bestie. If it succeeds, the filesystem context behind file descriptor fd now references the created filesystem instance, and it drops into a special "awaiting-mount" mode that lets you use fsmount(2) to make a mount object from that filesystem instance. If it fails, in most cases the filesystem context goes into failed mode and is done β you can't use it for any further fsconfig() operations (you can still pull diagnostic messages through the message retrieval interface though, as described in the corresponding subsection of fsopen(2)).
This command can only be issued against filesystem configuration contexts that were created with fsopen(2). And to create a filesystem instance at all, the calling process needs the CAP_SYS_ADMIN capability.
Now here's the important tea: the Linux kernel will silently reuse extant filesystem instances depending on the filesystem type and the parameters you configured (every filesystem driver has its own policy about how instances get reused). Which means the filesystem instance "created" by FSCONFIG_CMD_CREATE might, in fact, just be a reference to a filesystem instance that was already chilling in the kernel. (For reference, this behavior applies to mount(2) too.)
One side-effect of that: if an extant filesystem instance gets reused, all the parameters you configured for this filesystem configuration context are silently ignored β with the exception of the ro and rw flag parameters. And if the state of the read-only flag in the extant filesystem instance and the one in the filesystem configuration context don't match, this operation returns EBUSY. It also means any FSCONFIG_CMD_RECONFIGURE commands issued against the "created" filesystem instance will affect every mount object associated with that extant instance too. π
So if a program genuinely needs a brand-new filesystem instance with specific parameters β especially security-related ones like acl, which enables POSIX ACLs as described in acl(5) β it should use FSCONFIG_CMD_CREATE_EXCL instead. Periodt.
FSCONFIG_CMD_CREATE_EXCL(since Linux 6.6) β Same asFSCONFIG_CMD_CREATE, except the kernel is told not to reuse extant filesystem instances. If the operation would be forced to reuse one anyway, it returnsEBUSYinstead.
And as a result (unlike FSCONFIG_CMD_CREATE), if this operation succeeds, the calling process can be sure that every parameter it successfully configured with fsconfig() will actually be applied to the created filesystem instance. King behavior, honestly. π
FSCONFIG_CMD_RECONFIGUREβ This one tells the filesystem driver to apply the parameters in the filesystem configuration context to the extant filesystem instance that the context references. key and value must beNULL, and aux must be0.
It's mainly meant to be used with fspick(2), but you can also use it to modify the parameters of a filesystem instance after FSCONFIG_CMD_CREATE was used to create it and a mount object was created with fsmount(2). To reconfigure an extant filesystem instance, the calling process needs the CAP_SYS_ADMIN capability.
If it succeeds, the filesystem context gets reset but stays in reconfiguration mode, so you can reuse it for subsequent FSCONFIG_CMD_RECONFIGURE commands. If it fails, in most cases the filesystem context goes into failed mode and can't be used for any more fsconfig() operations (you can still retrieve diagnostic messages through the message retrieval interface though, as described in the corresponding subsection of fsopen(2)).
π«Ά Heads up bestie: parameters you set with anyFSCONFIG_SET_*command do not take effect until a correspondingFSCONFIG_CMD_CREATEorFSCONFIG_CMD_RECONFIGUREcommand gets issued. They're just vibing in the context until then.
π¦ RETURN VALUE π¦
On success, fsconfig() returns 0. On error, it returns -1, and errno is set to indicate the error. Slay when it's 0, cry when it's -1.
β¨ to be continuedβ¦ β¨
π₯ ERRORS π₯
Okay so when something goes sideways, bestie, the filesystem driver might have more to say about it. Like, it can drop extra deets about the error through the message retrieval interface for filesystem configuration contexts. You can grab that extra info whenever you want by calling read(2) on the filesystem instance or the filesystem configuration context that fd points at. (Peep the "Message retrieval interface" subsection over in fsopen(2) for the whole tea on the message format.) π«
And here's the iconically forgiving part: even after an error happens, the filesystem configuration context is not invalidated. She lives! So you can keep using her with other fsconfig() commands. Which means users can literally probe support for filesystem parameters one at a time, parameter by parameter, and vibe-check which ones they actually wanna set. πΈ
The error values down below are the filesystem-type-independent ones. Every filesystem type can have its own special little errors and its own special behavior β check the Linux kernel source code for those β¨
EACCESβ a component of a path you passed as a path parameter was not searchable. (Also seepath_resolution(7).)EACCESβFSCONFIG_CMD_CREATEwas attempted for a read-only filesystem without specifying theroflag parameter.EACCESβ a specified block device parameter is located on a filesystem mounted with theMS_NODEVoption.EBADFβ the file descriptor given byfd(or possibly byaux, depending on the command) is invalid.EBUSYβ the filesystem context associated withfdis in the wrong state for the given command.EBUSYβ the filesystem instance cannot be reconfigured as read-only withFSCONFIG_CMD_RECONFIGUREbecause some programs still hold files open for writing.EBUSYβ a new filesystem instance was requested withFSCONFIG_CMD_CREATE_EXCLbut a matching superblock already existed.EFAULTβ one of the pointer arguments points to a location outside the calling process's accessible address space.EINVALβfddoes not refer to a filesystem configuration context or filesystem instance.EINVALβ one of the values ofkey,value, and/orauxwere set to a non-zero value whencmdrequired that they be zero (orNULL).EINVALβ the parameter named bykeycannot be set using the type specified withcmd.EINVALβ one of the source parameters referred to an invalid superblock.ELOOPβ too many links encountered during pathname resolution of a path argument.ENAMETOOLONGβ a path argument was longer thanPATH_MAX.ENOENTβ a path argument had a non-existent component.ENOENTβ a path argument is an empty string, butcmdis notFSCONFIG_SET_PATH_EMPTY.ENOMEMβ the kernel could not allocate sufficient memory to complete the operation.ENOTBLKβ the parameter named bykeymust be a block device, but the provided parameter value was not a block device.ENOTDIRβ a component of the path prefix of a path argument was not a directory.EOPNOTSUPPβ the command given bycmdis not valid.ENXIOβ the major number of a block device parameter is out of range.EPERMβ the command given bycmdwasFSCONFIG_CMD_CREATE,FSCONFIG_CMD_CREATE_EXCL, orFSCONFIG_CMD_RECONFIGURE, but the calling process does not have the requiredCAP_SYS_ADMINcapability.
π STANDARDS π
Linux. That's it. That's the standard. π
π°οΈ HISTORY π°οΈ
Linux 5.2. glibc 2.36. Ancient history in tech years, honestly. π
π NOTES π
𧬠Generic filesystem parameters π§¬
So here's the thing: each filesystem driver is the one responsible for parsing most parameters you specify with fsconfig(). Meaning individual filesystems can act completely differently when they run into parameters with the same name. In general, do not assume that what fsconfig() does when you hand a parameter to one filesystem type will match what the same parameter does on a different filesystem type. It's giving "everyone's got their own rules." π
However β the following generic parameters apply to all filesystems and have unified behavior. You set them using the listed FSCONFIG_SET_* command. Slay, consistency! β¨
roandrw(FSCONFIG_SET_FLAG) β configure whether the filesystem instance is read-only.dirsync(FSCONFIG_SET_FLAG) β make directory changes on this filesystem instance synchronous.syncandasync(FSCONFIG_SET_FLAG) β configure whether writes on this filesystem instance will be made synchronous (as though theO_SYNCflag toopen(2)was specified for all file opens in this filesystem instance).lazytimeandnolazytime(FSCONFIG_SET_FLAG) β configure whether to reduce on-disk updates of inode timestamps on this filesystem instance (as described in theMS_LAZYTIMEsection ofmount(2)).mandandnomand(FSCONFIG_SET_FLAG) β configure whether the filesystem instance should permit mandatory locking. Since Linux 5.15, mandatory locking has been deprecated and setting this flag is a no-op. πsource(FSCONFIG_SET_STRING) β this parameter is equivalent to thesourceparameter passed tomount(2)for the same filesystem type, and is usually the pathname of a block device containing the filesystem. This parameter may only be set once per filesystem configuration context transaction.
Plus! Any filesystem parameters associated with Linux Security Modules (LSMs) are also generic with respect to the underlying filesystem. See the documentation for the LSM you wish to configure for more details. π
ποΈ Mount attributes and filesystem parameters ποΈ
Some filesystem parameters (traditionally associated with mount(8)-style options) have a sibling mount attribute with superficially similar user-facing behavior. Lowkey they look alike, highkey they're not the same thing.
For a full description of the distinction between mount attributes and filesystem parameters, go read the "Mount attributes and filesystem parameters" subsection of mount_setattr(2). π¦
β οΈ CAVEATS β οΈ
π Filesystem parameter types π
Because each filesystem driver is responsible for parsing most parameters specified with fsconfig(), some filesystem drivers may have unintuitive behavior with regards to which FSCONFIG_SET_* commands are permitted to configure a given parameter. Not them being mysterious about it. π
In order for filesystem parameters to be backwards compatible with mount(2), they must be parseable as strings; this almost universally means that FSCONFIG_SET_STRING can also be used to configure them. However, other FSCONFIG_SET_* commands need to be opted into by each filesystem driver's parameter parser.
One of the most user-visible instances of this inconsistency is that many filesystems do not support configuring path parameters with FSCONFIG_SET_PATH (despite the name, bestie, make it make sense), which can lead to somewhat confusing EINVAL errors. (For example, the generic source parameter β which is usually a path β can only be configured with FSCONFIG_SET_STRING.) π€
When writing programs that usefsconfig()to configure parameters with commands other thanFSCONFIG_SET_STRING, users should verify that theFSCONFIG_SET_*commands used to configure each parameter are supported by the corresponding filesystem driver. No cap, always check first. π«Ά
π EXAMPLES π
To illustrate the different kinds of flags that can be configured with fsconfig(), here are a few examples of some different filesystems being created:
int fsfd, mntfd;
fsfd = fsopen("tmpfs", FSOPEN_CLOEXEC);
fsconfig(fsfd, FSCONFIG_SET_FLAG, "inode64", NULL, 0);
fsconfig(fsfd, FSCONFIG_SET_STRING, "uid", "1234", 0);
fsconfig(fsfd, FSCONFIG_SET_STRING, "huge", "never", 0);
fsconfig(fsfd, FSCONFIG_SET_FLAG, "casefold", NULL, 0);
fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
mntfd = fsmount(fsfd, FSMOUNT_CLOEXEC, MOUNT_ATTR_NOEXEC);
move_mount(mntfd, "", AT_FDCWD, "/tmp", MOVE_MOUNT_F_EMPTY_PATH);
fsfd = fsopen("erofs", FSOPEN_CLOEXEC);
fsconfig(fsfd, FSCONFIG_SET_STRING, "source", "/dev/loop0", 0);
fsconfig(fsfd, FSCONFIG_SET_FLAG, "acl", NULL, 0);
fsconfig(fsfd, FSCONFIG_SET_FLAG, "user_xattr", NULL, 0);
fsconfig(fsfd, FSCONFIG_CMD_CREATE_EXCL, NULL, NULL, 0);
mntfd = fsmount(fsfd, FSMOUNT_CLOEXEC, MOUNT_ATTR_NOSUID);
move_mount(mntfd, "", AT_FDCWD, "/mnt", MOVE_MOUNT_F_EMPTY_PATH);
Usually, specifying the same parameter named by key multiple times with fsconfig() causes the parameter value to be replaced. However, some filesystems may have unique behavior. Main character filesystems don't follow the rules: π
int fsfd, mntfd;
int lowerdirfd = open("/o/ctr/lower1", O_DIRECTORY | O_CLOEXEC);
fsfd = fsopen("overlay", FSOPEN_CLOEXEC);
/* "lowerdir+" appends to the lower dir stack each time */
fsconfig(fsfd, FSCONFIG_SET_FD, "lowerdir+", NULL, lowerdirfd);
fsconfig(fsfd, FSCONFIG_SET_STRING, "lowerdir+", "/o/ctr/lower2", 0);
fsconfig(fsfd, FSCONFIG_SET_STRING, "lowerdir+", "/o/ctr/lower3", 0);
fsconfig(fsfd, FSCONFIG_SET_STRING, "lowerdir+", "/o/ctr/lower4", 0);
fsconfig(fsfd, FSCONFIG_SET_STRING, "xino", "auto", 0);
fsconfig(fsfd, FSCONFIG_SET_STRING, "nfs_export", "off", 0);
fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
mntfd = fsmount(fsfd, FSMOUNT_CLOEXEC, 0);
move_mount(mntfd, "", AT_FDCWD, "/mnt", MOVE_MOUNT_F_EMPTY_PATH);
And here is an example of how fspick(2) can be used with fsconfig() to reconfigure the parameters of an extant filesystem instance attached to /proc:
int fsfd = fspick(AT_FDCWD, "/proc", FSPICK_CLOEXEC);
fsconfig(fsfd, FSCONFIG_SET_STRING, "hidepid", "ptraceable", 0);
fsconfig(fsfd, FSCONFIG_SET_STRING, "subset", "pid", 0);
fsconfig(fsfd, FSCONFIG_CMD_RECONFIGURE, NULL, NULL, 0);
π SEE ALSO π
fsmount(2), fsopen(2), fspick(2), mount(2), mount_setattr(2), move_mount(2), open_tree(2), mount_namespaces(7)
OK bestie that's the whole page, we ate and left no crumbs. π½οΈβ¨ This one's from Linux man-pages 6.20, dated 2025-12-25, and it's all about fsconfig(2). Go mount something iconic. π
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: Linux-man-pages-copyleft
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms