【问题标题】:Linux stat(2) call gives non-existing device IDLinux stat(2) 调用给出了不存在的设备 ID
【发布时间】:2016-09-14 15:15:50
【问题描述】:

我的测试程序正在调用stat(2) 以获取文件所在的设备。

stat.c(用cc stat.c -o stat构建)

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/sysmacros.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char *path = "/home/smoku/test.txt";
    unsigned int maj, min;
    struct stat sb;
    if (stat(path, &sb) < 0) {
        fprintf(stderr, "Error getting stat for '%s': %d %s\n", path, errno, strerror(errno));
        return 1;
    }
    maj = major(sb.st_dev);
    min = minor(sb.st_dev);
    fprintf(stderr, "Found '%s' => %u:%u\n", path, maj, min);
    return 0;
}

得到0:44

$ ls -l /home/smoku/test.txt
-rw-r--r-- 1 smoku smoku 306 08-30 09:33 /home/smoku/test.txt

$ ./stat
Found '/home/smoku/test.txt' => 0:44

$ /usr/bin/stat -c "%d" /home/smoku/test.txt
44

但是...我的系统中没有这样的设备,/home0:35

$ grep /home /proc/self/mountinfo
75 59 0:35 /home /home rw,relatime shared:30 - btrfs /dev/bcache0 rw,ssd,space_cache,subvolid=258,subvol=/home

为什么我的系统中不存在设备 ID?

【问题讨论】:

  • 你检查stat返回什么?它不会返回失败 (-1)?
  • @JoachimPileborg ...它很可能会.​​..
  • 是的,我做到了。这只是真实程序的摘录。
  • 那么请尝试创建一个Minimal, Complete, and Verifiable Example,您可以向我们展示。用那个(不工作的)代码真的不可能说什么。
  • 当然。我将代码修复为已满。

标签: c linux std glibc proc


【解决方案1】:

fs/stat.c 中的stat(2) 使用inode-&gt;i_sb-&gt;s_dev 填充stat.st_dev

fs/proc_namespace.c 中的/proc/self/mountinfo 使用mnt-&gt;mnt_sb-&gt;s_dev

显然struct inode.i_sb superblock 可能不同于struct vfsmount.mnt_sb superblock 在挂载btrfs 子卷的情况下。

这是 btrfs 实现固有的问题,“需要在 VFS 层中进行重大更改” 来解决:https://mail-archive.com/linux-btrfs@vger.kernel.org/msg57667.html

【讨论】:

  • "kernel bug" -- 也许是这样,但如果是我,我不会特别依赖像 btrfs 这样的文件系统发出的设备号物理设备和 VFS 层之间的如此完整的抽象。如果 ZFS 有类似的效果,我不会感到惊讶。
  • 我可能已经有补丁了... ;-) 如果只重建 Fedora 内核不需要几个小时... :-(
猜你喜欢
  • 1970-01-01
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
  • 2017-08-22
  • 2015-01-31
  • 2011-06-25
相关资源
最近更新 更多