aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-12-18 15:00:07 -0500
committerBen Myers <bpm@sgi.com>2012-01-17 16:02:28 -0500
commit8096b1ebb59b94b3bc6abb6b7d121419e83447ba (patch)
tree3d01d19459cbb973dc8698b7fa44e1bee260303d /fs/xfs/xfs_bmap.c
parent3d2b3129c2c48cf0153e0f2058cf87e4b45ca3ac (diff)
xfs: remove the if_ext_max field in struct xfs_ifork
We spent a lot of effort to maintain this field, but it always equals to the fork size divided by the constant size of an extent. The prime use of it is to assert that the two stay in sync. Just divide the fork size by the extent size in the few places that we actually use it and remove the overhead of maintaining it. Also introduce a few helpers to consolidate the places where we actually care about the value. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c101
1 files changed, 47 insertions, 54 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index d0ab78837057..7a888ca2f7f6 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -249,7 +249,27 @@ xfs_bmbt_lookup_ge(
249} 249}
250 250
251/* 251/*
252* Update the record referred to by cur to the value given 252 * Check if the inode needs to be converted to btree format.
253 */
254static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
255{
256 return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
257 XFS_IFORK_NEXTENTS(ip, whichfork) >
258 XFS_IFORK_MAXEXT(ip, whichfork);
259}
260
261/*
262 * Check if the inode should be converted to extent format.
263 */
264static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork)
265{
266 return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
267 XFS_IFORK_NEXTENTS(ip, whichfork) <=
268 XFS_IFORK_MAXEXT(ip, whichfork);
269}
270
271/*
272 * Update the record referred to by cur to the value given
253 * by [off, bno, len, state]. 273 * by [off, bno, len, state].
254 * This either works (return 0) or gets an EFSCORRUPTED error. 274 * This either works (return 0) or gets an EFSCORRUPTED error.
255 */ 275 */
@@ -683,8 +703,8 @@ xfs_bmap_add_extent_delay_real(
683 goto done; 703 goto done;
684 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 704 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
685 } 705 }
686 if (bma->ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 706
687 bma->ip->i_d.di_nextents > bma->ip->i_df.if_ext_max) { 707 if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) {
688 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, 708 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
689 bma->firstblock, bma->flist, 709 bma->firstblock, bma->flist,
690 &bma->cur, 1, &tmp_rval, XFS_DATA_FORK); 710 &bma->cur, 1, &tmp_rval, XFS_DATA_FORK);
@@ -767,8 +787,8 @@ xfs_bmap_add_extent_delay_real(
767 goto done; 787 goto done;
768 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 788 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
769 } 789 }
770 if (bma->ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 790
771 bma->ip->i_d.di_nextents > bma->ip->i_df.if_ext_max) { 791 if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) {
772 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, 792 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
773 bma->firstblock, bma->flist, &bma->cur, 1, 793 bma->firstblock, bma->flist, &bma->cur, 1,
774 &tmp_rval, XFS_DATA_FORK); 794 &tmp_rval, XFS_DATA_FORK);
@@ -836,8 +856,8 @@ xfs_bmap_add_extent_delay_real(
836 goto done; 856 goto done;
837 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 857 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
838 } 858 }
839 if (bma->ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 859
840 bma->ip->i_d.di_nextents > bma->ip->i_df.if_ext_max) { 860 if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) {
841 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, 861 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
842 bma->firstblock, bma->flist, &bma->cur, 862 bma->firstblock, bma->flist, &bma->cur,
843 1, &tmp_rval, XFS_DATA_FORK); 863 1, &tmp_rval, XFS_DATA_FORK);
@@ -884,8 +904,7 @@ xfs_bmap_add_extent_delay_real(
884 } 904 }
885 905
886 /* convert to a btree if necessary */ 906 /* convert to a btree if necessary */
887 if (XFS_IFORK_FORMAT(bma->ip, XFS_DATA_FORK) == XFS_DINODE_FMT_EXTENTS && 907 if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) {
888 XFS_IFORK_NEXTENTS(bma->ip, XFS_DATA_FORK) > ifp->if_ext_max) {
889 int tmp_logflags; /* partial log flag return val */ 908 int tmp_logflags; /* partial log flag return val */
890 909
891 ASSERT(bma->cur == NULL); 910 ASSERT(bma->cur == NULL);
@@ -1421,8 +1440,7 @@ xfs_bmap_add_extent_unwritten_real(
1421 } 1440 }
1422 1441
1423 /* convert to a btree if necessary */ 1442 /* convert to a btree if necessary */
1424 if (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) == XFS_DINODE_FMT_EXTENTS && 1443 if (xfs_bmap_needs_btree(ip, XFS_DATA_FORK)) {
1425 XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > ifp->if_ext_max) {
1426 int tmp_logflags; /* partial log flag return val */ 1444 int tmp_logflags; /* partial log flag return val */
1427 1445
1428 ASSERT(cur == NULL); 1446 ASSERT(cur == NULL);
@@ -1812,8 +1830,7 @@ xfs_bmap_add_extent_hole_real(
1812 } 1830 }
1813 1831
1814 /* convert to a btree if necessary */ 1832 /* convert to a btree if necessary */
1815 if (XFS_IFORK_FORMAT(bma->ip, whichfork) == XFS_DINODE_FMT_EXTENTS && 1833 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
1816 XFS_IFORK_NEXTENTS(bma->ip, whichfork) > ifp->if_ext_max) {
1817 int tmp_logflags; /* partial log flag return val */ 1834 int tmp_logflags; /* partial log flag return val */
1818 1835
1819 ASSERT(bma->cur == NULL); 1836 ASSERT(bma->cur == NULL);
@@ -3037,8 +3054,7 @@ xfs_bmap_extents_to_btree(
3037 3054
3038 ifp = XFS_IFORK_PTR(ip, whichfork); 3055 ifp = XFS_IFORK_PTR(ip, whichfork);
3039 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); 3056 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
3040 ASSERT(ifp->if_ext_max == 3057
3041 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
3042 /* 3058 /*
3043 * Make space in the inode incore. 3059 * Make space in the inode incore.
3044 */ 3060 */
@@ -3184,13 +3200,8 @@ xfs_bmap_forkoff_reset(
3184 ip->i_d.di_format != XFS_DINODE_FMT_BTREE) { 3200 ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
3185 uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; 3201 uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
3186 3202
3187 if (dfl_forkoff > ip->i_d.di_forkoff) { 3203 if (dfl_forkoff > ip->i_d.di_forkoff)
3188 ip->i_d.di_forkoff = dfl_forkoff; 3204 ip->i_d.di_forkoff = dfl_forkoff;
3189 ip->i_df.if_ext_max =
3190 XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
3191 ip->i_afp->if_ext_max =
3192 XFS_IFORK_ASIZE(ip) / sizeof(xfs_bmbt_rec_t);
3193 }
3194 } 3205 }
3195} 3206}
3196 3207
@@ -3430,8 +3441,6 @@ xfs_bmap_add_attrfork(
3430 int error; /* error return value */ 3441 int error; /* error return value */
3431 3442
3432 ASSERT(XFS_IFORK_Q(ip) == 0); 3443 ASSERT(XFS_IFORK_Q(ip) == 0);
3433 ASSERT(ip->i_df.if_ext_max ==
3434 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
3435 3444
3436 mp = ip->i_mount; 3445 mp = ip->i_mount;
3437 ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); 3446 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
@@ -3486,12 +3495,9 @@ xfs_bmap_add_attrfork(
3486 error = XFS_ERROR(EINVAL); 3495 error = XFS_ERROR(EINVAL);
3487 goto error1; 3496 goto error1;
3488 } 3497 }
3489 ip->i_df.if_ext_max = 3498
3490 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
3491 ASSERT(ip->i_afp == NULL); 3499 ASSERT(ip->i_afp == NULL);
3492 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); 3500 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
3493 ip->i_afp->if_ext_max =
3494 XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
3495 ip->i_afp->if_flags = XFS_IFEXTENTS; 3501 ip->i_afp->if_flags = XFS_IFEXTENTS;
3496 logflags = 0; 3502 logflags = 0;
3497 xfs_bmap_init(&flist, &firstblock); 3503 xfs_bmap_init(&flist, &firstblock);
@@ -3535,20 +3541,17 @@ xfs_bmap_add_attrfork(
3535 } else 3541 } else
3536 spin_unlock(&mp->m_sb_lock); 3542 spin_unlock(&mp->m_sb_lock);
3537 } 3543 }
3538 if ((error = xfs_bmap_finish(&tp, &flist, &committed))) 3544
3545 error = xfs_bmap_finish(&tp, &flist, &committed);
3546 if (error)
3539 goto error2; 3547 goto error2;
3540 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); 3548 return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
3541 ASSERT(ip->i_df.if_ext_max ==
3542 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
3543 return error;
3544error2: 3549error2:
3545 xfs_bmap_cancel(&flist); 3550 xfs_bmap_cancel(&flist);
3546error1: 3551error1:
3547 xfs_iunlock(ip, XFS_ILOCK_EXCL); 3552 xfs_iunlock(ip, XFS_ILOCK_EXCL);
3548error0: 3553error0:
3549 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 3554 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
3550 ASSERT(ip->i_df.if_ext_max ==
3551 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
3552 return error; 3555 return error;
3553} 3556}
3554 3557
@@ -4379,8 +4382,6 @@ xfs_bmapi_read(
4379 XFS_STATS_INC(xs_blk_mapr); 4382 XFS_STATS_INC(xs_blk_mapr);
4380 4383
4381 ifp = XFS_IFORK_PTR(ip, whichfork); 4384 ifp = XFS_IFORK_PTR(ip, whichfork);
4382 ASSERT(ifp->if_ext_max ==
4383 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
4384 4385
4385 if (!(ifp->if_flags & XFS_IFEXTENTS)) { 4386 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
4386 error = xfs_iread_extents(NULL, ip, whichfork); 4387 error = xfs_iread_extents(NULL, ip, whichfork);
@@ -4871,8 +4872,6 @@ xfs_bmapi_write(
4871 return XFS_ERROR(EIO); 4872 return XFS_ERROR(EIO);
4872 4873
4873 ifp = XFS_IFORK_PTR(ip, whichfork); 4874 ifp = XFS_IFORK_PTR(ip, whichfork);
4874 ASSERT(ifp->if_ext_max ==
4875 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
4876 4875
4877 XFS_STATS_INC(xs_blk_mapw); 4876 XFS_STATS_INC(xs_blk_mapw);
4878 4877
@@ -4981,8 +4980,7 @@ xfs_bmapi_write(
4981 /* 4980 /*
4982 * Transform from btree to extents, give it cur. 4981 * Transform from btree to extents, give it cur.
4983 */ 4982 */
4984 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && 4983 if (xfs_bmap_wants_extents(ip, whichfork)) {
4985 XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
4986 int tmp_logflags = 0; 4984 int tmp_logflags = 0;
4987 4985
4988 ASSERT(bma.cur); 4986 ASSERT(bma.cur);
@@ -4992,10 +4990,10 @@ xfs_bmapi_write(
4992 if (error) 4990 if (error)
4993 goto error0; 4991 goto error0;
4994 } 4992 }
4995 ASSERT(ifp->if_ext_max == 4993
4996 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
4997 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || 4994 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
4998 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); 4995 XFS_IFORK_NEXTENTS(ip, whichfork) >
4996 XFS_IFORK_MAXEXT(ip, whichfork));
4999 error = 0; 4997 error = 0;
5000error0: 4998error0:
5001 /* 4999 /*
@@ -5095,8 +5093,7 @@ xfs_bunmapi(
5095 5093
5096 ASSERT(len > 0); 5094 ASSERT(len > 0);
5097 ASSERT(nexts >= 0); 5095 ASSERT(nexts >= 0);
5098 ASSERT(ifp->if_ext_max == 5096
5099 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
5100 if (!(ifp->if_flags & XFS_IFEXTENTS) && 5097 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
5101 (error = xfs_iread_extents(tp, ip, whichfork))) 5098 (error = xfs_iread_extents(tp, ip, whichfork)))
5102 return error; 5099 return error;
@@ -5322,7 +5319,8 @@ xfs_bunmapi(
5322 */ 5319 */
5323 if (!wasdel && xfs_trans_get_block_res(tp) == 0 && 5320 if (!wasdel && xfs_trans_get_block_res(tp) == 0 &&
5324 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && 5321 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
5325 XFS_IFORK_NEXTENTS(ip, whichfork) >= ifp->if_ext_max && 5322 XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */
5323 XFS_IFORK_MAXEXT(ip, whichfork) &&
5326 del.br_startoff > got.br_startoff && 5324 del.br_startoff > got.br_startoff &&
5327 del.br_startoff + del.br_blockcount < 5325 del.br_startoff + del.br_blockcount <
5328 got.br_startoff + got.br_blockcount) { 5326 got.br_startoff + got.br_blockcount) {
@@ -5353,13 +5351,11 @@ nodelete:
5353 } 5351 }
5354 } 5352 }
5355 *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; 5353 *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0;
5356 ASSERT(ifp->if_ext_max == 5354
5357 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
5358 /* 5355 /*
5359 * Convert to a btree if necessary. 5356 * Convert to a btree if necessary.
5360 */ 5357 */
5361 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && 5358 if (xfs_bmap_needs_btree(ip, whichfork)) {
5362 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) {
5363 ASSERT(cur == NULL); 5359 ASSERT(cur == NULL);
5364 error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, 5360 error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist,
5365 &cur, 0, &tmp_logflags, whichfork); 5361 &cur, 0, &tmp_logflags, whichfork);
@@ -5370,8 +5366,7 @@ nodelete:
5370 /* 5366 /*
5371 * transform from btree to extents, give it cur 5367 * transform from btree to extents, give it cur
5372 */ 5368 */
5373 else if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && 5369 else if (xfs_bmap_wants_extents(ip, whichfork)) {
5374 XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
5375 ASSERT(cur != NULL); 5370 ASSERT(cur != NULL);
5376 error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags, 5371 error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags,
5377 whichfork); 5372 whichfork);
@@ -5382,8 +5377,6 @@ nodelete:
5382 /* 5377 /*
5383 * transform from extents to local? 5378 * transform from extents to local?
5384 */ 5379 */
5385 ASSERT(ifp->if_ext_max ==
5386 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
5387 error = 0; 5380 error = 0;
5388error0: 5381error0:
5389 /* 5382 /*