madvise()系统掉用,用于向内核提供对于起始地址为 addr ,长度为 length 的内存空间的 *** 作建议或者指示。在大多数情况下,此类建议的目标是提高系统或者应用程序的性能。
最初,此系统调用,仅仅支持一组“常规的(conventional)”建议值,这些建议值在各种系统中也有实现,(但是请注意,POSIX中并没有指定madvise()),后来,又添加了许多特定于Linux的建议值。
常规建议值
以下建议值允许应用程序告诉内核,它期望如何使用某些映射或者共享内存区域,以便内核可以选择适当的预读以及缓存技术。这些建议并不会影响应用程序的寓意( MADV_DONTNEED 除外),但是可能会影响其性能。同样除 MADV_DONTNEED 之外,下列所有的建议值都与posix_madvise(3)函数类似,且具有相同的含义。
这些建议值,被指示为参数 advice ,参数值是以下之一:
Linux 特定建议值
以下是Linux下的特定建议值,在posix_madvise(3)中不存在对应项,并且在其他系统的实现中,可能有也可能没有对应项。同时,,其中一些 *** 作会更改内存访问的语义。
On success, madvise() returns zero. On error, it returns -1 and errno is set to indicate the error.
Since Linux 3.18, support for this system call is optional, depending on the setting of the CONFIG_ADVISE_SYSCALLS configuration option.
madvise() is not specified by any standards. Versions of this system call, implementing a wide variety of advice values, exist on many other implementations. Other implementations typically implement at least the flags listed above under Conventional advice flags, albeit with some variation in semantics.
POSIX.1-2001 describes posix_madvise(3) with constants POSIX_MADV_NORMAL, POSIX_MADV_RANDOM, POSIX_MADV_SEQUENTIAL, POSIX_MADV_WILLNEED, and POSIX_MADV_DONTNEED, and so on, with behavior close to the similarly named flags listed above.
Linux 实现要求地址 addr 是页对齐的,并允许长度为零。 如果指定地址范围的某些部分未映射,则 madvise() 的 Linux 版本将忽略它们并将调用应用于其余部分(但应从系统调用中返回 ENOMEM)。
fallocate - manipulate file space这是一个不可移植的、特定于 Linux 的系统调用。 For the portable, POSIX.1-specified method of ensuring that space is allocated for a file, see posix_fallocate(3).
fallocate() 允许调用者直接 *** 作 fd 引用的文件所分配的磁盘空间, *** 作的字节范围为[ offset , offset + len ]。
mode 参数确定要在给定范围上执行的 *** 作。 支持的 *** 作的详细信息在下面的小节中给出。
fallocate()的默认 *** 作(即 mode =0)是在参数 offset 和 len 指定的范围内分配磁盘空间。如果 offset + len 大于文件的大小,则文件大小将被修改。超过原范围的区域将会被初始化为0。此默认行为与 posix_fallocate(3) 库函数的行为非常相似,是实现 posix_fallocate(3) 的最佳实现方法。
调用成功后,后续写入 offset 和 len 指定的范围不会因为磁盘空间不足而失败。
注:这样做的有什么用呢?根据博客 用fallocate进行"文件预留"或"文件打洞" ,可以有以下好处:
(1)可以让文件尽可能的占用连续的磁盘扇区,减少后续写入和读取文件时的磁盘寻道开销;
(2)迅速占用磁盘空间,防止使用过程中所需空间不足。
(3)后面再追加数据的话,不会需要改变文件大小,所以后面将不涉及metadata的修改
如果在mode中指定了 FALLOC_FL_KEEP_SIZE 标志,调用的行为类似,即依然会为文件分配磁盘空间,但是不会修改文件大小。这种预分配的方式可以用来优化文件的append *** 作,也就是在执行append的时候不需要再额外申请磁盘空间了。
如果在 mode 中指定了 FALLOC_FL_UNSHARE_RANGE 标志,则共享文件数据范围将成为文件私有的,以保证后续写入不会因空间不足而失败。 通常,这将通过对文件中的所有共享数据执行写时复制 *** 作来完成。 并非所有文件系统都支持此标志。
由于分配是以块大小的块完成的,fallocate() 可能会分配比指定范围更大的磁盘空间。
当mode指定为 FALLOC_FL_PUNCH_HOLE 时,会释放指定范围内的空间,即创建一个空洞。在指定的范围内,部分的文件块(即文件块部分属于该范围)将会被置为0,全部的在范围内的文件块,将会被从文件系统中删除。成功调用后,后续的读取将会返回0。
FALLOC_FL_PUNCH_HOLE 必须和 FALLOC_FL_KEEP_SIZE 通过或运算一起使用,换句话说, FALLOC_FL_PUNCH_HOLE 是不能修改文件的大小的。
并非所有文件系统都支持 FALLOC_FL_PUNCH_HOLE; 如果文件系统不支持该 *** 作,则返回错误。 至少以下文件系统支持该 *** 作:
当mode指定为 FALLOC_FL_COLLAPSE_RANGE 标志时,将从文件中删除指定的字节范围,而不会留下空洞。 *** 作完成后,从 offset + len 开始位置的文件内容将会被追加到 offset 处。文件大小会减少 len
文件系统可能会限制 *** 作的粒度,以确保有效实施。 通常,offset 和 len 必须是文件系统逻辑块大小的倍数,这取决于文件系统类型和配置。 如果文件系统有这样的要求,如果违反了该要求,fallocate() 将失败并显示错误 EINVAL。
If the region specified by offset plus len reaches or passes the end of file, an error is returnedinstead, use ftruncate(2) to truncate a file.
FALLOC_FL_COLLAPSE_RANGE 标志和其他标志不兼容。
在 Linux 3.15 中,ext4(only for extent-based files)和 XFS 支持 FALLOC_FL_COLLAPSE_RANGE 标志。
当mode指定为 FALLOC_FL_COLLAPSE_RANGE 标志时,将会指定范围内分配磁盘空间,填补空洞。成功调用后后续读取将会返回0。
Zeroing is done within the filesystem preferably by converting the range into unwritten extents. This approach means that the specified range will not be physically zeroed out on the device (except for partial blocks at the either end of the range), and I/O is (otherwise) required only to update metadata.可能的意思是,最好不要将物理磁盘清零,而是配置一个为写入的状态,这样读取上来的pagecache就是0。这种情况下,仅仅需要修改文件元数据就可有了。
如果在mode中额外指定了FALLOC_FL_KEEP_SIZE标志,调用的行为类似,但即使offset+len大于文件大小,文件大小也不会改变。 此行为与在指定 FALLOC_FL_KEEP_SIZE 的情况下预分配空间时相同。
并非所有文件系统都支持 FALLOC_FL_ZERO_RANGE; 如果文件系统不支持该 *** 作,则返回错误。 至少以下文件系统支持该 *** 作:
如果在mode中额外指定了 FALLOC_FL_INSERT_RANGE 标志,那么将会在offset开始的位置插入一个大小为len的空洞,在不覆盖文件内容的前提下增加文件的空间。
此模式在 *** 作粒度方面与 FALLOC_FL_COLLAPSE_RANGE 具有相同的限制。 如果不满足粒度要求,fallocate() 将失败并显示错误 EINVAL。 如果偏移量等于或大于文件末尾,则返回错误。 对于此类 *** 作(即在文件末尾插入一个洞),应使用 ftruncate(2)。
FALLOC_FL_INSERT_RANGE 标志与其他标志不兼容。
目前只有XFS (since Linux 4.1) 和 ext4 (since Linux 4.2)支持此标志。
n success, fallocate() returns zero. On error, -1 is returned and errno is set to indicate the error.
fallocate() is available on Linux since kernel 2.6.23. Support is provided by glibc since version 2.10. The FALLOC_FL_* flags are defined in glibc headers only since version 2.18.
fallocate() is Linux-specific.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)