aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iomap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r--fs/xfs/xfs_iomap.c69
1 files changed, 30 insertions, 39 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 991f8a61f7c4..2edd6769e5d3 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -278,7 +278,9 @@ phase2:
278 switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) { 278 switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) {
279 case BMAPI_WRITE: 279 case BMAPI_WRITE:
280 /* If we found an extent, return it */ 280 /* If we found an extent, return it */
281 if (nimaps && (imap.br_startblock != HOLESTARTBLOCK)) { 281 if (nimaps &&
282 (imap.br_startblock != HOLESTARTBLOCK) &&
283 (imap.br_startblock != DELAYSTARTBLOCK)) {
282 xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io, 284 xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,
283 offset, count, iomapp, &imap, flags); 285 offset, count, iomapp, &imap, flags);
284 break; 286 break;
@@ -383,15 +385,15 @@ xfs_iomap_write_direct(
383 int nimaps, maps; 385 int nimaps, maps;
384 int error; 386 int error;
385 int bmapi_flag; 387 int bmapi_flag;
388 int quota_flag;
386 int rt; 389 int rt;
387 xfs_trans_t *tp; 390 xfs_trans_t *tp;
388 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp; 391 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp;
389 xfs_bmap_free_t free_list; 392 xfs_bmap_free_t free_list;
390 int aeof; 393 int aeof;
391 xfs_filblks_t datablocks; 394 xfs_filblks_t datablocks, qblocks, resblks;
392 int committed; 395 int committed;
393 int numrtextents; 396 int numrtextents;
394 uint resblks;
395 397
396 /* 398 /*
397 * Make sure that the dquots are there. This doesn't hold 399 * Make sure that the dquots are there. This doesn't hold
@@ -417,7 +419,6 @@ xfs_iomap_write_direct(
417 xfs_fileoff_t map_last_fsb; 419 xfs_fileoff_t map_last_fsb;
418 420
419 map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff; 421 map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff;
420
421 if (map_last_fsb < last_fsb) { 422 if (map_last_fsb < last_fsb) {
422 last_fsb = map_last_fsb; 423 last_fsb = map_last_fsb;
423 count_fsb = last_fsb - offset_fsb; 424 count_fsb = last_fsb - offset_fsb;
@@ -426,56 +427,47 @@ xfs_iomap_write_direct(
426 } 427 }
427 428
428 /* 429 /*
429 * determine if reserving space on 430 * Determine if reserving space on the data or realtime partition.
430 * the data or realtime partition.
431 */ 431 */
432 if ((rt = XFS_IS_REALTIME_INODE(ip))) { 432 if ((rt = XFS_IS_REALTIME_INODE(ip))) {
433 int sbrtextsize, iprtextsize; 433 xfs_extlen_t extsz;
434 434
435 sbrtextsize = mp->m_sb.sb_rextsize; 435 if (!(extsz = ip->i_d.di_extsize))
436 iprtextsize = 436 extsz = mp->m_sb.sb_rextsize;
437 ip->i_d.di_extsize ? ip->i_d.di_extsize : sbrtextsize; 437 numrtextents = qblocks = (count_fsb + extsz - 1);
438 numrtextents = (count_fsb + iprtextsize - 1); 438 do_div(numrtextents, mp->m_sb.sb_rextsize);
439 do_div(numrtextents, sbrtextsize); 439 quota_flag = XFS_QMOPT_RES_RTBLKS;
440 datablocks = 0; 440 datablocks = 0;
441 } else { 441 } else {
442 datablocks = count_fsb; 442 datablocks = qblocks = count_fsb;
443 quota_flag = XFS_QMOPT_RES_REGBLKS;
443 numrtextents = 0; 444 numrtextents = 0;
444 } 445 }
445 446
446 /* 447 /*
447 * allocate and setup the transaction 448 * Allocate and setup the transaction
448 */ 449 */
449 xfs_iunlock(ip, XFS_ILOCK_EXCL); 450 xfs_iunlock(ip, XFS_ILOCK_EXCL);
450 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); 451 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
451
452 resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks); 452 resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks);
453
454 error = xfs_trans_reserve(tp, resblks, 453 error = xfs_trans_reserve(tp, resblks,
455 XFS_WRITE_LOG_RES(mp), numrtextents, 454 XFS_WRITE_LOG_RES(mp), numrtextents,
456 XFS_TRANS_PERM_LOG_RES, 455 XFS_TRANS_PERM_LOG_RES,
457 XFS_WRITE_LOG_COUNT); 456 XFS_WRITE_LOG_COUNT);
458 457
459 /* 458 /*
460 * check for running out of space 459 * Check for running out of space, note: need lock to return
461 */ 460 */
462 if (error) 461 if (error)
463 /*
464 * Free the transaction structure.
465 */
466 xfs_trans_cancel(tp, 0); 462 xfs_trans_cancel(tp, 0);
467
468 xfs_ilock(ip, XFS_ILOCK_EXCL); 463 xfs_ilock(ip, XFS_ILOCK_EXCL);
469
470 if (error) 464 if (error)
471 goto error_out; /* Don't return in above if .. trans .., 465 goto error_out;
472 need lock to return */
473 466
474 if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) { 467 if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) {
475 error = (EDQUOT); 468 error = (EDQUOT);
476 goto error1; 469 goto error1;
477 } 470 }
478 nimaps = 1;
479 471
480 bmapi_flag = XFS_BMAPI_WRITE; 472 bmapi_flag = XFS_BMAPI_WRITE;
481 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 473 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
@@ -485,31 +477,29 @@ xfs_iomap_write_direct(
485 bmapi_flag |= XFS_BMAPI_PREALLOC; 477 bmapi_flag |= XFS_BMAPI_PREALLOC;
486 478
487 /* 479 /*
488 * issue the bmapi() call to allocate the blocks 480 * Issue the bmapi() call to allocate the blocks
489 */ 481 */
490 XFS_BMAP_INIT(&free_list, &firstfsb); 482 XFS_BMAP_INIT(&free_list, &firstfsb);
483 nimaps = 1;
491 imapp = &imap[0]; 484 imapp = &imap[0];
492 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 485 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
493 bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list); 486 bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list);
494 if (error) { 487 if (error)
495 goto error0; 488 goto error0;
496 }
497 489
498 /* 490 /*
499 * complete the transaction 491 * Complete the transaction
500 */ 492 */
501
502 error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); 493 error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
503 if (error) { 494 if (error)
504 goto error0; 495 goto error0;
505 }
506
507 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 496 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
508 if (error) { 497 if (error)
509 goto error_out; 498 goto error_out;
510 }
511 499
512 /* copy any maps to caller's array and return any error. */ 500 /*
501 * Copy any maps to caller's array and return any error.
502 */
513 if (nimaps == 0) { 503 if (nimaps == 0) {
514 error = (ENOSPC); 504 error = (ENOSPC);
515 goto error_out; 505 goto error_out;
@@ -528,10 +518,11 @@ xfs_iomap_write_direct(
528 } 518 }
529 return 0; 519 return 0;
530 520
531 error0: /* Cancel bmap, unlock inode, and cancel trans */ 521error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
532 xfs_bmap_cancel(&free_list); 522 xfs_bmap_cancel(&free_list);
523 XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag);
533 524
534 error1: /* Just cancel transaction */ 525error1: /* Just cancel transaction */
535 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); 526 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
536 *nmaps = 0; /* nothing set-up here */ 527 *nmaps = 0; /* nothing set-up here */
537 528