I'm presently writing a filesystem. The statvfs
(and even the statfs
) structs contain a field specifying the maximum length of a name in that path. As PATH_MAX
is defined in the pathconf
manpage (getconf
), this means it is defined on a per-directory basis (and thus, determined by the underlying filesystem). How does one specify this value?
Since this question is tagged "FUSE" ...
I just ran into this issue while working on a FUSE filesystem. I wrote an e-mail to the FUSE developers, seeking clarification. Reply from the current libfuse
maintainer (January 2018): There is not a way to specify the maximum path length in a FUSE filesystem [driver].
Is there a way for a FUSE filesystem to inform software running on top of it about the correct maximum path length?
Not at the moment, no.
If not, should there be?
Probably yes. Patches welcome :-)
For reference: Full e-mail thread
PATH_MAX
mostly behaves as a property of the file system function call interface, so I don't think it makes much sense to have it vary across directories.
For example, renaming or moving a directory with large directory trees in it may make the longest absolute pathname longer and it would be complicated and inefficient to limit that.
Instead, PATH_MAX
serves to allow the kernel to copy passed pathnames to temporary unpaged memory, which can then be processed without needing to allow for a page fault at each access. Allocating huge amounts of such memory may block most other things the kernel is doing or even cause kernel panics.
pathconf()
function can return different values depending on the filename you pass to it, which means it can vary depending on the file system represented by that directory. However, POSIX does also say: The value returned shall not be more restrictive than the corresponding value available to the application when it was compiled with the implementation's <limits.h>
or <unistd.h>
. –
Scylla {PATH_MAX}
values per directory are for user mode file system implementations (not fuse, but open() interpreting the name in the same address space). Even then, applications cannot use the differing values race-free (if they go to the trouble of calling pathconf()
for each component). Moreover, some things like calling realpath()
with a non-null buffer pointer become undefined when {PATH_MAX}
is not a constant, but this does not deny an implementation accepting longer pathnames. –
Tunis On Linux, glibc's implementation of pathconf
returns a compile-time constant value of PATH_MAX so there is no runtime magic FUSE or anyone else can perform to adjust it. (See sysdeps/unix/sysv/linux/pathconf.c which falls through to sysdeps/posix/pathconf.c.) The answer to your question "How do I specify my filesystem's PATH_MAX?" is "You can't. glibc doesn't let you and FUSE is just the messenger."
The end result is a sticky situation. Here's a blog post that discusses the code that does and does not care about PATH_MAX. Software that relies on paths no longer than PATH_MAX was broken long ago by other filesystems so it's safe for you to ignore PATH_MAX.
On MacOS X (and probably other BSDs): The implementation of pathconf
is entirely in the kernel and can be swapped out per filesystem. OSXFUSE includes a NOOP version of pathconf which should return the usual compile-time constants. However, in my tests it seems to be catching another NOOP function along the way which returns an ENXIO and I can't get pathconf to work.
Bonus: for NAME_MAX, implement statfs and set f_namemax.
POSIX allows _PC_PATH_MAX
to vary based on the current directory, but that doesn't mean that systems which don't vary it aren't compliant.
The real reason for PATH_MAX
existing is that the kernel copies the pathname into kernelspace before doing any actual work with it.
Your assertion that there is a PATH_MAX
-related field in statvfs
is just wrong. That's related to NAME_MAX
, which is a different thing.
Since this question is tagged "FUSE" ...
I just ran into this issue while working on a FUSE filesystem. I wrote an e-mail to the FUSE developers, seeking clarification. Reply from the current libfuse
maintainer (January 2018): There is not a way to specify the maximum path length in a FUSE filesystem [driver].
Is there a way for a FUSE filesystem to inform software running on top of it about the correct maximum path length?
Not at the moment, no.
If not, should there be?
Probably yes. Patches welcome :-)
For reference: Full e-mail thread
I do not enough about other OSes but imho this is a system-wide setting in at least FreeBSD 5.2.1
PATH_MAX is found in #62 sys/syslimits.h
Because static int ufs_pathconf()
which returns the PATHCONF
information for UFS FS, uses this variable in the manner you specified.
/*
* Return POSIX pathconf information applicable to ufs filesystems.
*/
int
ufs_pathconf(ap)
struct vop_pathconf_args /* {
struct vnode *a_vp;
int a_name;
int *a_retval;
} */ *ap;
{
switch (ap->a_name) {
.
.
.
.
case _PC_PATH_MAX:
*ap->a_retval = PATH_MAX;
return (0);
.
.
.
.
default:
return (EINVAL);
}
/* NOTREACHED */
}
PATH_MAX is a system wide setting and is usually defined in pathmax.h as:
define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 \
: pathconf ("/", _PC_PATH_MAX))
sort
command-line utility shipped with MacOS X and is not part of the kernel or standard C library. –
Arthritis © 2022 - 2024 — McMap. All rights reserved.