Defining PATH_MAX for a filesystem?
Asked Answered
R

6

22

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?

Romantic answered 24/7, 2010 at 16:11 Comment(3)
I'm somewhat amused by this question. It's evident that this value should be customizable, but it doesn't actually appear to be in practise.Romantic
This is the second or 3rd time I've run a bounty on this. Anyone!?Romantic
This is the 4th time I've run this bounty.Romantic
E
2

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

Enchilada answered 3/1, 2018 at 9:4 Comment(0)
T
3

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.

Tunis answered 10/9, 2010 at 22:27 Comment(3)
POSIX disagrees with you - and the question is correct that the 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
I think different {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
No - the reason it's per-directory is that is by far the easiest way to for an app to find out about filesystem properties, without having to track mount points and filesystem types itself. So the directory / can be a different fs than /cdrom, but the app only needs to look at the directory.Reflex
A
2

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.

Arthritis answered 6/6, 2013 at 23:29 Comment(0)
M
2

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.

Mantelletta answered 7/6, 2013 at 0:11 Comment(0)
E
2

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

Enchilada answered 3/1, 2018 at 9:4 Comment(0)
I
0

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 */
}
Investiture answered 11/10, 2011 at 23:40 Comment(0)
D
-1

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))
Dygall answered 24/7, 2010 at 17:49 Comment(2)
I think pathmax.h is some mac fail.Romantic
The PATH_MAX macro/pathmax.h referenced above is part of the old BSD 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.