From: yirgster on
[pls forgive if I've posted this (inadvertently) more than once.]

Does fsync(fd) imply that any areas of that file that were mmap'd only
are also synced, or is a separate msync() required.

I know the os can determine which pages in the process belong to the
file. My question is: must it do this whenever fsycn() is invoked?

The spec says: "all data for the open file descriptor named by fildes
is to be transferred to the storage device associated with the file
described by fildes" so I think the answer is 'yes', but I have that
worm of doubt that it's only talking about areas of the file that have
been read() and not those mmap()'d. In any case, I want to be sure.

For example:

int fd = open("my_file", ...);
vaddr *addr = mmap(0, len, ,,, , fd, 0);

/* do work on mmap'd area */
[ work ]

/* now want to sync the file */

msync(0, len); /* is this necessary if I do the fsync() below? */

fsync(fd); /* is this sufficent by itself? */

From: yirgster on
On May 8, 2:59 am, yirgster <yirg.ke...(a)gmail.com> wrote:
> [pls forgive if I've posted this (inadvertently) more than once.]
>
> Does fsync(fd) imply that any areas of that file that were mmap'd only
> are also synced, or is a separate msync() required.
>
> I know the os can determine which pages in the process belong to the
> file. My question is: must it do this whenever fsycn() is invoked?
>
> The spec says: "all data for the open file descriptor named by fildes
> is to be transferred to the storage device associated with the file
> described by fildes" so I think the answer is 'yes', but I have that
> worm of doubt that it's only talking about areas of the file that have
> been read() and not those mmap()'d. In any case, I want to be sure.
>
> For example:
>
> int fd = open("my_file", ...);
> vaddr *addr = mmap(0, len, ,,, , fd, 0);
>
> /* do work on mmap'd area */
> [ work ]
>
> /* now want to sync the file */
>
> msync(0, len);   /* is this necessary if I do the fsync() below? */
>
> fsync(fd);          /* is this sufficent by itself? */

I mean, msync(0, len, MS_SYNC);

Supposing that the only access to the file data in the process has
been through the mmap. Then if you did msync(0, len, MS_SYNC) and then
the fsync(fd), the os would now see (by looking at the page table
entries) that all the pages are clean (as a result of the msync) and
so not actually write again any of the data to disk. True (my choice)?
False? Depends?
From: Rainer Weikusat on
yirgster <yirg.kenya(a)gmail.com> writes:
> [pls forgive if I've posted this (inadvertently) more than once.]
>
> Does fsync(fd) imply that any areas of that file that were mmap'd only
> are also synced,

Theoretically, no.

> or is a separate msync() required.

Theoretically, yes.

Practically, this depends on the implementation. If a so-called
unified file/ page cache is used, fsync will necessarily sync all
mmaped areas, too, since only one copy of each file page exists in the
kernel. Historically, this wasn't always the case because the file
caching facilities in the UNIX(*) kernel already existed by the time
virtual memory support (including mmap) was added. As far as I know,
the 'lone holdout' in this respect used to be HP-UX but even that has
reportedly meanwhile been fixed.
From: Chris Friesen on
On 05/09/2010 12:37 PM, Rainer Weikusat wrote:
> yirgster <yirg.kenya(a)gmail.com> writes:
>> [pls forgive if I've posted this (inadvertently) more than once.]
>>
>> Does fsync(fd) imply that any areas of that file that were mmap'd only
>> are also synced,
>
> Theoretically, no.
>
>> or is a separate msync() required.
>
> Theoretically, yes.
>
> Practically, this depends on the implementation. If a so-called
> unified file/ page cache is used, fsync will necessarily sync all
> mmaped areas, too, since only one copy of each file page exists in the
> kernel.

I don't think that's correct. Last I checked fsync() didn't walk the
page tables looking for dirty pages to flush, while msync() does.

Chris
From: Chris Friesen on
On 05/10/2010 09:46 AM, Chris Friesen wrote:

> I don't think that's correct. Last I checked fsync() didn't walk the
> page tables looking for dirty pages to flush, while msync() does.

Looks like I was wrong and they now do that.

Chris