Linux 我可以在不使用mmap的情况下防止文件页逐出吗?
我的理解是,我可以通过对文件执行Linux 我可以在不使用mmap的情况下防止文件页逐出吗?,linux,linux-kernel,filesystems,page-caching,Linux,Linux Kernel,Filesystems,Page Caching,我的理解是,我可以通过对文件执行mmap,然后对映射的内存调用mlock,将文件保存在内存中 有没有一种方法可以在不执行mmap的情况下将文件数据保留在页面缓存中?具体地说,我希望确保在向文件追加数据时,我要写入的页面永远不会被逐出 我意识到这是罕见的,但我相信在某些情况下会发生。例如,应用程序写入数据,等待的时间超过了脏写回的百分之几秒(之后页面变干净,可以被逐出),然后写入更多的数据。我相信您在理解这些数据时有点错误。它的预期用途是: 断言由于数据尚未从磁盘加载或交换出去(出于性能原因很有用
mmap
,然后对映射的内存调用mlock
,将文件保存在内存中
有没有一种方法可以在不执行mmap的情况下将文件数据保留在页面缓存中?具体地说,我希望确保在向文件追加数据时,我要写入的页面永远不会被逐出
我意识到这是罕见的,但我相信在某些情况下会发生。例如,应用程序写入数据,等待的时间超过了脏写回的百分之几秒(之后页面变干净,可以被逐出),然后写入更多的数据。我相信您在理解这些数据时有点错误。它的预期用途是:
我不能肯定这一点,但我认为目前实际上没有办法禁止为特定文件写回脏页。也许有什么方法可以暗示,但我也看不到
mmap/mlock实验
alexander@goblin~/tmp$cat mmap.c
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义句柄错误(msg)\
do{perror(msg);exit(exit_FAILURE);}while(0)
int main(int argc,char*argv[]){
char*addr;
int-fd;
结构统计某人;
尺寸与长度;
如果(argc!=2){
fprintf(stderr,“%s文件\n”,argv[0]);
退出(退出失败);
}
fd=开路(argv[1],O_RDWR);
如果(fd==-1){
处理错误(“打开”);
}
if(fstat(fd,&sb)=-1){/*获取文件大小*/
处理错误(“fstat”);
}
长度=sb.st_尺寸;
addr=mmap(空,长度,保护读取,保护写入,映射共享,fd,0);
if(addr==MAP_失败){
处理错误(“mmap”);
}
if(mlock(addr,length)/dev/null | hextump-C
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
alexander@goblin~/tmp$gcc mmap.c
alexander@goblin~/tmp$./a.out foo&
[1] 26450
alexander@goblin~/tmp$sudo hdparm--fibmap foo
傅:
文件系统块大小4096,从LBA 0开始;假设为512字节扇区。
字节\u偏移开始\u LBA结束\u LBA扇区
0 279061632 279061639 8
alexander@goblin~/tmp$sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hextdump-C
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
alexander@goblin~/tmp$sleep 10
alexander@goblin~/tmp$sudo hdparm--fibmap foo
傅:
文件系统块大小4096,从LBA 0开始;假设为512字节扇区。
字节\u偏移开始\u LBA结束\u LBA扇区
0 279061632 279061639 8
alexander@goblin~/tmp$sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hextdump-C
00000000 68 65 6c 6c 6f 20 77 6f 72 6c 64 21 00 00 |你好世界|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
alexander@goblin~/tmp$fg
/a.out-foo
^C
我相信您在理解功能方面有点错误。它的预期用途是:
我不能肯定这一点,但我想目前实际上没有办法禁止为特定文件写回脏页。可能有某种方法可以暗示它,但我也看不到任何方法
mmap/mlock实验
alexander@goblin~/tmp$cat mmap.c
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义句柄错误(msg)\
do{perror(msg);exit(exit_FAILURE);}while(0)
int main(int argc,char*argv[]){
char*addr;
int-fd;
结构统计某人;
尺寸与长度;
如果(argc!=2){
fprintf(stderr,“%s文件\n”,argv[0]);
退出(退出失败);
}
fd=开路(argv[1],O_RDWR);
如果(fd==-1){
处理错误(“打开”);
}
if(fstat(fd,&sb)=-1){/*获取文件大小*/
处理错误(“fstat”);
}
长度=sb.st_尺寸;
addr=mmap(空,长度,保护读取,保护写入,映射共享,fd,0);
if(addr==MAP_失败){
处理错误(“mmap”);
}
if(mlock(addr,length)/dev/null | hextump-C
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
alexander@goblin~/tmp$gcc mmap.c
alexander@goblin~/tmp$./a.out foo&
[1] 26450
alexander@goblin~/tmp$sudo hdparm--fibmap foo
傅:
文件系统块大小4096,从LBA 0开始;假设为512字节
posix_fadvise(fd, offset, len, POSIX_FADV_RANDOM);
alexander@goblin ~/tmp $ cat mmap.c
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int main(int argc, char *argv[]) {
char *addr;
int fd;
struct stat sb;
size_t length;
if (argc != 2) {
fprintf(stderr, "%s file\n", argv[0]);
exit(EXIT_FAILURE);
}
fd = open(argv[1], O_RDWR);
if (fd == -1) {
handle_error("open");
}
if (fstat(fd, &sb) == -1) { /* To obtain file size */
handle_error("fstat");
}
length = sb.st_size;
addr = mmap(NULL, length , PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
handle_error("mmap");
}
if(mlock(addr, length)<0) {
handle_error("mlock");
}
strcpy(addr, "hello world!");
sleep(100);
munmap(addr, length);
close(fd);
exit(EXIT_SUCCESS);
}
alexander@goblin ~/tmp $ grep . /proc/sys/vm/dirty_{expire,writeback}_centisecs
/proc/sys/vm/dirty_expire_centisecs:1000
/proc/sys/vm/dirty_writeback_centisecs:500
alexander@goblin ~/tmp $ dd if=/dev/zero of=foo bs=4k count=1
1+0 records in
1+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 8.1296e-05 s, 50.4 MB/s
alexander@goblin ~/tmp $ fallocate -l 4096 foo
alexander@goblin ~/tmp $ sync foo
alexander@goblin ~/tmp $ sudo hdparm --fibmap foo
foo:
filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
byte_offset begin_LBA end_LBA sectors
0 279061632 279061639 8
alexander@goblin ~/tmp $ sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hexdump -C
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
alexander@goblin ~/tmp $ gcc mmap.c
alexander@goblin ~/tmp $ ./a.out foo &
[1] 26450
alexander@goblin ~/tmp $ sudo hdparm --fibmap foo
foo:
filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
byte_offset begin_LBA end_LBA sectors
0 279061632 279061639 8
alexander@goblin ~/tmp $ sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hexdump -C
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
alexander@goblin ~/tmp $ sleep 10
alexander@goblin ~/tmp $ sudo hdparm --fibmap foo
foo:
filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
byte_offset begin_LBA end_LBA sectors
0 279061632 279061639 8
alexander@goblin ~/tmp $ sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hexdump -C
00000000 68 65 6c 6c 6f 20 77 6f 72 6c 64 21 00 00 00 00 |hello world!....|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
alexander@goblin ~/tmp $ fg
./a.out foo
^C