2001-02-17 10:48:06

by Florian Weimer

[permalink] [raw]
Subject: Flushing buffer and page cache

Is it possible to flush all entries in the buffer cache corresponding
to a single block device (i.e. simply drop them if they aren't dirty,
or write them to disk and drop them after this if they are dirty)?

I've got another device in my SCSI chain which writes to the disk, and
if the caches are not flushed, the computer won't see the updates.
(Synchronization is done manually, so it's not an issue---trust me, I
know what I'm doing. ;-)

Kernel version doesn't matter. ;-)

--
Florian Weimer [email protected]
University of Stuttgart http://cert.uni-stuttgart.de/
RUS-CERT +49-711-685-5973/fax +49-711-685-5898


2001-02-17 16:12:39

by James Bottomley

[permalink] [raw]
Subject: Re: Flushing buffer and page cache

> Is it possible to flush all entries in the buffer cache corresponding
> to a single block device (i.e. simply drop them if they aren't dirty,
> or write them to disk and drop them after this if they are dirty)?

Yes, just send the BLKFLSBUF ioctl to the device this syncs the device then
removes all the buffers from the cache. We use it as a tool to move a SAN
device around a cluster, which is similar to what you want to do.

James Bottomley



2001-02-17 18:30:33

by Douglas Gilbert

[permalink] [raw]
Subject: Re: Flushing buffer and page cache

James Bottomley wrote:

> > Is it possible to flush all entries in the buffer cache corresponding
> > to a single block device (i.e. simply drop them if they aren't dirty,
> > or write them to disk and drop them after this if they are dirty)?
>
> Yes, just send the BLKFLSBUF ioctl to the device this syncs the device then
> removes all the buffers from the cache. We use it as a tool to move a SAN
> device around a cluster, which is similar to what you want to do.

Last time this question was raised, someone mentioned
a little utility called flushb . Here is its source:

/*
* flushb.c --- This routine flushes the disk buffers for a disk
*/

/*
* modified August 2000 by Juri Haberland
* [email protected]
*/

#include <stdio.h>
#include <fcntl.h>
#include <linux/fs.h>

#define NOARGS void

const char *progname;

static void usage(NOARGS)
{
fprintf(stderr, "Usage: %s disk\n", progname);
exit(1);
}

int main(int argc, char **argv)
{
int fd;

progname = argv[0];
if (argc != 2)
usage();

fd = open(argv[1], O_RDONLY, 0);
if (fd < 0) {
perror("open");
exit(1);
}
/*
* Note: to reread the partition table, use the ioctl
* BLKRRPART instead of BLKFSLBUF.
*/
if (ioctl(fd, BLKFLSBUF, 0) < 0) {
perror("ioctl BLKFLSBUF");
exit(1);
}
return 0;
}