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