Reprinted: http://passer-byb.com/blog/85.html
I 've been suffering from this problem for a week, because I have been conducting disk I/O tests recently, so I need to bypass or disable the VFS cache to directly read and write the disk. Google found that it was basically impossible to disable the cache, but it was only possible to bypass it. So I naturally thought of the write () and read (), but I didn't realize that buffer and cache are not one thing. Although write () and read () are called direct I/O, they actually bypass the buffer, that is, they do not buffer any data during reading and output, however, the cache of VFS still exists, and VFS still chooses to write the cache data to the disk when appropriate.
So I found a lot of methods, some of which are through the drop cache method, that is, the method "Echo 1>/proc/sys/Vm/drop_caches", but this method can only clear the cache once, reading and writing once is very troublesome. So I gave up this unreliable method.
Later I thought of an o_direct flag not mentioned in apue (because apue is talking about Unix programming, of course there is no need to take care of the unique features of GNU Linux ). How to use it? Let's talk about it below.
First, the file header needs to be defined
# DEFINE _ gnu_source
Then, this is the second parameter that is filled in when open () obtains the file descriptor, that is, the second parameter of open (path, flag, mode. For example, if you want to create a new file named "/home/user/Test. Test" in the write mode and directly bypass the cache by I/O, you can write it like this:
Int FD = open ("/home/user/Test. Test", o_wronly | o_creat | o_direct, s_irusr | s_iwusr );
When you need read () or write (), the first address of the buffer and the size of the buffer must be aligned with the page size of the file system. The page size can be obtained through getpagesize. So here I need to use a stupid method:
Int buffersize = getpagesize () * page_num;
Int pagesize = getpagesize ();
Char * t_buf = (char *) malloc (buffersize + pagesize );
Char * buffer = (char *) (unsigned INT) buffersize + pagesize-1)/pagesize * pagesize );
Then you can use this buffer to read () or write. For example:
Read (FD, buffer, buffersize );
Note that the buffersize must be an integer multiple of the page size, and the buffer must point to an integer multiple of the page size. The following simple calculation can be used to obtain the buffer that meets the condition. The subsequent I/O completely bypasses the direct I/O of the cache.