diff options
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r-- | fs/xfs/xfs_iomap.c | 76 |
1 files changed, 36 insertions, 40 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index ef14943829da..20576146369f 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -23,19 +23,14 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir2.h" | ||
27 | #include "xfs_alloc.h" | 26 | #include "xfs_alloc.h" |
28 | #include "xfs_dmapi.h" | ||
29 | #include "xfs_quota.h" | 27 | #include "xfs_quota.h" |
30 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 30 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 31 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir2_sf.h" | ||
35 | #include "xfs_attr_sf.h" | ||
36 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
37 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
38 | #include "xfs_ialloc.h" | ||
39 | #include "xfs_btree.h" | 34 | #include "xfs_btree.h" |
40 | #include "xfs_bmap.h" | 35 | #include "xfs_bmap.h" |
41 | #include "xfs_rtalloc.h" | 36 | #include "xfs_rtalloc.h" |
@@ -123,7 +118,7 @@ xfs_iomap( | |||
123 | error = xfs_bmapi(NULL, ip, offset_fsb, | 118 | error = xfs_bmapi(NULL, ip, offset_fsb, |
124 | (xfs_filblks_t)(end_fsb - offset_fsb), | 119 | (xfs_filblks_t)(end_fsb - offset_fsb), |
125 | bmapi_flags, NULL, 0, imap, | 120 | bmapi_flags, NULL, 0, imap, |
126 | nimaps, NULL, NULL); | 121 | nimaps, NULL); |
127 | 122 | ||
128 | if (error) | 123 | if (error) |
129 | goto out; | 124 | goto out; |
@@ -138,7 +133,7 @@ xfs_iomap( | |||
138 | break; | 133 | break; |
139 | } | 134 | } |
140 | 135 | ||
141 | if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) { | 136 | if (flags & BMAPI_DIRECT) { |
142 | error = xfs_iomap_write_direct(ip, offset, count, flags, | 137 | error = xfs_iomap_write_direct(ip, offset, count, flags, |
143 | imap, nimaps); | 138 | imap, nimaps); |
144 | } else { | 139 | } else { |
@@ -247,7 +242,7 @@ xfs_iomap_write_direct( | |||
247 | xfs_off_t offset, | 242 | xfs_off_t offset, |
248 | size_t count, | 243 | size_t count, |
249 | int flags, | 244 | int flags, |
250 | xfs_bmbt_irec_t *ret_imap, | 245 | xfs_bmbt_irec_t *imap, |
251 | int *nmaps) | 246 | int *nmaps) |
252 | { | 247 | { |
253 | xfs_mount_t *mp = ip->i_mount; | 248 | xfs_mount_t *mp = ip->i_mount; |
@@ -261,7 +256,6 @@ xfs_iomap_write_direct( | |||
261 | int quota_flag; | 256 | int quota_flag; |
262 | int rt; | 257 | int rt; |
263 | xfs_trans_t *tp; | 258 | xfs_trans_t *tp; |
264 | xfs_bmbt_irec_t imap; | ||
265 | xfs_bmap_free_t free_list; | 259 | xfs_bmap_free_t free_list; |
266 | uint qblocks, resblks, resrtextents; | 260 | uint qblocks, resblks, resrtextents; |
267 | int committed; | 261 | int committed; |
@@ -285,10 +279,10 @@ xfs_iomap_write_direct( | |||
285 | if (error) | 279 | if (error) |
286 | goto error_out; | 280 | goto error_out; |
287 | } else { | 281 | } else { |
288 | if (*nmaps && (ret_imap->br_startblock == HOLESTARTBLOCK)) | 282 | if (*nmaps && (imap->br_startblock == HOLESTARTBLOCK)) |
289 | last_fsb = MIN(last_fsb, (xfs_fileoff_t) | 283 | last_fsb = MIN(last_fsb, (xfs_fileoff_t) |
290 | ret_imap->br_blockcount + | 284 | imap->br_blockcount + |
291 | ret_imap->br_startoff); | 285 | imap->br_startoff); |
292 | } | 286 | } |
293 | count_fsb = last_fsb - offset_fsb; | 287 | count_fsb = last_fsb - offset_fsb; |
294 | ASSERT(count_fsb > 0); | 288 | ASSERT(count_fsb > 0); |
@@ -334,20 +328,22 @@ xfs_iomap_write_direct( | |||
334 | if (error) | 328 | if (error) |
335 | goto error1; | 329 | goto error1; |
336 | 330 | ||
337 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 331 | xfs_trans_ijoin(tp, ip); |
338 | xfs_trans_ihold(tp, ip); | ||
339 | 332 | ||
340 | bmapi_flag = XFS_BMAPI_WRITE; | 333 | bmapi_flag = XFS_BMAPI_WRITE; |
341 | if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz)) | 334 | if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz)) |
342 | bmapi_flag |= XFS_BMAPI_PREALLOC; | 335 | bmapi_flag |= XFS_BMAPI_PREALLOC; |
343 | 336 | ||
344 | /* | 337 | /* |
345 | * Issue the xfs_bmapi() call to allocate the blocks | 338 | * Issue the xfs_bmapi() call to allocate the blocks. |
339 | * | ||
340 | * From this point onwards we overwrite the imap pointer that the | ||
341 | * caller gave to us. | ||
346 | */ | 342 | */ |
347 | xfs_bmap_init(&free_list, &firstfsb); | 343 | xfs_bmap_init(&free_list, &firstfsb); |
348 | nimaps = 1; | 344 | nimaps = 1; |
349 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag, | 345 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag, |
350 | &firstfsb, 0, &imap, &nimaps, &free_list, NULL); | 346 | &firstfsb, 0, imap, &nimaps, &free_list); |
351 | if (error) | 347 | if (error) |
352 | goto error0; | 348 | goto error0; |
353 | 349 | ||
@@ -369,12 +365,11 @@ xfs_iomap_write_direct( | |||
369 | goto error_out; | 365 | goto error_out; |
370 | } | 366 | } |
371 | 367 | ||
372 | if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) { | 368 | if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip))) { |
373 | error = xfs_cmn_err_fsblock_zero(ip, &imap); | 369 | error = xfs_cmn_err_fsblock_zero(ip, imap); |
374 | goto error_out; | 370 | goto error_out; |
375 | } | 371 | } |
376 | 372 | ||
377 | *ret_imap = imap; | ||
378 | *nmaps = 1; | 373 | *nmaps = 1; |
379 | return 0; | 374 | return 0; |
380 | 375 | ||
@@ -425,7 +420,7 @@ xfs_iomap_eof_want_preallocate( | |||
425 | imaps = nimaps; | 420 | imaps = nimaps; |
426 | firstblock = NULLFSBLOCK; | 421 | firstblock = NULLFSBLOCK; |
427 | error = xfs_bmapi(NULL, ip, start_fsb, count_fsb, 0, | 422 | error = xfs_bmapi(NULL, ip, start_fsb, count_fsb, 0, |
428 | &firstblock, 0, imap, &imaps, NULL, NULL); | 423 | &firstblock, 0, imap, &imaps, NULL); |
429 | if (error) | 424 | if (error) |
430 | return error; | 425 | return error; |
431 | for (n = 0; n < imaps; n++) { | 426 | for (n = 0; n < imaps; n++) { |
@@ -500,7 +495,7 @@ retry: | |||
500 | (xfs_filblks_t)(last_fsb - offset_fsb), | 495 | (xfs_filblks_t)(last_fsb - offset_fsb), |
501 | XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | | 496 | XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | |
502 | XFS_BMAPI_ENTIRE, &firstblock, 1, imap, | 497 | XFS_BMAPI_ENTIRE, &firstblock, 1, imap, |
503 | &nimaps, NULL, NULL); | 498 | &nimaps, NULL); |
504 | if (error && (error != ENOSPC)) | 499 | if (error && (error != ENOSPC)) |
505 | return XFS_ERROR(error); | 500 | return XFS_ERROR(error); |
506 | 501 | ||
@@ -548,7 +543,7 @@ xfs_iomap_write_allocate( | |||
548 | xfs_inode_t *ip, | 543 | xfs_inode_t *ip, |
549 | xfs_off_t offset, | 544 | xfs_off_t offset, |
550 | size_t count, | 545 | size_t count, |
551 | xfs_bmbt_irec_t *map, | 546 | xfs_bmbt_irec_t *imap, |
552 | int *retmap) | 547 | int *retmap) |
553 | { | 548 | { |
554 | xfs_mount_t *mp = ip->i_mount; | 549 | xfs_mount_t *mp = ip->i_mount; |
@@ -557,7 +552,6 @@ xfs_iomap_write_allocate( | |||
557 | xfs_fsblock_t first_block; | 552 | xfs_fsblock_t first_block; |
558 | xfs_bmap_free_t free_list; | 553 | xfs_bmap_free_t free_list; |
559 | xfs_filblks_t count_fsb; | 554 | xfs_filblks_t count_fsb; |
560 | xfs_bmbt_irec_t imap; | ||
561 | xfs_trans_t *tp; | 555 | xfs_trans_t *tp; |
562 | int nimaps, committed; | 556 | int nimaps, committed; |
563 | int error = 0; | 557 | int error = 0; |
@@ -573,8 +567,8 @@ xfs_iomap_write_allocate( | |||
573 | return XFS_ERROR(error); | 567 | return XFS_ERROR(error); |
574 | 568 | ||
575 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 569 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
576 | count_fsb = map->br_blockcount; | 570 | count_fsb = imap->br_blockcount; |
577 | map_start_fsb = map->br_startoff; | 571 | map_start_fsb = imap->br_startoff; |
578 | 572 | ||
579 | XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); | 573 | XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); |
580 | 574 | ||
@@ -602,8 +596,7 @@ xfs_iomap_write_allocate( | |||
602 | return XFS_ERROR(error); | 596 | return XFS_ERROR(error); |
603 | } | 597 | } |
604 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 598 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
605 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 599 | xfs_trans_ijoin(tp, ip); |
606 | xfs_trans_ihold(tp, ip); | ||
607 | 600 | ||
608 | xfs_bmap_init(&free_list, &first_block); | 601 | xfs_bmap_init(&free_list, &first_block); |
609 | 602 | ||
@@ -654,10 +647,15 @@ xfs_iomap_write_allocate( | |||
654 | } | 647 | } |
655 | } | 648 | } |
656 | 649 | ||
657 | /* Go get the actual blocks */ | 650 | /* |
651 | * Go get the actual blocks. | ||
652 | * | ||
653 | * From this point onwards we overwrite the imap | ||
654 | * pointer that the caller gave to us. | ||
655 | */ | ||
658 | error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, | 656 | error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, |
659 | XFS_BMAPI_WRITE, &first_block, 1, | 657 | XFS_BMAPI_WRITE, &first_block, 1, |
660 | &imap, &nimaps, &free_list, NULL); | 658 | imap, &nimaps, &free_list); |
661 | if (error) | 659 | if (error) |
662 | goto trans_cancel; | 660 | goto trans_cancel; |
663 | 661 | ||
@@ -676,13 +674,12 @@ xfs_iomap_write_allocate( | |||
676 | * See if we were able to allocate an extent that | 674 | * See if we were able to allocate an extent that |
677 | * covers at least part of the callers request | 675 | * covers at least part of the callers request |
678 | */ | 676 | */ |
679 | if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) | 677 | if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip))) |
680 | return xfs_cmn_err_fsblock_zero(ip, &imap); | 678 | return xfs_cmn_err_fsblock_zero(ip, imap); |
681 | 679 | ||
682 | if ((offset_fsb >= imap.br_startoff) && | 680 | if ((offset_fsb >= imap->br_startoff) && |
683 | (offset_fsb < (imap.br_startoff + | 681 | (offset_fsb < (imap->br_startoff + |
684 | imap.br_blockcount))) { | 682 | imap->br_blockcount))) { |
685 | *map = imap; | ||
686 | *retmap = 1; | 683 | *retmap = 1; |
687 | XFS_STATS_INC(xs_xstrat_quick); | 684 | XFS_STATS_INC(xs_xstrat_quick); |
688 | return 0; | 685 | return 0; |
@@ -692,8 +689,8 @@ xfs_iomap_write_allocate( | |||
692 | * So far we have not mapped the requested part of the | 689 | * So far we have not mapped the requested part of the |
693 | * file, just surrounding data, try again. | 690 | * file, just surrounding data, try again. |
694 | */ | 691 | */ |
695 | count_fsb -= imap.br_blockcount; | 692 | count_fsb -= imap->br_blockcount; |
696 | map_start_fsb = imap.br_startoff + imap.br_blockcount; | 693 | map_start_fsb = imap->br_startoff + imap->br_blockcount; |
697 | } | 694 | } |
698 | 695 | ||
699 | trans_cancel: | 696 | trans_cancel: |
@@ -766,8 +763,7 @@ xfs_iomap_write_unwritten( | |||
766 | } | 763 | } |
767 | 764 | ||
768 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 765 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
769 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 766 | xfs_trans_ijoin(tp, ip); |
770 | xfs_trans_ihold(tp, ip); | ||
771 | 767 | ||
772 | /* | 768 | /* |
773 | * Modify the unwritten extent state of the buffer. | 769 | * Modify the unwritten extent state of the buffer. |
@@ -776,7 +772,7 @@ xfs_iomap_write_unwritten( | |||
776 | nimaps = 1; | 772 | nimaps = 1; |
777 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, | 773 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, |
778 | XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, | 774 | XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, |
779 | 1, &imap, &nimaps, &free_list, NULL); | 775 | 1, &imap, &nimaps, &free_list); |
780 | if (error) | 776 | if (error) |
781 | goto error_on_bmapi_transaction; | 777 | goto error_on_bmapi_transaction; |
782 | 778 | ||