aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c85
1 files changed, 60 insertions, 25 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 4111cd3966c7..fa00788de2f5 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1038,17 +1038,34 @@ xfs_bmap_add_extent_delay_real(
1038 * Filling in the middle part of a previous delayed allocation. 1038 * Filling in the middle part of a previous delayed allocation.
1039 * Contiguity is impossible here. 1039 * Contiguity is impossible here.
1040 * This case is avoided almost all the time. 1040 * This case is avoided almost all the time.
1041 *
1042 * We start with a delayed allocation:
1043 *
1044 * +ddddddddddddddddddddddddddddddddddddddddddddddddddddddd+
1045 * PREV @ idx
1046 *
1047 * and we are allocating:
1048 * +rrrrrrrrrrrrrrrrr+
1049 * new
1050 *
1051 * and we set it up for insertion as:
1052 * +ddddddddddddddddddd+rrrrrrrrrrrrrrrrr+ddddddddddddddddd+
1053 * new
1054 * PREV @ idx LEFT RIGHT
1055 * inserted at idx + 1
1041 */ 1056 */
1042 temp = new->br_startoff - PREV.br_startoff; 1057 temp = new->br_startoff - PREV.br_startoff;
1043 trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_);
1044 xfs_bmbt_set_blockcount(ep, temp);
1045 r[0] = *new;
1046 r[1].br_state = PREV.br_state;
1047 r[1].br_startblock = 0;
1048 r[1].br_startoff = new_endoff;
1049 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; 1058 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
1050 r[1].br_blockcount = temp2; 1059 trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_);
1051 xfs_iext_insert(ip, idx + 1, 2, &r[0], state); 1060 xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */
1061 LEFT = *new;
1062 RIGHT.br_state = PREV.br_state;
1063 RIGHT.br_startblock = nullstartblock(
1064 (int)xfs_bmap_worst_indlen(ip, temp2));
1065 RIGHT.br_startoff = new_endoff;
1066 RIGHT.br_blockcount = temp2;
1067 /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */
1068 xfs_iext_insert(ip, idx + 1, 2, &LEFT, state);
1052 ip->i_df.if_lastex = idx + 1; 1069 ip->i_df.if_lastex = idx + 1;
1053 ip->i_d.di_nextents++; 1070 ip->i_d.di_nextents++;
1054 if (cur == NULL) 1071 if (cur == NULL)
@@ -2348,6 +2365,13 @@ xfs_bmap_rtalloc(
2348 */ 2365 */
2349 if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN) 2366 if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN)
2350 ralen = MAXEXTLEN / mp->m_sb.sb_rextsize; 2367 ralen = MAXEXTLEN / mp->m_sb.sb_rextsize;
2368
2369 /*
2370 * Lock out other modifications to the RT bitmap inode.
2371 */
2372 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
2373 xfs_trans_ijoin_ref(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
2374
2351 /* 2375 /*
2352 * If it's an allocation to an empty file at offset 0, 2376 * If it's an allocation to an empty file at offset 0,
2353 * pick an extent that will space things out in the rt area. 2377 * pick an extent that will space things out in the rt area.
@@ -2430,7 +2454,7 @@ xfs_bmap_btalloc_nullfb(
2430 startag = ag = 0; 2454 startag = ag = 0;
2431 2455
2432 pag = xfs_perag_get(mp, ag); 2456 pag = xfs_perag_get(mp, ag);
2433 while (*blen < ap->alen) { 2457 while (*blen < args->maxlen) {
2434 if (!pag->pagf_init) { 2458 if (!pag->pagf_init) {
2435 error = xfs_alloc_pagf_init(mp, args->tp, ag, 2459 error = xfs_alloc_pagf_init(mp, args->tp, ag,
2436 XFS_ALLOC_FLAG_TRYLOCK); 2460 XFS_ALLOC_FLAG_TRYLOCK);
@@ -2452,7 +2476,7 @@ xfs_bmap_btalloc_nullfb(
2452 notinit = 1; 2476 notinit = 1;
2453 2477
2454 if (xfs_inode_is_filestream(ap->ip)) { 2478 if (xfs_inode_is_filestream(ap->ip)) {
2455 if (*blen >= ap->alen) 2479 if (*blen >= args->maxlen)
2456 break; 2480 break;
2457 2481
2458 if (ap->userdata) { 2482 if (ap->userdata) {
@@ -2498,14 +2522,14 @@ xfs_bmap_btalloc_nullfb(
2498 * If the best seen length is less than the request 2522 * If the best seen length is less than the request
2499 * length, use the best as the minimum. 2523 * length, use the best as the minimum.
2500 */ 2524 */
2501 else if (*blen < ap->alen) 2525 else if (*blen < args->maxlen)
2502 args->minlen = *blen; 2526 args->minlen = *blen;
2503 /* 2527 /*
2504 * Otherwise we've seen an extent as big as alen, 2528 * Otherwise we've seen an extent as big as maxlen,
2505 * use that as the minimum. 2529 * use that as the minimum.
2506 */ 2530 */
2507 else 2531 else
2508 args->minlen = ap->alen; 2532 args->minlen = args->maxlen;
2509 2533
2510 /* 2534 /*
2511 * set the failure fallback case to look in the selected 2535 * set the failure fallback case to look in the selected
@@ -2573,7 +2597,9 @@ xfs_bmap_btalloc(
2573 args.tp = ap->tp; 2597 args.tp = ap->tp;
2574 args.mp = mp; 2598 args.mp = mp;
2575 args.fsbno = ap->rval; 2599 args.fsbno = ap->rval;
2576 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); 2600
2601 /* Trim the allocation back to the maximum an AG can fit. */
2602 args.maxlen = MIN(ap->alen, XFS_ALLOC_AG_MAX_USABLE(mp));
2577 args.firstblock = ap->firstblock; 2603 args.firstblock = ap->firstblock;
2578 blen = 0; 2604 blen = 0;
2579 if (nullfb) { 2605 if (nullfb) {
@@ -2621,7 +2647,7 @@ xfs_bmap_btalloc(
2621 /* 2647 /*
2622 * Adjust for alignment 2648 * Adjust for alignment
2623 */ 2649 */
2624 if (blen > args.alignment && blen <= ap->alen) 2650 if (blen > args.alignment && blen <= args.maxlen)
2625 args.minlen = blen - args.alignment; 2651 args.minlen = blen - args.alignment;
2626 args.minalignslop = 0; 2652 args.minalignslop = 0;
2627 } else { 2653 } else {
@@ -2640,7 +2666,7 @@ xfs_bmap_btalloc(
2640 * of minlen+alignment+slop doesn't go up 2666 * of minlen+alignment+slop doesn't go up
2641 * between the calls. 2667 * between the calls.
2642 */ 2668 */
2643 if (blen > mp->m_dalign && blen <= ap->alen) 2669 if (blen > mp->m_dalign && blen <= args.maxlen)
2644 nextminlen = blen - mp->m_dalign; 2670 nextminlen = blen - mp->m_dalign;
2645 else 2671 else
2646 nextminlen = args.minlen; 2672 nextminlen = args.minlen;
@@ -3500,7 +3526,7 @@ xfs_bmap_search_extents(
3500 3526
3501 if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && 3527 if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
3502 !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { 3528 !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
3503 xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, 3529 xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO,
3504 "Access to block zero in inode %llu " 3530 "Access to block zero in inode %llu "
3505 "start_block: %llx start_off: %llx " 3531 "start_block: %llx start_off: %llx "
3506 "blkcnt: %llx extent-state: %x lastx: %x\n", 3532 "blkcnt: %llx extent-state: %x lastx: %x\n",
@@ -4174,12 +4200,11 @@ xfs_bmap_read_extents(
4174 num_recs = xfs_btree_get_numrecs(block); 4200 num_recs = xfs_btree_get_numrecs(block);
4175 if (unlikely(i + num_recs > room)) { 4201 if (unlikely(i + num_recs > room)) {
4176 ASSERT(i + num_recs <= room); 4202 ASSERT(i + num_recs <= room);
4177 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, 4203 xfs_warn(ip->i_mount,
4178 "corrupt dinode %Lu, (btree extents).", 4204 "corrupt dinode %Lu, (btree extents).",
4179 (unsigned long long) ip->i_ino); 4205 (unsigned long long) ip->i_ino);
4180 XFS_ERROR_REPORT("xfs_bmap_read_extents(1)", 4206 XFS_CORRUPTION_ERROR("xfs_bmap_read_extents(1)",
4181 XFS_ERRLEVEL_LOW, 4207 XFS_ERRLEVEL_LOW, ip->i_mount, block);
4182 ip->i_mount);
4183 goto error0; 4208 goto error0;
4184 } 4209 }
4185 XFS_WANT_CORRUPTED_GOTO( 4210 XFS_WANT_CORRUPTED_GOTO(
@@ -4485,6 +4510,16 @@ xfs_bmapi(
4485 /* Figure out the extent size, adjust alen */ 4510 /* Figure out the extent size, adjust alen */
4486 extsz = xfs_get_extsz_hint(ip); 4511 extsz = xfs_get_extsz_hint(ip);
4487 if (extsz) { 4512 if (extsz) {
4513 /*
4514 * make sure we don't exceed a single
4515 * extent length when we align the
4516 * extent by reducing length we are
4517 * going to allocate by the maximum
4518 * amount extent size aligment may
4519 * require.
4520 */
4521 alen = XFS_FILBLKS_MIN(len,
4522 MAXEXTLEN - (2 * extsz - 1));
4488 error = xfs_bmap_extsize_align(mp, 4523 error = xfs_bmap_extsize_align(mp,
4489 &got, &prev, extsz, 4524 &got, &prev, extsz,
4490 rt, eof, 4525 rt, eof,
@@ -5743,7 +5778,7 @@ xfs_check_block(
5743 else 5778 else
5744 thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr); 5779 thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr);
5745 if (*thispa == *pp) { 5780 if (*thispa == *pp) {
5746 cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld", 5781 xfs_warn(mp, "%s: thispa(%d) == pp(%d) %Ld",
5747 __func__, j, i, 5782 __func__, j, i,
5748 (unsigned long long)be64_to_cpu(*thispa)); 5783 (unsigned long long)be64_to_cpu(*thispa));
5749 panic("%s: ptrs are equal in node\n", 5784 panic("%s: ptrs are equal in node\n",
@@ -5908,11 +5943,11 @@ xfs_bmap_check_leaf_extents(
5908 return; 5943 return;
5909 5944
5910error0: 5945error0:
5911 cmn_err(CE_WARN, "%s: at error0", __func__); 5946 xfs_warn(mp, "%s: at error0", __func__);
5912 if (bp_release) 5947 if (bp_release)
5913 xfs_trans_brelse(NULL, bp); 5948 xfs_trans_brelse(NULL, bp);
5914error_norelse: 5949error_norelse:
5915 cmn_err(CE_WARN, "%s: BAD after btree leaves for %d extents", 5950 xfs_warn(mp, "%s: BAD after btree leaves for %d extents",
5916 __func__, i); 5951 __func__, i);
5917 panic("%s: CORRUPTED BTREE OR SOMETHING", __func__); 5952 panic("%s: CORRUPTED BTREE OR SOMETHING", __func__);
5918 return; 5953 return;
@@ -6115,7 +6150,7 @@ xfs_bmap_punch_delalloc_range(
6115 if (error) { 6150 if (error) {
6116 /* something screwed, just bail */ 6151 /* something screwed, just bail */
6117 if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { 6152 if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
6118 xfs_fs_cmn_err(CE_ALERT, ip->i_mount, 6153 xfs_alert(ip->i_mount,
6119 "Failed delalloc mapping lookup ino %lld fsb %lld.", 6154 "Failed delalloc mapping lookup ino %lld fsb %lld.",
6120 ip->i_ino, start_fsb); 6155 ip->i_ino, start_fsb);
6121 } 6156 }