diff options
author | Dave Chinner <dchinner@redhat.com> | 2011-09-18 16:40:44 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2011-10-11 22:15:03 -0400 |
commit | aef9a89586fc8475bf0333b8736d5aa8aa6f4897 (patch) | |
tree | c9f7a1d4744335f7bc36dd4b06b223af440cc170 /fs/xfs/xfs_bmap.c | |
parent | ecee76ba9d91fdcbdff933ca1bd41465ca4c4fdb (diff) |
xfs: factor extent map manipulations out of xfs_bmapi
To further improve the readability of xfs_bmapi(), factor the pure
extent map manipulations out into separate functions. This removes
large blocks of logic from the xfs_bmapi() code loop and makes it
easier to see the operational logic flow for xfs_bmapi().
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/xfs_bmap.c | 181 |
1 files changed, 107 insertions, 74 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 05d38adbb85e..59f63949d3bc 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -4249,6 +4249,107 @@ xfs_bmap_validate_ret( | |||
4249 | 4249 | ||
4250 | 4250 | ||
4251 | /* | 4251 | /* |
4252 | * Trim the returned map to the required bounds | ||
4253 | */ | ||
4254 | STATIC void | ||
4255 | xfs_bmapi_trim_map( | ||
4256 | struct xfs_bmbt_irec *mval, | ||
4257 | struct xfs_bmbt_irec *got, | ||
4258 | xfs_fileoff_t *bno, | ||
4259 | xfs_filblks_t len, | ||
4260 | xfs_fileoff_t obno, | ||
4261 | xfs_fileoff_t end, | ||
4262 | int n, | ||
4263 | int flags) | ||
4264 | { | ||
4265 | if ((flags & XFS_BMAPI_ENTIRE) || | ||
4266 | got->br_startoff + got->br_blockcount <= obno) { | ||
4267 | *mval = *got; | ||
4268 | if (isnullstartblock(got->br_startblock)) | ||
4269 | mval->br_startblock = DELAYSTARTBLOCK; | ||
4270 | return; | ||
4271 | } | ||
4272 | |||
4273 | if (obno > *bno) | ||
4274 | *bno = obno; | ||
4275 | ASSERT((*bno >= obno) || (n == 0)); | ||
4276 | ASSERT(*bno < end); | ||
4277 | mval->br_startoff = *bno; | ||
4278 | if (isnullstartblock(got->br_startblock)) | ||
4279 | mval->br_startblock = DELAYSTARTBLOCK; | ||
4280 | else | ||
4281 | mval->br_startblock = got->br_startblock + | ||
4282 | (*bno - got->br_startoff); | ||
4283 | /* | ||
4284 | * Return the minimum of what we got and what we asked for for | ||
4285 | * the length. We can use the len variable here because it is | ||
4286 | * modified below and we could have been there before coming | ||
4287 | * here if the first part of the allocation didn't overlap what | ||
4288 | * was asked for. | ||
4289 | */ | ||
4290 | mval->br_blockcount = XFS_FILBLKS_MIN(end - *bno, | ||
4291 | got->br_blockcount - (*bno - got->br_startoff)); | ||
4292 | mval->br_state = got->br_state; | ||
4293 | ASSERT(mval->br_blockcount <= len); | ||
4294 | return; | ||
4295 | } | ||
4296 | |||
4297 | /* | ||
4298 | * Update and validate the extent map to return | ||
4299 | */ | ||
4300 | STATIC void | ||
4301 | xfs_bmapi_update_map( | ||
4302 | struct xfs_bmbt_irec **map, | ||
4303 | xfs_fileoff_t *bno, | ||
4304 | xfs_filblks_t *len, | ||
4305 | xfs_fileoff_t obno, | ||
4306 | xfs_fileoff_t end, | ||
4307 | int *n, | ||
4308 | int flags) | ||
4309 | { | ||
4310 | xfs_bmbt_irec_t *mval = *map; | ||
4311 | |||
4312 | ASSERT((flags & XFS_BMAPI_ENTIRE) || | ||
4313 | ((mval->br_startoff + mval->br_blockcount) <= end)); | ||
4314 | ASSERT((flags & XFS_BMAPI_ENTIRE) || (mval->br_blockcount <= *len) || | ||
4315 | (mval->br_startoff < obno)); | ||
4316 | |||
4317 | *bno = mval->br_startoff + mval->br_blockcount; | ||
4318 | *len = end - *bno; | ||
4319 | if (*n > 0 && mval->br_startoff == mval[-1].br_startoff) { | ||
4320 | /* update previous map with new information */ | ||
4321 | ASSERT(mval->br_startblock == mval[-1].br_startblock); | ||
4322 | ASSERT(mval->br_blockcount > mval[-1].br_blockcount); | ||
4323 | ASSERT(mval->br_state == mval[-1].br_state); | ||
4324 | mval[-1].br_blockcount = mval->br_blockcount; | ||
4325 | mval[-1].br_state = mval->br_state; | ||
4326 | } else if (*n > 0 && mval->br_startblock != DELAYSTARTBLOCK && | ||
4327 | mval[-1].br_startblock != DELAYSTARTBLOCK && | ||
4328 | mval[-1].br_startblock != HOLESTARTBLOCK && | ||
4329 | mval->br_startblock == mval[-1].br_startblock + | ||
4330 | mval[-1].br_blockcount && | ||
4331 | ((flags & XFS_BMAPI_IGSTATE) || | ||
4332 | mval[-1].br_state == mval->br_state)) { | ||
4333 | ASSERT(mval->br_startoff == | ||
4334 | mval[-1].br_startoff + mval[-1].br_blockcount); | ||
4335 | mval[-1].br_blockcount += mval->br_blockcount; | ||
4336 | } else if (*n > 0 && | ||
4337 | mval->br_startblock == DELAYSTARTBLOCK && | ||
4338 | mval[-1].br_startblock == DELAYSTARTBLOCK && | ||
4339 | mval->br_startoff == | ||
4340 | mval[-1].br_startoff + mval[-1].br_blockcount) { | ||
4341 | mval[-1].br_blockcount += mval->br_blockcount; | ||
4342 | mval[-1].br_state = mval->br_state; | ||
4343 | } else if (!((*n == 0) && | ||
4344 | ((mval->br_startoff + mval->br_blockcount) <= | ||
4345 | obno))) { | ||
4346 | mval++; | ||
4347 | (*n)++; | ||
4348 | } | ||
4349 | *map = mval; | ||
4350 | } | ||
4351 | |||
4352 | /* | ||
4252 | * Map file blocks to filesystem blocks. | 4353 | * Map file blocks to filesystem blocks. |
4253 | * File range is given by the bno/len pair. | 4354 | * File range is given by the bno/len pair. |
4254 | * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) | 4355 | * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) |
@@ -4650,44 +4751,9 @@ xfs_bmapi( | |||
4650 | n++; | 4751 | n++; |
4651 | continue; | 4752 | continue; |
4652 | } | 4753 | } |
4653 | /* | 4754 | |
4654 | * Then deal with the allocated space we found. | 4755 | /* Deal with the allocated space we found. */ |
4655 | */ | 4756 | xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); |
4656 | ASSERT(ep != NULL); | ||
4657 | if (!(flags & XFS_BMAPI_ENTIRE) && | ||
4658 | (got.br_startoff + got.br_blockcount > obno)) { | ||
4659 | if (obno > bno) | ||
4660 | bno = obno; | ||
4661 | ASSERT((bno >= obno) || (n == 0)); | ||
4662 | ASSERT(bno < end); | ||
4663 | mval->br_startoff = bno; | ||
4664 | if (isnullstartblock(got.br_startblock)) { | ||
4665 | ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); | ||
4666 | mval->br_startblock = DELAYSTARTBLOCK; | ||
4667 | } else | ||
4668 | mval->br_startblock = | ||
4669 | got.br_startblock + | ||
4670 | (bno - got.br_startoff); | ||
4671 | /* | ||
4672 | * Return the minimum of what we got and what we | ||
4673 | * asked for for the length. We can use the len | ||
4674 | * variable here because it is modified below | ||
4675 | * and we could have been there before coming | ||
4676 | * here if the first part of the allocation | ||
4677 | * didn't overlap what was asked for. | ||
4678 | */ | ||
4679 | mval->br_blockcount = | ||
4680 | XFS_FILBLKS_MIN(end - bno, got.br_blockcount - | ||
4681 | (bno - got.br_startoff)); | ||
4682 | mval->br_state = got.br_state; | ||
4683 | ASSERT(mval->br_blockcount <= len); | ||
4684 | } else { | ||
4685 | *mval = got; | ||
4686 | if (isnullstartblock(mval->br_startblock)) { | ||
4687 | ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); | ||
4688 | mval->br_startblock = DELAYSTARTBLOCK; | ||
4689 | } | ||
4690 | } | ||
4691 | 4757 | ||
4692 | /* | 4758 | /* |
4693 | * Check if writing previously allocated but | 4759 | * Check if writing previously allocated but |
@@ -4730,42 +4796,9 @@ xfs_bmapi( | |||
4730 | continue; | 4796 | continue; |
4731 | } | 4797 | } |
4732 | 4798 | ||
4733 | ASSERT((flags & XFS_BMAPI_ENTIRE) || | 4799 | /* update the extent map to return */ |
4734 | ((mval->br_startoff + mval->br_blockcount) <= end)); | 4800 | xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); |
4735 | ASSERT((flags & XFS_BMAPI_ENTIRE) || | 4801 | |
4736 | (mval->br_blockcount <= len) || | ||
4737 | (mval->br_startoff < obno)); | ||
4738 | bno = mval->br_startoff + mval->br_blockcount; | ||
4739 | len = end - bno; | ||
4740 | if (n > 0 && mval->br_startoff == mval[-1].br_startoff) { | ||
4741 | ASSERT(mval->br_startblock == mval[-1].br_startblock); | ||
4742 | ASSERT(mval->br_blockcount > mval[-1].br_blockcount); | ||
4743 | ASSERT(mval->br_state == mval[-1].br_state); | ||
4744 | mval[-1].br_blockcount = mval->br_blockcount; | ||
4745 | mval[-1].br_state = mval->br_state; | ||
4746 | } else if (n > 0 && mval->br_startblock != DELAYSTARTBLOCK && | ||
4747 | mval[-1].br_startblock != DELAYSTARTBLOCK && | ||
4748 | mval[-1].br_startblock != HOLESTARTBLOCK && | ||
4749 | mval->br_startblock == | ||
4750 | mval[-1].br_startblock + mval[-1].br_blockcount && | ||
4751 | ((flags & XFS_BMAPI_IGSTATE) || | ||
4752 | mval[-1].br_state == mval->br_state)) { | ||
4753 | ASSERT(mval->br_startoff == | ||
4754 | mval[-1].br_startoff + mval[-1].br_blockcount); | ||
4755 | mval[-1].br_blockcount += mval->br_blockcount; | ||
4756 | } else if (n > 0 && | ||
4757 | mval->br_startblock == DELAYSTARTBLOCK && | ||
4758 | mval[-1].br_startblock == DELAYSTARTBLOCK && | ||
4759 | mval->br_startoff == | ||
4760 | mval[-1].br_startoff + mval[-1].br_blockcount) { | ||
4761 | mval[-1].br_blockcount += mval->br_blockcount; | ||
4762 | mval[-1].br_state = mval->br_state; | ||
4763 | } else if (!((n == 0) && | ||
4764 | ((mval->br_startoff + mval->br_blockcount) <= | ||
4765 | obno))) { | ||
4766 | mval++; | ||
4767 | n++; | ||
4768 | } | ||
4769 | /* | 4802 | /* |
4770 | * If we're done, stop now. Stop when we've allocated | 4803 | * If we're done, stop now. Stop when we've allocated |
4771 | * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise | 4804 | * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise |