NFS和64位inode的问题

本文同步自(最佳显示效果请点击):https://zohead.com/archives/nfs-64bitinode/

最近在 XFS 文件系统上使用 NFS 时发现一些比较老的 Linux 客户端在挂载时会提示 stale file handle 错误,这似乎是服务器端的 NFS 共享文件夹信息不正确了,比较奇怪为什么新的 Linux 系统又是可以挂载使用的,准备一探究竟。

首先登录到服务器端(也是 Linux 系统,RHEL6 x86_64 服务器),查看 NFS 共享文件夹的状态(NFS 共享路径为 /nfs/share2):

/nfs # ls -dil *
    259 drwxrwxrwx    2 root     root             6 Jul 15 15:31 share1
4294967616 drwxrwxrwx    3 root     root            24 Jul 15 16:09 share2
/nfs # ls -dil share2/*
8589934912 drwxrwxrwx    2 root     root            24 Jul 15 16:09 share2/ppp
/nfs # ls -dil share2/ppp/*
8589934913 -rwxrwxrwx    1 root     root            15 Jul 15 16:15 share2/ppp/ooo

上面的 ls 命令特别增加了 -i 参数用于显示文件的 inode 值,这时就发现 /nfs/share2、/nfs/share2/ppp 这两个文件夹和 /nfs/share2/ppp/ooo 文件的 inode 值非常大,已经超过了一般的 32 位 inode 值限制,分别为:4294967616、8589934912、8589934913,而 /nfs/share1 文件夹的 inode 值则是 259。

查看运行 mount 命令发现 XFS 文件系统在挂载时使用了 inode64 参数指定使用 64 位的 inode 值来存储文件,使用 64 位 inode 主要用于解决容量非常大的文件系统在有可用空间但在使用 32 位 inode 值时可能还是无法再写入文件的问题的。然后就在之前不能挂载的 Linux 客户端上重新挂载 /nfs/share1 这个文件夹,结果却可以挂载了,看来很有可能就是 64 位 inode 造成不能挂载 /nfs/share2 共享文件夹的问题。

后来经过查找 kernel 中 NFS 文件系统的说明,Linux kernel 在 2.6.23 版本中可以直接支持 64 位的 NFS 文件 inode 值了,而且是通过给 nfs 这个内核模块增加 enable_ino64 参数来设置的,这个参数还是运行时可写的,一般新的发行版中如果 kernel 版本高于 2.6.23 都会支持的。另外有些发行厂商例如 RedHat 会在更新中提供支持,例如 RHEL 4 Update 7 这个比较老的系统中也支持 NFS 64 位 inode 值了。

下面在几个常见的 Linux 客户端系统中测试对 NFS 64 位 inode 的支持情况了:

1、Fedora Core 5 32位系统(内核版本:2.6.22):

32 位的 Fedora Core 5 系统内核版本 2.6.22,虽然不支持 NFS 64 位 inode(也不支持 enable_ino64 参数),但还是能挂载的,而且使用时全部显示为 32 位 inode 值,看看效果:

[root@zzmlinux root]# mount -t nfs 192.168.1.145:/nfs/share2 /mnt
[root@zzmlinux root]# cd /mnt/
[root@zzmlinux mnt]# ls -dil
321 drwxrwxrwx  3 root root 24 Jul 15  2014 .
[root@zzmlinux mnt]# ls -dil *
322 drwxrwxrwx  2 root root 24 Jul 15  2014 ppp
[root@zzmlinux mnt]# cd ppp/
[root@zzmlinux ppp]# ls -dil *
323 -rwxrwxrwx  1 root root 5 Jul 15  2014 ooo
[root@zzmlinux ppp]# echo "test something" > ooo
[root@zzmlinux ppp]# cat ooo
test something

从上面的命令输出结果可以看出:

/nfs/share2 文件夹本身在服务器端的 inode 值原本为 64 位的 4294967616,但在 32 位的 NFS 客户端这被转换成了 321(其实:4294967616 = 0xFFFFFFFF + 321)。相应的 /nfs/share2/ppp 文件夹的 inode 值由 8589934912 转换为 322 了(8589934912 = 2 * 0xFFFFFFFF + 322),/nfs/share2/ppp/ooo 文件的 inode 值由 8589934913 转换为 323 了(8589934913 = 2 * 0xFFFFFFFF + 323)。

这样 NFS 客户端算是也能正常使用了,但不能保证文件数量太多时不会出现问题的。

2、RHEL 6 64位系统(内核版本:2.6.32):

[root@localhost work]# mount -t nfs 192.168.1.145:/nfs/share2 /mnt/nfs
[root@localhost work]# ls -dil /mnt/nfs
4294967616 drwxrwxrwx 3 root root 24  7月 15 2014 /mnt/nfs
[root@localhost work]# ls -dil /mnt/nfs/ppp
8589934912 drwxrwxrwx 2 root root 24  7月 15 2014 /mnt/nfs/ppp
[root@localhost work]# ls -dil /mnt/nfs/ppp/ooo
8589934913 -rwxrwxrwx 1 root root 15  7月 15 2014 /mnt/nfs/ppp/ooo
[root@localhost work]# cat /mnt/nfs/ppp/ooo
test something

RHEL6 64 位系统上的效果就比较明显了,所有文件显示的 inode 值与服务器端的完全一致,这样使用起来就完全没有问题了。

3、Fedora 14 32位系统(内核版本:2.6.35):

[root@fedora14 ~]# cat /sys/module/nfs/parameters/enable_ino64
Y
[root@fedora14 ~]# mount -t nfs 192.168.1.145:/nfs/share2 /mnt
[root@fedora14 ~]# ls -dil /mnt
4294967616 drwxrwxrwx 3 root root 24 Jul 15 16:09 /mnt
[root@fedora14 ~]# ls -dil /mnt/ppp
8589934912 drwxrwxrwx 2 root root 24 Jul 15 16:09 /mnt/ppp
[root@fedora14 ~]# ls -dil /mnt/ppp/ooo
8589934913 -rwxrwxrwx 1 root root 15 Jul 15 16:15 /mnt/ppp/ooo

这里由于 Fedora 14 是 32 位系统,我们在挂载 NFS 之前特地查看了 enable_ino64 参数,发现默认已启用的。这样在挂载之后查看到的文件的 inode 值也是和服务器一样为 64 位的了。如果有兴趣将 enable_ino64 参数改为 N 的话,你会发现这些 inode 也被转换为 32 位的了。

其实我碰到的主要就是 Linux 下老的程序和新的 64 位 inode 的兼容问题,SGI 推荐用户使用 64 位的 inode,btrfs 和 ext4 现在也开始准备改为 64 位 inode 了,当然不免还有一些老的程序存在兼容性问题,这里有 SGI 的研发人员实际测试 64 位 inode 的兼容结果:

http://blog.fmeh.org/2013/05/11/does-the-world-need-32-bit-inodes/

上面看到的只使用 32 位 inode 的程序占比结果 10% 还是比较令人满意的,只支持 32 位 inode 的程序现在越来越少了。

本文为个人测试及分析结果,如其中存在错误还请提出指正哦,玩的开心~~~ ^_^





*