diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-04-05 04:27:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-06-12 00:18:51 -0400 |
commit | 8d0207652cbe27d1f962050737848e5ad4671958 (patch) | |
tree | 2cd92ec3cfc66cdfd3cff1b4a46f1b5a4f4b8197 /fs/xfs/xfs_file.c | |
parent | 62a8067a7f35dba2de501c9cb00e4cf36da90bc0 (diff) |
->splice_write() via ->write_iter()
iter_file_splice_write() - a ->splice_write() instance that gathers the
pipe buffers, builds a bio_vec-based iov_iter covering those and feeds
it to ->write_iter(). A bunch of simple cases coverted to that...
[AV: fixed the braino spotted by Cyrill]
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r-- | fs/xfs/xfs_file.c | 43 |
1 files changed, 1 insertions, 42 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 5446e86d3485..b1c489c1fb2e 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -343,47 +343,6 @@ xfs_file_splice_read( | |||
343 | } | 343 | } |
344 | 344 | ||
345 | /* | 345 | /* |
346 | * xfs_file_splice_write() does not use xfs_rw_ilock() because | ||
347 | * generic_file_splice_write() takes the i_mutex itself. This, in theory, | ||
348 | * couuld cause lock inversions between the aio_write path and the splice path | ||
349 | * if someone is doing concurrent splice(2) based writes and write(2) based | ||
350 | * writes to the same inode. The only real way to fix this is to re-implement | ||
351 | * the generic code here with correct locking orders. | ||
352 | */ | ||
353 | STATIC ssize_t | ||
354 | xfs_file_splice_write( | ||
355 | struct pipe_inode_info *pipe, | ||
356 | struct file *outfilp, | ||
357 | loff_t *ppos, | ||
358 | size_t count, | ||
359 | unsigned int flags) | ||
360 | { | ||
361 | struct inode *inode = outfilp->f_mapping->host; | ||
362 | struct xfs_inode *ip = XFS_I(inode); | ||
363 | int ioflags = 0; | ||
364 | ssize_t ret; | ||
365 | |||
366 | XFS_STATS_INC(xs_write_calls); | ||
367 | |||
368 | if (outfilp->f_mode & FMODE_NOCMTIME) | ||
369 | ioflags |= IO_INVIS; | ||
370 | |||
371 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | ||
372 | return -EIO; | ||
373 | |||
374 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
375 | |||
376 | trace_xfs_file_splice_write(ip, count, *ppos, ioflags); | ||
377 | |||
378 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); | ||
379 | if (ret > 0) | ||
380 | XFS_STATS_ADD(xs_write_bytes, ret); | ||
381 | |||
382 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
383 | return ret; | ||
384 | } | ||
385 | |||
386 | /* | ||
387 | * This routine is called to handle zeroing any space in the last block of the | 346 | * This routine is called to handle zeroing any space in the last block of the |
388 | * file that is beyond the EOF. We do this since the size is being increased | 347 | * file that is beyond the EOF. We do this since the size is being increased |
389 | * without writing anything to that block and we don't want to read the | 348 | * without writing anything to that block and we don't want to read the |
@@ -1442,7 +1401,7 @@ const struct file_operations xfs_file_operations = { | |||
1442 | .read_iter = xfs_file_read_iter, | 1401 | .read_iter = xfs_file_read_iter, |
1443 | .write_iter = xfs_file_write_iter, | 1402 | .write_iter = xfs_file_write_iter, |
1444 | .splice_read = xfs_file_splice_read, | 1403 | .splice_read = xfs_file_splice_read, |
1445 | .splice_write = xfs_file_splice_write, | 1404 | .splice_write = iter_file_splice_write, |
1446 | .unlocked_ioctl = xfs_file_ioctl, | 1405 | .unlocked_ioctl = xfs_file_ioctl, |
1447 | #ifdef CONFIG_COMPAT | 1406 | #ifdef CONFIG_COMPAT |
1448 | .compat_ioctl = xfs_file_compat_ioctl, | 1407 | .compat_ioctl = xfs_file_compat_ioctl, |