【问题标题】:Defining PATH_MAX for a filesystem?为文件系统定义 PATH_MAX?
【发布时间】:2011-03-20 12:59:58
【问题描述】:

我目前正在编写一个文件系统。 statvfs(甚至statfs)结构包含一个字段,指定该路径中名称的最大长度。由于PATH_MAXpathconf 手册页(getconf)中定义,这意味着它是在每个目录的基础上定义的(因此,由底层文件系统确定)。如何指定这个值?

【问题讨论】:

  • 我对这个问题有点好笑。很明显,这个值应该是可定制的,但实际上并没有实际应用。
  • 这是我第二次或第三次为此提供赏金。有人!?
  • 这是我第四次运行这个赏金。

标签: unix filesystems posix fuse


【解决方案1】:

PATH_MAX 是系统范围的设置,通常在 pathmax.h 中定义为:

define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 \
            : pathconf ("/", _PC_PATH_MAX))

【讨论】:

  • 我认为 pathmax.h 是一些 mac 失败。
  • 上面引用的 PATH_MAX 宏/pathmax.h 是 MacOS X 附带的旧 BSD sort 命令行实用程序的一部分,不是内核或标准 C 库的一部分。
【解决方案2】:

PATH_MAX 主要表现为文件系统函数调用接口的属性,所以我认为让它在不同目录之间变化没有多大意义。

例如,重命名或移动其中包含大型目录树的目录可能会使最长的绝对路径名变长,并且限制它会很复杂且效率低下。

相反,PATH_MAX 用于允许内核将传递的路径名复制到临时未分页内存中,然后可以对其进行处理,而无需在每次访问时允许页面错误。分配大量此类内存可能会阻塞内核正在执行的大多数其他操作,甚至导致内核崩溃。

【讨论】:

  • POSIX 不同意你的观点——这个问题是正确的,pathconf() 函数可以根据你传递给它的文件名返回不同的值,这意味着它可能会根据它所代表的文件系统而有所不同目录。但是,POSIX 也确实说:返回的值不应比应用程序使用实现的 &lt;limits.h&gt;&lt;unistd.h&gt; 编译时可用的相应值更具限制性。
  • 我认为每个目录的不同 {PATH_MAX} 值用于用户模式文件系统实现(不是熔断器,而是 open() 解释同一地址空间中的名称)。即便如此,应用程序也不能使用不同的值来避免竞争(如果他们为每个组件都调用pathconf() 的麻烦)。此外,当{PATH_MAX} 不是常量时,使用非空缓冲区指针调用realpath() 之类的某些事情会变得未定义,但这并不否认实现接受更长的路径名。
  • 否 - 它是每个目录的原因是,这是迄今为止应用程序查找文件系统属性的最简单方法,而无需跟踪挂载点和文件系统类型本身。所以目录/可以是和/cdrom不同的fs,但是app只需要看目录即可。
【解决方案3】:

我对其他操作系统做得不够,但恕我直言,这是至少在 FreeBSD 5.2.1 中的系统范围设置

PATH_MAX 位于#62 sys/syslimits.h


因为 static int ufs_pathconf() 返回 UFS FS 的 PATHCONF 信息,所以以您指定的方式使用此变量。

/*
 * 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 */
}

【讨论】:

    【解决方案4】:

    在 Linux 上,glibc 的 pathconf 实现返回编译时常量值 PATH_MAX,因此没有运行时魔法 FUSE 或任何其他人都可以执行调整它。 (请参阅 sysdeps/unix/sysv/linux/pathconf.c,它属于 sysdeps/posix/pathconf.c。)您的问题“如何指定我的文件系统的 PATH_MAX?”的答案。是“你不能。glibc 不允许你,FUSE 只是信使。”

    最终结果是一个棘手的情况。 Here's a blog post that discusses the code that does and does not care about PATH_MAX. 依赖路径不超过 PATH_MAX 的软件很久以前就被其他文件系统破坏了,因此您可以安全地忽略 PATH_MAX。

    在 MacOS X(可能还有其他 BSD)上:pathconf 的实现完全在内核中,并且可以在每个文件系统中换出。 OSXFUSE 包含一个 NOOP 版本的 pathconf,它应该返回通常的编译时常量。但是,在我的测试中,它似乎正在捕获另一个返回 ENXIO 的 NOOP 函数,我无法让 pathconf 工作。

    奖励:对于 NAME_MAX,implement statfs and set f_namemax.

    【讨论】:

      【解决方案5】:

      POSIX 允许 _PC_PATH_MAX 根据当前目录变化,但这并不意味着 变化的系统不兼容。

      PATH_MAX 存在的真正原因是内核在对其进行任何实际操作之前将路径名复制到内核空间中。

      您断言statvfs 中存在与PATH_MAX 相关的字段是错误的。这与NAME_MAX 有关,这是另一回事。

      【讨论】:

        【解决方案6】:

        由于这个问题被标记为“FUSE”......

        我在处理 FUSE 文件系统时遇到了这个问题。我给 FUSE 开发人员写了一封电子邮件,寻求澄清。当前libfuse维护者的回复(2018 年 1 月):没有办法指定 FUSE 文件系统 [驱动程序] 中的最大路径长度。

        FUSE 文件系统有没有办法通知在上面运行的软件 关于正确的最大路径长度?

        暂时没有,没有。

        如果没有,应该有吗?

        可能是的。欢迎补丁:-)

        供参考:Full e-mail thread

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-09-23
          • 1970-01-01
          • 2019-09-23
          • 1970-01-01
          • 2012-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多