Skip to content

Commit

Permalink
fs/sync.c: sync_file_range(2) may use WB_SYNC_ALL writeback
Browse files Browse the repository at this point in the history
23d0127 ("fs/sync.c: make sync_file_range(2) use WB_SYNC_NONE
writeback") claims that sync_file_range(2) syscall was "created for
userspace to be able to issue background writeout and so waiting for
in-flight IO is undesirable there" and changes the writeback (back) to
WB_SYNC_NONE.

This claim is only partially true.  It is true for users that use the flag
SYNC_FILE_RANGE_WRITE by itself, as does PostgreSQL, the user that was the
reason for changing to WB_SYNC_NONE writeback.

However, that claim is not true for users that use that flag combination
SYNC_FILE_RANGE_{WAIT_BEFORE|WRITE|_WAIT_AFTER}.  Those users explicitly
requested to wait for in-flight IO as well as to writeback of dirty pages.

Re-brand that flag combination as SYNC_FILE_RANGE_WRITE_AND_WAIT and use
WB_SYNC_ALL writeback to perform the full range sync request.

Link: http://lkml.kernel.org/r/[email protected]
Link: http://lkml.kernel.org/r/[email protected]
Fixes: 23d0127 ("fs/sync.c: make sync_file_range(2) use WB_SYNC_NONE")
Signed-off-by: Amir Goldstein <[email protected]>
Acked-by: Jan Kara <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Al Viro <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
amir73il authored and torvalds committed May 14, 2019
1 parent 5326905 commit c553ea4
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
21 changes: 15 additions & 6 deletions fs/sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,14 @@ int sync_file_range(struct file *file, loff_t offset, loff_t nbytes,
}

if (flags & SYNC_FILE_RANGE_WRITE) {
int sync_mode = WB_SYNC_NONE;

if ((flags & SYNC_FILE_RANGE_WRITE_AND_WAIT) ==
SYNC_FILE_RANGE_WRITE_AND_WAIT)
sync_mode = WB_SYNC_ALL;

ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
WB_SYNC_NONE);
sync_mode);
if (ret < 0)
goto out;
}
Expand All @@ -306,9 +312,9 @@ int sync_file_range(struct file *file, loff_t offset, loff_t nbytes,
}

/*
* sys_sync_file_range() permits finely controlled syncing over a segment of
* ksys_sync_file_range() permits finely controlled syncing over a segment of
* a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is
* zero then sys_sync_file_range() will operate from offset out to EOF.
* zero then ksys_sync_file_range() will operate from offset out to EOF.
*
* The flag bits are:
*
Expand All @@ -325,7 +331,7 @@ int sync_file_range(struct file *file, loff_t offset, loff_t nbytes,
* Useful combinations of the flag bits are:
*
* SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE: ensures that all pages
* in the range which were dirty on entry to sys_sync_file_range() are placed
* in the range which were dirty on entry to ksys_sync_file_range() are placed
* under writeout. This is a start-write-for-data-integrity operation.
*
* SYNC_FILE_RANGE_WRITE: start writeout of all dirty pages in the range which
Expand All @@ -337,10 +343,13 @@ int sync_file_range(struct file *file, loff_t offset, loff_t nbytes,
* earlier SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE operation to wait
* for that operation to complete and to return the result.
*
* SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER:
* SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER
* (a.k.a. SYNC_FILE_RANGE_WRITE_AND_WAIT):
* a traditional sync() operation. This is a write-for-data-integrity operation
* which will ensure that all pages in the range which were dirty on entry to
* sys_sync_file_range() are committed to disk.
* ksys_sync_file_range() are written to disk. It should be noted that disk
* caches are not flushed by this call, so there are no guarantees here that the
* data will be available on disk after a crash.
*
*
* SYNC_FILE_RANGE_WAIT_BEFORE and SYNC_FILE_RANGE_WAIT_AFTER will detect any
Expand Down
3 changes: 3 additions & 0 deletions include/uapi/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,9 @@ struct fscrypt_key {
#define SYNC_FILE_RANGE_WAIT_BEFORE 1
#define SYNC_FILE_RANGE_WRITE 2
#define SYNC_FILE_RANGE_WAIT_AFTER 4
#define SYNC_FILE_RANGE_WRITE_AND_WAIT (SYNC_FILE_RANGE_WRITE | \
SYNC_FILE_RANGE_WAIT_BEFORE | \
SYNC_FILE_RANGE_WAIT_AFTER)

/*
* Flags for preadv2/pwritev2:
Expand Down

0 comments on commit c553ea4

Please sign in to comment.