Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "This the bunch that sat in -next + lock_parent() fix. This is the minimal set; there's more pending stuff. In particular, I really hope to get acct.c fixes merged this cycle - we need that to deal sanely with delayed-mntput stuff. In the next pile, hopefully - that series is fairly short and localized (kernel/acct.c, fs/super.c and fs/namespace.c). In this pile: more iov_iter work. Most of prereqs for ->splice_write with sane locking order are there and Kent's dio rewrite would also fit nicely on top of this pile" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (70 commits) lock_parent: don't step on stale ->d_parent of all-but-freed one kill generic_file_splice_write() ceph: switch to iter_file_splice_write() shmem: switch to iter_file_splice_write() nfs: switch to iter_splice_write_file() fs/splice.c: remove unneeded exports ocfs2: switch to iter_file_splice_write() ->splice_write() via ->write_iter() bio_vec-backed iov_iter optimize copy_page_{to,from}_iter() bury generic_file_aio_{read,write} lustre: get rid of messing with iovecs ceph: switch to ->write_iter() ceph_sync_direct_write: stop poking into iov_iter guts ceph_sync_read: stop poking into iov_iter guts new helper: copy_page_from_iter() fuse: switch to ->write_iter() btrfs: switch to ->write_iter() ocfs2: switch to ->write_iter() xfs: switch to ->write_iter() ...
This commit is contained in:
@@ -229,34 +229,27 @@ xfs_file_fsync(
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
xfs_file_aio_read(
|
||||
xfs_file_read_iter(
|
||||
struct kiocb *iocb,
|
||||
const struct iovec *iovp,
|
||||
unsigned long nr_segs,
|
||||
loff_t pos)
|
||||
struct iov_iter *to)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
struct xfs_inode *ip = XFS_I(inode);
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
size_t size = 0;
|
||||
size_t size = iov_iter_count(to);
|
||||
ssize_t ret = 0;
|
||||
int ioflags = 0;
|
||||
xfs_fsize_t n;
|
||||
loff_t pos = iocb->ki_pos;
|
||||
|
||||
XFS_STATS_INC(xs_read_calls);
|
||||
|
||||
BUG_ON(iocb->ki_pos != pos);
|
||||
|
||||
if (unlikely(file->f_flags & O_DIRECT))
|
||||
ioflags |= IO_ISDIRECT;
|
||||
if (file->f_mode & FMODE_NOCMTIME)
|
||||
ioflags |= IO_INVIS;
|
||||
|
||||
ret = generic_segment_checks(iovp, &nr_segs, &size, VERIFY_WRITE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (unlikely(ioflags & IO_ISDIRECT)) {
|
||||
xfs_buftarg_t *target =
|
||||
XFS_IS_REALTIME_INODE(ip) ?
|
||||
@@ -309,7 +302,7 @@ xfs_file_aio_read(
|
||||
|
||||
trace_xfs_file_read(ip, size, pos, ioflags);
|
||||
|
||||
ret = generic_file_aio_read(iocb, iovp, nr_segs, pos);
|
||||
ret = generic_file_read_iter(iocb, to);
|
||||
if (ret > 0)
|
||||
XFS_STATS_ADD(xs_read_bytes, ret);
|
||||
|
||||
@@ -349,47 +342,6 @@ xfs_file_splice_read(
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfs_file_splice_write() does not use xfs_rw_ilock() because
|
||||
* generic_file_splice_write() takes the i_mutex itself. This, in theory,
|
||||
* couuld cause lock inversions between the aio_write path and the splice path
|
||||
* if someone is doing concurrent splice(2) based writes and write(2) based
|
||||
* writes to the same inode. The only real way to fix this is to re-implement
|
||||
* the generic code here with correct locking orders.
|
||||
*/
|
||||
STATIC ssize_t
|
||||
xfs_file_splice_write(
|
||||
struct pipe_inode_info *pipe,
|
||||
struct file *outfilp,
|
||||
loff_t *ppos,
|
||||
size_t count,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct inode *inode = outfilp->f_mapping->host;
|
||||
struct xfs_inode *ip = XFS_I(inode);
|
||||
int ioflags = 0;
|
||||
ssize_t ret;
|
||||
|
||||
XFS_STATS_INC(xs_write_calls);
|
||||
|
||||
if (outfilp->f_mode & FMODE_NOCMTIME)
|
||||
ioflags |= IO_INVIS;
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
|
||||
return -EIO;
|
||||
|
||||
xfs_ilock(ip, XFS_IOLOCK_EXCL);
|
||||
|
||||
trace_xfs_file_splice_write(ip, count, *ppos, ioflags);
|
||||
|
||||
ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
|
||||
if (ret > 0)
|
||||
XFS_STATS_ADD(xs_write_bytes, ret);
|
||||
|
||||
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is called to handle zeroing any space in the last block of the
|
||||
* file that is beyond the EOF. We do this since the size is being increased
|
||||
@@ -625,10 +577,7 @@ restart:
|
||||
STATIC ssize_t
|
||||
xfs_file_dio_aio_write(
|
||||
struct kiocb *iocb,
|
||||
const struct iovec *iovp,
|
||||
unsigned long nr_segs,
|
||||
loff_t pos,
|
||||
size_t ocount)
|
||||
struct iov_iter *from)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct address_space *mapping = file->f_mapping;
|
||||
@@ -636,9 +585,10 @@ xfs_file_dio_aio_write(
|
||||
struct xfs_inode *ip = XFS_I(inode);
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
ssize_t ret = 0;
|
||||
size_t count = ocount;
|
||||
int unaligned_io = 0;
|
||||
int iolock;
|
||||
size_t count = iov_iter_count(from);
|
||||
loff_t pos = iocb->ki_pos;
|
||||
struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ?
|
||||
mp->m_rtdev_targp : mp->m_ddev_targp;
|
||||
|
||||
@@ -677,6 +627,7 @@ xfs_file_dio_aio_write(
|
||||
ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock);
|
||||
if (ret)
|
||||
goto out;
|
||||
iov_iter_truncate(from, count);
|
||||
|
||||
if (mapping->nrpages) {
|
||||
ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
|
||||
@@ -698,8 +649,7 @@ xfs_file_dio_aio_write(
|
||||
}
|
||||
|
||||
trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0);
|
||||
ret = generic_file_direct_write(iocb, iovp,
|
||||
&nr_segs, pos, count, ocount);
|
||||
ret = generic_file_direct_write(iocb, from, pos);
|
||||
|
||||
out:
|
||||
xfs_rw_iunlock(ip, iolock);
|
||||
@@ -712,10 +662,7 @@ out:
|
||||
STATIC ssize_t
|
||||
xfs_file_buffered_aio_write(
|
||||
struct kiocb *iocb,
|
||||
const struct iovec *iovp,
|
||||
unsigned long nr_segs,
|
||||
loff_t pos,
|
||||
size_t count)
|
||||
struct iov_iter *from)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct address_space *mapping = file->f_mapping;
|
||||
@@ -724,7 +671,8 @@ xfs_file_buffered_aio_write(
|
||||
ssize_t ret;
|
||||
int enospc = 0;
|
||||
int iolock = XFS_IOLOCK_EXCL;
|
||||
struct iov_iter from;
|
||||
loff_t pos = iocb->ki_pos;
|
||||
size_t count = iov_iter_count(from);
|
||||
|
||||
xfs_rw_ilock(ip, iolock);
|
||||
|
||||
@@ -732,13 +680,13 @@ xfs_file_buffered_aio_write(
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
iov_iter_init(&from, iovp, nr_segs, count, 0);
|
||||
iov_iter_truncate(from, count);
|
||||
/* We can write back this queue in page reclaim */
|
||||
current->backing_dev_info = mapping->backing_dev_info;
|
||||
|
||||
write_retry:
|
||||
trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0);
|
||||
ret = generic_perform_write(file, &from, pos);
|
||||
ret = generic_perform_write(file, from, pos);
|
||||
if (likely(ret >= 0))
|
||||
iocb->ki_pos = pos + ret;
|
||||
/*
|
||||
@@ -759,40 +707,29 @@ out:
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
xfs_file_aio_write(
|
||||
xfs_file_write_iter(
|
||||
struct kiocb *iocb,
|
||||
const struct iovec *iovp,
|
||||
unsigned long nr_segs,
|
||||
loff_t pos)
|
||||
struct iov_iter *from)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct address_space *mapping = file->f_mapping;
|
||||
struct inode *inode = mapping->host;
|
||||
struct xfs_inode *ip = XFS_I(inode);
|
||||
ssize_t ret;
|
||||
size_t ocount = 0;
|
||||
size_t ocount = iov_iter_count(from);
|
||||
|
||||
XFS_STATS_INC(xs_write_calls);
|
||||
|
||||
BUG_ON(iocb->ki_pos != pos);
|
||||
|
||||
ret = generic_segment_checks(iovp, &nr_segs, &ocount, VERIFY_READ);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (ocount == 0)
|
||||
return 0;
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
|
||||
return -EIO;
|
||||
|
||||
if (unlikely(file->f_flags & O_DIRECT))
|
||||
ret = xfs_file_dio_aio_write(iocb, iovp, nr_segs, pos, ocount);
|
||||
ret = xfs_file_dio_aio_write(iocb, from);
|
||||
else
|
||||
ret = xfs_file_buffered_aio_write(iocb, iovp, nr_segs, pos,
|
||||
ocount);
|
||||
ret = xfs_file_buffered_aio_write(iocb, from);
|
||||
|
||||
if (ret > 0) {
|
||||
ssize_t err;
|
||||
@@ -804,8 +741,6 @@ xfs_file_aio_write(
|
||||
if (err < 0)
|
||||
ret = err;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1461,12 +1396,12 @@ xfs_file_llseek(
|
||||
|
||||
const struct file_operations xfs_file_operations = {
|
||||
.llseek = xfs_file_llseek,
|
||||
.read = do_sync_read,
|
||||
.write = do_sync_write,
|
||||
.aio_read = xfs_file_aio_read,
|
||||
.aio_write = xfs_file_aio_write,
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = xfs_file_read_iter,
|
||||
.write_iter = xfs_file_write_iter,
|
||||
.splice_read = xfs_file_splice_read,
|
||||
.splice_write = xfs_file_splice_write,
|
||||
.splice_write = iter_file_splice_write,
|
||||
.unlocked_ioctl = xfs_file_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = xfs_file_compat_ioctl,
|
||||
|
Reference in New Issue
Block a user