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.c104
1 files changed, 97 insertions, 7 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 59f63949d3b..fc5acf0b921 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -4350,6 +4350,98 @@ xfs_bmapi_update_map(
4350} 4350}
4351 4351
4352/* 4352/*
4353 * Map file blocks to filesystem blocks without allocation.
4354 */
4355int
4356xfs_bmapi_read(
4357 struct xfs_inode *ip,
4358 xfs_fileoff_t bno,
4359 xfs_filblks_t len,
4360 struct xfs_bmbt_irec *mval,
4361 int *nmap,
4362 int flags)
4363{
4364 struct xfs_mount *mp = ip->i_mount;
4365 struct xfs_ifork *ifp;
4366 struct xfs_bmbt_irec got;
4367 struct xfs_bmbt_irec prev;
4368 xfs_fileoff_t obno;
4369 xfs_fileoff_t end;
4370 xfs_extnum_t lastx;
4371 int error;
4372 int eof;
4373 int n = 0;
4374 int whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
4375 XFS_ATTR_FORK : XFS_DATA_FORK;
4376
4377 ASSERT(*nmap >= 1);
4378 ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE|
4379 XFS_BMAPI_IGSTATE)));
4380
4381 if (unlikely(XFS_TEST_ERROR(
4382 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
4383 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
4384 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
4385 XFS_ERROR_REPORT("xfs_bmapi_read", XFS_ERRLEVEL_LOW, mp);
4386 return XFS_ERROR(EFSCORRUPTED);
4387 }
4388
4389 if (XFS_FORCED_SHUTDOWN(mp))
4390 return XFS_ERROR(EIO);
4391
4392 XFS_STATS_INC(xs_blk_mapr);
4393
4394 ifp = XFS_IFORK_PTR(ip, whichfork);
4395 ASSERT(ifp->if_ext_max ==
4396 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
4397
4398 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
4399 error = xfs_iread_extents(NULL, ip, whichfork);
4400 if (error)
4401 return error;
4402 }
4403
4404 xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev);
4405 end = bno + len;
4406 obno = bno;
4407
4408 while (bno < end && n < *nmap) {
4409 /* Reading past eof, act as though there's a hole up to end. */
4410 if (eof)
4411 got.br_startoff = end;
4412 if (got.br_startoff > bno) {
4413 /* Reading in a hole. */
4414 mval->br_startoff = bno;
4415 mval->br_startblock = HOLESTARTBLOCK;
4416 mval->br_blockcount =
4417 XFS_FILBLKS_MIN(len, got.br_startoff - bno);
4418 mval->br_state = XFS_EXT_NORM;
4419 bno += mval->br_blockcount;
4420 len -= mval->br_blockcount;
4421 mval++;
4422 n++;
4423 continue;
4424 }
4425
4426 /* set up the extent map to return. */
4427 xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
4428 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
4429
4430 /* If we're done, stop now. */
4431 if (bno >= end || n >= *nmap)
4432 break;
4433
4434 /* Else go on to the next record. */
4435 if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
4436 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got);
4437 else
4438 eof = 1;
4439 }
4440 *nmap = n;
4441 return 0;
4442}
4443
4444/*
4353 * Map file blocks to filesystem blocks. 4445 * Map file blocks to filesystem blocks.
4354 * File range is given by the bno/len pair. 4446 * File range is given by the bno/len pair.
4355 * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) 4447 * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set)
@@ -5490,10 +5582,9 @@ xfs_getbmap(
5490 5582
5491 do { 5583 do {
5492 nmap = (nexleft > subnex) ? subnex : nexleft; 5584 nmap = (nexleft > subnex) ? subnex : nexleft;
5493 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), 5585 error = xfs_bmapi_read(ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
5494 XFS_BB_TO_FSB(mp, bmv->bmv_length), 5586 XFS_BB_TO_FSB(mp, bmv->bmv_length),
5495 bmapi_flags, NULL, 0, map, &nmap, 5587 map, &nmap, bmapi_flags);
5496 NULL);
5497 if (error) 5588 if (error)
5498 goto out_free_map; 5589 goto out_free_map;
5499 ASSERT(nmap <= subnex); 5590 ASSERT(nmap <= subnex);
@@ -6084,9 +6175,8 @@ xfs_bmap_punch_delalloc_range(
6084 * trying to remove a real extent (which requires a 6175 * trying to remove a real extent (which requires a
6085 * transaction) or a hole, which is probably a bad idea... 6176 * transaction) or a hole, which is probably a bad idea...
6086 */ 6177 */
6087 error = xfs_bmapi(NULL, ip, start_fsb, 1, 6178 error = xfs_bmapi_read(ip, start_fsb, 1, &imap, &nimaps,
6088 XFS_BMAPI_ENTIRE, NULL, 0, &imap, 6179 XFS_BMAPI_ENTIRE);
6089 &nimaps, NULL);
6090 6180
6091 if (error) { 6181 if (error) {
6092 /* something screwed, just bail */ 6182 /* something screwed, just bail */