1

我正在检查 linux 内核的所有系统调用,我看到两个函数将获取目录的内容:

asmlinkage long sys_getdents(unsigned int fd,
                struct linux_dirent __user *dirent,
                unsigned int count);
asmlinkage long sys_getdents64(unsigned int fd,
                struct linux_dirent64 __user *dirent,
                unsigned int count);

那么为什么要同时存在linux_dirent64linux_dirent结构呢?我的意思是,一个结构就足够了

4

3 回答 3

2

32 位版本支持在 64 位只是一个神话时编译回的代码,例如飞行汽车或响应迅速的政客。

于 2013-10-21T14:59:06.327 回答
1

好的,这不仅仅是因为需要向后兼容。还有一个原因。Linux 内核支持在用户空间上运行的 32 位进程,即使内核运行在 64 位模式下。这称为 32 位兼容模式。因此,对于以 32 位模式运行的进程,一切看起来都像是 32 位系统。他们仍然会调用 32 位旧式系统调用等。但是在内核中保留了每个 64 位系统调用的 32 位等价物,最终在进行所需的转换为 64 后调用 64 位系统调用本身。这称为 64 位兼容模式和系统调用是兼容的系统调用。所有这些马戏团的原因是使用户空间进程能够以内核模式透明运行。

于 2013-10-21T22:36:00.483 回答
1

从历史上看,文件大小、偏移量、inode 编号等在 UNIX API 中是“无符号长的”,它在 32 位平台上具有 32 位,因此适用于 2GB(有符号时)文件大小。那时非常庞大,甚至不足以制作 DVD 图像或现在的许多电影。

要处理比这更大的文件,必须更改处理此问题的大多数系统调用(以及传递给/从它们传递的结构),并且该版本通常具有“64”后缀。

getdents 就是其中之一 - getdents 使用带有“unsigned long”的结构来表示目录偏移量和 inode 编号,而 getdents64 则使用 s64 和 u64(64 位类型)。

类似的系统调用有 stat/stat64、statfs/statfs64、sendfile/sendfile64 等。

在 64 位系统上,其中一些较旧的系统调用不存在,因为它们通常与基本版本相同。有些有 64 位对应物,因为即使是 64 位系统也可能存在向后兼容性问题(例如,使用 32 位 inode 编号)。

于 2015-07-27T19:31:58.310 回答