diff options
| -rw-r--r-- | fs/xfs/xfs_itable.c | 68 |
1 files changed, 31 insertions, 37 deletions
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 305a9d0436f4..e6dbe6ba6fbd 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
| @@ -325,9 +325,9 @@ xfs_bulkstat( | |||
| 325 | int i; /* loop index */ | 325 | int i; /* loop index */ |
| 326 | int icount; /* count of inodes good in irbuf */ | 326 | int icount; /* count of inodes good in irbuf */ |
| 327 | xfs_ino_t ino; /* inode number (filesystem) */ | 327 | xfs_ino_t ino; /* inode number (filesystem) */ |
| 328 | xfs_inobt_rec_t *irbp; /* current irec buffer pointer */ | 328 | xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */ |
| 329 | xfs_inobt_rec_t *irbuf; /* start of irec buffer */ | 329 | xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ |
| 330 | xfs_inobt_rec_t *irbufend; /* end of good irec buffer entries */ | 330 | xfs_inobt_rec_incore_t *irbufend; /* end of good irec buffer entries */ |
| 331 | xfs_ino_t lastino=0; /* last inode number returned */ | 331 | xfs_ino_t lastino=0; /* last inode number returned */ |
| 332 | int nbcluster; /* # of blocks in a cluster */ | 332 | int nbcluster; /* # of blocks in a cluster */ |
| 333 | int nicluster; /* # of inodes in a cluster */ | 333 | int nicluster; /* # of inodes in a cluster */ |
| @@ -398,7 +398,7 @@ xfs_bulkstat( | |||
| 398 | * Allocate and initialize a btree cursor for ialloc btree. | 398 | * Allocate and initialize a btree cursor for ialloc btree. |
| 399 | */ | 399 | */ |
| 400 | cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO, | 400 | cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO, |
| 401 | (xfs_inode_t *)0, 0); | 401 | (xfs_inode_t *)0, 0); |
| 402 | irbp = irbuf; | 402 | irbp = irbuf; |
| 403 | irbufend = irbuf + nirbuf; | 403 | irbufend = irbuf + nirbuf; |
| 404 | end_of_ag = 0; | 404 | end_of_ag = 0; |
| @@ -435,9 +435,9 @@ xfs_bulkstat( | |||
| 435 | gcnt++; | 435 | gcnt++; |
| 436 | } | 436 | } |
| 437 | gfree |= XFS_INOBT_MASKN(0, chunkidx); | 437 | gfree |= XFS_INOBT_MASKN(0, chunkidx); |
| 438 | irbp->ir_startino = cpu_to_be32(gino); | 438 | irbp->ir_startino = gino; |
| 439 | irbp->ir_freecount = cpu_to_be32(gcnt); | 439 | irbp->ir_freecount = gcnt; |
| 440 | irbp->ir_free = cpu_to_be64(gfree); | 440 | irbp->ir_free = gfree; |
| 441 | irbp++; | 441 | irbp++; |
| 442 | agino = gino + XFS_INODES_PER_CHUNK; | 442 | agino = gino + XFS_INODES_PER_CHUNK; |
| 443 | icount = XFS_INODES_PER_CHUNK - gcnt; | 443 | icount = XFS_INODES_PER_CHUNK - gcnt; |
| @@ -491,11 +491,27 @@ xfs_bulkstat( | |||
| 491 | } | 491 | } |
| 492 | /* | 492 | /* |
| 493 | * If this chunk has any allocated inodes, save it. | 493 | * If this chunk has any allocated inodes, save it. |
| 494 | * Also start read-ahead now for this chunk. | ||
| 494 | */ | 495 | */ |
| 495 | if (gcnt < XFS_INODES_PER_CHUNK) { | 496 | if (gcnt < XFS_INODES_PER_CHUNK) { |
| 496 | irbp->ir_startino = cpu_to_be32(gino); | 497 | /* |
| 497 | irbp->ir_freecount = cpu_to_be32(gcnt); | 498 | * Loop over all clusters in the next chunk. |
| 498 | irbp->ir_free = cpu_to_be64(gfree); | 499 | * Do a readahead if there are any allocated |
| 500 | * inodes in that cluster. | ||
| 501 | */ | ||
| 502 | for (agbno = XFS_AGINO_TO_AGBNO(mp, gino), | ||
| 503 | chunkidx = 0; | ||
| 504 | chunkidx < XFS_INODES_PER_CHUNK; | ||
| 505 | chunkidx += nicluster, | ||
| 506 | agbno += nbcluster) { | ||
| 507 | if (XFS_INOBT_MASKN(chunkidx, | ||
| 508 | nicluster) & ~gfree) | ||
| 509 | xfs_btree_reada_bufs(mp, agno, | ||
| 510 | agbno, nbcluster); | ||
| 511 | } | ||
| 512 | irbp->ir_startino = gino; | ||
| 513 | irbp->ir_freecount = gcnt; | ||
| 514 | irbp->ir_free = gfree; | ||
| 499 | irbp++; | 515 | irbp++; |
| 500 | icount += XFS_INODES_PER_CHUNK - gcnt; | 516 | icount += XFS_INODES_PER_CHUNK - gcnt; |
| 501 | } | 517 | } |
| @@ -519,33 +535,11 @@ xfs_bulkstat( | |||
| 519 | for (irbp = irbuf; | 535 | for (irbp = irbuf; |
| 520 | irbp < irbufend && ubleft >= statstruct_size; irbp++) { | 536 | irbp < irbufend && ubleft >= statstruct_size; irbp++) { |
| 521 | /* | 537 | /* |
| 522 | * Read-ahead the next chunk's worth of inodes. | ||
| 523 | */ | ||
| 524 | if (&irbp[1] < irbufend) { | ||
| 525 | /* | ||
| 526 | * Loop over all clusters in the next chunk. | ||
| 527 | * Do a readahead if there are any allocated | ||
| 528 | * inodes in that cluster. | ||
| 529 | */ | ||
| 530 | for (agbno = XFS_AGINO_TO_AGBNO(mp, | ||
| 531 | be32_to_cpu(irbp[1].ir_startino)), | ||
| 532 | chunkidx = 0; | ||
| 533 | chunkidx < XFS_INODES_PER_CHUNK; | ||
| 534 | chunkidx += nicluster, | ||
| 535 | agbno += nbcluster) { | ||
| 536 | if (XFS_INOBT_MASKN(chunkidx, | ||
| 537 | nicluster) & | ||
| 538 | ~(be64_to_cpu(irbp[1].ir_free))) | ||
| 539 | xfs_btree_reada_bufs(mp, agno, | ||
| 540 | agbno, nbcluster); | ||
| 541 | } | ||
| 542 | } | ||
| 543 | /* | ||
| 544 | * Now process this chunk of inodes. | 538 | * Now process this chunk of inodes. |
| 545 | */ | 539 | */ |
| 546 | for (agino = be32_to_cpu(irbp->ir_startino), chunkidx = 0, clustidx = 0; | 540 | for (agino = irbp->ir_startino, chunkidx = clustidx = 0; |
| 547 | ubleft > 0 && | 541 | ubleft > 0 && |
| 548 | be32_to_cpu(irbp->ir_freecount) < XFS_INODES_PER_CHUNK; | 542 | irbp->ir_freecount < XFS_INODES_PER_CHUNK; |
| 549 | chunkidx++, clustidx++, agino++) { | 543 | chunkidx++, clustidx++, agino++) { |
| 550 | ASSERT(chunkidx < XFS_INODES_PER_CHUNK); | 544 | ASSERT(chunkidx < XFS_INODES_PER_CHUNK); |
| 551 | /* | 545 | /* |
| @@ -565,7 +559,7 @@ xfs_bulkstat( | |||
| 565 | */ | 559 | */ |
| 566 | if ((chunkidx & (nicluster - 1)) == 0) { | 560 | if ((chunkidx & (nicluster - 1)) == 0) { |
| 567 | agbno = XFS_AGINO_TO_AGBNO(mp, | 561 | agbno = XFS_AGINO_TO_AGBNO(mp, |
| 568 | be32_to_cpu(irbp->ir_startino)) + | 562 | irbp->ir_startino) + |
| 569 | ((chunkidx & nimask) >> | 563 | ((chunkidx & nimask) >> |
| 570 | mp->m_sb.sb_inopblog); | 564 | mp->m_sb.sb_inopblog); |
| 571 | 565 | ||
| @@ -605,13 +599,13 @@ xfs_bulkstat( | |||
| 605 | /* | 599 | /* |
| 606 | * Skip if this inode is free. | 600 | * Skip if this inode is free. |
| 607 | */ | 601 | */ |
| 608 | if (XFS_INOBT_MASK(chunkidx) & be64_to_cpu(irbp->ir_free)) | 602 | if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) |
| 609 | continue; | 603 | continue; |
| 610 | /* | 604 | /* |
| 611 | * Count used inodes as free so we can tell | 605 | * Count used inodes as free so we can tell |
| 612 | * when the chunk is used up. | 606 | * when the chunk is used up. |
| 613 | */ | 607 | */ |
| 614 | be32_add(&irbp->ir_freecount, 1); | 608 | irbp->ir_freecount++; |
| 615 | ino = XFS_AGINO_TO_INO(mp, agno, agino); | 609 | ino = XFS_AGINO_TO_INO(mp, agno, agino); |
| 616 | bno = XFS_AGB_TO_DADDR(mp, agno, agbno); | 610 | bno = XFS_AGB_TO_DADDR(mp, agno, agbno); |
| 617 | if (!xfs_bulkstat_use_dinode(mp, flags, bp, | 611 | if (!xfs_bulkstat_use_dinode(mp, flags, bp, |
