fs: simplify the generic_write_sync prototype
The kiocb already has the new position, so use that. The only interesting case is AIO, where we currently don't bother updating ki_pos. We're about to free the kiocb after we're done, so we might as well update it to make everyone's life simpler. While we're at it also return the bytes written argument passed in if we were successful so that the boilerplate error switch code in the callers can go away. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
dde0c2e798
Коммит
e259221763
|
@ -1660,12 +1660,8 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
|
|
||||||
blk_start_plug(&plug);
|
blk_start_plug(&plug);
|
||||||
ret = __generic_file_write_iter(iocb, from);
|
ret = __generic_file_write_iter(iocb, from);
|
||||||
if (ret > 0) {
|
if (ret > 0)
|
||||||
ssize_t err;
|
ret = generic_write_sync(iocb, ret);
|
||||||
err = generic_write_sync(iocb, iocb->ki_pos - ret, ret);
|
|
||||||
if (err < 0)
|
|
||||||
ret = err;
|
|
||||||
}
|
|
||||||
blk_finish_plug(&plug);
|
blk_finish_plug(&plug);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1851,11 +1851,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
|
||||||
spin_lock(&BTRFS_I(inode)->lock);
|
spin_lock(&BTRFS_I(inode)->lock);
|
||||||
BTRFS_I(inode)->last_sub_trans = root->log_transid;
|
BTRFS_I(inode)->last_sub_trans = root->log_transid;
|
||||||
spin_unlock(&BTRFS_I(inode)->lock);
|
spin_unlock(&BTRFS_I(inode)->lock);
|
||||||
if (num_written > 0) {
|
if (num_written > 0)
|
||||||
err = generic_write_sync(iocb, pos, num_written);
|
num_written = generic_write_sync(iocb, num_written);
|
||||||
if (err < 0)
|
|
||||||
num_written = err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sync)
|
if (sync)
|
||||||
atomic_dec(&BTRFS_I(inode)->sync_writers);
|
atomic_dec(&BTRFS_I(inode)->sync_writers);
|
||||||
|
|
|
@ -2687,11 +2687,8 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
|
||||||
out:
|
out:
|
||||||
inode_unlock(inode);
|
inode_unlock(inode);
|
||||||
|
|
||||||
if (rc > 0) {
|
if (rc > 0)
|
||||||
ssize_t err = generic_write_sync(iocb, iocb->ki_pos - rc, rc);
|
rc = generic_write_sync(iocb, rc);
|
||||||
if (err < 0)
|
|
||||||
rc = err;
|
|
||||||
}
|
|
||||||
up_read(&cinode->lock_sem);
|
up_read(&cinode->lock_sem);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,6 +256,7 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, bool is_async)
|
||||||
if (dio->end_io) {
|
if (dio->end_io) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
// XXX: ki_pos??
|
||||||
err = dio->end_io(dio->iocb, offset, ret, dio->private);
|
err = dio->end_io(dio->iocb, offset, ret, dio->private);
|
||||||
if (err)
|
if (err)
|
||||||
ret = err;
|
ret = err;
|
||||||
|
@ -265,15 +266,15 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, bool is_async)
|
||||||
inode_dio_end(dio->inode);
|
inode_dio_end(dio->inode);
|
||||||
|
|
||||||
if (is_async) {
|
if (is_async) {
|
||||||
if (dio->rw & WRITE) {
|
/*
|
||||||
int err;
|
* generic_write_sync expects ki_pos to have been updated
|
||||||
|
* already, but the submission path only does this for
|
||||||
err = generic_write_sync(dio->iocb, offset,
|
* synchronous I/O.
|
||||||
transferred);
|
*/
|
||||||
if (err < 0 && ret > 0)
|
dio->iocb->ki_pos += transferred;
|
||||||
ret = err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (dio->rw & WRITE)
|
||||||
|
ret = generic_write_sync(dio->iocb, transferred);
|
||||||
dio->iocb->ki_complete(dio->iocb, ret, 0);
|
dio->iocb->ki_complete(dio->iocb, ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,13 +169,8 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
ret = __generic_file_write_iter(iocb, from);
|
ret = __generic_file_write_iter(iocb, from);
|
||||||
inode_unlock(inode);
|
inode_unlock(inode);
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0)
|
||||||
ssize_t err;
|
ret = generic_write_sync(iocb, ret);
|
||||||
|
|
||||||
err = generic_write_sync(iocb, iocb->ki_pos - ret, ret);
|
|
||||||
if (err < 0)
|
|
||||||
ret = err;
|
|
||||||
}
|
|
||||||
if (o_direct)
|
if (o_direct)
|
||||||
blk_finish_plug(&plug);
|
blk_finish_plug(&plug);
|
||||||
|
|
||||||
|
|
|
@ -1882,13 +1882,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
}
|
}
|
||||||
inode_unlock(inode);
|
inode_unlock(inode);
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0)
|
||||||
ssize_t err;
|
ret = generic_write_sync(iocb, ret);
|
||||||
|
|
||||||
err = generic_write_sync(iocb, iocb->ki_pos - ret, ret);
|
|
||||||
if (err < 0)
|
|
||||||
ret = err;
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1054,7 +1054,9 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
|
||||||
if (i_size_read(inode) < iocb->ki_pos)
|
if (i_size_read(inode) < iocb->ki_pos)
|
||||||
i_size_write(inode, iocb->ki_pos);
|
i_size_write(inode, iocb->ki_pos);
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
generic_write_sync(iocb, pos, result);
|
|
||||||
|
/* XXX: should check the generic_write_sync retval */
|
||||||
|
generic_write_sync(iocb, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nfs_direct_req_release(dreq);
|
nfs_direct_req_release(dreq);
|
||||||
|
|
|
@ -1952,12 +1952,9 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
written = ntfs_perform_write(file, from, iocb->ki_pos);
|
written = ntfs_perform_write(file, from, iocb->ki_pos);
|
||||||
current->backing_dev_info = NULL;
|
current->backing_dev_info = NULL;
|
||||||
inode_unlock(vi);
|
inode_unlock(vi);
|
||||||
if (likely(written > 0)) {
|
|
||||||
err = generic_write_sync(iocb, iocb->ki_pos, written);
|
|
||||||
if (err < 0)
|
|
||||||
written = 0;
|
|
||||||
}
|
|
||||||
iocb->ki_pos += written;
|
iocb->ki_pos += written;
|
||||||
|
if (likely(written > 0))
|
||||||
|
written = generic_write_sync(iocb, written);
|
||||||
return written ? written : err;
|
return written ? written : err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,9 +152,7 @@ out:
|
||||||
|
|
||||||
if (retval > 0) {
|
if (retval > 0) {
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
err = generic_write_sync(iocb, iocb->ki_pos - retval, retval);
|
retval = generic_write_sync(iocb, retval);
|
||||||
if (err < 0)
|
|
||||||
retval = err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -903,14 +903,10 @@ xfs_file_write_iter(
|
||||||
ret = xfs_file_buffered_aio_write(iocb, from);
|
ret = xfs_file_buffered_aio_write(iocb, from);
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
ssize_t err;
|
|
||||||
|
|
||||||
XFS_STATS_ADD(ip->i_mount, xs_write_bytes, ret);
|
XFS_STATS_ADD(ip->i_mount, xs_write_bytes, ret);
|
||||||
|
|
||||||
/* Handle various SYNC-type writes */
|
/* Handle various SYNC-type writes */
|
||||||
err = generic_write_sync(iocb, iocb->ki_pos - ret, ret);
|
ret = generic_write_sync(iocb, ret);
|
||||||
if (err < 0)
|
|
||||||
ret = err;
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2487,13 +2487,25 @@ extern int filemap_fdatawrite_range(struct address_space *mapping,
|
||||||
extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
|
extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
|
||||||
int datasync);
|
int datasync);
|
||||||
extern int vfs_fsync(struct file *file, int datasync);
|
extern int vfs_fsync(struct file *file, int datasync);
|
||||||
static inline int generic_write_sync(struct kiocb *iocb, loff_t pos, loff_t count)
|
|
||||||
|
/*
|
||||||
|
* Sync the bytes written if this was a synchronous write. Expect ki_pos
|
||||||
|
* to already be updated for the write, and will return either the amount
|
||||||
|
* of bytes passed in, or an error if syncing the file failed.
|
||||||
|
*/
|
||||||
|
static inline ssize_t generic_write_sync(struct kiocb *iocb, ssize_t count)
|
||||||
{
|
{
|
||||||
if (!(iocb->ki_flags & IOCB_DSYNC))
|
if (iocb->ki_flags & IOCB_DSYNC) {
|
||||||
return 0;
|
int ret = vfs_fsync_range(iocb->ki_filp,
|
||||||
return vfs_fsync_range(iocb->ki_filp, pos, pos + count - 1,
|
iocb->ki_pos - count, iocb->ki_pos - 1,
|
||||||
(iocb->ki_flags & IOCB_SYNC) ? 0 : 1);
|
(iocb->ki_flags & IOCB_SYNC) ? 0 : 1);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void emergency_sync(void);
|
extern void emergency_sync(void);
|
||||||
extern void emergency_remount(void);
|
extern void emergency_remount(void);
|
||||||
#ifdef CONFIG_BLOCK
|
#ifdef CONFIG_BLOCK
|
||||||
|
|
|
@ -2791,13 +2791,8 @@ ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
ret = __generic_file_write_iter(iocb, from);
|
ret = __generic_file_write_iter(iocb, from);
|
||||||
inode_unlock(inode);
|
inode_unlock(inode);
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0)
|
||||||
ssize_t err;
|
ret = generic_write_sync(iocb, ret);
|
||||||
|
|
||||||
err = generic_write_sync(iocb, iocb->ki_pos - ret, ret);
|
|
||||||
if (err < 0)
|
|
||||||
ret = err;
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(generic_file_write_iter);
|
EXPORT_SYMBOL(generic_file_write_iter);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче