posix_fadvise.2: Note that POSIX_FADV_DONTNEED *may* try to write back dirty pages

Looking at the code in mm/fadvise.c, we have

    case POSIX_FADV_DONTNEED:
        if (!inode_write_congested(mapping->host))
            __filemap_fdatawrite_range(mapping, offset, endbyte,
                                       WB_SYNC_NONE);

This suggests that *if* the backing device is not congested, then
__filemap_fdatawrite_range() is called. The comments for that
function say:

    __filemap_fdatawrite_range - start writeback on mapping dirty pages in range

So, my reading of this is that *maybe* some dirty pages will be
written to the backing device by the time that POSIX_FADV_DONTNEED
gets to calling invalidate_mapping_pages() whose description says:

/**
 * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode
 * @mapping: the address_space which holds the pages to invalidate
 * @start: the offset 'from' which to invalidate
 * @end: the offset 'to' which to invalidate (inclusive)
 *
 * This function only removes the unlocked pages, if you want to
 * remove all the pages of one inode, you must call truncate_inode_pages.
 *
 * invalidate_mapping_pages() will not block on IO activity. It will not
 * invalidate pages which are dirty, locked, under writeback or mapped into
 * pagetables.
 */

So, my reading of this is that the handling of dirty pages is an
optimization. If some pages can be written in time, they will be
freed by POSIX_MADV_DONTFREE. But there are no guarantees.

All of that said, some experimentation suggests that, in a lot
of cases, POSIX_MADV_DONTFREE does often free dirty pages.

See https://bugzilla.kernel.org/show_bug.cgi?id=95421.

Reported-by: Maik Zumstrull <maik@zumstrull.net>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
Michael Kerrisk 2017-01-26 14:42:46 +13:00
parent a6b80261c8
commit f90b94e32c
1 changed files with 7 additions and 3 deletions

View File

@ -112,9 +112,13 @@ and
.I len
must be page-aligned.
Pages that have not yet been written out will be unaffected, so if the
application wishes to guarantee that pages will be released, it should
call
The implementation
.I may
attempt to write back dirty pages in the specified region,
but this is not guaranteed.
Any unwritten dirty pages will not be freed.
If the application wishes to ensure that dirty pages will be released,
it should call
.BR fsync (2)
or
.BR fdatasync (2)