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?

Matt Joiner
  • 112,946
  • 110
  • 377
  • 526

6 Answers6

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.

jilles
  • 10,509
  • 2
  • 26
  • 39
  • 2
    POSIX disagrees with you - and the question is correct that the [`pathconf()`](http://www.opengroup.org/onlinepubs/9699919799/functions/fpathconf.html) 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 `` or ``._ – Jonathan Leffler Sep 13 '10 at 21:15
  • 4
    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. – jilles Sep 15 '10 at 22:04
  • 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. – Phil Lello May 04 '11 at 01:10
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.

ldrg
  • 4,150
  • 4
  • 43
  • 52
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.

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

s-m-e
  • 3,433
  • 2
  • 34
  • 71
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 */
}
Lelouch Lamperouge
  • 8,171
  • 8
  • 49
  • 60
-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))
ennuikiller
  • 46,381
  • 14
  • 112
  • 137
  • 2
    I think pathmax.h is some mac fail. – Matt Joiner Jul 25 '10 at 02:23
  • 1
    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. – ldrg Jun 06 '13 at 22:11