vfs: Introduce new helpers for syncing after writing to O_SYNC file or IS_SYNC inode

Introduce new function for generic inode syncing (vfs_fsync_range) and use
it from fsync() path. Introduce also new helper for syncing after a sync
write (generic_write_sync) using the generic function.

Use these new helpers for syncing from generic VFS functions. This makes
O_SYNC writes to block devices acquire i_mutex for syncing. If we really
care about this, we can make block_fsync() drop the i_mutex and reacquire
it before it returns.

CC: Evgeniy Polyakov <[email protected]>
CC: [email protected]
CC: Joel Becker <[email protected]>
CC: Felix Blyakher <[email protected]>
CC: [email protected]
CC: Anton Altaparmakov <[email protected]>
CC: [email protected]
CC: OGAWA Hirofumi <[email protected]>
CC: [email protected]
CC: [email protected]
Acked-by: Christoph Hellwig <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
This commit is contained in:
Jan Kara 2009-08-17 19:52:36 +02:00
commit 148f948ba8
4 changed files with 61 additions and 30 deletions

View file

@ -39,11 +39,10 @@
/*
* FIXME: remove all knowledge of the buffer layer from the core VM
*/
#include <linux/buffer_head.h> /* for generic_osync_inode */
#include <linux/buffer_head.h> /* for try_to_free_buffers */
#include <asm/mman.h>
/*
* Shared mappings implemented 30.11.1994. It's not fully working yet,
* though.
@ -2477,8 +2476,7 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
struct inode *inode = file->f_mapping->host;
ssize_t ret;
BUG_ON(iocb->ki_pos != pos);
@ -2487,11 +2485,10 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
mutex_unlock(&inode->i_mutex);
if ((ret > 0 || ret == -EIOCBQUEUED) &&
((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
if (ret > 0 || ret == -EIOCBQUEUED) {
ssize_t err;
err = sync_page_range(inode, mapping, pos, ret);
err = generic_write_sync(file, pos, ret);
if (err < 0 && ret > 0)
ret = err;
}