Date: Fri, 2 Mar 2001 08:44:58 -0500 (EST) From: Peter Dufault <dufault@hda.hda.com> To: Dag-Erling Smorgrav <des@ofug.org> Cc: Anton Berezin <tobez@tobez.org>, hackers@FreeBSD.ORG Subject: Re: how to actually find out whether data hit the disk? Message-ID: <200103021344.f22Diw636709@hda.hda.com> In-Reply-To: <xzpvgpsmimh.fsf@flood.ping.uio.no> from Dag-Erling Smorgrav at "Mar 2, 2001 01:59:34 pm"
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
> Peter Dufault <dufault@hda.hda.com> writes:
> > > > Do an msync with MS_SYNC someplace. Also, use MAP_NOSYNC in
> > > > mmap until 4.3 when Matt Dillon plans to make that the default behavior.
> > > Ahh, no. That's the other way around - I do not *want* it to hit the
> > > disk, but would like to *know* when it nevertheless does.
> > OK, doing a stat and checking the mtime should give you
> > the info at the expense of polling, I can't think of another way.
>
> Won't help. You'll get the same mtime no matter whether the file is
> actually written to disk or not.
No, the spec says:
If there was no such call [to msync] these fields [st_ctime and
st_mtime] may be marked for update at any time after a write
reference if the underlying file is modified as a result.
I wrote a program (attached) to verify it. Here's the output:
> mapped at 08:34:04.206204 modification time 08:34:04.000000000
> modified at 08:34:05.210740 modification time 08:34:04.000000000
> unmapped at 08:34:06.220744 modification time 08:34:04.000000000
> remapped at 08:34:07.230750 modification time 08:34:04.000000000
> msync at 08:34:08.247007 modification time 08:34:08.000000000
Peter
--
Peter Dufault (dufault@hda.com) Realtime development, Machine control,
HD Associates, Inc. Fail-Safe systems, Agency approval
[-- Attachment #2 --]
#include <unistd.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef MAP_NOSYNC
#define MAP_NOSYNC 0
#endif
static const char *name = "mapped_file";
static void
put_tv(FILE *f, struct timeval *pTv) {
struct tm tm;
struct timeval tv;
if (pTv == 0) {
gettimeofday(&tv, 0);
pTv = &tv;
}
localtime_r(&pTv->tv_sec, &tm);
fprintf(f, "%02d:%02d:%02d.%06ld",
tm.tm_hour, tm.tm_min, tm.tm_sec, pTv->tv_usec);
}
static void
put_ts(FILE *f, struct timespec *pTs) {
struct tm tm;
localtime_r(&pTs->tv_sec, &tm);
fprintf(f, "%02d:%02d:%02d.%09ld",
tm.tm_hour, tm.tm_min, tm.tm_sec, pTs->tv_nsec);
}
static void quit_if(long code, long value, const char *s)
{
if (code == value) {
perror(s);
exit(1);
}
}
static void
status(FILE *f, const char *p, const int fd)
{
struct stat st;
fstat(fd, &st);
fprintf(f, "%12s ", p);
put_tv(f, 0);
fprintf(f, " modification time ");
put_ts(f, &st.st_mtimespec);
putchar('\n');
}
int main(int ac, char *av[]) {
void *p;
long pagesize;
int i, fd;
void *buff;
pagesize = sysconf(_SC_PAGESIZE);
(void)unlink(name);
errno = 0;
quit_if((fd = open(name, O_RDWR|O_CREAT, 0666)), -1, "open");
buff = calloc(1, pagesize);
quit_if((long)(p = mmap(0, 10*pagesize,
PROT_READ|PROT_WRITE, MAP_NOSYNC|MAP_SHARED, fd, (off_t)0)),
(long)MAP_FAILED, "mmap");
for (i = 0; i < 10; i++) {
write(fd, buff, pagesize);
}
status(stdout, "mapped at", fd);
sleep(1);
*(long *)p = -1;
status(stdout, "modified at", fd);
sleep(1);
munmap(p, 10*pagesize);
status(stdout, "unmapped at", fd);
sleep(1);
quit_if((long)(p = mmap(0, 10*pagesize,
PROT_READ|PROT_WRITE, MAP_NOSYNC|MAP_SHARED, fd, (off_t)0)),
(long)MAP_FAILED, "mmap");
status(stdout, "remapped at", fd);
sleep(1);
quit_if(msync(p, 10*pagesize, MS_SYNC), -1, "msync");
status(stdout, "msync at", fd);
close(fd);
return 0;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103021344.f22Diw636709>
