diff options
author | Nathan Scott <nathans@sgi.com> | 2006-03-30 22:08:59 -0500 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-03-30 22:08:59 -0500 |
commit | 1b895840ce93fd2d150a86c800a3085eaab4eb9e (patch) | |
tree | 2f1c664ca2f948ec8c47f2c66e03cb21f2b9a45c /fs/xfs/linux-2.6/xfs_lrw.c | |
parent | 3bbcc8e3976f8bba2fd607c8850d7dfe7e332fda (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.c | 120 |
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 | ||
337 | ssize_t | ||
338 | xfs_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 | |||
380 | ssize_t | ||
381 | xfs_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. |