aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_lrw.c
diff options
context:
space:
mode:
authorNathan Scott <nathans@sgi.com>2006-03-30 22:08:59 -0500
committerNathan Scott <nathans@sgi.com>2006-03-30 22:08:59 -0500
commit1b895840ce93fd2d150a86c800a3085eaab4eb9e (patch)
tree2f1c664ca2f948ec8c47f2c66e03cb21f2b9a45c /fs/xfs/linux-2.6/xfs_lrw.c
parent3bbcc8e3976f8bba2fd607c8850d7dfe7e332fda (diff)
[XFS] Provide XFS support for the splice syscall.
Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_lrw.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c120
1 files changed, 93 insertions, 27 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 84ddf1893894..90cd314acbaa 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -301,36 +301,23 @@ xfs_sendfile(
301 void *target, 301 void *target,
302 cred_t *credp) 302 cred_t *credp)
303{ 303{
304 xfs_inode_t *ip = XFS_BHVTOI(bdp);
305 xfs_mount_t *mp = ip->i_mount;
304 ssize_t ret; 306 ssize_t ret;
305 xfs_fsize_t n;
306 xfs_inode_t *ip;
307 xfs_mount_t *mp;
308 vnode_t *vp;
309
310 ip = XFS_BHVTOI(bdp);
311 vp = BHV_TO_VNODE(bdp);
312 mp = ip->i_mount;
313 307
314 XFS_STATS_INC(xs_read_calls); 308 XFS_STATS_INC(xs_read_calls);
315 309 if (XFS_FORCED_SHUTDOWN(mp))
316 n = XFS_MAXIOFFSET(mp) - *offset;
317 if ((n <= 0) || (count == 0))
318 return 0;
319
320 if (n < count)
321 count = n;
322
323 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
324 return -EIO; 310 return -EIO;
325 311
326 xfs_ilock(ip, XFS_IOLOCK_SHARED); 312 xfs_ilock(ip, XFS_IOLOCK_SHARED);
327 313
328 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && 314 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
329 (!(ioflags & IO_INVIS))) { 315 (!(ioflags & IO_INVIS))) {
330 vrwlock_t locktype = VRWLOCK_READ; 316 vrwlock_t locktype = VRWLOCK_READ;
331 int error; 317 int error;
332 318
333 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), *offset, count, 319 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
320 *offset, count,
334 FILP_DELAY_FLAG(filp), &locktype); 321 FILP_DELAY_FLAG(filp), &locktype);
335 if (error) { 322 if (error) {
336 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 323 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -340,12 +327,96 @@ xfs_sendfile(
340 xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore, 327 xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
341 (void *)(unsigned long)target, count, *offset, ioflags); 328 (void *)(unsigned long)target, count, *offset, ioflags);
342 ret = generic_file_sendfile(filp, offset, count, actor, target); 329 ret = generic_file_sendfile(filp, offset, count, actor, target);
330 if (ret > 0)
331 XFS_STATS_ADD(xs_read_bytes, ret);
343 332
344 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 333 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
334 return ret;
335}
345 336
337ssize_t
338xfs_splice_read(
339 bhv_desc_t *bdp,
340 struct file *infilp,
341 struct inode *pipe,
342 size_t count,
343 int flags,
344 int ioflags,
345 cred_t *credp)
346{
347 xfs_inode_t *ip = XFS_BHVTOI(bdp);
348 xfs_mount_t *mp = ip->i_mount;
349 ssize_t ret;
350
351 XFS_STATS_INC(xs_read_calls);
352 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
353 return -EIO;
354
355 xfs_ilock(ip, XFS_IOLOCK_SHARED);
356
357 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
358 (!(ioflags & IO_INVIS))) {
359 vrwlock_t locktype = VRWLOCK_READ;
360 int error;
361
362 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
363 infilp->f_pos, count,
364 FILP_DELAY_FLAG(infilp), &locktype);
365 if (error) {
366 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
367 return -error;
368 }
369 }
370 xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, &ip->i_iocore,
371 pipe, count, infilp->f_pos, ioflags);
372 ret = generic_file_splice_read(infilp, pipe, count, flags);
346 if (ret > 0) 373 if (ret > 0)
347 XFS_STATS_ADD(xs_read_bytes, ret); 374 XFS_STATS_ADD(xs_read_bytes, ret);
348 375
376 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
377 return ret;
378}
379
380ssize_t
381xfs_splice_write(
382 bhv_desc_t *bdp,
383 struct inode *pipe,
384 struct file *outfilp,
385 size_t count,
386 int flags,
387 int ioflags,
388 cred_t *credp)
389{
390 xfs_inode_t *ip = XFS_BHVTOI(bdp);
391 xfs_mount_t *mp = ip->i_mount;
392 ssize_t ret;
393
394 XFS_STATS_INC(xs_write_calls);
395 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
396 return -EIO;
397
398 xfs_ilock(ip, XFS_IOLOCK_EXCL);
399
400 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
401 (!(ioflags & IO_INVIS))) {
402 vrwlock_t locktype = VRWLOCK_WRITE;
403 int error;
404
405 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
406 outfilp->f_pos, count,
407 FILP_DELAY_FLAG(outfilp), &locktype);
408 if (error) {
409 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
410 return -error;
411 }
412 }
413 xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore,
414 pipe, count, outfilp->f_pos, ioflags);
415 ret = generic_file_splice_write(pipe, outfilp, count, flags);
416 if (ret > 0)
417 XFS_STATS_ADD(xs_write_bytes, ret);
418
419 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
349 return ret; 420 return ret;
350} 421}
351 422
@@ -363,7 +434,7 @@ xfs_zero_last_block(
363 xfs_fsize_t end_size) 434 xfs_fsize_t end_size)
364{ 435{
365 xfs_fileoff_t last_fsb; 436 xfs_fileoff_t last_fsb;
366 xfs_mount_t *mp; 437 xfs_mount_t *mp = io->io_mount;
367 int nimaps; 438 int nimaps;
368 int zero_offset; 439 int zero_offset;
369 int zero_len; 440 int zero_len;
@@ -373,8 +444,6 @@ xfs_zero_last_block(
373 444
374 ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0); 445 ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0);
375 446
376 mp = io->io_mount;
377
378 zero_offset = XFS_B_FSB_OFFSET(mp, isize); 447 zero_offset = XFS_B_FSB_OFFSET(mp, isize);
379 if (zero_offset == 0) { 448 if (zero_offset == 0) {
380 /* 449 /*
@@ -405,10 +474,9 @@ xfs_zero_last_block(
405 * don't deadlock when the buffer cache calls back to us. 474 * don't deadlock when the buffer cache calls back to us.
406 */ 475 */
407 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD); 476 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
408 loff = XFS_FSB_TO_B(mp, last_fsb);
409 477
478 loff = XFS_FSB_TO_B(mp, last_fsb);
410 zero_len = mp->m_sb.sb_blocksize - zero_offset; 479 zero_len = mp->m_sb.sb_blocksize - zero_offset;
411
412 error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size); 480 error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size);
413 481
414 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); 482 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
@@ -441,7 +509,7 @@ xfs_zero_eof(
441 xfs_fileoff_t zero_count_fsb; 509 xfs_fileoff_t zero_count_fsb;
442 xfs_fileoff_t last_fsb; 510 xfs_fileoff_t last_fsb;
443 xfs_extlen_t buf_len_fsb; 511 xfs_extlen_t buf_len_fsb;
444 xfs_mount_t *mp; 512 xfs_mount_t *mp = io->io_mount;
445 int nimaps; 513 int nimaps;
446 int error = 0; 514 int error = 0;
447 xfs_bmbt_irec_t imap; 515 xfs_bmbt_irec_t imap;
@@ -450,8 +518,6 @@ xfs_zero_eof(
450 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); 518 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
451 ASSERT(offset > isize); 519 ASSERT(offset > isize);
452 520
453 mp = io->io_mount;
454
455 /* 521 /*
456 * First handle zeroing the block on which isize resides. 522 * First handle zeroing the block on which isize resides.
457 * We only zero a part of that block so it is handled specially. 523 * We only zero a part of that block so it is handled specially.